about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock15
-rw-r--r--RELEASES.md2
-rw-r--r--compiler/rustc_arena/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/lib.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/block.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/delegation.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/errors.rs14
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs18
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs43
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs104
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs97
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs17
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs18
-rw-r--r--compiler/rustc_ast_passes/src/lib.rs2
-rw-r--r--compiler/rustc_ast_pretty/src/lib.rs2
-rw-r--r--compiler/rustc_attr/src/lib.rs2
-rw-r--r--compiler/rustc_borrowck/src/borrow_set.rs2
-rw-r--r--compiler/rustc_borrowck/src/borrowck_errors.rs3
-rw-r--r--compiler/rustc_borrowck/src/constraints/mod.rs3
-rw-r--r--compiler/rustc_borrowck/src/consumers.rs2
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs2
-rw-r--r--compiler/rustc_borrowck/src/def_use.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs124
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs5
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/find_use.rs3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/move_errors.rs3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs17
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs5
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs61
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/var_name.rs3
-rw-r--r--compiler/rustc_borrowck/src/facts.rs2
-rw-r--r--compiler/rustc_borrowck/src/lib.rs9
-rw-r--r--compiler/rustc_borrowck/src/location.rs2
-rw-r--r--compiler/rustc_borrowck/src/member_constraints.rs2
-rw-r--r--compiler/rustc_borrowck/src/nll.rs4
-rw-r--r--compiler/rustc_borrowck/src/path_utils.rs2
-rw-r--r--compiler/rustc_borrowck/src/place_ext.rs2
-rw-r--r--compiler/rustc_borrowck/src/places_conflict.rs2
-rw-r--r--compiler/rustc_borrowck/src/polonius/loan_invalidations.rs2
-rw-r--r--compiler/rustc_borrowck/src/polonius/loan_kills.rs2
-rw-r--r--compiler/rustc_borrowck/src/prefixes.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/dump_mir.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/graphviz.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs41
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs2
-rw-r--r--compiler/rustc_borrowck/src/region_infer/values.rs2
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs118
-rw-r--r--compiler/rustc_borrowck/src/type_check/free_region_relations.rs69
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs10
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs3
-rw-r--r--compiler/rustc_borrowck/src/used_muts.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/errors.rs12
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/attributes.rs3
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/messages.ftl2
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs16
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs25
-rw-r--r--compiler/rustc_codegen_ssa/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs7
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs116
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs20
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs5
-rw-r--r--compiler/rustc_const_eval/src/lib.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs34
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs32
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs4
-rw-r--r--compiler/rustc_data_structures/Cargo.toml2
-rw-r--r--compiler/rustc_data_structures/src/jobserver.rs5
-rw-r--r--compiler/rustc_data_structures/src/lib.rs2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs17
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0724.md7
-rw-r--r--compiler/rustc_error_codes/src/lib.rs2
-rw-r--r--compiler/rustc_error_messages/src/lib.rs4
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs22
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs27
-rw-r--r--compiler/rustc_errors/src/diagnostic_builder.rs16
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs4
-rw-r--r--compiler/rustc_errors/src/emitter.rs42
-rw-r--r--compiler/rustc_errors/src/json.rs52
-rw-r--r--compiler/rustc_errors/src/lib.rs335
-rw-r--r--compiler/rustc_expand/src/base.rs2
-rw-r--r--compiler/rustc_expand/src/lib.rs2
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs3
-rw-r--r--compiler/rustc_feature/src/lib.rs2
-rw-r--r--compiler/rustc_feature/src/removed.rs5
-rw-r--r--compiler/rustc_feature/src/unstable.rs10
-rw-r--r--compiler/rustc_fluent_macro/src/lib.rs2
-rw-r--r--compiler/rustc_fs_util/src/lib.rs2
-rw-r--r--compiler/rustc_graphviz/src/lib.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs38
-rw-r--r--compiler/rustc_hir/src/intravisit.rs7
-rw-r--r--compiler/rustc_hir/src/lib.rs2
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl7
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs51
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs34
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs92
-rw-r--r--compiler/rustc_hir_analysis/src/check/entry.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs18
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/structured_errors/wrong_number_of_generic_args.rs3
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs116
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs49
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs22
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs30
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs76
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/mem_categorization.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs77
-rw-r--r--compiler/rustc_hir_typeck/src/rvalue_scopes.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs14
-rw-r--r--compiler/rustc_incremental/src/lib.rs2
-rw-r--r--compiler/rustc_index/src/lib.rs2
-rw-r--r--compiler/rustc_index_macros/src/lib.rs14
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs47
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs7
-rw-r--r--compiler/rustc_infer/src/infer/at.rs1
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs2
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs8
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs9
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs9
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs83
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs3
-rw-r--r--compiler/rustc_infer/src/infer/outlives/mod.rs13
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs80
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs43
-rw-r--r--compiler/rustc_infer/src/infer/relate/higher_ranked.rs64
-rw-r--r--compiler/rustc_infer/src/infer/relate/nll.rs97
-rw-r--r--compiler/rustc_infer/src/infer/resolve.rs9
-rw-r--r--compiler/rustc_infer/src/lib.rs2
-rw-r--r--compiler/rustc_infer/src/traits/error_reporting/mod.rs3
-rw-r--r--compiler/rustc_interface/src/lib.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs4
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lexer/src/lib.rs3
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs50
-rw-r--r--compiler/rustc_lint/src/errors.rs7
-rw-r--r--compiler/rustc_lint/src/internal.rs4
-rw-r--r--compiler/rustc_lint/src/late.rs9
-rw-r--r--compiler/rustc_lint/src/lib.rs9
-rw-r--r--compiler/rustc_lint/src/lints.rs50
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs181
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs51
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h1
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp2
-rw-r--r--compiler/rustc_llvm/src/lib.rs2
-rw-r--r--compiler/rustc_log/src/lib.rs3
-rw-r--r--compiler/rustc_macros/src/diagnostics/subdiagnostic.rs5
-rw-r--r--compiler/rustc_macros/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/creader.rs15
-rw-r--r--compiler/rustc_metadata/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs7
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs15
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs14
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs133
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs7
-rw-r--r--compiler/rustc_middle/src/infer/unify_key.rs42
-rw-r--r--compiler/rustc_middle/src/lib.rs7
-rw-r--r--compiler/rustc_middle/src/middle/codegen_fn_attrs.rs23
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs8
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs1
-rw-r--r--compiler/rustc_middle/src/mir/query.rs3
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs2
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs1
-rw-r--r--compiler/rustc_middle/src/thir.rs1
-rw-r--r--compiler/rustc_middle/src/traits/util.rs54
-rw-r--r--compiler/rustc_middle/src/ty/_match.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs2
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs4
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs9
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs60
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs50
-rw-r--r--compiler/rustc_middle/src/util/common.rs16
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs110
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs37
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs12
-rw-r--r--compiler/rustc_mir_build/src/errors.rs12
-rw-r--r--compiler/rustc_mir_build/src/lib.rs3
-rw-r--r--compiler/rustc_mir_build/src/lints.rs11
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs113
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs18
-rw-r--r--compiler/rustc_mir_dataflow/src/lib.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs5
-rw-r--r--compiler/rustc_mir_transform/src/abort_unwinding_calls.rs1
-rw-r--r--compiler/rustc_mir_transform/src/const_prop_lint.rs10
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs7
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs70
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs89
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs1
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs5
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs25
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs25
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs2
-rw-r--r--compiler/rustc_mir_transform/src/lower_intrinsics.rs11
-rw-r--r--compiler/rustc_mir_transform/src/pass_manager.rs12
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs1
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs2
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs2
-rw-r--r--compiler/rustc_parse/src/errors.rs9
-rw-r--r--compiler/rustc_parse/src/lib.rs4
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs12
-rw-r--r--compiler/rustc_parse_format/src/lib.rs2
-rw-r--r--compiler/rustc_passes/messages.ftl3
-rw-r--r--compiler/rustc_passes/src/check_attr.rs23
-rw-r--r--compiler/rustc_passes/src/dead.rs91
-rw-r--r--compiler/rustc_passes/src/errors.rs14
-rw-r--r--compiler/rustc_passes/src/lib.rs2
-rw-r--r--compiler/rustc_passes/src/liveness.rs10
-rw-r--r--compiler/rustc_passes/src/loops.rs4
-rw-r--r--compiler/rustc_pattern_analysis/src/errors.rs12
-rw-r--r--compiler/rustc_pattern_analysis/src/lib.rs11
-rw-r--r--compiler/rustc_pattern_analysis/src/lints.rs2
-rw-r--r--compiler/rustc_pattern_analysis/src/pat.rs32
-rw-r--r--compiler/rustc_pattern_analysis/src/pat_column.rs4
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs69
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs107
-rw-r--r--compiler/rustc_privacy/Cargo.toml1
-rw-r--r--compiler/rustc_privacy/src/lib.rs113
-rw-r--r--compiler/rustc_query_impl/src/lib.rs2
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs5
-rw-r--r--compiler/rustc_query_system/src/lib.rs2
-rw-r--r--compiler/rustc_resolve/messages.ftl17
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs10
-rw-r--r--compiler/rustc_resolve/src/errors.rs25
-rw-r--r--compiler/rustc_resolve/src/ident.rs30
-rw-r--r--compiler/rustc_resolve/src/late.rs76
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs38
-rw-r--r--compiler/rustc_resolve/src/lib.rs9
-rw-r--r--compiler/rustc_serialize/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_session/src/session.rs9
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs1
-rw-r--r--compiler/rustc_span/src/lib.rs9
-rw-r--r--compiler/rustc_span/src/source_map/tests.rs49
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs2
-rw-r--r--compiler/rustc_target/src/lib.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs12
-rw-r--r--compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs35
-rw-r--r--compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs1
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs7
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
-rw-r--r--compiler/rustc_trait_selection/src/regions.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs191
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs57
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs17
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs183
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs19
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs29
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs11
-rw-r--r--compiler/rustc_trait_selection/src/traits/auto_trait.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs87
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/on_unimplemented.rs53
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs188
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs157
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs100
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs23
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs149
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs39
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs104
-rw-r--r--compiler/rustc_traits/src/lib.rs2
-rw-r--r--compiler/rustc_transmute/src/lib.rs2
-rw-r--r--compiler/rustc_ty_utils/src/lib.rs4
-rw-r--r--compiler/rustc_ty_utils/src/representability.rs2
-rw-r--r--compiler/rustc_ty_utils/src/sig_types.rs28
-rw-r--r--compiler/rustc_type_ir/src/lib.rs2
-rw-r--r--compiler/rustc_type_ir/src/region_kind.rs3
-rw-r--r--compiler/stable_mir/src/mir/body.rs3
-rw-r--r--library/alloc/src/raw_vec.rs13
-rw-r--r--library/alloc/src/slice.rs2
-rw-r--r--library/alloc/src/vec/cow.rs2
-rw-r--r--library/alloc/src/vec/into_iter.rs2
-rw-r--r--library/alloc/src/vec/mod.rs6
-rw-r--r--library/core/src/array/mod.rs4
-rw-r--r--library/core/src/async_iter/async_iter.rs4
-rw-r--r--library/core/src/char/convert.rs2
-rw-r--r--library/core/src/hint.rs2
-rw-r--r--library/core/src/intrinsics.rs147
-rw-r--r--library/core/src/intrinsics/mir.rs2
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/marker.rs89
-rw-r--r--library/core/src/mem/mod.rs12
-rw-r--r--library/core/src/net/mod.rs2
-rw-r--r--library/core/src/num/nonzero.rs190
-rw-r--r--library/core/src/ops/arith.rs4
-rw-r--r--library/core/src/ops/async_function.rs6
-rw-r--r--library/core/src/ops/coroutine.rs2
-rw-r--r--library/core/src/ops/range.rs2
-rw-r--r--library/core/src/option.rs17
-rw-r--r--library/core/src/primitive_docs.rs36
-rw-r--r--library/core/src/ptr/const_ptr.rs12
-rw-r--r--library/core/src/ptr/mod.rs52
-rw-r--r--library/core/src/ptr/mut_ptr.rs8
-rw-r--r--library/core/src/ptr/non_null.rs17
-rw-r--r--library/core/src/ptr/unique.rs9
-rw-r--r--library/core/src/result.rs8
-rw-r--r--library/core/src/slice/iter.rs39
-rw-r--r--library/core/src/slice/mod.rs33
-rw-r--r--library/core/src/slice/raw.rs21
-rw-r--r--library/core/src/time.rs19
-rw-r--r--library/core/src/tuple.rs8
-rw-r--r--library/core/tests/lib.rs5
-rw-r--r--library/core/tests/macros.rs1
-rw-r--r--library/panic_unwind/src/seh.rs4
-rw-r--r--library/proc_macro/src/bridge/client.rs9
-rw-r--r--library/proc_macro/src/bridge/handle.rs10
-rw-r--r--library/proc_macro/src/bridge/mod.rs1
-rw-r--r--library/std/src/f32.rs2
-rw-r--r--library/std/src/f64.rs2
-rw-r--r--library/std/src/fs.rs2
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/panicking.rs2
-rw-r--r--library/std/src/sync/mutex.rs2
-rw-r--r--library/std/src/sync/rwlock.rs2
-rw-r--r--library/std/src/sys/mod.rs1
-rw-r--r--library/std/src/sys/pal/common/thread_local/fast_local.rs2
-rw-r--r--library/std/src/sys/pal/common/thread_local/static_local.rs2
-rw-r--r--library/std/src/sys/pal/hermit/mod.rs2
-rw-r--r--library/std/src/sys/pal/sgx/mod.rs1
-rw-r--r--library/std/src/sys/pal/solid/mod.rs1
-rw-r--r--library/std/src/sys/pal/teeos/mod.rs2
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs8
-rw-r--r--library/std/src/sys/pal/uefi/mod.rs2
-rw-r--r--library/std/src/sys/pal/uefi/path.rs25
-rw-r--r--library/std/src/sys/pal/uefi/tests.rs20
-rw-r--r--library/std/src/sys/pal/uefi/time.rs105
-rw-r--r--library/std/src/sys/pal/unix/locks/pthread_mutex.rs19
-rw-r--r--library/std/src/sys/pal/unix/mod.rs1
-rw-r--r--library/std/src/sys/pal/unix/thread_local_dtor.rs1
-rw-r--r--library/std/src/sys/pal/unsupported/mod.rs2
-rw-r--r--library/std/src/sys/pal/wasi/mod.rs2
-rw-r--r--library/std/src/sys/pal/wasm/mod.rs2
-rw-r--r--library/std/src/sys/pal/windows/fs.rs2
-rw-r--r--library/std/src/sys/pal/windows/mod.rs5
-rw-r--r--library/std/src/sys/pal/xous/mod.rs2
-rw-r--r--library/std/src/sys/pal/zkvm/mod.rs4
-rw-r--r--library/std/src/sys/path/mod.rs18
-rw-r--r--library/std/src/sys/path/sgx.rs (renamed from library/std/src/sys/pal/sgx/path.rs)0
-rw-r--r--library/std/src/sys/path/unix.rs (renamed from library/std/src/sys/pal/unix/path.rs)0
-rw-r--r--library/std/src/sys/path/unsupported_backslash.rs (renamed from library/std/src/sys/pal/solid/path.rs)0
-rw-r--r--library/std/src/sys/path/windows.rs (renamed from library/std/src/sys/pal/windows/path.rs)4
-rw-r--r--library/std/src/sys/path/windows/tests.rs (renamed from library/std/src/sys/pal/windows/path/tests.rs)0
-rw-r--r--library/std/src/sys_common/mod.rs2
-rw-r--r--library/std/src/thread/local.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs36
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs116
-rw-r--r--src/bootstrap/src/core/builder.rs260
-rw-r--r--src/bootstrap/src/core/builder/tests.rs17
-rw-r--r--src/bootstrap/src/core/download.rs6
-rw-r--r--src/bootstrap/src/lib.rs12
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh2
-rwxr-xr-xsrc/ci/docker/run.sh7
-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/arm-none-eabi.md1
-rw-r--r--src/doc/rustc/src/platform-support/armv8r-none-eabihf.md40
-rw-r--r--src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md16
-rw-r--r--src/librustdoc/clean/inline.rs27
-rw-r--r--src/librustdoc/clean/mod.rs2
-rw-r--r--src/librustdoc/config.rs96
-rw-r--r--src/librustdoc/formats/item_type.rs37
-rw-r--r--src/librustdoc/html/format.rs194
-rw-r--r--src/librustdoc/html/render/span_map.rs4
-rw-r--r--src/librustdoc/lib.rs43
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs2
-rw-r--r--src/librustdoc/passes/lint/redundant_explicit_links.rs49
-rw-r--r--src/librustdoc/scrape_examples.rs49
-rw-r--r--src/stage0.json824
-rw-r--r--src/tools/build-manifest/src/main.rs1
m---------src/tools/cargo0
-rwxr-xr-x[-rw-r--r--]src/tools/clippy/.github/driver.sh15
-rw-r--r--src/tools/clippy/CHANGELOG.md66
-rw-r--r--src/tools/clippy/Cargo.toml2
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md33
-rw-r--r--src/tools/clippy/clippy_config/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs22
-rw-r--r--src/tools/clippy/clippy_config/src/lib.rs4
-rw-r--r--src/tools/clippy/clippy_config/src/msrvs.rs13
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/src/absolute_paths.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs168
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/mod.rs43
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/empty_drop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs50
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/incompatible_msrv.rs133
-rw-r--r--src/tools/clippy/clippy_lints/src/index_refutable_slice.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/same_item_push.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs141
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_next.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs197
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs65
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs95
-rw-r--r--src/tools/clippy/clippy_lints/src/min_ident_chars.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/mod.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs27
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs31
-rw-r--r--src/tools/clippy/clippy_lints/src/same_name_method.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/self_named_constructors.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs67
-rw-r--r--src/tools/clippy/clippy_lints/src/unconditional_recursion.rs86
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_io_amount.rs101
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/wildcard_imports.rs16
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs377
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs29
-rw-r--r--src/tools/clippy/declare_clippy_lint/Cargo.toml2
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/src/driver.rs27
-rw-r--r--src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr45
-rw-r--r--src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.toml20
-rw-r--r--src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/src/lib.rs1
-rw-r--r--src/tools/clippy/tests/ui-cargo/lint_groups_priority/pass/Cargo.toml10
-rw-r--r--src/tools/clippy/tests/ui-cargo/lint_groups_priority/pass/src/lib.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.fixed2
-rw-r--r--src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/modulo_arithmetic/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs10
-rw-r--r--src/tools/clippy/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.stderr40
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr6
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml3
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed19
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs19
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr20
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.fixed26
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs26
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.stderr11
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.fixed1
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.rs1
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr.stderr4
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed1
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs1
-rw-r--r--src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr4
-rw-r--r--src/tools/clippy/tests/ui/eta.fixed71
-rw-r--r--src/tools/clippy/tests/ui/eta.rs71
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr28
-rw-r--r--src/tools/clippy/tests/ui/format_args.fixed1
-rw-r--r--src/tools/clippy/tests/ui/format_args.rs1
-rw-r--r--src/tools/clippy/tests/ui/format_args.stderr50
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.fixed7
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.rs7
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.stderr18
-rw-r--r--src/tools/clippy/tests/ui/incompatible_msrv.rs23
-rw-r--r--src/tools/clippy/tests/ui/incompatible_msrv.stderr23
-rw-r--r--src/tools/clippy/tests/ui/manual_c_str_literals.fixed60
-rw-r--r--src/tools/clippy/tests/ui/manual_c_str_literals.rs60
-rw-r--r--src/tools/clippy/tests/ui/manual_c_str_literals.stderr83
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.fixed63
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.rs63
-rw-r--r--src/tools/clippy/tests/ui/manual_retain.stderr142
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs8
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.fixed3
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr20
-rw-r--r--src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed50
-rw-r--r--src/tools/clippy/tests/ui/needless_return_with_question_mark.rs50
-rw-r--r--src/tools/clippy/tests/ui/never_loop.rs11
-rw-r--r--src/tools/clippy/tests/ui/nonminimal_bool.rs11
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed9
-rw-r--r--src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs9
-rw-r--r--src/tools/clippy/tests/ui/redundant_locals.rs46
-rw-r--r--src/tools/clippy/tests/ui/redundant_locals.stderr56
-rw-r--r--src/tools/clippy/tests/ui/redundant_type_annotations.rs7
-rw-r--r--src/tools/clippy/tests/ui/redundant_type_annotations.stderr4
-rw-r--r--src/tools/clippy/tests/ui/ref_as_ptr.fixed110
-rw-r--r--src/tools/clippy/tests/ui/ref_as_ptr.rs110
-rw-r--r--src/tools/clippy/tests/ui/ref_as_ptr.stderr269
-rw-r--r--src/tools/clippy/tests/ui/strlen_on_c_strings.fixed2
-rw-r--r--src/tools/clippy/tests/ui/strlen_on_c_strings.rs2
-rw-r--r--src/tools/clippy/tests/ui/to_string_trait_impl.rs31
-rw-r--r--src/tools/clippy/tests/ui/to_string_trait_impl.stderr16
-rw-r--r--src/tools/clippy/tests/ui/unconditional_recursion.rs62
-rw-r--r--src/tools/clippy/tests/ui/unconditional_recursion.stderr14
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_fold.fixed6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_fold.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_fold.stderr41
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.fixed7
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.rs7
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_result_map_or_else.fixed61
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_result_map_or_else.rs69
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_result_map_or_else.stderr35
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed3
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs3
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.stderr170
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.fixed1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.rs1
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.stderr18
-rw-r--r--src/tools/clippy/tests/ui/unused_io_amount.rs43
-rw-r--r--src/tools/clippy/tests/ui/unused_io_amount.stderr8
-rw-r--r--src/tools/clippy/tests/ui/while_let_on_iterator.fixed16
-rw-r--r--src/tools/clippy/tests/ui/while_let_on_iterator.rs14
-rw-r--r--src/tools/clippy/tests/ui/while_let_on_iterator.stderr12
-rw-r--r--src/tools/compiletest/src/runtest.rs1
-rw-r--r--src/tools/coverage-dump/src/covfun.rs2
-rw-r--r--src/tools/miri/src/bin/miri.rs4
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs2
-rw-r--r--src/tools/miri/src/lib.rs6
-rw-r--r--src/tools/miri/src/machine.rs34
-rw-r--r--src/tools/miri/src/provenance_gc.rs1
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs12
-rw-r--r--src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs1
-rw-r--r--src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs6
-rw-r--r--src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs12
-rw-r--r--src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr14
-rw-r--r--src/tools/miri/tests/pass/align_offset_symbolic.rs23
-rw-r--r--src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs1
-rw-r--r--src/tools/miri/tests/pass/dyn-upcast.rs3
-rw-r--r--src/tools/miri/tests/pass/weak_memory/weak.rs1
-rw-r--r--src/tools/rustfmt/src/parse/session.rs20
-rw-r--r--src/tools/tidy/src/ui_tests.rs3
-rw-r--r--tests/assembly/is_aligned.rs4
-rw-r--r--tests/assembly/targets/targets-elf.rs3
-rw-r--r--tests/codegen-units/item-collection/instantiation-through-vtable.rs4
-rw-r--r--tests/codegen-units/item-collection/trait-method-default-impl.rs3
-rw-r--r--tests/codegen-units/item-collection/unsizing.rs2
-rw-r--r--tests/codegen/async-closure-debug.rs21
-rw-r--r--tests/codegen/cffi/ffi-returns-twice.rs11
-rw-r--r--tests/codegen/direct-access-external-data.rs21
-rw-r--r--tests/incremental/const-generics/issue-62536.rs3
-rw-r--r--tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-1.rs2
-rw-r--r--tests/incremental/struct_change_field_name.rs1
-rw-r--r--tests/mir-opt/async_closure_shims.rs2
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff60
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff68
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff60
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff68
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff63
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff71
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff63
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff71
-rw-r--r--tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff6
-rw-r--r--tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff6
-rw-r--r--tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff6
-rw-r--r--tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff12
-rw-r--r--tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff48
-rw-r--r--tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff6
-rw-r--r--tests/mir-opt/fn_ptr_shim.rs2
-rw-r--r--tests/mir-opt/gvn_copy_moves.fn0.GVN.diff27
-rw-r--r--tests/mir-opt/gvn_copy_moves.rs46
-rw-r--r--tests/mir-opt/inline/cycle.g.Inline.panic-abort.diff21
-rw-r--r--tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff29
-rw-r--r--tests/mir-opt/inline/cycle.rs4
-rw-r--r--tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff6
-rw-r--r--tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff6
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.rs2
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff39
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff51
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir34
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir34
-rw-r--r--tests/mir-opt/issue_99325.main.built.after.32bit.mir4
-rw-r--r--tests/mir-opt/issue_99325.main.built.after.64bit.mir4
-rw-r--r--tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir22
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.panic-abort.mir (renamed from tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir)0
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.panic-unwind.mir16
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir66
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir33
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir33
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.rs3
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir240
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir240
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir216
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir216
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir244
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir244
-rw-r--r--tests/mir-opt/remove_storage_markers.rs5
-rw-r--r--tests/mir-opt/retag.rs2
-rw-r--r--tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff6
-rw-r--r--tests/mir-opt/simplify_if.rs5
-rw-r--r--tests/mir-opt/slice_drop_shim.rs6
-rw-r--r--tests/mir-opt/sroa/lifetimes.rs5
-rw-r--r--tests/mir-opt/sroa/structs.rs125
-rw-r--r--tests/mir-opt/unusual_item_types.rs2
-rw-r--r--tests/rustdoc-ui/issues/issue-102986.stderr4
-rw-r--r--tests/rustdoc-ui/issues/issue-120444-1.rs17
-rw-r--r--tests/rustdoc-ui/issues/issue-120444-1.stderr22
-rw-r--r--tests/rustdoc-ui/issues/issue-120444-2.rs17
-rw-r--r--tests/rustdoc-ui/issues/issue-120444-2.stderr22
-rw-r--r--tests/rustdoc/jump-to-non-local-method.rs48
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.rs11
-rw-r--r--tests/ui-fulldeps/internal-lints/diagnostics.stderr8
-rw-r--r--tests/ui-fulldeps/rustc_encodable_hygiene.rs2
-rw-r--r--tests/ui/anon-params/anon-params-deprecated.fixed1
-rw-r--r--tests/ui/anon-params/anon-params-deprecated.rs1
-rw-r--r--tests/ui/anon-params/anon-params-deprecated.stderr6
-rw-r--r--tests/ui/asm/bad-template.aarch64.stderr52
-rw-r--r--tests/ui/asm/bad-template.rs3
-rw-r--r--tests/ui/asm/bad-template.x86_64.stderr52
-rw-r--r--tests/ui/asm/naked-functions.rs16
-rw-r--r--tests/ui/asm/naked-functions.stderr78
-rw-r--r--tests/ui/associated-consts/associated-const-outer-ty-refs.rs3
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameters.rs2
-rw-r--r--tests/ui/associated-consts/associated-const-type-parameters.stderr10
-rw-r--r--tests/ui/associated-consts/issue-105330.rs1
-rw-r--r--tests/ui/associated-consts/issue-105330.stderr12
-rw-r--r--tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs32
-rw-r--r--tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr39
-rw-r--r--tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs5
-rw-r--r--tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr26
-rw-r--r--tests/ui/associated-type-bounds/duplicate.rs3
-rw-r--r--tests/ui/associated-type-bounds/duplicate.stderr50
-rw-r--r--tests/ui/associated-type-bounds/dyn-impl-trait-type.rs2
-rw-r--r--tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr12
-rw-r--r--tests/ui/associated-type-bounds/dyn-rpit-and-let.rs2
-rw-r--r--tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr12
-rw-r--r--tests/ui/associated-type-bounds/higher-ranked.rs17
-rw-r--r--tests/ui/associated-type-bounds/nested-bounds-dont-eliminate-alias-bounds.rs37
-rw-r--r--tests/ui/associated-type-bounds/rpit.rs2
-rw-r--r--tests/ui/associated-type-bounds/rpit.stderr12
-rw-r--r--tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.fixed1
-rw-r--r--tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.rs1
-rw-r--r--tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr2
-rw-r--r--tests/ui/associated-type-bounds/trait-alias-impl-trait.rs1
-rw-r--r--tests/ui/associated-types/associated-types-eq-hr.rs10
-rw-r--r--tests/ui/associated-types/associated-types-eq-hr.stderr111
-rw-r--r--tests/ui/associated-types/associated-types-for-unimpl-trait.fixed1
-rw-r--r--tests/ui/associated-types/associated-types-for-unimpl-trait.rs1
-rw-r--r--tests/ui/associated-types/associated-types-for-unimpl-trait.stderr2
-rw-r--r--tests/ui/associated-types/associated-types-in-bound-type-arg.rs2
-rw-r--r--tests/ui/associated-types/associated-types-issue-20220.rs2
-rw-r--r--tests/ui/associated-types/associated-types-issue-20220.stderr10
-rw-r--r--tests/ui/associated-types/associated-types-issue-20371.rs2
-rw-r--r--tests/ui/associated-types/associated-types-nested-projections.rs2
-rw-r--r--tests/ui/associated-types/associated-types-nested-projections.stderr13
-rw-r--r--tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs2
-rw-r--r--tests/ui/associated-types/associated-types-normalize-in-bounds.rs2
-rw-r--r--tests/ui/associated-types/associated-types-projection-bound-in-supertraits.rs2
-rw-r--r--tests/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs2
-rw-r--r--tests/ui/associated-types/associated-types-projection-from-known-type-in-impl.stderr13
-rw-r--r--tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed1
-rw-r--r--tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs1
-rw-r--r--tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr2
-rw-r--r--tests/ui/associated-types/associated-types-projection-to-unrelated-trait.rs2
-rw-r--r--tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs2
-rw-r--r--tests/ui/associated-types/associated-types-resolve-lifetime.rs2
-rw-r--r--tests/ui/associated-types/hr-associated-type-bound-object.stderr4
-rw-r--r--tests/ui/associated-types/impl-wf-cycle-5.fixed2
-rw-r--r--tests/ui/associated-types/impl-wf-cycle-5.rs2
-rw-r--r--tests/ui/associated-types/impl-wf-cycle-5.stderr4
-rw-r--r--tests/ui/associated-types/impl-wf-cycle-6.fixed2
-rw-r--r--tests/ui/associated-types/impl-wf-cycle-6.rs2
-rw-r--r--tests/ui/associated-types/impl-wf-cycle-6.stderr4
-rw-r--r--tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs9
-rw-r--r--tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs9
-rw-r--r--tests/ui/async-await/async-closures/auxiliary/block-on.rs2
-rw-r--r--tests/ui/async-await/async-closures/brand.rs5
-rw-r--r--tests/ui/async-await/async-closures/drop.rs6
-rw-r--r--tests/ui/async-await/async-closures/mangle.rs7
-rw-r--r--tests/ui/async-await/async-closures/tainted-body.rs13
-rw-r--r--tests/ui/async-await/async-closures/tainted-body.stderr9
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.rs8
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.stderr10
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed.rs7
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr21
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-manual.rs9
-rw-r--r--tests/ui/async-await/in-trait/async-example-desugared-manual.stderr21
-rw-r--r--tests/ui/async-await/in-trait/auxiliary/bad-region.rs7
-rw-r--r--tests/ui/async-await/in-trait/bad-region.rs17
-rw-r--r--tests/ui/async-await/in-trait/bad-region.stderr14
-rw-r--r--tests/ui/async-await/in-trait/coherence-constrained.rs2
-rw-r--r--tests/ui/async-await/in-trait/coherence-constrained.stderr19
-rw-r--r--tests/ui/async-await/in-trait/fn-not-async-err.rs2
-rw-r--r--tests/ui/async-await/in-trait/fn-not-async-err.stderr11
-rw-r--r--tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2015.stderr (renamed from tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr)0
-rw-r--r--tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2018.stderr (renamed from tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr)0
-rw-r--r--tests/ui/async-await/issue-65634-raw-ident-suggestion.rs (renamed from tests/ui/issues/issue-65634-raw-ident-suggestion.rs)0
-rw-r--r--tests/ui/async-await/issue-70935-complex-spans.rs1
-rw-r--r--tests/ui/async-await/issue-70935-complex-spans.stderr47
-rw-r--r--tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr28
-rw-r--r--tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr2
-rw-r--r--tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs5
-rw-r--r--tests/ui/auto-traits/auto-trait-validation.fixed1
-rw-r--r--tests/ui/auto-traits/auto-trait-validation.rs1
-rw-r--r--tests/ui/auto-traits/auto-trait-validation.stderr8
-rw-r--r--tests/ui/auto-traits/auto-traits.rs4
-rw-r--r--tests/ui/auto-traits/auto-traits.stderr16
-rw-r--r--tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs1
-rw-r--r--tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr19
-rw-r--r--tests/ui/binding/irrefutable-if-let-without-else.fixed25
-rw-r--r--tests/ui/binding/irrefutable-if-let-without-else.rs28
-rw-r--r--tests/ui/binding/irrefutable-if-let-without-else.stderr61
-rw-r--r--tests/ui/binop/issue-62375.rs (renamed from tests/ui/issues/issue-62375.rs)0
-rw-r--r--tests/ui/binop/issue-62375.stderr (renamed from tests/ui/issues/issue-62375.stderr)0
-rw-r--r--tests/ui/binop/issue-77910-1.rs2
-rw-r--r--tests/ui/binop/issue-77910-1.stderr17
-rw-r--r--tests/ui/binop/issue-77910-2.rs2
-rw-r--r--tests/ui/binop/issue-77910-2.stderr18
-rw-r--r--tests/ui/box/unit/unique-object-noncopyable.stderr3
-rw-r--r--tests/ui/box/unit/unique-pinned-nocopy.stderr3
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-in-metadata2.rs2
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs2
-rw-r--r--tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs2
-rw-r--r--tests/ui/cast/cast-rfc0401-vtable-kinds.rs2
-rw-r--r--tests/ui/cast/cast-rfc0401-vtable-kinds.stderr10
-rw-r--r--tests/ui/cast/enum-to-numeric-cast.rs46
-rw-r--r--tests/ui/cast/enum-to-numeric-cast.stderr35
-rw-r--r--tests/ui/cast/fat-ptr-cast-rpass.rs2
-rw-r--r--tests/ui/cast/fat-ptr-cast-rpass.stderr12
-rw-r--r--tests/ui/cast/issue-88621.stderr4
-rw-r--r--tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs12
-rw-r--r--tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr13
-rw-r--r--tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs12
-rw-r--r--tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr21
-rw-r--r--tests/ui/check-cfg/cfg-value-for-cfg-name.rs18
-rw-r--r--tests/ui/check-cfg/cfg-value-for-cfg-name.stderr22
-rw-r--r--tests/ui/class-cast-to-trait.rs8
-rw-r--r--tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs2
-rw-r--r--tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr13
-rw-r--r--tests/ui/closures/2229_closure_analysis/run_pass/multivariant.min_exhaustive_patterns.stderr11
-rw-r--r--tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs5
-rw-r--r--tests/ui/closures/binder/implicit-stuff.rs1
-rw-r--r--tests/ui/closures/binder/implicit-stuff.stderr11
-rw-r--r--tests/ui/closures/issue-109188.rs4
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs7
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr2
-rw-r--r--tests/ui/codegen/issue-82833-slice-miscompile.rs (renamed from tests/ui/issues/issue-82833-slice-miscompile.rs)0
-rw-r--r--tests/ui/coercion/issue-14589.rs2
-rw-r--r--tests/ui/coercion/issue-14589.stderr12
-rw-r--r--tests/ui/coercion/issue-26905-rpass.rs (renamed from tests/ui/issues/issue-26905-rpass.rs)0
-rw-r--r--tests/ui/coercion/issue-26905.rs (renamed from tests/ui/issues/issue-26905.rs)0
-rw-r--r--tests/ui/coercion/issue-26905.stderr (renamed from tests/ui/issues/issue-26905.stderr)0
-rw-r--r--tests/ui/coherence/associated-type2.rs20
-rw-r--r--tests/ui/coherence/associated-type2.stderr12
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs1
-rw-r--r--tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr22
-rw-r--r--tests/ui/coherence/coherence-multidispatch-tuple.rs2
-rw-r--r--tests/ui/coherence/coherence-orphan.rs3
-rw-r--r--tests/ui/coherence/coherence-orphan.stderr33
-rw-r--r--tests/ui/coherence/deep-bad-copy-reason.rs5
-rw-r--r--tests/ui/coherence/deep-bad-copy-reason.stderr31
-rw-r--r--tests/ui/coherence/occurs-check/opaques.next.stderr13
-rw-r--r--tests/ui/coherence/occurs-check/opaques.rs1
-rw-r--r--tests/ui/const-generics/associated-type-bound.rs2
-rw-r--r--tests/ui/const-generics/condition-in-trait-const-arg.rs2
-rw-r--r--tests/ui/const-generics/dyn-supertraits.rs6
-rw-r--r--tests/ui/const-generics/dyn-supertraits.stderr22
-rw-r--r--tests/ui/const-generics/issues/issue-69654-run-pass.rs2
-rw-r--r--tests/ui/const-generics/issues/issue-69654-run-pass.stderr10
-rw-r--r--tests/ui/const-generics/issues/issue-90318.rs2
-rw-r--r--tests/ui/const-generics/issues/issue-90318.stderr27
-rw-r--r--tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr34
-rw-r--r--tests/ui/consts/const-block-item.rs2
-rw-r--r--tests/ui/consts/const-block-item.stderr10
-rw-r--r--tests/ui/consts/const-eval/raw-pointer-ub.rs2
-rw-r--r--tests/ui/consts/const-for-feature-gate.rs3
-rw-r--r--tests/ui/consts/const-for-feature-gate.stderr35
-rw-r--r--tests/ui/consts/const-try-feature-gate.rs2
-rw-r--r--tests/ui/consts/const-try-feature-gate.stderr27
-rw-r--r--tests/ui/consts/const_in_pattern/accept_structural.rs14
-rw-r--r--tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs3
-rw-r--r--tests/ui/consts/const_in_pattern/custom-eq-branch-warn.rs38
-rw-r--r--tests/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr14
-rw-r--r--tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr68
-rw-r--r--tests/ui/consts/const_in_pattern/issue-44333.stderr34
-rw-r--r--tests/ui/consts/const_in_pattern/issue-73431.stderr1
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_structural.rs2
-rw-r--r--tests/ui/consts/const_in_pattern/reject_non_structural.stderr19
-rw-r--r--tests/ui/consts/const_in_pattern/warn_corner_cases.rs41
-rw-r--r--tests/ui/consts/const_in_pattern/warn_corner_cases.stderr36
-rw-r--r--tests/ui/consts/control-flow/loop.rs6
-rw-r--r--tests/ui/consts/control-flow/loop.stderr73
-rw-r--r--tests/ui/consts/control-flow/try.rs2
-rw-r--r--tests/ui/consts/control-flow/try.stderr27
-rw-r--r--tests/ui/consts/fn_trait_refs.stderr98
-rw-r--r--tests/ui/consts/issue-89088.stderr17
-rw-r--r--tests/ui/consts/promoted_const_call.stderr22
-rw-r--r--tests/ui/consts/promoted_const_call3.rs7
-rw-r--r--tests/ui/consts/promoted_const_call3.stderr55
-rw-r--r--tests/ui/consts/promoted_const_call5.rs4
-rw-r--r--tests/ui/consts/promoted_const_call5.stderr22
-rw-r--r--tests/ui/consts/transmute-size-mismatch-before-typeck.rs2
-rw-r--r--tests/ui/consts/transmute-size-mismatch-before-typeck.stderr8
-rw-r--r--tests/ui/consts/try-operator.stderr49
-rw-r--r--tests/ui/consts/underscore_const_names.rs4
-rw-r--r--tests/ui/consts/unstable-const-fn-in-libcore.stderr35
-rw-r--r--tests/ui/coroutine/polymorphize-args.rs17
-rw-r--r--tests/ui/default-method-parsing.rs2
-rw-r--r--tests/ui/delegation/target-expr-pass.rs6
-rw-r--r--tests/ui/delegation/target-expr-pass.stderr22
-rw-r--r--tests/ui/derives/derive-assoc-type-not-impl.stderr3
-rw-r--r--tests/ui/deriving/deriving-bounds.rs2
-rw-r--r--tests/ui/diagnostic-width/tabs-trimming.rs1
-rw-r--r--tests/ui/diagnostic-width/tabs-trimming.stderr16
-rw-r--r--tests/ui/drop/drop-struct-as-object.rs2
-rw-r--r--tests/ui/drop/drop-struct-as-object.stderr12
-rw-r--r--tests/ui/drop/recursion-check-on-erroneous-impl.rs11
-rw-r--r--tests/ui/drop/recursion-check-on-erroneous-impl.stderr11
-rw-r--r--tests/ui/dyn-keyword/dyn-2018-edition-lint.rs8
-rw-r--r--tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr60
-rw-r--r--tests/ui/dynamically-sized-types/dst-coercions.rs2
-rw-r--r--tests/ui/dynamically-sized-types/dst-coercions.stderr12
-rw-r--r--tests/ui/empty-type-parameter-list.rs2
-rw-r--r--tests/ui/empty-type-parameter-list.stderr10
-rw-r--r--tests/ui/enum/enum-and-module-in-same-scope.rs1
-rw-r--r--tests/ui/enum/enum-and-module-in-same-scope.stderr13
-rw-r--r--tests/ui/error-codes/E0117.rs1
-rw-r--r--tests/ui/error-codes/E0117.stderr14
-rw-r--r--tests/ui/error-codes/E0120.rs1
-rw-r--r--tests/ui/error-codes/E0374.rs2
-rw-r--r--tests/ui/error-codes/E0374.stderr13
-rw-r--r--tests/ui/error-codes/E0375.rs2
-rw-r--r--tests/ui/error-codes/E0375.stderr30
-rw-r--r--tests/ui/error-codes/E0401.stderr4
-rw-r--r--tests/ui/error-codes/E0582.rs2
-rw-r--r--tests/ui/error-codes/E0582.stderr19
-rw-r--r--tests/ui/error-codes/E0637.rs4
-rw-r--r--tests/ui/error-codes/E0637.stderr20
-rw-r--r--tests/ui/explicit-tail-calls/return-mismatches.rs2
-rw-r--r--tests/ui/explicit-tail-calls/return-mismatches.stderr13
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed1
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.rs1
-rw-r--r--tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr2
-rw-r--r--tests/ui/expr/if/if-no-match-bindings.rs1
-rw-r--r--tests/ui/expr/if/if-no-match-bindings.stderr30
-rw-r--r--tests/ui/extern-flag/empty-extern-arg.stderr9
-rw-r--r--tests/ui/extern-mod-syntax.rs11
-rw-r--r--tests/ui/extern/issue-16250.rs (renamed from tests/ui/issues/issue-16250.rs)0
-rw-r--r--tests/ui/extern/issue-16250.stderr (renamed from tests/ui/issues/issue-16250.stderr)0
-rw-r--r--tests/ui/extern/issue-47725.rs (renamed from tests/ui/issues/issue-47725.rs)0
-rw-r--r--tests/ui/extern/issue-47725.stderr (renamed from tests/ui/issues/issue-47725.stderr)0
-rw-r--r--tests/ui/extern/no-mangle-associated-fn.rs2
-rw-r--r--tests/ui/extern/no-mangle-associated-fn.stderr10
-rw-r--r--tests/ui/feature-gates/feature-gate-associated_type_bounds.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr47
-rw-r--r--tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-cfg-target-thread-local.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-custom_mir.rs7
-rw-r--r--tests/ui/feature-gates/feature-gate-custom_mir.stderr22
-rw-r--r--tests/ui/feature-gates/feature-gate-ffi_returns_twice.rs6
-rw-r--r--tests/ui/feature-gates/feature-gate-ffi_returns_twice.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-naked_functions.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-naked_functions.stderr23
-rw-r--r--tests/ui/feature-gates/feature-gated-feature-in-macro-arg.rs2
-rw-r--r--tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr13
-rw-r--r--tests/ui/ffi_returns_twice.rs15
-rw-r--r--tests/ui/ffi_returns_twice.stderr21
-rw-r--r--tests/ui/fn/suggest-return-closure.rs10
-rw-r--r--tests/ui/fn/suggest-return-closure.stderr29
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88460.rs5
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-88460.stderr29
-rw-r--r--tests/ui/generic-associated-types/extended/lending_iterator.base.stderr8
-rw-r--r--tests/ui/generic-associated-types/extended/lending_iterator.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-70304.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-70304.stderr18
-rw-r--r--tests/ui/generic-associated-types/issue-74684-2.rs2
-rw-r--r--tests/ui/generic-associated-types/issue-74684-2.stderr21
-rw-r--r--tests/ui/generic-associated-types/issue-80433.rs5
-rw-r--r--tests/ui/generic-associated-types/issue-80433.stderr41
-rw-r--r--tests/ui/generic-associated-types/issue-88360.fixed1
-rw-r--r--tests/ui/generic-associated-types/issue-88360.rs1
-rw-r--r--tests/ui/generic-associated-types/issue-88360.stderr2
-rw-r--r--tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.rs2
-rw-r--r--tests/ui/generic-associated-types/method-unsatisfied-assoc-type-predicate.stderr6
-rw-r--r--tests/ui/generics/generic-extern.rs2
-rw-r--r--tests/ui/generics/generic-extern.stderr13
-rw-r--r--tests/ui/generics/generic-no-mangle.fixed2
-rw-r--r--tests/ui/generics/generic-no-mangle.rs2
-rw-r--r--tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs1
-rw-r--r--tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr19
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs1
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr21
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.rs3
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.stderr18
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs2
-rw-r--r--tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr43
-rw-r--r--tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs1
-rw-r--r--tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr19
-rw-r--r--tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs2
-rw-r--r--tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr18
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs4
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr27
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-30786.stderr12
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs3
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr29
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs3
-rw-r--r--tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr23
-rw-r--r--tests/ui/hygiene/panic-location.run.stderr2
-rw-r--r--tests/ui/impl-trait/equality-in-canonical-query.clone.stderr2
-rw-r--r--tests/ui/impl-trait/example-st.rs2
-rw-r--r--tests/ui/impl-trait/example-st.stderr10
-rw-r--r--tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs4
-rw-r--r--tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr30
-rw-r--r--tests/ui/impl-trait/in-trait/suggest-missing-item.fixed1
-rw-r--r--tests/ui/impl-trait/in-trait/suggest-missing-item.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/suggest-missing-item.stderr2
-rw-r--r--tests/ui/impl-trait/must_outlive_least_region_or_bound.rs4
-rw-r--r--tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr68
-rw-r--r--tests/ui/impl-trait/normalize-tait-in-const.stderr26
-rw-r--r--tests/ui/impl-trait/type-alias-generic-param.rs2
-rw-r--r--tests/ui/impl-trait/type-alias-generic-param.stderr10
-rw-r--r--tests/ui/imports/empty-import-prefix-pass-2015.rs10
-rw-r--r--tests/ui/imports/empty-import-prefix-pass.rs10
-rw-r--r--tests/ui/infinite/infinite-tag-type-recursion.rs1
-rw-r--r--tests/ui/infinite/infinite-tag-type-recursion.stderr15
-rw-r--r--tests/ui/inner-static-type-parameter.stderr2
-rw-r--r--tests/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs4
-rw-r--r--tests/ui/issues/issue-11374.rs1
-rw-r--r--tests/ui/issues/issue-11374.stderr16
-rw-r--r--tests/ui/issues/issue-13497.rs1
-rw-r--r--tests/ui/issues/issue-13497.stderr14
-rw-r--r--tests/ui/issues/issue-14399.rs2
-rw-r--r--tests/ui/issues/issue-14399.stderr12
-rw-r--r--tests/ui/issues/issue-15858.rs2
-rw-r--r--tests/ui/issues/issue-15858.stderr12
-rw-r--r--tests/ui/issues/issue-17351.rs2
-rw-r--r--tests/ui/issues/issue-17351.stderr12
-rw-r--r--tests/ui/issues/issue-18173.rs2
-rw-r--r--tests/ui/issues/issue-20055-box-trait.rs2
-rw-r--r--tests/ui/issues/issue-20055-box-trait.stderr12
-rw-r--r--tests/ui/issues/issue-21909.rs2
-rw-r--r--tests/ui/issues/issue-23485.rs2
-rw-r--r--tests/ui/issues/issue-23485.stderr13
-rw-r--r--tests/ui/issues/issue-2848.rs1
-rw-r--r--tests/ui/issues/issue-2848.stderr13
-rw-r--r--tests/ui/issues/issue-28971.rs1
-rw-r--r--tests/ui/issues/issue-28971.stderr16
-rw-r--r--tests/ui/issues/issue-2989.rs4
-rw-r--r--tests/ui/issues/issue-2989.stderr10
-rw-r--r--tests/ui/issues/issue-34074.rs2
-rw-r--r--tests/ui/issues/issue-34503.rs2
-rw-r--r--tests/ui/issues/issue-34503.stderr14
-rw-r--r--tests/ui/issues/issue-3563-3.rs2
-rw-r--r--tests/ui/issues/issue-3563-3.stderr13
-rw-r--r--tests/ui/issues/issue-3878.rs9
-rw-r--r--tests/ui/issues/issue-50571.fixed1
-rw-r--r--tests/ui/issues/issue-50571.rs1
-rw-r--r--tests/ui/issues/issue-50571.stderr2
-rw-r--r--tests/ui/issues/issue-67535.rs6
-rw-r--r--tests/ui/issues/issue-67535.stderr41
-rw-r--r--tests/ui/issues/issue-7575.rs2
-rw-r--r--tests/ui/issues/issue-7575.stderr10
-rw-r--r--tests/ui/issues/issue-7911.rs2
-rw-r--r--tests/ui/issues/issue-7911.stderr12
-rw-r--r--tests/ui/issues/issue-8248.rs2
-rw-r--r--tests/ui/issues/issue-8248.stderr12
-rw-r--r--tests/ui/issues/issue-9951.rs2
-rw-r--r--tests/ui/issues/issue-9951.stderr12
-rw-r--r--tests/ui/kindck/kindck-impl-type-params.rs1
-rw-r--r--tests/ui/kindck/kindck-impl-type-params.stderr15
-rw-r--r--tests/ui/kindck/kindck-send-object1.rs1
-rw-r--r--tests/ui/kindck/kindck-send-object1.stderr12
-rw-r--r--tests/ui/lifetimes/issue-17728.rs2
-rw-r--r--tests/ui/lifetimes/issue-17728.stderr18
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs2
-rw-r--r--tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr18
-rw-r--r--tests/ui/lint/dead-code/associated-type.rs2
-rw-r--r--tests/ui/lint/dead-code/issue-41883.rs29
-rw-r--r--tests/ui/lint/dead-code/issue-41883.stderr36
-rw-r--r--tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs2
-rw-r--r--tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr12
-rw-r--r--tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs4
-rw-r--r--tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr30
-rw-r--r--tests/ui/lint/force-warn/cap-lints-allow.rs4
-rw-r--r--tests/ui/lint/force-warn/cap-lints-allow.stderr30
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs4
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr30
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-lint-group.rs4
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr30
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs4
-rw-r--r--tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr30
-rw-r--r--tests/ui/lint/future-incompat-json-test.stderr2
-rw-r--r--tests/ui/lint/issue-20343.rs3
-rw-r--r--tests/ui/lint/lint-stability-deprecated.rs3
-rw-r--r--tests/ui/lint/lint-stability-deprecated.stderr170
-rw-r--r--tests/ui/liveness/liveness-forgot-ret.rs1
-rw-r--r--tests/ui/liveness/liveness-forgot-ret.stderr15
-rw-r--r--tests/ui/loops/loop-else-break-with-value.rs5
-rw-r--r--tests/ui/loops/loop-else-break-with-value.stderr23
-rw-r--r--tests/ui/macros/auxiliary/hello_macro.rs (renamed from tests/ui/auxiliary/hello_macro.rs)0
-rw-r--r--tests/ui/macros/issue-22463.rs2
-rw-r--r--tests/ui/macros/issue-46438.rs (renamed from tests/ui/issues/issue-46438.rs)0
-rw-r--r--tests/ui/macros/issue-46438.stderr (renamed from tests/ui/issues/issue-46438.stderr)0
-rw-r--r--tests/ui/macros/macro-quote-test.rs (renamed from tests/ui/macro-quote-test.rs)0
-rw-r--r--tests/ui/marker_trait_attr/override-item-on-marker-trait.rs2
-rw-r--r--tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr21
-rw-r--r--tests/ui/methods/assign-to-method.rs2
-rw-r--r--tests/ui/methods/method-call-err-msg.stderr5
-rw-r--r--tests/ui/methods/method-lookup-order.rs1
-rw-r--r--tests/ui/methods/method-recursive-blanket-impl.rs2
-rw-r--r--tests/ui/methods/method-recursive-blanket-impl.stderr10
-rw-r--r--tests/ui/methods/method-two-trait-defer-resolution-2.rs2
-rw-r--r--tests/ui/methods/method-two-trait-defer-resolution-2.stderr12
-rw-r--r--tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs2
-rw-r--r--tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr10
-rw-r--r--tests/ui/mir/drop-elaboration-after-borrowck-error.rs2
-rw-r--r--tests/ui/mir/drop-elaboration-after-borrowck-error.stderr34
-rw-r--r--tests/ui/mir/mir_raw_fat_ptr.rs2
-rw-r--r--tests/ui/mir/mir_raw_fat_ptr.stderr12
-rw-r--r--tests/ui/mir/validate/error-body.rs9
-rw-r--r--tests/ui/mir/validate/error-body.stderr9
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch.rs3
-rw-r--r--tests/ui/mismatched_types/closure-arg-type-mismatch.stderr50
-rw-r--r--tests/ui/moves/issue-22536-copy-mustnt-zero.rs2
-rw-r--r--tests/ui/moves/issue-22536-copy-mustnt-zero.stderr13
-rw-r--r--tests/ui/nll/continue-after-missing-main.rs2
-rw-r--r--tests/ui/nll/continue-after-missing-main.stderr36
-rw-r--r--tests/ui/object-safety/assoc_type_bounds_implicit_sized.fixed1
-rw-r--r--tests/ui/object-safety/assoc_type_bounds_implicit_sized.rs1
-rw-r--r--tests/ui/object-safety/assoc_type_bounds_implicit_sized.stderr4
-rw-r--r--tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.rs2
-rw-r--r--tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr20
-rw-r--r--tests/ui/or-patterns/missing-bindings.rs4
-rw-r--r--tests/ui/or-patterns/missing-bindings.stderr86
-rw-r--r--tests/ui/overloaded/issue-14958.rs2
-rw-r--r--tests/ui/overloaded/issue-14958.stderr12
-rw-r--r--tests/ui/overloaded/overloaded-index-in-field.rs2
-rw-r--r--tests/ui/overloaded/overloaded-index-in-field.stderr15
-rw-r--r--tests/ui/parallel-rustc/cache-after-waiting-issue-111528.rs16
-rw-r--r--tests/ui/parallel-rustc/cache-after-waiting-issue-111528.stderr8
-rw-r--r--tests/ui/parallel-rustc/export-symbols-deadlock-issue-118205-2.rs7
-rw-r--r--tests/ui/parallel-rustc/export-symbols-deadlock-issue-118205.rs22
-rw-r--r--tests/ui/parallel-rustc/hello_world.rs6
-rw-r--r--tests/ui/parallel-rustc/read-stolen-value-issue-111520.rs18
-rw-r--r--tests/ui/parser/bad-let-else-statement.rs20
-rw-r--r--tests/ui/parser/bad-let-else-statement.stderr303
-rw-r--r--tests/ui/parser/issues/issue-35813-postfix-after-cast.rs1
-rw-r--r--tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr39
-rw-r--r--tests/ui/parser/issues/issue-87086-colon-path-sep.rs3
-rw-r--r--tests/ui/parser/issues/issue-87086-colon-path-sep.stderr20
-rw-r--r--tests/ui/parser/parse-assoc-type-lt.rs2
-rw-r--r--tests/ui/parser/recover/recover-range-pats.rs9
-rw-r--r--tests/ui/parser/recover/recover-range-pats.stderr176
-rw-r--r--tests/ui/parser/suggest-assoc-const.fixed1
-rw-r--r--tests/ui/parser/suggest-assoc-const.rs1
-rw-r--r--tests/ui/parser/suggest-assoc-const.stderr2
-rw-r--r--tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed1
-rw-r--r--tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs1
-rw-r--r--tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr2
-rw-r--r--tests/ui/parser/variadic-ffi-semantic-restrictions.rs5
-rw-r--r--tests/ui/parser/variadic-ffi-semantic-restrictions.stderr79
-rw-r--r--tests/ui/pattern/bindings-after-at/bind-by-copy.rs44
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-move-and-move.rs4
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr30
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs7
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr75
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs3
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr58
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs10
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr102
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs6
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr48
-rw-r--r--tests/ui/pattern/bindings-after-at/pat-at-same-name-both.rs4
-rw-r--r--tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr26
-rw-r--r--tests/ui/pattern/issue-22546.rs2
-rw-r--r--tests/ui/pattern/issue-22546.stderr10
-rw-r--r--tests/ui/pattern/issue-28992-empty.rs (renamed from tests/ui/issues/issue-28992-empty.rs)0
-rw-r--r--tests/ui/pattern/issue-28992-empty.stderr (renamed from tests/ui/issues/issue-28992-empty.stderr)0
-rw-r--r--tests/ui/pattern/pattern-binding-disambiguation.rs4
-rw-r--r--tests/ui/pattern/pattern-binding-disambiguation.stderr51
-rw-r--r--tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs16
-rw-r--r--tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr61
-rw-r--r--tests/ui/pattern/usefulness/always-inhabited-union-ref.exhaustive_patterns.stderr (renamed from tests/ui/pattern/usefulness/always-inhabited-union-ref.stderr)6
-rw-r--r--tests/ui/pattern/usefulness/always-inhabited-union-ref.min_exhaustive_patterns.stderr46
-rw-r--r--tests/ui/pattern/usefulness/always-inhabited-union-ref.rs7
-rw-r--r--tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr18
-rw-r--r--tests/ui/pattern/usefulness/consts-opaque.stderr104
-rw-r--r--tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr6
-rw-r--r--tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr6
-rw-r--r--tests/ui/pattern/usefulness/empty-match-check-notes.rs4
-rw-r--r--tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr105
-rw-r--r--tests/ui/pattern/usefulness/empty-match.normal.stderr105
-rw-r--r--tests/ui/pattern/usefulness/empty-match.rs8
-rw-r--r--tests/ui/pattern/usefulness/match-privately-empty.exhaustive_patterns.stderr (renamed from tests/ui/pattern/usefulness/match-privately-empty.stderr)4
-rw-r--r--tests/ui/pattern/usefulness/match-privately-empty.min_exhaustive_patterns.stderr30
-rw-r--r--tests/ui/pattern/usefulness/match-privately-empty.rs12
-rw-r--r--tests/ui/pattern/usefulness/slice_of_empty.exhaustive_patterns.stderr (renamed from tests/ui/pattern/usefulness/slice_of_empty.stderr)2
-rw-r--r--tests/ui/pattern/usefulness/slice_of_empty.min_exhaustive_patterns.stderr38
-rw-r--r--tests/ui/pattern/usefulness/slice_of_empty.rs9
-rw-r--r--tests/ui/precondition-checks/misaligned-slice.rs11
-rw-r--r--tests/ui/precondition-checks/null-slice.rs11
-rw-r--r--tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs12
-rw-r--r--tests/ui/print_type_sizes/niche-filling.rs4
-rw-r--r--tests/ui/print_type_sizes/niche-filling.stdout4
-rw-r--r--tests/ui/privacy/associated-item-privacy-trait.stderr22
-rw-r--r--tests/ui/privacy/associated-item-privacy-type-binding.stderr8
-rw-r--r--tests/ui/privacy/auxiliary/private-trait-xc.rs (renamed from tests/ui/issues/auxiliary/private-trait-xc.rs)0
-rw-r--r--tests/ui/privacy/issue-11593.rs (renamed from tests/ui/issues/issue-11593.rs)0
-rw-r--r--tests/ui/privacy/issue-11593.stderr (renamed from tests/ui/issues/issue-11593.stderr)0
-rw-r--r--tests/ui/privacy/private-type-in-interface.stderr8
-rw-r--r--tests/ui/privacy/projections.rs60
-rw-r--r--tests/ui/privacy/projections.stderr62
-rw-r--r--tests/ui/privacy/projections2.rs38
-rw-r--r--tests/ui/privacy/projections2.stderr34
-rw-r--r--tests/ui/privacy/sealed-traits/re-exported-trait.fixed1
-rw-r--r--tests/ui/privacy/sealed-traits/re-exported-trait.rs1
-rw-r--r--tests/ui/privacy/sealed-traits/re-exported-trait.stderr4
-rw-r--r--tests/ui/privacy/struct-field-type.rs10
-rw-r--r--tests/ui/privacy/struct-field-type.stderr21
-rw-r--r--tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.fixed1
-rw-r--r--tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.rs1
-rw-r--r--tests/ui/proc-macro/issue-89566-suggest-fix-invalid-top-level-macro-attr.stderr1
-rw-r--r--tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs4
-rw-r--r--tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr31
-rw-r--r--tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs4
-rw-r--r--tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr31
-rw-r--r--tests/ui/regions/regions-lifetime-bounds-on-fns.rs4
-rw-r--r--tests/ui/regions/regions-lifetime-bounds-on-fns.stderr31
-rw-r--r--tests/ui/regions/regions-no-variance-from-fn-generics.rs2
-rw-r--r--tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr6
-rw-r--r--tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr6
-rw-r--r--tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed1
-rw-r--r--tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs1
-rw-r--r--tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr6
-rw-r--r--tests/ui/resolve/issue-12796.rs2
-rw-r--r--tests/ui/resolve/issue-12796.stderr4
-rw-r--r--tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr2
-rw-r--r--tests/ui/resolve/issue-65035-static-with-parent-generics.stderr10
-rw-r--r--tests/ui/resolve/use-self-in-inner-fn.rs4
-rw-r--r--tests/ui/resolve/use-self-in-inner-fn.stderr4
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.rs3
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.stderr31
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/bindings.rs1
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/bindings.stderr16
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/check.rs6
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/check.stderr41
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs4
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr19
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr19
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr19
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr19
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr130
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs2
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr40
-rw-r--r--tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr34
-rw-r--r--tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr15
-rw-r--r--tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr15
-rw-r--r--tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs2
-rw-r--r--tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs8
-rw-r--r--tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs2
-rw-r--r--tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr12
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr16
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr16
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr42
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs8
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr30
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr10
-rw-r--r--tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr14
-rw-r--r--tests/ui/rust-2018/issue-51008-1.rs2
-rw-r--r--tests/ui/rust-2018/issue-51008.rs2
-rw-r--r--tests/ui/sized/coinductive-2.rs2
-rw-r--r--tests/ui/sized/coinductive-2.stderr10
-rw-r--r--tests/ui/span/issue-23827.rs1
-rw-r--r--tests/ui/span/issue-23827.stderr2
-rw-r--r--tests/ui/span/issue-39698.rs1
-rw-r--r--tests/ui/span/issue-39698.stderr17
-rw-r--r--tests/ui/specialization/assoc-ty-graph-cycle.rs2
-rw-r--r--tests/ui/specialization/const_trait_impl.stderr30
-rw-r--r--tests/ui/specialization/defaultimpl/out-of-order.rs2
-rw-r--r--tests/ui/specialization/defaultimpl/overlap-projection.rs2
-rw-r--r--tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr11
-rw-r--r--tests/ui/specialization/specialization-default-items-drop-coherence.rs14
-rw-r--r--tests/ui/specialization/specialization-out-of-order.rs2
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.rs2
-rw-r--r--tests/ui/specialization/specialization-supertraits.rs2
-rw-r--r--tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs1
-rw-r--r--tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr10
-rw-r--r--tests/ui/static/static-drop-scope.rs2
-rw-r--r--tests/ui/static/static-drop-scope.stderr39
-rw-r--r--tests/ui/statics/static-impl.rs2
-rw-r--r--tests/ui/statics/static-impl.stderr13
-rw-r--r--tests/ui/stdlib-unit-tests/raw-fat-ptr.rs2
-rw-r--r--tests/ui/stdlib-unit-tests/raw-fat-ptr.stderr12
-rw-r--r--tests/ui/structs-enums/enum-null-pointer-opt.rs2
-rw-r--r--tests/ui/structs-enums/enum-null-pointer-opt.stderr12
-rw-r--r--tests/ui/structs-enums/enum-rec/issue-17431-6.rs3
-rw-r--r--tests/ui/structs-enums/enum-rec/issue-17431-6.stderr17
-rw-r--r--tests/ui/suggestions/bound-suggestions.fixed5
-rw-r--r--tests/ui/suggestions/bound-suggestions.rs5
-rw-r--r--tests/ui/suggestions/bound-suggestions.stderr10
-rw-r--r--tests/ui/suggestions/constrain-trait.fixed1
-rw-r--r--tests/ui/suggestions/constrain-trait.rs1
-rw-r--r--tests/ui/suggestions/constrain-trait.stderr4
-rw-r--r--tests/ui/suggestions/derive-trait-for-method-call.rs2
-rw-r--r--tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs3
-rw-r--r--tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr50
-rw-r--r--tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs2
-rw-r--r--tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr64
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime.rs1
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime.stderr12
-rw-r--r--tests/ui/suggestions/invalid-bin-op.stderr4
-rw-r--r--tests/ui/suggestions/issue-102892.rs1
-rw-r--r--tests/ui/suggestions/issue-102892.stderr27
-rw-r--r--tests/ui/suggestions/issue-109195.rs20
-rw-r--r--tests/ui/suggestions/issue-109195.stderr69
-rw-r--r--tests/ui/suggestions/issue-61963.rs10
-rw-r--r--tests/ui/suggestions/issue-61963.stderr74
-rw-r--r--tests/ui/suggestions/issue-86667.rs7
-rw-r--r--tests/ui/suggestions/issue-86667.stderr11
-rw-r--r--tests/ui/suggestions/lifetimes/type-param-bound-scope.fixed1
-rw-r--r--tests/ui/suggestions/lifetimes/type-param-bound-scope.rs1
-rw-r--r--tests/ui/suggestions/lifetimes/type-param-bound-scope.stderr10
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed4
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs2
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr21
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs2
-rw-r--r--tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr37
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed1
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs1
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr4
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed1
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs1
-rw-r--r--tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr2
-rw-r--r--tests/ui/suggestions/missing-lifetime-specifier.rs12
-rw-r--r--tests/ui/suggestions/missing-lifetime-specifier.stderr232
-rw-r--r--tests/ui/suggestions/missing-lt-for-hrtb.rs2
-rw-r--r--tests/ui/suggestions/missing-lt-for-hrtb.stderr24
-rw-r--r--tests/ui/suggestions/missing-trait-item.fixed1
-rw-r--r--tests/ui/suggestions/missing-trait-item.rs1
-rw-r--r--tests/ui/suggestions/missing-trait-item.stderr4
-rw-r--r--tests/ui/tag-variant-cast-non-nullary.stderr3
-rw-r--r--tests/ui/threads-sendsync/sync-send-atomics.rs2
-rw-r--r--tests/ui/traits/alias/bounds.rs2
-rw-r--r--tests/ui/traits/alias/bounds.stderr10
-rw-r--r--tests/ui/traits/alias/syntax.rs2
-rw-r--r--tests/ui/traits/bound/impl-comparison-duplicates.rs2
-rw-r--r--tests/ui/traits/bound/recursion.rs2
-rw-r--r--tests/ui/traits/composition-trivial.rs2
-rw-r--r--tests/ui/traits/cycle-generic-bound.rs2
-rw-r--r--tests/ui/traits/default-method/bound-subst4.rs2
-rw-r--r--tests/ui/traits/default-method/bound-subst4.stderr13
-rw-r--r--tests/ui/traits/default-method/mut.rs2
-rw-r--r--tests/ui/traits/impl-inherent-prefer-over-trait.rs2
-rw-r--r--tests/ui/traits/impl-inherent-prefer-over-trait.stderr12
-rw-r--r--tests/ui/traits/impl-object-overlap-issue-23853.rs2
-rw-r--r--tests/ui/traits/impl-object-overlap-issue-23853.stderr12
-rw-r--r--tests/ui/traits/impl.rs2
-rw-r--r--tests/ui/traits/impl.stderr12
-rw-r--r--tests/ui/traits/issue-33096.rs (renamed from tests/ui/issues/issue-33096.rs)0
-rw-r--r--tests/ui/traits/issue-38033.rs2
-rw-r--r--tests/ui/traits/issue-38033.stderr13
-rw-r--r--tests/ui/traits/issue-40085.rs (renamed from tests/ui/issues/issue-40085.rs)0
-rw-r--r--tests/ui/traits/issue-50480.rs2
-rw-r--r--tests/ui/traits/issue-50480.stderr28
-rw-r--r--tests/ui/traits/issue-56488.rs2
-rw-r--r--tests/ui/traits/issue-58344.rs (renamed from tests/ui/issues/issue-58344.rs)0
-rw-r--r--tests/ui/traits/issue-59029-2.rs2
-rw-r--r--tests/ui/traits/issue-6128.rs2
-rw-r--r--tests/ui/traits/issue-6128.stderr14
-rw-r--r--tests/ui/traits/issue-78372.rs3
-rw-r--r--tests/ui/traits/issue-78372.stderr33
-rw-r--r--tests/ui/traits/method-on-unbounded-type-param.rs15
-rw-r--r--tests/ui/traits/method-on-unbounded-type-param.stderr84
-rw-r--r--tests/ui/traits/multidispatch-conditional-impl-not-considered.rs2
-rw-r--r--tests/ui/traits/multidispatch-conditional-impl-not-considered.stderr10
-rw-r--r--tests/ui/traits/multidispatch-infer-convert-target.rs2
-rw-r--r--tests/ui/traits/multidispatch-infer-convert-target.stderr12
-rw-r--r--tests/ui/traits/negative-impls/negative-specializes-negative.rs2
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs1
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr24
-rw-r--r--tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs12
-rw-r--r--tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr2
-rw-r--r--tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs40
-rw-r--r--tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-1.rs30
-rw-r--r--tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-2.rs29
-rw-r--r--tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-3.rs18
-rw-r--r--tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.rs29
-rw-r--r--tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.stderr (renamed from tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr)10
-rw-r--r--tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs31
-rw-r--r--tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr19
-rw-r--r--tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr8
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.rs1
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.stderr12
-rw-r--r--tests/ui/traits/next-solver/normalize-param-env-2.rs17
-rw-r--r--tests/ui/traits/next-solver/normalize-param-env-2.stderr35
-rw-r--r--tests/ui/traits/next-solver/normalize-param-env-4.next.stderr19
-rw-r--r--tests/ui/traits/next-solver/normalize-param-env-4.rs34
-rw-r--r--tests/ui/traits/next-solver/normalize-region-obligations.rs9
-rw-r--r--tests/ui/traits/next-solver/normalize-type-outlives-in-param-env.rs18
-rw-r--r--tests/ui/traits/next-solver/normalize-type-outlives.rs13
-rw-r--r--tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.rs40
-rw-r--r--tests/ui/traits/next-solver/param-candidate-doesnt-shadow-project.rs25
-rw-r--r--tests/ui/traits/next-solver/specialization-transmute.rs2
-rw-r--r--tests/ui/traits/next-solver/specialization-transmute.stderr2
-rw-r--r--tests/ui/traits/object/pretty.rs37
-rw-r--r--tests/ui/traits/object/pretty.stderr157
-rw-r--r--tests/ui/traits/pointee-normalize-equate.rs56
-rw-r--r--tests/ui/traits/self-without-lifetime-constraint.rs1
-rw-r--r--tests/ui/traits/self-without-lifetime-constraint.stderr16
-rw-r--r--tests/ui/traits/trait-upcasting/lifetime.rs4
-rw-r--r--tests/ui/traits/trait-upcasting/lifetime.stderr25
-rw-r--r--tests/ui/traits/trait-upcasting/replace-vptr.rs4
-rw-r--r--tests/ui/traits/trait-upcasting/replace-vptr.stderr20
-rw-r--r--tests/ui/traits/use-before-def.rs2
-rw-r--r--tests/ui/traits/wf-object/reverse-order.rs2
-rw-r--r--tests/ui/trivial_casts-rpass.rs2
-rw-r--r--tests/ui/trivial_casts-rpass.stderr12
-rw-r--r--tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs3
-rw-r--r--tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr22
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/issue-58887.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-77179.rs1
-rw-r--r--tests/ui/type-alias-impl-trait/issue-77179.stderr16
-rw-r--r--tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs4
-rw-r--r--tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr2
-rw-r--r--tests/ui/typeck/issue-16338.rs (renamed from tests/ui/issues/issue-16338.rs)0
-rw-r--r--tests/ui/typeck/issue-16338.stderr (renamed from tests/ui/issues/issue-16338.stderr)0
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.rs1
-rw-r--r--tests/ui/typeck/typeck_type_placeholder_item.stderr37
-rw-r--r--tests/ui/typeof/issue-100183.stderr4
-rw-r--r--tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr26
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs1
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr20
-rw-r--r--tests/ui/underscore-lifetime/underscore-lifetime-binders.rs1
-rw-r--r--tests/ui/underscore-lifetime/underscore-lifetime-binders.stderr10
-rw-r--r--tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.fixed1
-rw-r--r--tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.rs1
-rw-r--r--tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.stderr2
-rw-r--r--tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.fixed1
-rw-r--r--tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.rs1
-rw-r--r--tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.stderr2
-rw-r--r--tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.fixed1
-rw-r--r--tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.rs1
-rw-r--r--tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.stderr2
-rw-r--r--tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.fixed2
-rw-r--r--tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.rs2
-rw-r--r--tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.stderr2
-rw-r--r--tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr (renamed from tests/ui/uninhabited/uninhabited-irrefutable.stderr)4
-rw-r--r--tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr26
-rw-r--r--tests/ui/uninhabited/uninhabited-irrefutable.rs5
-rw-r--r--tests/ui/wf/hir-wf-canonicalized.rs4
-rw-r--r--tests/ui/wf/hir-wf-canonicalized.stderr8
-rw-r--r--tests/ui/where-clauses/issue-50825-1.rs2
-rw-r--r--tests/ui/where-clauses/where-clause-bounds-inconsistency.rs2
-rw-r--r--tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs2
-rw-r--r--tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr12
-rw-r--r--tests/ui/where-clauses/where-clause-method-substituion-rpass.rs2
-rw-r--r--tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr12
-rw-r--r--tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed2
-rw-r--r--tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs2
-rw-r--r--tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr6
-rw-r--r--tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed1
-rw-r--r--tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.rs1
-rw-r--r--tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr4
-rw-r--r--triagebot.toml2
1409 files changed, 18768 insertions, 8871 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 29c8c7ef004..fff30b0f27b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -556,7 +556,7 @@ checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
 
 [[package]]
 name = "clippy"
-version = "0.1.77"
+version = "0.1.78"
 dependencies = [
  "anstream",
  "clippy_config",
@@ -584,7 +584,7 @@ dependencies = [
 
 [[package]]
 name = "clippy_config"
-version = "0.1.77"
+version = "0.1.78"
 dependencies = [
  "rustc-semver",
  "serde",
@@ -607,7 +607,7 @@ dependencies = [
 
 [[package]]
 name = "clippy_lints"
-version = "0.1.77"
+version = "0.1.78"
 dependencies = [
  "arrayvec",
  "cargo_metadata 0.18.0",
@@ -632,7 +632,7 @@ dependencies = [
 
 [[package]]
 name = "clippy_utils"
-version = "0.1.77"
+version = "0.1.78"
 dependencies = [
  "arrayvec",
  "clippy_config",
@@ -1003,7 +1003,7 @@ checksum = "a0afaad2b26fa326569eb264b1363e8ae3357618c43982b3f285f0774ce76b69"
 
 [[package]]
 name = "declare_clippy_lint"
-version = "0.1.77"
+version = "0.1.78"
 dependencies = [
  "itertools",
  "quote",
@@ -2090,9 +2090,9 @@ dependencies = [
 
 [[package]]
 name = "jobserver"
-version = "0.1.27"
+version = "0.1.28"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
+checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6"
 dependencies = [
  "libc",
 ]
@@ -4374,6 +4374,7 @@ dependencies = [
  "rustc_middle",
  "rustc_session",
  "rustc_span",
+ "rustc_ty_utils",
  "tracing",
 ]
 
diff --git a/RELEASES.md b/RELEASES.md
index 038a83cde84..20e317a4d23 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -7,7 +7,7 @@ Language
 --------
 - [Document Rust ABI compatibility between various types](https://github.com/rust-lang/rust/pull/115476/)
 - [Also: guarantee that char and u32 are ABI-compatible](https://github.com/rust-lang/rust/pull/118032/)
-- [Warn against ambiguous wide pointer comparisons](https://github.com/rust-lang/rust/pull/117758/)
+- [Add lint `ambiguous_wide_pointer_comparisons` that supersedes `clippy::vtable_address_comparisons`](https://github.com/rust-lang/rust/pull/117758)
 
 <a id="1.76.0-Compiler"></a>
 
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index 90ddeec4bc7..5cb79d9eea5 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -22,8 +22,6 @@
 #![cfg_attr(test, feature(test))]
 #![feature(strict_provenance)]
 #![deny(unsafe_op_in_unsafe_fn)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
 #![allow(clippy::mut_from_ref)] // Arena allocators are one of the places where this pattern is fine.
 
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index 76d838308b4..356e9fef439 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -18,8 +18,6 @@
 #![feature(min_specialization)]
 #![feature(negative_impls)]
 #![feature(stmt_expr_attributes)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs
index 3742cf9d881..fd717e82d26 100644
--- a/compiler/rustc_ast_lowering/src/asm.rs
+++ b/compiler/rustc_ast_lowering/src/asm.rs
@@ -205,7 +205,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                                 &sym.qself,
                                 &sym.path,
                                 ParamMode::Optional,
-                                &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                                ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                                 None,
                             );
                             hir::InlineAsmOperand::SymStatic { path, def_id }
diff --git a/compiler/rustc_ast_lowering/src/block.rs b/compiler/rustc_ast_lowering/src/block.rs
index d310f72f7a3..865a56b2c1f 100644
--- a/compiler/rustc_ast_lowering/src/block.rs
+++ b/compiler/rustc_ast_lowering/src/block.rs
@@ -85,7 +85,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         let ty = l
             .ty
             .as_ref()
-            .map(|t| self.lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
+            .map(|t| self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::Variable)));
         let init = l.kind.init().map(|init| self.lower_expr(init));
         let hir_id = self.lower_node_id(l.id);
         let pat = self.lower_pat(&l.pat);
diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs
index 6ccf39b0cb1..d1ba93f0675 100644
--- a/compiler/rustc_ast_lowering/src/delegation.rs
+++ b/compiler/rustc_ast_lowering/src/delegation.rs
@@ -218,7 +218,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             &delegation.qself,
             &delegation.path,
             ParamMode::Optional,
-            &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
             None,
         );
         let block = delegation.body.as_deref();
diff --git a/compiler/rustc_ast_lowering/src/errors.rs b/compiler/rustc_ast_lowering/src/errors.rs
index ec92afee47a..62253585695 100644
--- a/compiler/rustc_ast_lowering/src/errors.rs
+++ b/compiler/rustc_ast_lowering/src/errors.rs
@@ -1,4 +1,6 @@
-use rustc_errors::{codes::*, DiagnosticArgFromDisplay};
+use rustc_errors::{
+    codes::*, AddToDiagnostic, Diagnostic, DiagnosticArgFromDisplay, SubdiagnosticMessageOp,
+};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
 
@@ -38,14 +40,8 @@ pub struct InvalidAbi {
 
 pub struct InvalidAbiReason(pub &'static str);
 
-impl rustc_errors::AddToDiagnostic for InvalidAbiReason {
-    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
-    where
-        F: Fn(
-            &mut rustc_errors::Diagnostic,
-            rustc_errors::SubdiagnosticMessage,
-        ) -> rustc_errors::SubdiagnosticMessage,
-    {
+impl AddToDiagnostic for InvalidAbiReason {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         #[allow(rustc::untranslatable_diagnostic)]
         diag.note(self.0);
     }
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index c4798887637..942aae3d536 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -99,7 +99,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         seg,
                         ParamMode::Optional,
                         ParenthesizedGenericArgs::Err,
-                        &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         None,
                         // Method calls can't have bound modifiers
                         None,
@@ -141,13 +141,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ExprKind::Cast(expr, ty) => {
                     let expr = self.lower_expr(expr);
                     let ty =
-                        self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
+                        self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
                     hir::ExprKind::Cast(expr, ty)
                 }
                 ExprKind::Type(expr, ty) => {
                     let expr = self.lower_expr(expr);
                     let ty =
-                        self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
+                        self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::Cast));
                     hir::ExprKind::Type(expr, ty)
                 }
                 ExprKind::AddrOf(k, m, ohs) => {
@@ -267,7 +267,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         qself,
                         path,
                         ParamMode::Optional,
-                        &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         None,
                     );
                     hir::ExprKind::Path(qpath)
@@ -295,7 +295,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ExprKind::OffsetOf(container, fields) => hir::ExprKind::OffsetOf(
                     self.lower_ty(
                         container,
-                        &ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf),
+                        ImplTraitContext::Disallowed(ImplTraitPosition::OffsetOf),
                     ),
                     self.arena.alloc_from_iter(fields.iter().map(|&ident| self.lower_ident(ident))),
                 ),
@@ -314,7 +314,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             &se.qself,
                             &se.path,
                             ParamMode::Optional,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                             None,
                         )),
                         self.arena
@@ -1241,7 +1241,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         qself,
                         path,
                         ParamMode::Optional,
-                        &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         None,
                     );
                     // Destructure like a tuple struct.
@@ -1261,7 +1261,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         qself,
                         path,
                         ParamMode::Optional,
-                        &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                         None,
                     );
                     // Destructure like a unit struct.
@@ -1286,7 +1286,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &se.qself,
                     &se.path,
                     ParamMode::Optional,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     None,
                 );
                 let fields_omitted = match &se.rest {
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index 993ddf00eb5..11aa6b250b1 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -15,7 +15,7 @@ struct NodeCollector<'a, 'hir> {
     bodies: &'a SortedMap<ItemLocalId, &'hir Body<'hir>>,
 
     /// Outputs
-    nodes: IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>,
+    nodes: IndexVec<ItemLocalId, ParentedNode<'hir>>,
     parenting: LocalDefIdMap<ItemLocalId>,
 
     /// The parent of this node
@@ -29,16 +29,19 @@ pub(super) fn index_hir<'hir>(
     tcx: TyCtxt<'hir>,
     item: hir::OwnerNode<'hir>,
     bodies: &SortedMap<ItemLocalId, &'hir Body<'hir>>,
-) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, LocalDefIdMap<ItemLocalId>) {
-    let mut nodes = IndexVec::new();
+    num_nodes: usize,
+) -> (IndexVec<ItemLocalId, ParentedNode<'hir>>, LocalDefIdMap<ItemLocalId>) {
+    let zero_id = ItemLocalId::new(0);
+    let err_node = ParentedNode { parent: zero_id, node: Node::Err(item.span()) };
+    let mut nodes = IndexVec::from_elem_n(err_node, num_nodes);
     // This node's parent should never be accessed: the owner's parent is computed by the
     // hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
     // used.
-    nodes.push(Some(ParentedNode { parent: ItemLocalId::INVALID, node: item.into() }));
+    nodes[zero_id] = ParentedNode { parent: ItemLocalId::INVALID, node: item.into() };
     let mut collector = NodeCollector {
         tcx,
         owner: item.def_id(),
-        parent_node: ItemLocalId::new(0),
+        parent_node: zero_id,
         nodes,
         bodies,
         parenting: Default::default(),
@@ -54,6 +57,14 @@ pub(super) fn index_hir<'hir>(
         OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
     };
 
+    for (local_id, node) in collector.nodes.iter_enumerated() {
+        if let Node::Err(span) = node.node {
+            let hir_id = HirId { owner: item.def_id(), local_id };
+            let msg = format!("ID {hir_id} not encountered when visiting item HIR");
+            tcx.dcx().span_delayed_bug(*span, msg);
+        }
+    }
+
     (collector.nodes, collector.parenting)
 }
 
@@ -88,7 +99,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
             }
         }
 
-        self.nodes.insert(hir_id.local_id, ParentedNode { parent: self.parent_node, node });
+        self.nodes[hir_id.local_id] = ParentedNode { parent: self.parent_node, node };
     }
 
     fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
@@ -254,6 +265,7 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
     }
 
     fn visit_path_segment(&mut self, path_segment: &'hir PathSegment<'hir>) {
+        // FIXME: walk path segment with `path_segment.hir_id` parent.
         self.insert(path_segment.ident.span, path_segment.hir_id, Node::PathSegment(path_segment));
         intravisit::walk_path_segment(self, path_segment);
     }
@@ -348,4 +360,23 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
 
         self.visit_nested_foreign_item(id);
     }
+
+    fn visit_where_predicate(&mut self, predicate: &'hir WherePredicate<'hir>) {
+        match predicate {
+            WherePredicate::BoundPredicate(pred) => {
+                self.insert(pred.span, pred.hir_id, Node::WhereBoundPredicate(pred));
+                self.with_parent(pred.hir_id, |this| {
+                    intravisit::walk_where_predicate(this, predicate)
+                })
+            }
+            _ => intravisit::walk_where_predicate(self, predicate),
+        }
+    }
+
+    fn visit_array_length(&mut self, len: &'hir ArrayLen) {
+        match len {
+            ArrayLen::Infer(inf) => self.insert(inf.span, inf.hir_id, Node::ArrayLenInfer(inf)),
+            ArrayLen::Body(..) => intravisit::walk_array_len(self, len),
+        }
+    }
 }
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 2a3e172f771..fb52f9cf58f 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -189,7 +189,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     generics,
                     Const::No,
                     id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
                         this.lower_const_item(ty, span, expr.as_deref(), ImplTraitPosition::ConstTy)
                     },
@@ -218,7 +218,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
                     let itctx = ImplTraitContext::Universal;
                     let (generics, decl) =
-                        this.lower_generics(generics, header.constness, id, &itctx, |this| {
+                        this.lower_generics(generics, header.constness, id, itctx, |this| {
                             this.lower_fn_decl(
                                 decl,
                                 id,
@@ -263,7 +263,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &generics,
                     Const::No,
                     id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| match ty {
                         None => {
                             let guar = this.dcx().span_delayed_bug(
@@ -274,7 +274,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         }
                         Some(ty) => this.lower_ty(
                             ty,
-                            &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
+                            ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: false },
                         ),
                     },
                 );
@@ -285,7 +285,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     generics,
                     Const::No,
                     id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
                         this.arena.alloc_from_iter(
                             enum_definition.variants.iter().map(|x| this.lower_variant(x)),
@@ -299,7 +299,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     generics,
                     Const::No,
                     id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| this.lower_variant_data(hir_id, struct_def),
                 );
                 hir::ItemKind::Struct(struct_def, generics)
@@ -309,7 +309,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     generics,
                     Const::No,
                     id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| this.lower_variant_data(hir_id, vdata),
                 );
                 hir::ItemKind::Union(vdata, generics)
@@ -339,7 +339,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 // parent lifetime.
                 let itctx = ImplTraitContext::Universal;
                 let (generics, (trait_ref, lowered_ty)) =
-                    self.lower_generics(ast_generics, *constness, id, &itctx, |this| {
+                    self.lower_generics(ast_generics, *constness, id, itctx, |this| {
                         let modifiers = TraitBoundModifiers {
                             constness: match *constness {
                                 Const::Yes(span) => BoundConstness::Maybe(span),
@@ -354,13 +354,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                             this.lower_trait_ref(
                                 modifiers,
                                 trait_ref,
-                                &ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
+                                ImplTraitContext::Disallowed(ImplTraitPosition::Trait),
                             )
                         });
 
                         let lowered_ty = this.lower_ty(
                             ty,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::ImplSelf),
                         );
 
                         (trait_ref, lowered_ty)
@@ -400,11 +400,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     generics,
                     constness,
                     id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
                         let bounds = this.lower_param_bounds(
                             bounds,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
                         );
                         let items = this.arena.alloc_from_iter(
                             items.iter().map(|item| this.lower_trait_item_ref(item)),
@@ -420,11 +420,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     generics,
                     Const::No,
                     id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
                         this.lower_param_bounds(
                             bounds,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
                         )
                     },
                 );
@@ -464,7 +464,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         body: Option<&Expr>,
         impl_trait_position: ImplTraitPosition,
     ) -> (&'hir hir::Ty<'hir>, hir::BodyId) {
-        let ty = self.lower_ty(ty, &ImplTraitContext::Disallowed(impl_trait_position));
+        let ty = self.lower_ty(ty, ImplTraitContext::Disallowed(impl_trait_position));
         (ty, self.lower_const_body(span, body))
     }
 
@@ -498,8 +498,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     }
                 }
 
-                let res =
-                    self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
+                let res = self.lower_import_res(id, path.span);
                 let path = self.lower_use_path(res, &path, ParamMode::Explicit);
                 hir::ItemKind::Use(path, hir::UseKind::Single)
             }
@@ -535,7 +534,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 // for that we return the `{}` import (called the
                 // `ListStem`).
 
-                let prefix = Path { segments, span: prefix.span.to(path.span), tokens: None };
+                let span = prefix.span.to(path.span);
+                let prefix = Path { segments, span, tokens: None };
 
                 // Add all the nested `PathListItem`s to the HIR.
                 for &(ref use_tree, id) in trees {
@@ -569,9 +569,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     });
                 }
 
-                let res =
-                    self.expect_full_res_from_use(id).map(|res| self.lower_res(res)).collect();
-                let path = self.lower_use_path(res, &prefix, ParamMode::Explicit);
+                // Condition should match `build_reduced_graph_for_use_tree`.
+                let path = if trees.is_empty()
+                    && !(prefix.segments.is_empty()
+                        || prefix.segments.len() == 1
+                            && prefix.segments[0].ident.name == kw::PathRoot)
+                {
+                    // For empty lists we need to lower the prefix so it is checked for things
+                    // like stability later.
+                    let res = self.lower_import_res(id, span);
+                    self.lower_use_path(res, &prefix, ParamMode::Explicit)
+                } else {
+                    // For non-empty lists we can just drop all the data, the prefix is already
+                    // present in HIR as a part of nested imports.
+                    self.arena.alloc(hir::UsePath { res: smallvec![], segments: &[], span })
+                };
                 hir::ItemKind::Use(path, hir::UseKind::ListStem)
             }
         }
@@ -626,7 +638,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let fdec = &sig.decl;
                     let itctx = ImplTraitContext::Universal;
                     let (generics, (fn_dec, fn_args)) =
-                        self.lower_generics(generics, Const::No, i.id, &itctx, |this| {
+                        self.lower_generics(generics, Const::No, i.id, itctx, |this| {
                             (
                                 // Disallow `impl Trait` in foreign items.
                                 this.lower_fn_decl(
@@ -643,8 +655,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     hir::ForeignItemKind::Fn(fn_dec, fn_args, generics)
                 }
                 ForeignItemKind::Static(t, m, _) => {
-                    let ty = self
-                        .lower_ty(t, &ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
+                    let ty =
+                        self.lower_ty(t, ImplTraitContext::Disallowed(ImplTraitPosition::StaticTy));
                     hir::ForeignItemKind::Static(ty, *m)
                 }
                 ForeignItemKind::TyAlias(..) => hir::ForeignItemKind::Type,
@@ -715,11 +727,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 qself,
                 path,
                 ParamMode::ExplicitNamed, // no `'_` in declarations (Issue #61124)
-                &ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy),
+                ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy),
             );
             self.arena.alloc(t)
         } else {
-            self.lower_ty(&f.ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy))
+            self.lower_ty(&f.ty, ImplTraitContext::Disallowed(ImplTraitPosition::FieldTy))
         };
         let hir_id = self.lower_node_id(f.id);
         self.lower_attrs(hir_id, &f.attrs);
@@ -748,12 +760,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     generics,
                     Const::No,
                     i.id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
-                        let ty = this.lower_ty(
-                            ty,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy),
-                        );
+                        let ty = this
+                            .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
                         let body = expr.as_ref().map(|x| this.lower_const_body(i.span, Some(x)));
 
                         hir::TraitItemKind::Const(ty, body)
@@ -796,18 +806,18 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &generics,
                     Const::No,
                     i.id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| {
                         let ty = ty.as_ref().map(|x| {
                             this.lower_ty(
                                 x,
-                                &ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),
+                                ImplTraitContext::Disallowed(ImplTraitPosition::AssocTy),
                             )
                         });
                         hir::TraitItemKind::Type(
                             this.lower_param_bounds(
                                 bounds,
-                                &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                                ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                             ),
                             ty,
                         )
@@ -875,10 +885,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 generics,
                 Const::No,
                 i.id,
-                &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                 |this| {
-                    let ty = this
-                        .lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
+                    let ty =
+                        this.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::ConstTy));
                     let body = this.lower_const_body(i.span, expr.as_deref());
 
                     hir::ImplItemKind::Const(ty, body)
@@ -909,7 +919,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     &generics,
                     Const::No,
                     i.id,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Generic),
                     |this| match ty {
                         None => {
                             let guar = this.dcx().span_delayed_bug(
@@ -922,7 +932,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         Some(ty) => {
                             let ty = this.lower_ty(
                                 ty,
-                                &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
+                                ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty: true },
                             );
                             hir::ImplItemKind::Type(ty)
                         }
@@ -1316,7 +1326,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         // synthesize a host effect param for them. We reject `const` on them during AST validation.
         let constness = if kind == FnDeclKind::Inherent { sig.header.constness } else { Const::No };
         let itctx = ImplTraitContext::Universal;
-        let (generics, decl) = self.lower_generics(generics, constness, id, &itctx, |this| {
+        let (generics, decl) = self.lower_generics(generics, constness, id, itctx, |this| {
             this.lower_fn_decl(&sig.decl, id, sig.span, kind, coroutine_kind)
         });
         (generics, hir::FnSig { header, decl, span: self.lower_span(sig.span) })
@@ -1394,7 +1404,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         generics: &Generics,
         constness: Const,
         parent_node_id: NodeId,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
         f: impl FnOnce(&mut Self) -> T,
     ) -> (&'hir hir::Generics<'hir>, T) {
         debug_assert!(self.impl_trait_defs.is_empty());
@@ -1600,7 +1610,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         bounds: &[GenericBound],
         colon_span: Option<Span>,
         parent_span: Span,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
         origin: PredicateOrigin,
     ) -> Option<hir::WherePredicate<'hir>> {
         // Do not create a clause if we do not have anything inside it.
@@ -1674,10 +1684,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 bound_generic_params: self
                     .lower_generic_params(bound_generic_params, hir::GenericParamSource::Binder),
                 bounded_ty: self
-                    .lower_ty(bounded_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
+                    .lower_ty(bounded_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
                 bounds: self.lower_param_bounds(
                     bounds,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
                 ),
                 span: self.lower_span(*span),
                 origin: PredicateOrigin::WhereClause,
@@ -1688,7 +1698,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     lifetime: self.lower_lifetime(lifetime),
                     bounds: self.lower_param_bounds(
                         bounds,
-                        &ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
+                        ImplTraitContext::Disallowed(ImplTraitPosition::Bound),
                     ),
                     in_where_clause: true,
                 })
@@ -1696,9 +1706,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
             WherePredicate::EqPredicate(WhereEqPredicate { lhs_ty, rhs_ty, span }) => {
                 hir::WherePredicate::EqPredicate(hir::WhereEqPredicate {
                     lhs_ty: self
-                        .lower_ty(lhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
+                        .lower_ty(lhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
                     rhs_ty: self
-                        .lower_ty(rhs_ty, &ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
+                        .lower_ty(rhs_ty, ImplTraitContext::Disallowed(ImplTraitPosition::Bound)),
                     span: self.lower_span(*span),
                 })
             }
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index d6abaa8428b..4ef9c7607be 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -36,8 +36,6 @@
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(let_chains)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate tracing;
@@ -64,7 +62,7 @@ use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
 use rustc_session::parse::{add_feature_diagnostics, feature_err};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::{DesugaringKind, Span, DUMMY_SP};
-use smallvec::SmallVec;
+use smallvec::{smallvec, SmallVec};
 use std::collections::hash_map::Entry;
 use thin_vec::ThinVec;
 
@@ -675,7 +673,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         } else {
             (None, None)
         };
-        let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies);
+        let num_nodes = self.item_local_id_counter.as_usize();
+        let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);
         let nodes = hir::OwnerNodes { opt_hash_including_bodies, nodes, bodies };
         let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash };
 
@@ -750,8 +749,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.resolver.get_partial_res(id).map_or(Res::Err, |pr| pr.expect_full_res())
     }
 
-    fn expect_full_res_from_use(&mut self, id: NodeId) -> impl Iterator<Item = Res<NodeId>> {
-        self.resolver.get_import_res(id).present_items()
+    fn lower_import_res(&mut self, id: NodeId, span: Span) -> SmallVec<[Res; 3]> {
+        let res = self.resolver.get_import_res(id).present_items();
+        let res: SmallVec<_> = res.map(|res| self.lower_res(res)).collect();
+        if res.is_empty() {
+            self.dcx().span_delayed_bug(span, "no resolution for an import");
+            return smallvec![Res::Err];
+        }
+        res
     }
 
     fn make_lang_item_qpath(&mut self, lang_item: hir::LangItem, span: Span) -> hir::QPath<'hir> {
@@ -1000,7 +1005,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_assoc_ty_constraint(
         &mut self,
         constraint: &AssocConstraint,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> hir::TypeBinding<'hir> {
         debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", constraint, itctx);
         // lower generic arguments of identifier in constraint
@@ -1079,32 +1084,30 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 hir::TypeBindingKind::Equality { term }
             }
             AssocConstraintKind::Bound { bounds } => {
-                enum DesugarKind<'a> {
+                enum DesugarKind {
                     ImplTrait,
-                    Error(&'a ImplTraitPosition),
+                    Error(ImplTraitPosition),
                     Bound,
                 }
 
                 // Piggy-back on the `impl Trait` context to figure out the correct behavior.
                 let desugar_kind = match itctx {
-                    // We are in the return position:
-                    //
-                    //     fn foo() -> impl Iterator<Item: Debug>
-                    //
-                    // so desugar to
-                    //
-                    //     fn foo() -> impl Iterator<Item = impl Debug>
-                    ImplTraitContext::ReturnPositionOpaqueTy { .. }
-                    | ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait,
-
-                    // We are in the argument position, but within a dyn type:
+                    // in an argument, RPIT, or TAIT, if we are within a dyn type:
                     //
                     //     fn foo(x: dyn Iterator<Item: Debug>)
                     //
-                    // so desugar to
+                    // then desugar to:
                     //
                     //     fn foo(x: dyn Iterator<Item = impl Debug>)
-                    ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait,
+                    //
+                    // This is because dyn traits must have all of their associated types specified.
+                    ImplTraitContext::ReturnPositionOpaqueTy { .. }
+                    | ImplTraitContext::TypeAliasesOpaqueTy { .. }
+                    | ImplTraitContext::Universal
+                        if self.is_in_dyn_type =>
+                    {
+                        DesugarKind::ImplTrait
+                    }
 
                     ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => {
                         DesugarKind::Error(position)
@@ -1157,7 +1160,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     DesugarKind::Error(position) => {
                         let guar = self.dcx().emit_err(errors::MisplacedAssocTyBinding {
                             span: constraint.span,
-                            position: DiagnosticArgFromDisplay(position),
+                            position: DiagnosticArgFromDisplay(&position),
                         });
                         let err_ty =
                             &*self.arena.alloc(self.ty(constraint.span, hir::TyKind::Err(guar)));
@@ -1204,7 +1207,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_generic_arg(
         &mut self,
         arg: &ast::GenericArg,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> hir::GenericArg<'hir> {
         match arg {
             ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(lt)),
@@ -1283,7 +1286,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn lower_ty(&mut self, t: &Ty, itctx: &ImplTraitContext) -> &'hir hir::Ty<'hir> {
+    fn lower_ty(&mut self, t: &Ty, itctx: ImplTraitContext) -> &'hir hir::Ty<'hir> {
         self.arena.alloc(self.lower_ty_direct(t, itctx))
     }
 
@@ -1293,7 +1296,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         qself: &Option<ptr::P<QSelf>>,
         path: &Path,
         param_mode: ParamMode,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> hir::Ty<'hir> {
         // Check whether we should interpret this as a bare trait object.
         // This check mirrors the one in late resolution. We only introduce this special case in
@@ -1335,7 +1338,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.ty(span, hir::TyKind::Tup(tys))
     }
 
-    fn lower_ty_direct(&mut self, t: &Ty, itctx: &ImplTraitContext) -> hir::Ty<'hir> {
+    fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
         let kind = match &t.kind {
             TyKind::Infer => hir::TyKind::Infer,
             TyKind::Err => {
@@ -1454,13 +1457,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     ImplTraitContext::ReturnPositionOpaqueTy { origin, fn_kind } => self
                         .lower_opaque_impl_trait(
                             span,
-                            *origin,
+                            origin,
                             *def_node_id,
                             bounds,
-                            Some(*fn_kind),
+                            Some(fn_kind),
                             itctx,
                         ),
-                    &ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
+                    ImplTraitContext::TypeAliasesOpaqueTy { in_assoc_ty } => self
                         .lower_opaque_impl_trait(
                             span,
                             hir::OpaqueTyOrigin::TyAlias { in_assoc_ty },
@@ -1507,9 +1510,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             .create_feature_err(
                                 MisplacedImplTrait {
                                     span: t.span,
-                                    position: DiagnosticArgFromDisplay(position),
+                                    position: DiagnosticArgFromDisplay(&position),
                                 },
-                                *feature,
+                                feature,
                             )
                             .emit();
                         hir::TyKind::Err(guar)
@@ -1517,7 +1520,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     ImplTraitContext::Disallowed(position) => {
                         let guar = self.dcx().emit_err(MisplacedImplTrait {
                             span: t.span,
-                            position: DiagnosticArgFromDisplay(position),
+                            position: DiagnosticArgFromDisplay(&position),
                         });
                         hir::TyKind::Err(guar)
                     }
@@ -1575,7 +1578,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         opaque_ty_node_id: NodeId,
         bounds: &GenericBounds,
         fn_kind: Option<FnDeclKind>,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> hir::TyKind<'hir> {
         // Make sure we know that some funky desugaring has been going on here.
         // This is a first: there is code in other places like for loop
@@ -1842,7 +1845,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     ImplTraitContext::Disallowed(ImplTraitPosition::PointerParam)
                 }
             };
-            self.lower_ty_direct(&param.ty, &itctx)
+            self.lower_ty_direct(&param.ty, itctx)
         }));
 
         let output = match coro {
@@ -1870,7 +1873,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             ImplTraitContext::Disallowed(ImplTraitPosition::PointerReturn)
                         }
                     };
-                    hir::FnRetTy::Return(self.lower_ty(ty, &itctx))
+                    hir::FnRetTy::Return(self.lower_ty(ty, itctx))
                 }
                 FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(self.lower_span(*span)),
             },
@@ -1971,7 +1974,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         output: &FnRetTy,
         coro: CoroutineKind,
         opaque_ty_span: Span,
-        nested_impl_trait_context: ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> hir::GenericBound<'hir> {
         // Compute the `T` in `Future<Output = T>` from the return type.
         let output_ty = match output {
@@ -1979,7 +1982,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
                 // `impl Future` opaque type that `async fn` implicitly
                 // generates.
-                self.lower_ty(ty, &nested_impl_trait_context)
+                self.lower_ty(ty, itctx)
             }
             FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
         };
@@ -2019,7 +2022,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_param_bound(
         &mut self,
         tpb: &GenericBound,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> hir::GenericBound<'hir> {
         match tpb {
             GenericBound::Trait(p, modifiers) => hir::GenericBound::Trait(
@@ -2158,7 +2161,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     .map(|def| {
                         self.lower_ty(
                             def,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
                         )
                     });
 
@@ -2168,7 +2171,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             }
             GenericParamKind::Const { ty, kw_span: _, default } => {
                 let ty = self
-                    .lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
+                    .lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault));
 
                 // Not only do we deny const param defaults in binders but we also map them to `None`
                 // since later compiler stages cannot handle them (and shouldn't need to be able to).
@@ -2198,7 +2201,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         modifiers: ast::TraitBoundModifiers,
         p: &TraitRef,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> hir::TraitRef<'hir> {
         let path = match self.lower_qpath(
             p.ref_id,
@@ -2218,7 +2221,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_poly_trait_ref(
         &mut self,
         p: &PolyTraitRef,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
         modifiers: ast::TraitBoundModifiers,
     ) -> hir::PolyTraitRef<'hir> {
         let bound_generic_params =
@@ -2227,7 +2230,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         hir::PolyTraitRef { bound_generic_params, trait_ref, span: self.lower_span(p.span) }
     }
 
-    fn lower_mt(&mut self, mt: &MutTy, itctx: &ImplTraitContext) -> hir::MutTy<'hir> {
+    fn lower_mt(&mut self, mt: &MutTy, itctx: ImplTraitContext) -> hir::MutTy<'hir> {
         hir::MutTy { ty: self.lower_ty(&mt.ty, itctx), mutbl: mt.mutbl }
     }
 
@@ -2235,7 +2238,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_param_bounds(
         &mut self,
         bounds: &[GenericBound],
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> hir::GenericBounds<'hir> {
         self.arena.alloc_from_iter(self.lower_param_bounds_mut(bounds, itctx))
     }
@@ -2243,7 +2246,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_param_bounds_mut<'s>(
         &'s mut self,
         bounds: &'s [GenericBound],
-        itctx: &'s ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> impl Iterator<Item = hir::GenericBound<'hir>> + Captures<'s> + Captures<'a> {
         bounds.iter().map(move |bound| self.lower_param_bound(bound, itctx))
     }
@@ -2279,7 +2282,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             bounds,
             /* colon_span */ None,
             span,
-            &ImplTraitContext::Universal,
+            ImplTraitContext::Universal,
             hir::PredicateOrigin::ImplTrait,
         );
 
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 0af141ff99a..c097feb6b34 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -38,7 +38,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                             None,
                         );
                         let (pats, ddpos) = self.lower_pat_tuple(pats, "tuple struct");
@@ -55,7 +55,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                             None,
                         );
                         break hir::PatKind::Path(qpath);
@@ -66,7 +66,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             qself,
                             path,
                             ParamMode::Optional,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                             None,
                         );
 
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index b58ac5c3dae..48941a232c2 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -27,7 +27,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         qself: &Option<ptr::P<QSelf>>,
         p: &Path,
         param_mode: ParamMode,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
         // modifiers of the impl/bound if this is a trait path
         modifiers: Option<ast::TraitBoundModifiers>,
     ) -> hir::QPath<'hir> {
@@ -196,6 +196,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         p: &Path,
         param_mode: ParamMode,
     ) -> &'hir hir::UsePath<'hir> {
+        assert!((1..=3).contains(&res.len()));
         self.arena.alloc(hir::UsePath {
             res,
             segments: self.arena.alloc_from_iter(p.segments.iter().map(|segment| {
@@ -204,7 +205,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     segment,
                     param_mode,
                     ParenthesizedGenericArgs::Err,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     None,
                     None,
                 )
@@ -219,7 +220,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         segment: &PathSegment,
         param_mode: ParamMode,
         parenthesized_generic_args: ParenthesizedGenericArgs,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
         constness: Option<ast::BoundConstness>,
         // Additional features ungated with a bound modifier like `async`.
         // This is passed down to the implicit associated type binding in
@@ -373,7 +374,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         &mut self,
         data: &AngleBracketedArgs,
         param_mode: ParamMode,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
     ) -> (GenericArgsCtor<'hir>, bool) {
         let has_non_lt_args = data.args.iter().any(|arg| match arg {
             AngleBracketedArg::Arg(ast::GenericArg::Lifetime(_))
@@ -404,7 +405,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_parenthesized_parameter_data(
         &mut self,
         data: &ParenthesizedArgs,
-        itctx: &ImplTraitContext,
+        itctx: ImplTraitContext,
         bound_modifier_allowed_features: Option<Lrc<[Symbol]>>,
     ) -> (GenericArgsCtor<'hir>, bool) {
         // Switch to `PassThrough` mode for anonymous lifetimes; this
@@ -414,7 +415,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // we generally don't permit such things (see #51008).
         let ParenthesizedArgs { span, inputs, inputs_span, output } = data;
         let inputs = self.arena.alloc_from_iter(inputs.iter().map(|ty| {
-            self.lower_ty_direct(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
+            self.lower_ty_direct(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitParam))
         }));
         let output_ty = match output {
             // Only allow `impl Trait` in return position. i.e.:
@@ -428,7 +429,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 } else {
                     self.lower_ty(
                         ty,
-                        &ImplTraitContext::FeatureGated(
+                        ImplTraitContext::FeatureGated(
                             ImplTraitPosition::FnTraitReturn,
                             sym::impl_trait_in_fn_trait_return,
                         ),
@@ -436,7 +437,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }
             }
             FnRetTy::Ty(ty) => {
-                self.lower_ty(ty, &ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
+                self.lower_ty(ty, ImplTraitContext::Disallowed(ImplTraitPosition::FnTraitReturn))
             }
             FnRetTy::Default(_) => self.arena.alloc(self.ty_tup(*span, &[])),
         };
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 5f54a0ddf8c..9662c73ca85 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::{codes::*, AddToDiagnostic, Applicability};
+use rustc_errors::{codes::*, AddToDiagnostic, Applicability, Diagnostic, SubdiagnosticMessageOp};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
 
@@ -372,13 +372,7 @@ pub struct EmptyLabelManySpans(pub Vec<Span>);
 
 // The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
 impl AddToDiagnostic for EmptyLabelManySpans {
-    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
-    where
-        F: Fn(
-            &mut rustc_errors::Diagnostic,
-            rustc_errors::SubdiagnosticMessage,
-        ) -> rustc_errors::SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         diag.span_labels(self.0, "");
     }
 }
@@ -735,13 +729,7 @@ pub struct StableFeature {
 }
 
 impl AddToDiagnostic for StableFeature {
-    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
-    where
-        F: Fn(
-            &mut rustc_errors::Diagnostic,
-            rustc_errors::SubdiagnosticMessage,
-        ) -> rustc_errors::SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         diag.arg("name", self.name);
         diag.arg("since", self.since);
         diag.help(fluent::ast_passes_stable_since);
diff --git a/compiler/rustc_ast_passes/src/lib.rs b/compiler/rustc_ast_passes/src/lib.rs
index fa6cdd55c3d..74d0fff2734 100644
--- a/compiler/rustc_ast_passes/src/lib.rs
+++ b/compiler/rustc_ast_passes/src/lib.rs
@@ -11,8 +11,6 @@
 #![feature(if_let_guard)]
 #![feature(iter_is_partitioned)]
 #![feature(let_chains)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 pub mod ast_validation;
 mod errors;
diff --git a/compiler/rustc_ast_pretty/src/lib.rs b/compiler/rustc_ast_pretty/src/lib.rs
index 61617beb86b..b9e217a21e3 100644
--- a/compiler/rustc_ast_pretty/src/lib.rs
+++ b/compiler/rustc_ast_pretty/src/lib.rs
@@ -1,8 +1,6 @@
 #![allow(internal_features)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![feature(box_patterns)]
 
 mod helpers;
diff --git a/compiler/rustc_attr/src/lib.rs b/compiler/rustc_attr/src/lib.rs
index 3c5bcecddea..dd87a5c4dc3 100644
--- a/compiler/rustc_attr/src/lib.rs
+++ b/compiler/rustc_attr/src/lib.rs
@@ -8,8 +8,6 @@
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![feature(let_chains)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs
index 948af039537..6a683d129de 100644
--- a/compiler/rustc_borrowck/src/borrow_set.rs
+++ b/compiler/rustc_borrowck/src/borrow_set.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use crate::path_utils::allow_two_phase_borrow;
 use crate::place_ext::PlaceExt;
 use crate::BorrowIndex;
diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs
index 6cbcda37f50..429bcb74a8e 100644
--- a/compiler/rustc_borrowck/src/borrowck_errors.rs
+++ b/compiler/rustc_borrowck/src/borrowck_errors.rs
@@ -1,3 +1,6 @@
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
+
 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/constraints/mod.rs b/compiler/rustc_borrowck/src/constraints/mod.rs
index 041ac75ec01..ff11e4db121 100644
--- a/compiler/rustc_borrowck/src/constraints/mod.rs
+++ b/compiler/rustc_borrowck/src/constraints/mod.rs
@@ -1,6 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
-
 use rustc_data_structures::graph::scc::Sccs;
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::mir::ConstraintCategory;
diff --git a/compiler/rustc_borrowck/src/consumers.rs b/compiler/rustc_borrowck/src/consumers.rs
index becfa535a59..a58fe2b7447 100644
--- a/compiler/rustc_borrowck/src/consumers.rs
+++ b/compiler/rustc_borrowck/src/consumers.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 //! This file provides API for compiler consumers.
 
 use rustc_hir::def_id::LocalDefId;
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 1bd891bdd68..bc5bd787956 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::graph::WithSuccessors;
 use rustc_index::bit_set::BitSet;
diff --git a/compiler/rustc_borrowck/src/def_use.rs b/compiler/rustc_borrowck/src/def_use.rs
index d0cf339e7ba..6fd80d005d9 100644
--- a/compiler/rustc_borrowck/src/def_use.rs
+++ b/compiler/rustc_borrowck/src/def_use.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use rustc_middle::mir::visit::{
     MutatingUseContext, NonMutatingUseContext, NonUseContext, PlaceContext,
 };
diff --git a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
index bb5335febbf..a540fcee871 100644
--- a/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs
@@ -1,6 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
-
 use rustc_errors::DiagnosticBuilder;
 use rustc_infer::infer::canonical::Canonical;
 use rustc_infer::infer::error_reporting::nice_region_error::NiceRegionError;
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 6debb3362b0..f87269960bc 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1,5 +1,8 @@
 // ignore-tidy-filelength
 
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
+
 use either::Either;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxIndexSet;
@@ -401,66 +404,60 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 }
                 let typeck = self.infcx.tcx.typeck(self.mir_def_id());
                 let hir_id = hir.parent_id(expr.hir_id);
-                if let Some(parent) = self.infcx.tcx.opt_hir_node(hir_id) {
-                    let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
-                        && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
-                        && let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
-                    {
-                        (def_id.as_local(), args, 1)
-                    } else if let hir::Node::Expr(parent_expr) = parent
-                        && let hir::ExprKind::Call(call, args) = parent_expr.kind
-                        && let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
-                    {
-                        (def_id.as_local(), args, 0)
-                    } else {
-                        (None, &[][..], 0)
+                let parent = self.infcx.tcx.hir_node(hir_id);
+                let (def_id, args, offset) = if let hir::Node::Expr(parent_expr) = parent
+                    && let hir::ExprKind::MethodCall(_, _, args, _) = parent_expr.kind
+                    && let Some(def_id) = typeck.type_dependent_def_id(parent_expr.hir_id)
+                {
+                    (def_id.as_local(), args, 1)
+                } else if let hir::Node::Expr(parent_expr) = parent
+                    && let hir::ExprKind::Call(call, args) = parent_expr.kind
+                    && let ty::FnDef(def_id, _) = typeck.node_type(call.hir_id).kind()
+                {
+                    (def_id.as_local(), args, 0)
+                } else {
+                    (None, &[][..], 0)
+                };
+                if let Some(def_id) = def_id
+                    && let node =
+                        self.infcx.tcx.hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
+                    && let Some(fn_sig) = node.fn_sig()
+                    && let Some(ident) = node.ident()
+                    && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
+                    && let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
+                {
+                    let mut span: MultiSpan = arg.span.into();
+                    span.push_span_label(
+                        arg.span,
+                        "this parameter takes ownership of the value".to_string(),
+                    );
+                    let descr = match node.fn_kind() {
+                        Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
+                        Some(hir::intravisit::FnKind::Method(..)) => "method",
+                        Some(hir::intravisit::FnKind::Closure) => "closure",
                     };
-                    if let Some(def_id) = def_id
-                        && let Some(node) = self
-                            .infcx
-                            .tcx
-                            .opt_hir_node(self.infcx.tcx.local_def_id_to_hir_id(def_id))
-                        && let Some(fn_sig) = node.fn_sig()
-                        && let Some(ident) = node.ident()
-                        && let Some(pos) = args.iter().position(|arg| arg.hir_id == expr.hir_id)
-                        && let Some(arg) = fn_sig.decl.inputs.get(pos + offset)
-                    {
-                        let mut span: MultiSpan = arg.span.into();
-                        span.push_span_label(
-                            arg.span,
-                            "this parameter takes ownership of the value".to_string(),
-                        );
-                        let descr = match node.fn_kind() {
-                            Some(hir::intravisit::FnKind::ItemFn(..)) | None => "function",
-                            Some(hir::intravisit::FnKind::Method(..)) => "method",
-                            Some(hir::intravisit::FnKind::Closure) => "closure",
-                        };
-                        span.push_span_label(ident.span, format!("in this {descr}"));
-                        err.span_note(
-                            span,
-                            format!(
-                                "consider changing this parameter type in {descr} `{ident}` to \
+                    span.push_span_label(ident.span, format!("in this {descr}"));
+                    err.span_note(
+                        span,
+                        format!(
+                            "consider changing this parameter type in {descr} `{ident}` to \
                                  borrow instead if owning the value isn't necessary",
-                            ),
-                        );
-                    }
-                    let place = &self.move_data.move_paths[mpi].place;
-                    let ty = place.ty(self.body, self.infcx.tcx).ty;
-                    if let hir::Node::Expr(parent_expr) = parent
-                        && let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
-                        && let hir::ExprKind::Path(hir::QPath::LangItem(
-                            LangItem::IntoIterIntoIter,
-                            _,
-                        )) = call_expr.kind
-                    {
-                        // Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
-                    } else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } =
-                        move_spans
-                    {
-                        // We already suggest cloning for these cases in `explain_captures`.
-                    } else {
-                        self.suggest_cloning(err, ty, expr, move_span);
-                    }
+                        ),
+                    );
+                }
+                let place = &self.move_data.move_paths[mpi].place;
+                let ty = place.ty(self.body, self.infcx.tcx).ty;
+                if let hir::Node::Expr(parent_expr) = parent
+                    && let hir::ExprKind::Call(call_expr, _) = parent_expr.kind
+                    && let hir::ExprKind::Path(hir::QPath::LangItem(LangItem::IntoIterIntoIter, _)) =
+                        call_expr.kind
+                {
+                    // Do not suggest `.clone()` in a `for` loop, we already suggest borrowing.
+                } else if let UseSpans::FnSelfUse { kind: CallKind::Normal { .. }, .. } = move_spans
+                {
+                    // We already suggest cloning for these cases in `explain_captures`.
+                } else {
+                    self.suggest_cloning(err, ty, expr, move_span);
                 }
             }
             if let Some(pat) = finder.pat {
@@ -1762,7 +1759,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                         fn_decl: hir::FnDecl { inputs, .. },
                         ..
                     }) = e.kind
-                        && let Some(hir::Node::Expr(body)) = self.tcx.opt_hir_node(body.hir_id)
+                        && let hir::Node::Expr(body) = self.tcx.hir_node(body.hir_id)
                     {
                         self.suggest_arg = "this: &Self".to_string();
                         if inputs.len() > 0 {
@@ -1828,11 +1825,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
             }
         }
 
-        if let Some(hir::Node::ImplItem(hir::ImplItem {
+        if let hir::Node::ImplItem(hir::ImplItem {
             kind: hir::ImplItemKind::Fn(_fn_sig, body_id),
             ..
-        })) = self.infcx.tcx.opt_hir_node(self.mir_hir_id())
-            && let Some(hir::Node::Expr(expr)) = self.infcx.tcx.opt_hir_node(body_id.hir_id)
+        }) = self.infcx.tcx.hir_node(self.mir_hir_id())
+            && let hir::Node::Expr(expr) = self.infcx.tcx.hir_node(body_id.hir_id)
         {
             let mut finder = ExpressionFinder {
                 capture_span: *capture_kind_span,
@@ -2400,8 +2397,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                 let proper_span = proper_span.source_callsite();
                 if let Some(scope) = self.body.source_scopes.get(source_info.scope)
                     && let ClearCrossCrate::Set(scope_data) = &scope.local_data
-                    && let Some(node) = self.infcx.tcx.opt_hir_node(scope_data.lint_root)
-                    && let Some(id) = node.body_id()
+                    && let Some(id) = self.infcx.tcx.hir_node(scope_data.lint_root).body_id()
                     && let hir::ExprKind::Block(block, _) = self.infcx.tcx.hir().body(id).value.kind
                 {
                     for stmt in block.stmts {
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 4f66468a865..483ecee850b 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -1,5 +1,8 @@
 //! Print diagnostics to explain why values are borrowed.
 
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
+
 use rustc_errors::{Applicability, Diagnostic};
 use rustc_hir as hir;
 use rustc_hir::intravisit::Visitor;
@@ -87,7 +90,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
                     if let hir::ExprKind::Path(hir::QPath::Resolved(None, p)) = expr.kind
                         && let [hir::PathSegment { ident, args: None, .. }] = p.segments
                         && let hir::def::Res::Local(hir_id) = p.res
-                        && let Some(hir::Node::Pat(pat)) = tcx.opt_hir_node(hir_id)
+                        && let hir::Node::Pat(pat) = tcx.hir_node(hir_id)
                     {
                         err.span_label(pat.span, format!("binding `{ident}` declared here"));
                     }
diff --git a/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs b/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs
index 2c4d953f011..ff4f2bb9614 100644
--- a/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/find_all_local_uses.rs
@@ -1,6 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
-
 use std::collections::BTreeSet;
 
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
diff --git a/compiler/rustc_borrowck/src/diagnostics/find_use.rs b/compiler/rustc_borrowck/src/diagnostics/find_use.rs
index 2495613fea1..94b17e0a2f9 100644
--- a/compiler/rustc_borrowck/src/diagnostics/find_use.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/find_use.rs
@@ -1,6 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
-
 use std::collections::VecDeque;
 use std::rc::Rc;
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
index 0a0bb75a2a3..126a50c91b4 100644
--- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs
@@ -1,3 +1,6 @@
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
+
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
 use rustc_middle::mir::*;
 use rustc_middle::ty::{self, Ty};
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 55649ec2f16..9e7fd45ec19 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -1,3 +1,6 @@
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
+
 use hir::ExprKind;
 use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder};
 use rustc_hir as hir;
@@ -396,7 +399,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
 
                 let upvar_hir_id = captured_place.get_root_variable();
 
-                if let Some(Node::Pat(pat)) = self.infcx.tcx.opt_hir_node(upvar_hir_id)
+                if let Node::Pat(pat) = self.infcx.tcx.hir_node(upvar_hir_id)
                     && let hir::PatKind::Binding(hir::BindingAnnotation::NONE, _, upvar_ident, _) =
                         pat.kind
                 {
@@ -688,15 +691,15 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         break;
                     }
                     f_in_trait_opt.and_then(|f_in_trait| {
-                        match self.infcx.tcx.opt_hir_node(f_in_trait) {
-                            Some(Node::TraitItem(hir::TraitItem {
+                        match self.infcx.tcx.hir_node(f_in_trait) {
+                            Node::TraitItem(hir::TraitItem {
                                 kind:
                                     hir::TraitItemKind::Fn(
                                         hir::FnSig { decl: hir::FnDecl { inputs, .. }, .. },
                                         _,
                                     ),
                                 ..
-                            })) => {
+                            }) => {
                                 let hir::Ty { span, .. } = inputs[local.index() - 1];
                                 Some(span)
                             }
@@ -759,10 +762,10 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         //
         // `let &b = a;` -> `let &(mut b) = a;`
         if let Some(hir_id) = hir_id
-            && let Some(hir::Node::Local(hir::Local {
+            && let hir::Node::Local(hir::Local {
                 pat: hir::Pat { kind: hir::PatKind::Ref(_, _), .. },
                 ..
-            })) = self.infcx.tcx.opt_hir_node(hir_id)
+            }) = self.infcx.tcx.hir_node(hir_id)
             && let Ok(name) =
                 self.infcx.tcx.sess.source_map().span_to_snippet(local_decl.source_info.span)
         {
@@ -1206,7 +1209,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 };
 
                 if let Some(hir_id) = hir_id
-                    && let Some(hir::Node::Local(local)) = self.infcx.tcx.opt_hir_node(hir_id)
+                    && let hir::Node::Local(local) = self.infcx.tcx.hir_node(hir_id)
                 {
                     let tables = self.infcx.tcx.typeck(def_id.as_local().unwrap());
                     if let Some(clone_trait) = self.infcx.tcx.lang_items().clone_trait()
diff --git a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
index bac1d9dd57f..93e28a5f3f3 100644
--- a/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/outlives_suggestion.rs
@@ -1,6 +1,9 @@
 //! Contains utilities for generating suggestions for borrowck errors related to unsatisfied
 //! outlives constraints.
 
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
+
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::Diagnostic;
 use rustc_middle::ty::RegionVid;
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 8c8ca1ead40..e69d2ca966b 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 //! Error reporting machinery for lifetime errors.
 
 use rustc_data_structures::fx::FxIndexSet;
@@ -216,7 +214,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                 if let Some(id) = placeholder.bound.kind.get_id()
                     && let Some(placeholder_id) = id.as_local()
                     && let gat_hir_id = self.infcx.tcx.local_def_id_to_hir_id(placeholder_id)
-                    && let Some(generics_impl) = hir.get_parent(gat_hir_id).generics()
+                    && let Some(generics_impl) =
+                        hir.get_parent(hir.parent_id(gat_hir_id)).generics()
                 {
                     Some((gat_hir_id, generics_impl))
                 } else {
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index c91b8eaab05..e008d230656 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -1,6 +1,10 @@
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
+
 use std::fmt::{self, Display};
 use std::iter;
 
+use rustc_data_structures::fx::IndexEntry;
 use rustc_errors::Diagnostic;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -14,7 +18,7 @@ use crate::{universal_regions::DefiningTy, MirBorrowckCtxt};
 
 /// A name for a particular region used in emitting diagnostics. This name could be a generated
 /// name like `'1`, a name used by the user like `'a`, or a name like `'static`.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Copy)]
 pub(crate) struct RegionName {
     /// The name of the region (interned).
     pub(crate) name: Symbol,
@@ -25,7 +29,7 @@ pub(crate) struct RegionName {
 /// Denotes the source of a region that is named by a `RegionName`. For example, a free region that
 /// was named by the user would get `NamedLateParamRegion` and `'static` lifetime would get `Static`.
 /// This helps to print the right kinds of diagnostics.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Copy)]
 pub(crate) enum RegionNameSource {
     /// A bound (not free) region that was instantiated at the def site (not an HRTB).
     NamedEarlyParamRegion(Span),
@@ -42,7 +46,7 @@ pub(crate) enum RegionNameSource {
     /// The region corresponding to the return type of a closure.
     AnonRegionFromOutput(RegionNameHighlight, &'static str),
     /// The region from a type yielded by a coroutine.
-    AnonRegionFromYieldTy(Span, String),
+    AnonRegionFromYieldTy(Span, Symbol),
     /// An anonymous region from an async fn.
     AnonRegionFromAsyncFn(Span),
     /// An anonymous region from an impl self type or trait
@@ -51,7 +55,7 @@ pub(crate) enum RegionNameSource {
 
 /// Describes what to highlight to explain to the user that we're giving an anonymous region a
 /// synthesized name, and how to highlight it.
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, Copy)]
 pub(crate) enum RegionNameHighlight {
     /// The anonymous region corresponds to a reference that was found by traversing the type in the HIR.
     MatchedHirTy(Span),
@@ -59,11 +63,11 @@ pub(crate) enum RegionNameHighlight {
     MatchedAdtAndSegment(Span),
     /// The anonymous region corresponds to a region where the type annotation is completely missing
     /// from the code, e.g. in a closure arguments `|x| { ... }`, where `x` is a reference.
-    CannotMatchHirTy(Span, String),
+    CannotMatchHirTy(Span, Symbol),
     /// The anonymous region corresponds to a region where the type annotation is completely missing
     /// from the code, and *even if* we print out the full name of the type, the region name won't
     /// be included. This currently occurs for opaque types like `impl Future`.
-    Occluded(Span, String),
+    Occluded(Span, Symbol),
 }
 
 impl RegionName {
@@ -247,25 +251,28 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
 
         assert!(self.regioncx.universal_regions().is_universal_region(fr));
 
-        if let Some(value) = self.region_names.try_borrow_mut().unwrap().get(&fr) {
-            return Some(value.clone());
-        }
+        match self.region_names.borrow_mut().entry(fr) {
+            IndexEntry::Occupied(precomputed_name) => Some(*precomputed_name.get()),
+            IndexEntry::Vacant(slot) => {
+                let new_name = self
+                    .give_name_from_error_region(fr)
+                    .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr))
+                    .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
+                    .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
+                    .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr))
+                    .or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
+                    .or_else(|| {
+                        self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr)
+                    });
+
+                if let Some(new_name) = new_name {
+                    slot.insert(new_name);
+                }
+                debug!("give_region_a_name: gave name {:?}", new_name);
 
-        let value = self
-            .give_name_from_error_region(fr)
-            .or_else(|| self.give_name_if_anonymous_region_appears_in_arguments(fr))
-            .or_else(|| self.give_name_if_anonymous_region_appears_in_upvars(fr))
-            .or_else(|| self.give_name_if_anonymous_region_appears_in_output(fr))
-            .or_else(|| self.give_name_if_anonymous_region_appears_in_yield_ty(fr))
-            .or_else(|| self.give_name_if_anonymous_region_appears_in_impl_signature(fr))
-            .or_else(|| self.give_name_if_anonymous_region_appears_in_arg_position_impl_trait(fr));
-
-        if let Some(value) = &value {
-            self.region_names.try_borrow_mut().unwrap().insert(fr, value.clone());
+                new_name
+            }
         }
-
-        debug!("give_region_a_name: gave name {:?}", value);
-        value
     }
 
     /// Checks for the case where `fr` maps to something that the
@@ -457,9 +464,9 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
         );
         if type_name.contains(&format!("'{counter}")) {
             // Only add a label if we can confirm that a region was labelled.
-            RegionNameHighlight::CannotMatchHirTy(span, type_name)
+            RegionNameHighlight::CannotMatchHirTy(span, Symbol::intern(&type_name))
         } else {
-            RegionNameHighlight::Occluded(span, type_name)
+            RegionNameHighlight::Occluded(span, Symbol::intern(&type_name))
         }
     }
 
@@ -888,7 +895,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
 
         Some(RegionName {
             name: self.synthesize_region_name(),
-            source: RegionNameSource::AnonRegionFromYieldTy(yield_span, type_name),
+            source: RegionNameSource::AnonRegionFromYieldTy(yield_span, Symbol::intern(&type_name)),
         })
     }
 
@@ -980,7 +987,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
             Some(RegionName {
                 name: region_name,
                 source: RegionNameSource::AnonRegionFromArgument(
-                    RegionNameHighlight::CannotMatchHirTy(arg_span, arg_name?.to_string()),
+                    RegionNameHighlight::CannotMatchHirTy(arg_span, arg_name?),
                 ),
             })
         } else {
diff --git a/compiler/rustc_borrowck/src/diagnostics/var_name.rs b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
index 28e07f2a81e..0479cd8af35 100644
--- a/compiler/rustc_borrowck/src/diagnostics/var_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/var_name.rs
@@ -1,6 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
-
 use crate::region_infer::RegionInferenceContext;
 use rustc_index::IndexSlice;
 use rustc_middle::mir::{Body, Local};
diff --git a/compiler/rustc_borrowck/src/facts.rs b/compiler/rustc_borrowck/src/facts.rs
index c54e7070478..68dc9a6764b 100644
--- a/compiler/rustc_borrowck/src/facts.rs
+++ b/compiler/rustc_borrowck/src/facts.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use crate::location::{LocationIndex, LocationTable};
 use crate::BorrowIndex;
 use polonius_engine::AllFacts as PoloniusFacts;
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index bb64571889b..4dba34c11f9 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -111,14 +111,16 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
     let (input_body, promoted) = tcx.mir_promoted(def);
     debug!("run query mir_borrowck: {}", tcx.def_path_str(def));
 
-    if input_body.borrow().should_skip() {
-        debug!("Skipping borrowck because of injected body");
+    let input_body: &Body<'_> = &input_body.borrow();
+
+    if input_body.should_skip() || input_body.tainted_by_errors.is_some() {
+        debug!("Skipping borrowck because of injected body or tainted body");
         // Let's make up a borrowck result! Fun times!
         let result = BorrowCheckResult {
             concrete_opaque_types: FxIndexMap::default(),
             closure_requirements: None,
             used_mut_upvars: SmallVec::new(),
-            tainted_by_errors: None,
+            tainted_by_errors: input_body.tainted_by_errors,
         };
         return tcx.arena.alloc(result);
     }
@@ -127,7 +129,6 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
 
     let infcx =
         tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)).build();
-    let input_body: &Body<'_> = &input_body.borrow();
     let promoted: &IndexSlice<_, _> = &promoted.borrow();
     let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, None).0;
     debug!("mir_borrowck done");
diff --git a/compiler/rustc_borrowck/src/location.rs b/compiler/rustc_borrowck/src/location.rs
index 6f09393169f..63e59217e5d 100644
--- a/compiler/rustc_borrowck/src/location.rs
+++ b/compiler/rustc_borrowck/src/location.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use rustc_index::IndexVec;
 use rustc_middle::mir::{BasicBlock, Body, Location};
 
diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs
index 842e9008058..5129b32d492 100644
--- a/compiler/rustc_borrowck/src/member_constraints.rs
+++ b/compiler/rustc_borrowck/src/member_constraints.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_index::{IndexSlice, IndexVec};
diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs
index 7ace013975e..80d79e1beb7 100644
--- a/compiler/rustc_borrowck/src/nll.rs
+++ b/compiler/rustc_borrowck/src/nll.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 //! The entry point of the NLL borrow checker.
 
 use polonius_engine::{Algorithm, Output};
@@ -184,7 +182,7 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
 
     // Solve the region constraints.
     let (closure_region_requirements, nll_errors) =
-        regioncx.solve(infcx, param_env, body, polonius_output.clone());
+        regioncx.solve(infcx, body, polonius_output.clone());
 
     if !nll_errors.is_empty() {
         // Suppress unhelpful extra errors in `infer_opaque_types`.
diff --git a/compiler/rustc_borrowck/src/path_utils.rs b/compiler/rustc_borrowck/src/path_utils.rs
index 4cfde47664e..adafad7fa2f 100644
--- a/compiler/rustc_borrowck/src/path_utils.rs
+++ b/compiler/rustc_borrowck/src/path_utils.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use crate::borrow_set::{BorrowData, BorrowSet, TwoPhaseActivation};
 use crate::places_conflict;
 use crate::AccessDepth;
diff --git a/compiler/rustc_borrowck/src/place_ext.rs b/compiler/rustc_borrowck/src/place_ext.rs
index 3d7e8c6ebf3..b59ab7fafa5 100644
--- a/compiler/rustc_borrowck/src/place_ext.rs
+++ b/compiler/rustc_borrowck/src/place_ext.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use crate::borrow_set::LocalsStateAtExit;
 use rustc_hir as hir;
 use rustc_middle::mir::ProjectionElem;
diff --git a/compiler/rustc_borrowck/src/places_conflict.rs b/compiler/rustc_borrowck/src/places_conflict.rs
index 777ebf0d438..7e8dba43b71 100644
--- a/compiler/rustc_borrowck/src/places_conflict.rs
+++ b/compiler/rustc_borrowck/src/places_conflict.rs
@@ -50,8 +50,6 @@
 //!    and either equal or disjoint.
 //!  - If we did run out of access, the borrow can access a part of it.
 
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use crate::ArtificialField;
 use crate::Overlap;
 use crate::{AccessDepth, Deep, Shallow};
diff --git a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
index 5c9056272cc..93aae1a7f97 100644
--- a/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
+++ b/compiler/rustc_borrowck/src/polonius/loan_invalidations.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::{self, BasicBlock, Body, Location, NonDivergingIntrinsic, Place, Rvalue};
diff --git a/compiler/rustc_borrowck/src/polonius/loan_kills.rs b/compiler/rustc_borrowck/src/polonius/loan_kills.rs
index 5df94383702..53adad5561e 100644
--- a/compiler/rustc_borrowck/src/polonius/loan_kills.rs
+++ b/compiler/rustc_borrowck/src/polonius/loan_kills.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::{
     Body, Local, Location, Place, PlaceRef, ProjectionElem, Rvalue, Statement, StatementKind,
diff --git a/compiler/rustc_borrowck/src/prefixes.rs b/compiler/rustc_borrowck/src/prefixes.rs
index e9c9709bd1f..8bb3dc88b34 100644
--- a/compiler/rustc_borrowck/src/prefixes.rs
+++ b/compiler/rustc_borrowck/src/prefixes.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 //! From the NLL RFC: "The deep [aka 'supporting'] prefixes for an
 //! place are formed by stripping away fields and derefs, except that
 //! we stop when we reach the deref of a shared reference. [...] "
diff --git a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs
index cfbb2766c33..53541b33c41 100644
--- a/compiler/rustc_borrowck/src/region_infer/dump_mir.rs
+++ b/compiler/rustc_borrowck/src/region_infer/dump_mir.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 //! As part of generating the regions, if you enable `-Zdump-mir=nll`,
 //! we will generate an annotated copy of the MIR that includes the
 //! state of region inference. This code handles emitting the region
diff --git a/compiler/rustc_borrowck/src/region_infer/graphviz.rs b/compiler/rustc_borrowck/src/region_infer/graphviz.rs
index 408c8390e76..c103ba3c407 100644
--- a/compiler/rustc_borrowck/src/region_infer/graphviz.rs
+++ b/compiler/rustc_borrowck/src/region_infer/graphviz.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 //! This module provides linkage between RegionInferenceContext and
 //! `rustc_graphviz` traits, specialized to attaching borrowck analysis
 //! data to rendered labels.
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 89b203f80a4..3153b709ffe 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -658,7 +658,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     pub(super) fn solve(
         &mut self,
         infcx: &InferCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
         body: &Body<'tcx>,
         polonius_output: Option<Rc<PoloniusOutput>>,
     ) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>) {
@@ -674,7 +673,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         // eagerly.
         let mut outlives_requirements = infcx.tcx.is_typeck_child(mir_def_id).then(Vec::new);
 
-        self.check_type_tests(infcx, body, outlives_requirements.as_mut(), &mut errors_buffer);
+        self.check_type_tests(infcx, outlives_requirements.as_mut(), &mut errors_buffer);
 
         debug!(?errors_buffer);
         debug!(?outlives_requirements);
@@ -932,7 +931,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     fn check_type_tests(
         &self,
         infcx: &InferCtxt<'tcx>,
-        body: &Body<'tcx>,
         mut propagated_outlives_requirements: Option<&mut Vec<ClosureOutlivesRequirement<'tcx>>>,
         errors_buffer: &mut RegionErrors<'tcx>,
     ) {
@@ -957,12 +955,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             }
 
             if let Some(propagated_outlives_requirements) = &mut propagated_outlives_requirements {
-                if self.try_promote_type_test(
-                    infcx,
-                    body,
-                    type_test,
-                    propagated_outlives_requirements,
-                ) {
+                if self.try_promote_type_test(infcx, type_test, propagated_outlives_requirements) {
                     continue;
                 }
             }
@@ -1016,7 +1009,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     fn try_promote_type_test(
         &self,
         infcx: &InferCtxt<'tcx>,
-        body: &Body<'tcx>,
         type_test: &TypeTest<'tcx>,
         propagated_outlives_requirements: &mut Vec<ClosureOutlivesRequirement<'tcx>>,
     ) -> bool {
@@ -1179,35 +1171,6 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         Some(ClosureOutlivesSubject::Ty(ClosureOutlivesSubjectTy::bind(tcx, ty)))
     }
 
-    /// Returns a universally quantified region that outlives the
-    /// value of `r` (`r` may be existentially or universally
-    /// quantified).
-    ///
-    /// Since `r` is (potentially) an existential region, it has some
-    /// value which may include (a) any number of points in the CFG
-    /// and (b) any number of `end('x)` elements of universally
-    /// quantified regions. To convert this into a single universal
-    /// region we do as follows:
-    ///
-    /// - Ignore the CFG points in `'r`. All universally quantified regions
-    ///   include the CFG anyhow.
-    /// - For each `end('x)` element in `'r`, compute the mutual LUB, yielding
-    ///   a result `'y`.
-    #[instrument(skip(self), level = "debug", ret)]
-    pub(crate) fn universal_upper_bound(&self, r: RegionVid) -> RegionVid {
-        debug!(r = %self.region_value_str(r));
-
-        // Find the smallest universal region that contains all other
-        // universal regions within `region`.
-        let mut lub = self.universal_regions.fr_fn_body;
-        let r_scc = self.constraint_sccs.scc(r);
-        for ur in self.scc_values.universal_regions_outlived_by(r_scc) {
-            lub = self.universal_region_relations.postdom_upper_bound(lub, ur);
-        }
-
-        lub
-    }
-
     /// Like `universal_upper_bound`, but returns an approximation more suitable
     /// for diagnostics. If `r` contains multiple disjoint universal regions
     /// (e.g. 'a and 'b in `fn foo<'a, 'b> { ... }`, we pick the lower-numbered region.
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index 462b5c8da42..636c174e002 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -418,6 +418,8 @@ fn check_opaque_type_parameter_valid(
                 .into_iter()
                 .map(|i| tcx.def_span(opaque_generics.param_at(i, tcx).def_id))
                 .collect();
+            #[allow(rustc::diagnostic_outside_of_impl)]
+            #[allow(rustc::untranslatable_diagnostic)]
             return Err(tcx
                 .dcx()
                 .struct_span_err(span, "non-defining opaque type use in defining scope")
diff --git a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
index fe56bd54a3f..eeb944702a7 100644
--- a/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
+++ b/compiler/rustc_borrowck/src/region_infer/reverse_sccs.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use crate::constraints::ConstraintSccIndex;
 use crate::RegionInferenceContext;
 use itertools::Itertools;
diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs
index e147f62011d..b1caaa63881 100644
--- a/compiler/rustc_borrowck/src/region_infer/values.rs
+++ b/compiler/rustc_borrowck/src/region_infer/values.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_index::bit_set::SparseBitMatrix;
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index a31d39e14cd..dca8df32800 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use crate::BorrowckInferCtxt;
 use rustc_index::IndexSlice;
 use rustc_infer::infer::NllRegionVariableOrigin;
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 52559f9039b..c97e3170166 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -5,10 +5,13 @@ use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelega
 use rustc_infer::infer::region_constraints::{GenericKind, VerifyBound};
 use rustc_infer::infer::{self, InferCtxt, SubregionOrigin};
 use rustc_middle::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, ConstraintCategory};
-use rustc_middle::ty::GenericArgKind;
-use rustc_middle::ty::{self, TyCtxt};
-use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
+use rustc_middle::traits::query::NoSolution;
+use rustc_middle::traits::ObligationCause;
+use rustc_middle::ty::{self, GenericArgKind, Ty, TyCtxt, TypeFoldable, TypeVisitableExt};
 use rustc_span::{Span, DUMMY_SP};
+use rustc_trait_selection::solve::deeply_normalize;
+use rustc_trait_selection::traits::query::type_op::custom::CustomTypeOp;
+use rustc_trait_selection::traits::query::type_op::{TypeOp, TypeOpOutput};
 
 use crate::{
     constraints::OutlivesConstraint,
@@ -33,6 +36,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,
@@ -47,6 +51,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,
@@ -59,6 +64,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
             universal_regions,
             region_bound_pairs,
             implicit_region_bound,
+            param_env,
             known_type_outlives_obligations,
             locations,
             span,
@@ -137,36 +143,68 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
         // Extract out various useful fields we'll need below.
         let ConstraintConversion {
             tcx,
+            infcx,
             region_bound_pairs,
             implicit_region_bound,
             known_type_outlives_obligations,
             ..
         } = *self;
 
-        let ty::OutlivesPredicate(k1, r2) = predicate;
-        match k1.unpack() {
-            GenericArgKind::Lifetime(r1) => {
-                let r1_vid = self.to_region_vid(r1);
-                let r2_vid = self.to_region_vid(r2);
-                self.add_outlives(r1_vid, r2_vid, constraint_category);
+        let mut outlives_predicates = vec![(predicate, constraint_category)];
+        for iteration in 0.. {
+            if outlives_predicates.is_empty() {
+                break;
+            }
+
+            if !self.tcx.recursion_limit().value_within_limit(iteration) {
+                bug!(
+                    "FIXME(-Znext-solver): Overflowed when processing region obligations: {outlives_predicates:#?}"
+                );
             }
 
-            GenericArgKind::Type(t1) => {
-                // we don't actually use this for anything, but
-                // the `TypeOutlives` code needs an origin.
-                let origin = infer::RelateParamBound(DUMMY_SP, t1, None);
+            let mut next_outlives_predicates = vec![];
+            for (ty::OutlivesPredicate(k1, r2), constraint_category) in outlives_predicates {
+                match k1.unpack() {
+                    GenericArgKind::Lifetime(r1) => {
+                        let r1_vid = self.to_region_vid(r1);
+                        let r2_vid = self.to_region_vid(r2);
+                        self.add_outlives(r1_vid, r2_vid, constraint_category);
+                    }
 
-                TypeOutlives::new(
-                    &mut *self,
-                    tcx,
-                    region_bound_pairs,
-                    Some(implicit_region_bound),
-                    known_type_outlives_obligations,
-                )
-                .type_must_outlive(origin, t1, r2, constraint_category);
+                    GenericArgKind::Type(mut t1) => {
+                        // Normalize the type we receive from a `TypeOutlives` obligation
+                        // in the new trait solver.
+                        if infcx.next_trait_solver() {
+                            t1 = self.normalize_and_add_type_outlives_constraints(
+                                t1,
+                                &mut next_outlives_predicates,
+                            );
+                        }
+
+                        // we don't actually use this for anything, but
+                        // the `TypeOutlives` code needs an origin.
+                        let origin = infer::RelateParamBound(DUMMY_SP, t1, None);
+
+                        TypeOutlives::new(
+                            &mut *self,
+                            tcx,
+                            region_bound_pairs,
+                            Some(implicit_region_bound),
+                            known_type_outlives_obligations,
+                        )
+                        .type_must_outlive(
+                            origin,
+                            t1,
+                            r2,
+                            constraint_category,
+                        );
+                    }
+
+                    GenericArgKind::Const(_) => unreachable!(),
+                }
             }
 
-            GenericArgKind::Const(_) => unreachable!(),
+            outlives_predicates = next_outlives_predicates;
         }
     }
 
@@ -232,6 +270,42 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
         debug!("add_type_test(type_test={:?})", type_test);
         self.constraints.type_tests.push(type_test);
     }
+
+    fn normalize_and_add_type_outlives_constraints(
+        &self,
+        ty: Ty<'tcx>,
+        next_outlives_predicates: &mut Vec<(
+            ty::OutlivesPredicate<ty::GenericArg<'tcx>, ty::Region<'tcx>>,
+            ConstraintCategory<'tcx>,
+        )>,
+    ) -> Ty<'tcx> {
+        let result = CustomTypeOp::new(
+            |ocx| {
+                deeply_normalize(
+                    ocx.infcx.at(&ObligationCause::dummy_with_span(self.span), self.param_env),
+                    ty,
+                )
+                .map_err(|_| NoSolution)
+            },
+            "normalize type outlives obligation",
+        )
+        .fully_perform(self.infcx, self.span);
+
+        match result {
+            Ok(TypeOpOutput { output: ty, constraints, .. }) => {
+                if let Some(constraints) = constraints {
+                    assert!(
+                        constraints.member_constraints.is_empty(),
+                        "no member constraints expected from normalizing: {:#?}",
+                        constraints.member_constraints
+                    );
+                    next_outlives_predicates.extend(constraints.outlives.iter().copied());
+                }
+                ty
+            }
+            Err(_) => ty,
+        }
+    }
 }
 
 impl<'a, 'b, 'tcx> TypeOutlivesDelegate<'tcx> for &'a mut ConstraintConversion<'b, 'tcx> {
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 d518f54fd25..2e0caf44819 100644
--- a/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
+++ b/compiler/rustc_borrowck/src/type_check/free_region_relations.rs
@@ -8,8 +8,11 @@ use rustc_infer::infer::region_constraints::GenericKind;
 use rustc_infer::infer::InferCtxt;
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::query::OutlivesBound;
+use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{self, RegionVid, Ty, TypeVisitableExt};
-use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
+use rustc_span::{ErrorGuaranteed, DUMMY_SP};
+use rustc_trait_selection::solve::deeply_normalize;
+use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
 use rustc_trait_selection::traits::query::type_op::{self, TypeOp};
 use std::rc::Rc;
 use type_op::TypeOpOutput;
@@ -52,7 +55,6 @@ pub(crate) struct CreateResult<'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>,
@@ -60,7 +62,6 @@ pub(crate) fn create<'tcx>(
     UniversalRegionRelationsBuilder {
         infcx,
         param_env,
-        known_type_outlives_obligations,
         implicit_region_bound,
         constraints,
         universal_regions: universal_regions.clone(),
@@ -178,7 +179,6 @@ 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>,
@@ -222,6 +222,32 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
             self.relate_universal_regions(fr, fr_fn_body);
         }
 
+        // Normalize the assumptions we use to borrowck the program.
+        let mut constraints = vec![];
+        let mut known_type_outlives_obligations = vec![];
+        for bound in param_env.caller_bounds() {
+            let Some(mut outlives) = bound.as_type_outlives_clause() else { continue };
+
+            // In the new solver, normalize the type-outlives obligation assumptions.
+            if self.infcx.next_trait_solver() {
+                match deeply_normalize(
+                    self.infcx.at(&ObligationCause::misc(span, defining_ty_def_id), self.param_env),
+                    outlives,
+                ) {
+                    Ok(normalized_outlives) => {
+                        outlives = normalized_outlives;
+                    }
+                    Err(e) => {
+                        self.infcx.err_ctxt().report_fulfillment_errors(e);
+                    }
+                }
+            }
+
+            known_type_outlives_obligations.push(outlives);
+        }
+        let known_type_outlives_obligations =
+            self.infcx.tcx.arena.alloc_slice(&known_type_outlives_obligations);
+
         let unnormalized_input_output_tys = self
             .universal_regions
             .unnormalized_input_tys
@@ -239,7 +265,6 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
         //   the `relations` is built.
         let mut normalized_inputs_and_output =
             Vec::with_capacity(self.universal_regions.unnormalized_input_tys.len() + 1);
-        let mut constraints = vec![];
         for ty in unnormalized_input_output_tys {
             debug!("build: input_or_output={:?}", ty);
             // We add implied bounds from both the unnormalized and normalized ty.
@@ -304,7 +329,19 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
         }
 
         for c in constraints {
-            self.push_region_constraints(c, span);
+            constraint_conversion::ConstraintConversion::new(
+                self.infcx,
+                &self.universal_regions,
+                &self.region_bound_pairs,
+                self.implicit_region_bound,
+                param_env,
+                known_type_outlives_obligations,
+                Locations::All(span),
+                span,
+                ConstraintCategory::Internal,
+                self.constraints,
+            )
+            .convert_all(c);
         }
 
         CreateResult {
@@ -313,30 +350,12 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
                 outlives: self.outlives.freeze(),
                 inverse_outlives: self.inverse_outlives.freeze(),
             }),
-            known_type_outlives_obligations: self.known_type_outlives_obligations,
+            known_type_outlives_obligations,
             region_bound_pairs: self.region_bound_pairs,
             normalized_inputs_and_output,
         }
     }
 
-    #[instrument(skip(self, data), level = "debug")]
-    fn push_region_constraints(&mut self, data: &QueryRegionConstraints<'tcx>, span: Span) {
-        debug!("constraints generated: {:#?}", data);
-
-        constraint_conversion::ConstraintConversion::new(
-            self.infcx,
-            &self.universal_regions,
-            &self.region_bound_pairs,
-            self.implicit_region_bound,
-            self.known_type_outlives_obligations,
-            Locations::All(span),
-            span,
-            ConstraintCategory::Internal,
-            self.constraints,
-        )
-        .convert_all(data);
-    }
-
     /// Update the type of a single local, which should represent
     /// either the return type of the MIR or one of its arguments. At
     /// the same time, compute and add any implied bounds that come
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index cdb187e0776..cfb46f3ac8a 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 //! This pass type-checks the MIR to ensure it is not broken.
 
 use std::rc::Rc;
@@ -156,10 +154,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
     } = 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,
@@ -217,7 +211,6 @@ pub(crate) fn type_check<'mir, 'tcx>(
                 CustomTypeOp::new(
                     |ocx| {
                         ocx.infcx.register_member_constraints(
-                            param_env,
                             opaque_type_key,
                             decl.hidden_type.ty,
                             decl.hidden_type.span,
@@ -1144,6 +1137,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),
@@ -1987,6 +1981,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     ConstraintCategory::SizedBound,
                 );
             }
+            &Rvalue::NullaryOp(NullOp::DebugAssertions, _) => {}
 
             Rvalue::ShallowInitBox(operand, ty) => {
                 self.check_operand(operand, location);
@@ -2759,6 +2754,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,
                 DUMMY_SP,                   // irrelevant; will be overridden.
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 111eaaf60f7..a7bdfa4eae7 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -12,6 +12,9 @@
 //! The code in this file doesn't *do anything* with those results; it
 //! just returns them for other code to use.
 
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
+
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::Diagnostic;
 use rustc_hir::def_id::{DefId, LocalDefId};
diff --git a/compiler/rustc_borrowck/src/used_muts.rs b/compiler/rustc_borrowck/src/used_muts.rs
index 6ac8e1ba715..81757a62e5b 100644
--- a/compiler/rustc_borrowck/src/used_muts.rs
+++ b/compiler/rustc_borrowck/src/used_muts.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
 use rustc_middle::mir::{
diff --git a/compiler/rustc_builtin_macros/src/errors.rs b/compiler/rustc_builtin_macros/src/errors.rs
index eadb48ddd36..8d2e06bf30d 100644
--- a/compiler/rustc_builtin_macros/src/errors.rs
+++ b/compiler/rustc_builtin_macros/src/errors.rs
@@ -1,6 +1,6 @@
 use rustc_errors::{
-    codes::*, AddToDiagnostic, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
-    Level, MultiSpan, SingleLabelManySpans,
+    codes::*, AddToDiagnostic, DiagCtxt, Diagnostic, DiagnosticBuilder, EmissionGuarantee,
+    IntoDiagnostic, Level, MultiSpan, SingleLabelManySpans, SubdiagnosticMessageOp,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{symbol::Ident, Span, Symbol};
@@ -611,13 +611,7 @@ pub(crate) struct FormatUnusedArg {
 // Allow the singular form to be a subdiagnostic of the multiple-unused
 // form of diagnostic.
 impl AddToDiagnostic for FormatUnusedArg {
-    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, f: F)
-    where
-        F: Fn(
-            &mut rustc_errors::Diagnostic,
-            rustc_errors::SubdiagnosticMessage,
-        ) -> rustc_errors::SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) {
         diag.arg("named", self.named);
         let msg = f(diag, crate::fluent_generated::builtin_macros_format_unused_arg.into());
         diag.span_label(self.span, msg);
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 4d7957ef4dd..d30ccab2394 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -2,6 +2,8 @@
 //! injecting code into the crate before it is lowered to HIR.
 
 #![allow(internal_features)]
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 0afd6d0e670..a7e76fbc128 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -767,6 +767,15 @@ fn codegen_stmt<'tcx>(
                         NullOp::OffsetOf(fields) => {
                             layout.offset_of_subfield(fx, fields.iter()).bytes()
                         }
+                        NullOp::DebugAssertions => {
+                            let val = fx.tcx.sess.opts.debug_assertions;
+                            let val = CValue::by_val(
+                                fx.bcx.ins().iconst(types::I8, i64::try_from(val).unwrap()),
+                                fx.layout_of(fx.tcx.types.bool),
+                            );
+                            lval.write_cvalue(fx, val);
+                            return;
+                        }
                     };
                     let val = CValue::by_val(
                         fx.bcx.ins().iconst(fx.pointer_type, i64::try_from(val).unwrap()),
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index 416f87fcc87..7c432e9c590 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -3,6 +3,8 @@
 #![cfg_attr(doc, doc(rust_logo))]
 #![feature(rustc_private)]
 // Note: please avoid adding other feature gates where possible
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![warn(rust_2018_idioms)]
 #![warn(unused_lifetimes)]
 #![warn(unreachable_pub)]
diff --git a/compiler/rustc_codegen_gcc/src/attributes.rs b/compiler/rustc_codegen_gcc/src/attributes.rs
index 9f361d36886..142f86b003d 100644
--- a/compiler/rustc_codegen_gcc/src/attributes.rs
+++ b/compiler/rustc_codegen_gcc/src/attributes.rs
@@ -62,9 +62,6 @@ pub fn from_fn_attrs<'gcc, 'tcx>(
         if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::COLD) {
             func.add_attribute(FnAttribute::Cold);
         }
-        if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_RETURNS_TWICE) {
-            func.add_attribute(FnAttribute::ReturnsTwice);
-        }
         if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_PURE) {
             func.add_attribute(FnAttribute::Pure);
         }
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index f8f054db65e..863b6333bcc 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -27,8 +27,6 @@
 #![recursion_limit="256"]
 #![warn(rust_2018_idioms)]
 #![warn(unused_lifetimes)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 extern crate rustc_apfloat;
 extern crate rustc_ast;
diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl
index d5bc04f594d..d14fe0299e6 100644
--- a/compiler/rustc_codegen_llvm/messages.ftl
+++ b/compiler/rustc_codegen_llvm/messages.ftl
@@ -28,6 +28,8 @@ codegen_llvm_invalid_minimum_alignment_not_power_of_two =
 codegen_llvm_invalid_minimum_alignment_too_large =
     invalid minimum global alignment: {$align} is too large
 
+codegen_llvm_invalid_target_feature_prefix = target feature `{$feature}` must begin with a `+` or `-`"
+
 codegen_llvm_load_bitcode = failed to load bitcode of module "{$name}"
 codegen_llvm_load_bitcode_with_llvm_err = failed to load bitcode of module "{$name}": {$llvm_err}
 
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 0a7ea599431..07c83f1aa08 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -356,9 +356,6 @@ pub fn from_fn_attrs<'ll, 'tcx>(
     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::COLD) {
         to_add.push(AttributeKind::Cold.create_attr(cx.llcx));
     }
-    if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_RETURNS_TWICE) {
-        to_add.push(AttributeKind::ReturnsTwice.create_attr(cx.llcx));
-    }
     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::FFI_PURE) {
         to_add.push(MemoryEffects::ReadOnly.create_attr(cx.llcx));
     }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 76c9ac6614a..f961cd2d00b 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -461,6 +461,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
         }
         ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
         ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
+        ty::CoroutineClosure(..) => build_closure_env_di_node(cx, unique_type_id),
         ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id),
         ty::Adt(def, ..) => match def.adt_kind() {
             AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id),
@@ -1068,6 +1069,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
     let (&def_id, up_var_tys) = match closure_or_coroutine_ty.kind() {
         ty::Coroutine(def_id, args) => (def_id, args.as_coroutine().prefix_tys()),
         ty::Closure(def_id, args) => (def_id, args.as_closure().upvar_tys()),
+        ty::CoroutineClosure(def_id, args) => (def_id, args.as_coroutine_closure().upvar_tys()),
         _ => {
             bug!(
                 "build_upvar_field_di_nodes() called with non-closure-or-coroutine-type: {:?}",
@@ -1153,7 +1155,8 @@ fn build_closure_env_di_node<'ll, 'tcx>(
     unique_type_id: UniqueTypeId<'tcx>,
 ) -> DINodeCreationResult<'ll> {
     let closure_env_type = unique_type_id.expect_ty();
-    let &ty::Closure(def_id, _args) = closure_env_type.kind() else {
+    let &(ty::Closure(def_id, _) | ty::CoroutineClosure(def_id, _)) = closure_env_type.kind()
+    else {
         bug!("build_closure_env_di_node() called with non-closure-type: {:?}", closure_env_type)
     };
     let containing_scope = get_namespace_for_item(cx, def_id);
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index e839d278bea..587c5e9e8d2 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -253,3 +253,9 @@ pub struct MismatchedDataLayout<'a> {
     pub llvm_target: &'a str,
     pub llvm_layout: &'a str,
 }
+
+#[derive(Diagnostic)]
+#[diag(codegen_llvm_invalid_target_feature_prefix)]
+pub(crate) struct InvalidTargetFeaturePrefix<'a> {
+    pub feature: &'a str,
+}
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index b4512af38e3..e3e48ecb3aa 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -1985,10 +1985,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
 
         match in_elem.kind() {
             ty::RawPtr(p) => {
-                let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
+                let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
                     bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
                 });
-                assert!(!check_sized); // we are in codegen, so we shouldn't see these types
                 require!(
                     metadata.is_unit(),
                     InvalidMonomorphization::CastFatPointer { span, name, ty: in_elem }
@@ -2000,10 +1999,9 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         }
         match out_elem.kind() {
             ty::RawPtr(p) => {
-                let (metadata, check_sized) = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
+                let metadata = p.ty.ptr_metadata_ty(bx.tcx, |ty| {
                     bx.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty)
                 });
-                assert!(!check_sized); // we are in codegen, so we shouldn't see these types
                 require!(
                     metadata.is_unit(),
                     InvalidMonomorphization::CastFatPointer { span, name, ty: out_elem }
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index f4f29078190..de96bf477ad 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -15,8 +15,6 @@
 #![feature(let_chains)]
 #![feature(min_specialization)]
 #![feature(impl_trait_in_assoc_type)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 4ad44a42738..d0044086c61 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -184,7 +184,6 @@ pub enum AttributeKind {
     SanitizeMemory = 22,
     NonLazyBind = 23,
     OptimizeNone = 24,
-    ReturnsTwice = 25,
     ReadNone = 26,
     SanitizeHWAddress = 28,
     WillReturn = 29,
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 99f4488ac0f..4bb400b1879 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -1,7 +1,7 @@
 use crate::back::write::create_informational_target_machine;
 use crate::errors::{
-    PossibleFeature, TargetFeatureDisableOrEnable, UnknownCTargetFeature,
-    UnknownCTargetFeaturePrefix, UnstableCTargetFeature,
+    InvalidTargetFeaturePrefix, PossibleFeature, TargetFeatureDisableOrEnable,
+    UnknownCTargetFeature, UnknownCTargetFeaturePrefix, UnstableCTargetFeature,
 };
 use crate::llvm;
 use libc::c_int;
@@ -511,7 +511,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
         sess.target
             .features
             .split(',')
-            .filter(|v| !v.is_empty() && backend_feature_name(v).is_some())
+            .filter(|v| !v.is_empty() && backend_feature_name(sess, v).is_some())
             .map(String::from),
     );
 
@@ -535,7 +535,7 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
                 }
             };
 
-            let feature = backend_feature_name(s)?;
+            let feature = backend_feature_name(sess, s)?;
             // Warn against use of LLVM specific feature names and unstable features on the CLI.
             if diagnostics {
                 let feature_state = supported_features.iter().find(|&&(v, _)| v == feature);
@@ -611,11 +611,11 @@ pub(crate) fn global_llvm_features(sess: &Session, diagnostics: bool) -> Vec<Str
 /// Returns a feature name for the given `+feature` or `-feature` string.
 ///
 /// Only allows features that are backend specific (i.e. not [`RUSTC_SPECIFIC_FEATURES`].)
-fn backend_feature_name(s: &str) -> Option<&str> {
+fn backend_feature_name<'a>(sess: &Session, s: &'a str) -> Option<&'a str> {
     // features must start with a `+` or `-`.
-    let feature = s.strip_prefix(&['+', '-'][..]).unwrap_or_else(|| {
-        bug!("target feature `{}` must begin with a `+` or `-`", s);
-    });
+    let feature = s
+        .strip_prefix(&['+', '-'][..])
+        .unwrap_or_else(|| sess.dcx().emit_fatal(InvalidTargetFeaturePrefix { feature: s }));
     // Rustc-specific feature requests like `+crt-static` or `-crt-static`
     // are not passed down to LLVM.
     if RUSTC_SPECIFIC_FEATURES.contains(&feature) {
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index f796ce0990f..f7630719368 100644
--- a/compiler/rustc_codegen_llvm/src/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
@@ -123,6 +123,17 @@ impl CodegenCx<'_, '_> {
             return false;
         }
 
+        // Match clang by only supporting COFF and ELF for now.
+        if self.tcx.sess.target.is_like_osx {
+            return false;
+        }
+
+        // With pie relocation model calls of functions defined in the translation
+        // unit can use copy relocations.
+        if self.tcx.sess.relocation_model() == RelocModel::Pie && !is_declaration {
+            return true;
+        }
+
         // Thread-local variables generally don't support copy relocations.
         let is_thread_local_var = llvm::LLVMIsAGlobalVariable(llval)
             .is_some_and(|v| llvm::LLVMIsThreadLocal(v) == llvm::True);
@@ -130,18 +141,12 @@ impl CodegenCx<'_, '_> {
             return false;
         }
 
-        // Match clang by only supporting COFF and ELF for now.
-        if self.tcx.sess.target.is_like_osx {
-            return false;
+        // Respect the direct-access-external-data to override default behavior if present.
+        if let Some(direct) = self.tcx.sess.direct_access_external_data() {
+            return direct;
         }
 
         // Static relocation model should force copy relocations everywhere.
-        if self.tcx.sess.relocation_model() == RelocModel::Static {
-            return true;
-        }
-
-        // With pie relocation model calls of functions defined in the translation
-        // unit can use copy relocations.
-        self.tcx.sess.relocation_model() == RelocModel::Pie && !is_declaration
+        self.tcx.sess.relocation_model() == RelocModel::Static
     }
 }
diff --git a/compiler/rustc_codegen_ssa/Cargo.toml b/compiler/rustc_codegen_ssa/Cargo.toml
index 7d2f5bb193a..c4aaf421444 100644
--- a/compiler/rustc_codegen_ssa/Cargo.toml
+++ b/compiler/rustc_codegen_ssa/Cargo.toml
@@ -9,7 +9,7 @@ ar_archive_writer = "0.1.5"
 bitflags = "2.4.1"
 cc = "1.0.69"
 itertools = "0.11"
-jobserver = "0.1.27"
+jobserver = "0.1.28"
 pathdiff = "0.2.0"
 regex = "1.4"
 rustc_arena = { path = "../rustc_arena" }
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 4211f875dd0..9b24339d255 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -1810,7 +1810,7 @@ impl Translate for SharedEmitter {
 }
 
 impl Emitter for SharedEmitter {
-    fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
+    fn emit_diagnostic(&mut self, diag: rustc_errors::Diagnostic) {
         let args: FxHashMap<DiagnosticArgName, DiagnosticArgValue> =
             diag.args().map(|(name, arg)| (name.clone(), arg.clone())).collect();
         drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 47b1b080119..b387d0b2258 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -103,9 +103,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
         match name {
             sym::cold => codegen_fn_attrs.flags |= CodegenFnAttrFlags::COLD,
             sym::rustc_allocator => codegen_fn_attrs.flags |= CodegenFnAttrFlags::ALLOCATOR,
-            sym::ffi_returns_twice => {
-                codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE
-            }
             sym::ffi_pure => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_PURE,
             sym::ffi_const => codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_CONST,
             sym::rustc_nounwind => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NEVER_UNWIND,
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index fc833a3863e..1afc597a7ef 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -2,6 +2,8 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 266505d3f26..5c6060a7159 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -672,17 +672,23 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let val = match null_op {
                     mir::NullOp::SizeOf => {
                         assert!(bx.cx().type_is_sized(ty));
-                        layout.size.bytes()
+                        let val = layout.size.bytes();
+                        bx.cx().const_usize(val)
                     }
                     mir::NullOp::AlignOf => {
                         assert!(bx.cx().type_is_sized(ty));
-                        layout.align.abi.bytes()
+                        let val = layout.align.abi.bytes();
+                        bx.cx().const_usize(val)
                     }
                     mir::NullOp::OffsetOf(fields) => {
-                        layout.offset_of_subfield(bx.cx(), fields.iter()).bytes()
+                        let val = layout.offset_of_subfield(bx.cx(), fields.iter()).bytes();
+                        bx.cx().const_usize(val)
+                    }
+                    mir::NullOp::DebugAssertions => {
+                        let val = bx.tcx().sess.opts.debug_assertions;
+                        bx.cx().const_bool(val)
                     }
                 };
-                let val = bx.cx().const_usize(val);
                 let tcx = self.cx.tcx();
                 OperandRef {
                     val: OperandValue::Immediate(val),
diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index a158fc6e260..ac7dfbb261d 100644
--- a/compiler/rustc_codegen_ssa/src/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
@@ -1,5 +1,6 @@
 use rustc_middle::mir;
 use rustc_middle::mir::NonDivergingIntrinsic;
+use rustc_session::config::OptLevel;
 
 use super::FunctionCx;
 use super::LocalRef;
@@ -67,8 +68,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 self.codegen_coverage(bx, coverage, statement.source_info.scope);
             }
             mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
-                let op_val = self.codegen_operand(bx, op);
-                bx.assume(op_val.immediate());
+                if !matches!(bx.tcx().sess.opts.optimize, OptLevel::No | OptLevel::Less) {
+                    let op_val = self.codegen_operand(bx, op);
+                    bx.assume(op_val.immediate());
+                }
             }
             mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
                 mir::CopyNonOverlapping { ref count, ref src, ref dst },
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index 6a92ed9717d..a2d0f1c5583 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -1,5 +1,3 @@
-use std::mem;
-
 use either::{Left, Right};
 
 use rustc_hir::def::DefKind;
@@ -24,12 +22,13 @@ use crate::interpret::{
 };
 
 // Returns a pointer to where the result lives
+#[instrument(level = "trace", skip(ecx, body), ret)]
 fn eval_body_using_ecx<'mir, 'tcx>(
     ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
     cid: GlobalId<'tcx>,
     body: &'mir mir::Body<'tcx>,
 ) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
-    debug!("eval_body_using_ecx: {:?}, {:?}", cid, ecx.param_env);
+    trace!(?ecx.param_env);
     let tcx = *ecx.tcx;
     assert!(
         cid.promoted.is_some()
@@ -75,11 +74,8 @@ fn eval_body_using_ecx<'mir, 'tcx>(
             None => InternKind::Constant,
         }
     };
-    let check_alignment = mem::replace(&mut ecx.machine.check_alignment, CheckAlignment::No); // interning doesn't need to respect alignment
     intern_const_alloc_recursive(ecx, intern_kind, &ret)?;
-    ecx.machine.check_alignment = check_alignment;
 
-    debug!("eval_body_using_ecx done: {:?}", ret);
     Ok(ret)
 }
 
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 751fbfacaad..38e7843761b 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -41,13 +41,12 @@ pub trait CompileTimeMachine<'mir, 'tcx: 'mir, T> = Machine<
 /// allocation is interned immutably; if it is `Mutability::Mut`, then the allocation *must be*
 /// already mutable (as a sanity check).
 ///
-/// `recursive_alloc` is called for all recursively encountered allocations.
+/// Returns an iterator over all relocations referred to by this allocation.
 fn intern_shallow<'rt, 'mir, 'tcx, T, M: CompileTimeMachine<'mir, 'tcx, T>>(
     ecx: &'rt mut InterpCx<'mir, 'tcx, M>,
     alloc_id: AllocId,
     mutability: Mutability,
-    mut recursive_alloc: impl FnMut(&InterpCx<'mir, 'tcx, M>, CtfeProvenance),
-) -> Result<(), ()> {
+) -> Result<impl Iterator<Item = CtfeProvenance> + 'tcx, ()> {
     trace!("intern_shallow {:?}", alloc_id);
     // remove allocation
     let Some((_kind, mut alloc)) = ecx.memory.alloc_map.remove(&alloc_id) else {
@@ -65,14 +64,10 @@ fn intern_shallow<'rt, 'mir, 'tcx, T, M: CompileTimeMachine<'mir, 'tcx, T>>(
             assert_eq!(alloc.mutability, Mutability::Mut);
         }
     }
-    // record child allocations
-    for &(_, prov) in alloc.provenance().ptrs().iter() {
-        recursive_alloc(ecx, prov);
-    }
     // link the alloc id to the actual allocation
     let alloc = ecx.tcx.mk_const_alloc(alloc);
     ecx.tcx.set_alloc_id_memory(alloc_id, alloc);
-    Ok(())
+    Ok(alloc.0.0.provenance().ptrs().iter().map(|&(_, prov)| prov))
 }
 
 /// How a constant value should be interned.
@@ -128,12 +123,16 @@ pub fn intern_const_alloc_recursive<
         }
     };
 
-    // Initialize recursive interning.
+    // Intern the base allocation, and initialize todo list for recursive interning.
     let base_alloc_id = ret.ptr().provenance.unwrap().alloc_id();
-    let mut todo = vec![(base_alloc_id, base_mutability)];
+    // First we intern the base allocation, as it requires a different mutability.
+    // This gives us the initial set of nested allocations, which will then all be processed
+    // recursively in the loop below.
+    let mut todo: Vec<_> =
+        intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().map(|prov| prov).collect();
     // We need to distinguish "has just been interned" from "was already in `tcx`",
     // so we track this in a separate set.
-    let mut just_interned = FxHashSet::default();
+    let mut just_interned: FxHashSet<_> = std::iter::once(base_alloc_id).collect();
     // Whether we encountered a bad mutable pointer.
     // We want to first report "dangling" and then "mutable", so we need to delay reporting these
     // errors.
@@ -147,52 +146,56 @@ pub fn intern_const_alloc_recursive<
     // raw pointers, so we cannot rely on validation to catch them -- and since interning runs
     // before validation, and interning doesn't know the type of anything, this means we can't show
     // better errors. Maybe we should consider doing validation before interning in the future.
-    while let Some((alloc_id, mutability)) = todo.pop() {
+    while let Some(prov) = todo.pop() {
+        let alloc_id = prov.alloc_id();
+        // Crucially, we check this *before* checking whether the `alloc_id`
+        // has already been interned. The point of this check is to ensure that when
+        // there are multiple pointers to the same allocation, they are *all* immutable.
+        // Therefore it would be bad if we only checked the first pointer to any given
+        // allocation.
+        // (It is likely not possible to actually have multiple pointers to the same allocation,
+        // so alternatively we could also check that and ICE if there are multiple such pointers.)
+        if intern_kind != InternKind::Promoted
+            && inner_mutability == Mutability::Not
+            && !prov.immutable()
+        {
+            if ecx.tcx.try_get_global_alloc(alloc_id).is_some()
+                && !just_interned.contains(&alloc_id)
+            {
+                // This is a pointer to some memory from another constant. We encounter mutable
+                // pointers to such memory since we do not always track immutability through
+                // these "global" pointers. Allowing them is harmless; the point of these checks
+                // during interning is to justify why we intern the *new* allocations immutably,
+                // so we can completely ignore existing allocations. We also don't need to add
+                // this to the todo list, since after all it is already interned.
+                continue;
+            }
+            // Found a mutable pointer inside a const where inner allocations should be
+            // immutable. We exclude promoteds from this, since things like `&mut []` and
+            // `&None::<Cell<i32>>` lead to promotion that can produce mutable pointers. We rely
+            // on the promotion analysis not screwing up to ensure that it is sound to intern
+            // promoteds as immutable.
+            found_bad_mutable_pointer = true;
+        }
         if ecx.tcx.try_get_global_alloc(alloc_id).is_some() {
             // Already interned.
             debug_assert!(!ecx.memory.alloc_map.contains_key(&alloc_id));
             continue;
         }
         just_interned.insert(alloc_id);
-        intern_shallow(ecx, alloc_id, mutability, |ecx, prov| {
-            let alloc_id = prov.alloc_id();
-            if intern_kind != InternKind::Promoted
-                && inner_mutability == Mutability::Not
-                && !prov.immutable()
-            {
-                if ecx.tcx.try_get_global_alloc(alloc_id).is_some()
-                    && !just_interned.contains(&alloc_id)
-                {
-                    // This is a pointer to some memory from another constant. We encounter mutable
-                    // pointers to such memory since we do not always track immutability through
-                    // these "global" pointers. Allowing them is harmless; the point of these checks
-                    // during interning is to justify why we intern the *new* allocations immutably,
-                    // so we can completely ignore existing allocations. We also don't need to add
-                    // this to the todo list, since after all it is already interned.
-                    return;
-                }
-                // Found a mutable pointer inside a const where inner allocations should be
-                // immutable. We exclude promoteds from this, since things like `&mut []` and
-                // `&None::<Cell<i32>>` lead to promotion that can produce mutable pointers. We rely
-                // on the promotion analysis not screwing up to ensure that it is sound to intern
-                // promoteds as immutable.
-                found_bad_mutable_pointer = true;
-            }
-            // We always intern with `inner_mutability`, and furthermore we ensured above that if
-            // that is "immutable", then there are *no* mutable pointers anywhere in the newly
-            // interned memory -- justifying that we can indeed intern immutably. However this also
-            // means we can *not* easily intern immutably here if `prov.immutable()` is true and
-            // `inner_mutability` is `Mut`: there might be other pointers to that allocation, and
-            // we'd have to somehow check that they are *all* immutable before deciding that this
-            // allocation can be made immutable. In the future we could consider analyzing all
-            // pointers before deciding which allocations can be made immutable; but for now we are
-            // okay with losing some potential for immutability here. This can anyway only affect
-            // `static mut`.
-            todo.push((alloc_id, inner_mutability));
-        })
-        .map_err(|()| {
+        // We always intern with `inner_mutability`, and furthermore we ensured above that if
+        // that is "immutable", then there are *no* mutable pointers anywhere in the newly
+        // interned memory -- justifying that we can indeed intern immutably. However this also
+        // means we can *not* easily intern immutably here if `prov.immutable()` is true and
+        // `inner_mutability` is `Mut`: there might be other pointers to that allocation, and
+        // we'd have to somehow check that they are *all* immutable before deciding that this
+        // allocation can be made immutable. In the future we could consider analyzing all
+        // pointers before deciding which allocations can be made immutable; but for now we are
+        // okay with losing some potential for immutability here. This can anyway only affect
+        // `static mut`.
+        todo.extend(intern_shallow(ecx, alloc_id, inner_mutability).map_err(|()| {
             ecx.tcx.dcx().emit_err(DanglingPtrInFinal { span: ecx.tcx.span, kind: intern_kind })
-        })?;
+        })?);
     }
     if found_bad_mutable_pointer {
         return Err(ecx
@@ -220,13 +223,13 @@ pub fn intern_const_alloc_for_constprop<
         return Ok(());
     }
     // Move allocation to `tcx`.
-    intern_shallow(ecx, alloc_id, Mutability::Not, |_ecx, _| {
+    for _ in intern_shallow(ecx, alloc_id, Mutability::Not).map_err(|()| err_ub!(DeadLocal))? {
         // We are not doing recursive interning, so we don't currently support provenance.
         // (If this assertion ever triggers, we should just implement a
         // proper recursive interning loop -- or just call `intern_const_alloc_recursive`.
         panic!("`intern_const_alloc_for_constprop` called on allocation with nested provenance")
-    })
-    .map_err(|()| err_ub!(DeadLocal).into())
+    }
+    Ok(())
 }
 
 impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>>
@@ -247,15 +250,14 @@ impl<'mir, 'tcx: 'mir, M: super::intern::CompileTimeMachine<'mir, 'tcx, !>>
         let dest = self.allocate(layout, MemoryKind::Stack)?;
         f(self, &dest.clone().into())?;
         let alloc_id = dest.ptr().provenance.unwrap().alloc_id(); // this was just allocated, it must have provenance
-        intern_shallow(self, alloc_id, Mutability::Not, |ecx, prov| {
+        for prov in intern_shallow(self, alloc_id, Mutability::Not).unwrap() {
             // We are not doing recursive interning, so we don't currently support provenance.
             // (If this assertion ever triggers, we should just implement a
             // proper recursive interning loop -- or just call `intern_const_alloc_recursive`.
-            if !ecx.tcx.try_get_global_alloc(prov.alloc_id()).is_some() {
+            if !self.tcx.try_get_global_alloc(prov.alloc_id()).is_some() {
                 panic!("`intern_with_temp_alloc` with nested allocations");
             }
-        })
-        .unwrap();
+        }
         Ok(alloc_id)
     }
 }
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index d48329b6c69..f0f1008aba8 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -246,13 +246,25 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     );
                 }
                 let val = match null_op {
-                    mir::NullOp::SizeOf => layout.size.bytes(),
-                    mir::NullOp::AlignOf => layout.align.abi.bytes(),
+                    mir::NullOp::SizeOf => {
+                        let val = layout.size.bytes();
+                        Scalar::from_target_usize(val, self)
+                    }
+                    mir::NullOp::AlignOf => {
+                        let val = layout.align.abi.bytes();
+                        Scalar::from_target_usize(val, self)
+                    }
                     mir::NullOp::OffsetOf(fields) => {
-                        layout.offset_of_subfield(self, fields.iter()).bytes()
+                        let val = layout.offset_of_subfield(self, fields.iter()).bytes();
+                        Scalar::from_target_usize(val, self)
+                    }
+                    mir::NullOp::DebugAssertions => {
+                        // The checks hidden behind this are always better done by the interpreter
+                        // itself, because it knows the runtime state better.
+                        Scalar::from_bool(false)
                     }
                 };
-                self.write_scalar(Scalar::from_target_usize(val, self), &dest)?;
+                self.write_scalar(val, &dest)?;
             }
 
             ShallowInitBox(ref operand, _) => {
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 85a2e4778d2..ff20fc5092c 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -377,12 +377,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 // to fields, which can yield non-normalized types. So we need to provide a
                 // normalization function.
                 let normalize = |ty| self.tcx.normalize_erasing_regions(self.param_env, ty);
-                let (meta, only_if_sized) = ty.ptr_metadata_ty(*self.tcx, normalize);
-                assert!(
-                    !only_if_sized,
-                    "there should be no more 'maybe has that metadata' types during interpretation"
-                );
-                meta
+                ty.ptr_metadata_ty(*self.tcx, normalize)
             };
             return Ok(meta_ty(caller) == meta_ty(callee));
         }
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 811c2c3c208..90cde81c018 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -993,10 +993,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             // Complain about any other kind of error -- those are bad because we'd like to
             // report them in a way that shows *where* in the value the issue lies.
             Err(err) => {
-                bug!(
-                    "Unexpected Undefined Behavior error during validation: {}",
-                    self.format_error(err)
-                );
+                bug!("Unexpected error during validation: {}", self.format_error(err));
             }
         }
     }
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 946a49982aa..839cfd8d85a 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -5,9 +5,9 @@ Rust MIR: a lowered representation of Rust.
 */
 
 #![allow(internal_features)]
+#![allow(rustc::diagnostic_outside_of_impl)]
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
-#![deny(rustc::untranslatable_diagnostic)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(decl_macro)]
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 89c65d92325..ee3f349c6b8 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -20,7 +20,7 @@ use std::mem;
 use std::ops::{ControlFlow, Deref};
 
 use super::ops::{self, NonConstOp, Status};
-use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
+use super::qualifs::{self, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
 use super::resolver::FlowSensitiveAnalysis;
 use super::{ConstCx, Qualif};
 use crate::const_eval::is_unstable_const_fn;
@@ -149,37 +149,10 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
 
         let return_loc = ccx.body.terminator_loc(return_block);
 
-        let custom_eq = match ccx.const_kind() {
-            // We don't care whether a `const fn` returns a value that is not structurally
-            // matchable. Functions calls are opaque and always use type-based qualification, so
-            // this value should never be used.
-            hir::ConstContext::ConstFn => true,
-
-            // If we know that all values of the return type are structurally matchable, there's no
-            // need to run dataflow.
-            // Opaque types do not participate in const generics or pattern matching, so we can safely count them out.
-            _ if ccx.body.return_ty().has_opaque_types()
-                || !CustomEq::in_any_value_of_ty(ccx, ccx.body.return_ty()) =>
-            {
-                false
-            }
-
-            hir::ConstContext::Const { .. } | hir::ConstContext::Static(_) => {
-                let mut cursor = FlowSensitiveAnalysis::new(CustomEq, ccx)
-                    .into_engine(ccx.tcx, ccx.body)
-                    .iterate_to_fixpoint()
-                    .into_results_cursor(ccx.body);
-
-                cursor.seek_after_primary_effect(return_loc);
-                cursor.get().contains(RETURN_PLACE)
-            }
-        };
-
         ConstQualifs {
             needs_drop: self.needs_drop(ccx, RETURN_PLACE, return_loc),
             needs_non_const_drop: self.needs_non_const_drop(ccx, RETURN_PLACE, return_loc),
             has_mut_interior: self.has_mut_interior(ccx, RETURN_PLACE, return_loc),
-            custom_eq,
             tainted_by_errors,
         }
     }
@@ -571,7 +544,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
             Rvalue::Cast(_, _, _) => {}
 
-            Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) => {}
+            Rvalue::NullaryOp(
+                NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::DebugAssertions,
+                _,
+            ) => {}
             Rvalue::ShallowInitBox(_, _) => {}
 
             Rvalue::UnaryOp(_, operand) => {
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
index 1efa52df581..67fef208079 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/qualifs.rs
@@ -10,7 +10,7 @@ use rustc_middle::mir::*;
 use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::ty::{self, AdtDef, GenericArgsRef, Ty};
 use rustc_trait_selection::traits::{
-    self, ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
+    ImplSource, Obligation, ObligationCause, ObligationCtxt, SelectionContext,
 };
 
 use super::ConstCx;
@@ -24,7 +24,6 @@ pub fn in_any_value_of_ty<'tcx>(
         has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty),
         needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty),
         needs_non_const_drop: NeedsNonConstDrop::in_any_value_of_ty(cx, ty),
-        custom_eq: CustomEq::in_any_value_of_ty(cx, ty),
         tainted_by_errors,
     }
 }
@@ -213,35 +212,6 @@ impl Qualif for NeedsNonConstDrop {
     }
 }
 
-/// A constant that cannot be used as part of a pattern in a `match` expression.
-pub struct CustomEq;
-
-impl Qualif for CustomEq {
-    const ANALYSIS_NAME: &'static str = "flow_custom_eq";
-
-    fn in_qualifs(qualifs: &ConstQualifs) -> bool {
-        qualifs.custom_eq
-    }
-
-    fn in_any_value_of_ty<'tcx>(cx: &ConstCx<'_, 'tcx>, ty: Ty<'tcx>) -> bool {
-        // If *any* component of a composite data type does not implement `Structural{Partial,}Eq`,
-        // we know that at least some values of that type are not structural-match. I say "some"
-        // because that component may be part of an enum variant (e.g.,
-        // `Option::<NonStructuralMatchTy>::Some`), in which case some values of this type may be
-        // structural-match (`Option::None`).
-        traits::search_for_structural_match_violation(cx.body.span, cx.tcx, ty).is_some()
-    }
-
-    fn in_adt_inherently<'tcx>(
-        cx: &ConstCx<'_, 'tcx>,
-        def: AdtDef<'tcx>,
-        args: GenericArgsRef<'tcx>,
-    ) -> bool {
-        let ty = Ty::new_adt(cx.tcx, def, args);
-        !ty.is_structural_eq_shallow(cx.tcx)
-    }
-}
-
 // FIXME: Use `mir::visit::Visitor` for the `in_*` functions if/when it supports early return.
 
 /// Returns `true` if this `Rvalue` contains qualif `Q`.
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index c4542aaa7b2..5ce6a71c4bd 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -60,6 +60,8 @@ impl<'tcx> MirPass<'tcx> for Validator {
                 ty::Closure(..) => Abi::RustCall,
                 ty::CoroutineClosure(..) => Abi::RustCall,
                 ty::Coroutine(..) => Abi::Rust,
+                // No need to do MIR validation on error bodies
+                ty::Error(_) => return,
                 _ => {
                     span_bug!(body.span, "unexpected body ty: {:?} phase {:?}", body_ty, mir_phase)
                 }
@@ -1139,7 +1141,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
             Rvalue::Repeat(_, _)
             | Rvalue::ThreadLocalRef(_)
             | Rvalue::AddressOf(_, _)
-            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _)
+            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::DebugAssertions, _)
             | Rvalue::Discriminant(_) => {}
         }
         self.super_rvalue(rvalue, location);
diff --git a/compiler/rustc_data_structures/Cargo.toml b/compiler/rustc_data_structures/Cargo.toml
index 08aa68ca54a..0635d8552ae 100644
--- a/compiler/rustc_data_structures/Cargo.toml
+++ b/compiler/rustc_data_structures/Cargo.toml
@@ -11,7 +11,7 @@ either = "1.0"
 elsa = "=1.7.1"
 ena = "0.14.2"
 indexmap = { version = "2.0.0" }
-jobserver_crate = { version = "0.1.27", package = "jobserver" }
+jobserver_crate = { version = "0.1.28", package = "jobserver" }
 libc = "0.2"
 measureme = "11"
 rustc-hash = "1.1.0"
diff --git a/compiler/rustc_data_structures/src/jobserver.rs b/compiler/rustc_data_structures/src/jobserver.rs
index 412e33aaa65..89088bc5c1b 100644
--- a/compiler/rustc_data_structures/src/jobserver.rs
+++ b/compiler/rustc_data_structures/src/jobserver.rs
@@ -23,7 +23,10 @@ static GLOBAL_CLIENT: LazyLock<Result<Client, String>> = LazyLock::new(|| {
 
     if matches!(
         error.kind(),
-        FromEnvErrorKind::NoEnvVar | FromEnvErrorKind::NoJobserver | FromEnvErrorKind::Unsupported
+        FromEnvErrorKind::NoEnvVar
+            | FromEnvErrorKind::NoJobserver
+            | FromEnvErrorKind::NegativeFd
+            | FromEnvErrorKind::Unsupported
     ) {
         return Ok(default_client());
     }
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index a71d012db2d..2b799d6f5d3 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -11,8 +11,6 @@
 #![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)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 5903c43ae98..60f11b1bdd4 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -12,8 +12,6 @@
 #![feature(let_chains)]
 #![feature(panic_update_hook)]
 #![feature(result_flattening)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate tracing;
@@ -24,7 +22,9 @@ use rustc_data_structures::profiling::{
     get_resident_set_size, print_time_passes_entry, TimePassesFormat,
 };
 use rustc_errors::registry::Registry;
-use rustc_errors::{markdown, ColorConfig, DiagCtxt, ErrCode, ErrorGuaranteed, PResult};
+use rustc_errors::{
+    markdown, ColorConfig, DiagCtxt, ErrCode, ErrorGuaranteed, FatalError, PResult,
+};
 use rustc_feature::find_gated_cfg;
 use rustc_interface::util::{self, collect_crate_types, get_codegen_backend};
 use rustc_interface::{interface, Queries};
@@ -1231,11 +1231,10 @@ fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
 /// The compiler currently unwinds with a special sentinel value to abort
 /// compilation on fatal errors. This function catches that sentinel and turns
 /// the panic into a `Result` instead.
-pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorGuaranteed> {
+pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, FatalError> {
     catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| {
         if value.is::<rustc_errors::FatalErrorMarker>() {
-            #[allow(deprecated)]
-            ErrorGuaranteed::unchecked_claim_error_was_emitted()
+            FatalError
         } else {
             panic::resume_unwind(value);
         }
@@ -1245,9 +1244,9 @@ pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, ErrorGuarantee
 /// Variant of `catch_fatal_errors` for the `interface::Result` return type
 /// that also computes the exit code.
 pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 {
-    match catch_fatal_errors(f).flatten() {
-        Ok(()) => EXIT_SUCCESS,
-        Err(_) => EXIT_FAILURE,
+    match catch_fatal_errors(f) {
+        Ok(Ok(())) => EXIT_SUCCESS,
+        _ => EXIT_FAILURE,
     }
 }
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0724.md b/compiler/rustc_error_codes/src/error_codes/E0724.md
index 70578acbe0d..bcefd0a7479 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0724.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0724.md
@@ -1,9 +1,12 @@
+#### Note: this error code is no longer emitted by the compiler.
+
+
 `#[ffi_returns_twice]` was used on something other than a foreign function
 declaration.
 
 Erroneous code example:
 
-```compile_fail,E0724
+```compile_fail
 #![feature(ffi_returns_twice)]
 #![crate_type = "lib"]
 
@@ -15,7 +18,7 @@ pub fn foo() {}
 For example, we might correct the previous example by declaring
 the function inside of an `extern` block.
 
-```
+```compile_fail
 #![feature(ffi_returns_twice)]
 
 extern "C" {
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index 5b2766618fc..da688e385aa 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -5,8 +5,6 @@
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![deny(rustdoc::invalid_codeblock_attributes)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 // 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
diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs
index 8fd7c576479..e174cba7813 100644
--- a/compiler/rustc_error_messages/src/lib.rs
+++ b/compiler/rustc_error_messages/src/lib.rs
@@ -3,8 +3,6 @@
 #![feature(lazy_cell)]
 #![feature(rustc_attrs)]
 #![feature(type_alias_impl_trait)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
 
 #[macro_use]
@@ -378,7 +376,7 @@ impl From<Cow<'static, str>> for DiagnosticMessage {
     }
 }
 
-/// A workaround for "good path" ICEs when formatting types in disabled lints.
+/// A workaround for good_path_delayed_bug ICEs when formatting types in disabled lints.
 ///
 /// Delays formatting until `.into(): DiagnosticMessage` is used.
 pub struct DelayDm<F>(pub F);
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index 949f52ef6b5..37f568f12a7 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -44,15 +44,15 @@ impl Translate for AnnotateSnippetEmitter {
 
 impl Emitter for AnnotateSnippetEmitter {
     /// The entry point for the diagnostics generation
-    fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+    fn emit_diagnostic(&mut self, mut diag: Diagnostic) {
         let fluent_args = to_fluent_args(diag.args());
 
-        let mut children = diag.children.clone();
-        let (mut primary_span, suggestions) = self.primary_span_formatted(diag, &fluent_args);
+        let mut suggestions = diag.suggestions.unwrap_or(vec![]);
+        self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args);
 
         self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
-            &mut primary_span,
-            &mut children,
+            &mut diag.span,
+            &mut diag.children,
             &diag.level,
             self.macro_backtrace,
         );
@@ -62,9 +62,9 @@ impl Emitter for AnnotateSnippetEmitter {
             &diag.messages,
             &fluent_args,
             &diag.code,
-            &primary_span,
-            &children,
-            suggestions,
+            &diag.span,
+            &diag.children,
+            &suggestions,
         );
     }
 
@@ -85,7 +85,11 @@ fn source_string(file: Lrc<SourceFile>, line: &Line) -> String {
 /// Maps `Diagnostic::Level` to `snippet::AnnotationType`
 fn annotation_type_for_level(level: Level) -> AnnotationType {
     match level {
-        Level::Bug | Level::DelayedBug(_) | Level::Fatal | Level::Error => AnnotationType::Error,
+        Level::Bug
+        | Level::Fatal
+        | Level::Error
+        | Level::DelayedBug
+        | Level::GoodPathDelayedBug => AnnotationType::Error,
         Level::ForceWarning(_) | Level::Warning => AnnotationType::Warning,
         Level::Note | Level::OnceNote => AnnotationType::Note,
         Level::Help | Level::OnceHelp => AnnotationType::Help,
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 8ad4925cff2..03717a4d654 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -1,8 +1,7 @@
 use crate::snippet::Style;
 use crate::{
-    CodeSuggestion, DelayedBugKind, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee,
-    ErrCode, Level, MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart,
-    SuggestionStyle,
+    CodeSuggestion, 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;
@@ -78,11 +77,12 @@ where
 
     /// Add a subdiagnostic to an existing diagnostic where `f` is invoked on every message used
     /// (to optionally perform eager translation).
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage;
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F);
 }
 
+pub trait SubdiagnosticMessageOp =
+    Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage;
+
 /// Trait implemented by lint types. This should not be implemented manually. Instead, use
 /// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic].
 #[rustc_diagnostic_item = "DecorateLint"]
@@ -235,19 +235,16 @@ impl Diagnostic {
 
     pub fn is_error(&self) -> bool {
         match self.level {
-            Level::Bug
-            | Level::DelayedBug(DelayedBugKind::Normal)
-            | Level::Fatal
-            | Level::Error
-            | Level::FailureNote => true,
+            Level::Bug | Level::Fatal | Level::Error | Level::DelayedBug => true,
 
-            Level::ForceWarning(_)
+            Level::GoodPathDelayedBug
+            | Level::ForceWarning(_)
             | Level::Warning
-            | Level::DelayedBug(DelayedBugKind::GoodPath)
             | Level::Note
             | Level::OnceNote
             | Level::Help
             | Level::OnceHelp
+            | Level::FailureNote
             | Level::Allow
             | Level::Expect(_) => false,
         }
@@ -306,11 +303,11 @@ impl Diagnostic {
     #[track_caller]
     pub fn downgrade_to_delayed_bug(&mut self) {
         assert!(
-            self.is_error(),
+            matches!(self.level, Level::Error | Level::DelayedBug),
             "downgrade_to_delayed_bug: cannot downgrade {:?} to DelayedBug: not an error",
             self.level
         );
-        self.level = Level::DelayedBug(DelayedBugKind::Normal);
+        self.level = Level::DelayedBug;
     }
 
     /// Appends a labeled span to the diagnostic.
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs
index faff7f0b526..e484bef0e0b 100644
--- a/compiler/rustc_errors/src/diagnostic_builder.rs
+++ b/compiler/rustc_errors/src/diagnostic_builder.rs
@@ -99,16 +99,20 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
     }
 
     /// `ErrorGuaranteed::emit_producing_guarantee` uses this.
-    // FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`.
     fn emit_producing_error_guaranteed(mut self) -> ErrorGuaranteed {
         let diag = self.take_diag();
 
-        // Only allow a guarantee if the `level` wasn't switched to a
-        // non-error. The field isn't `pub`, but the whole `Diagnostic` can be
-        // overwritten with a new one, thanks to `DerefMut`.
+        // The only error levels that produce `ErrorGuaranteed` are
+        // `Error` and `DelayedBug`. But `DelayedBug` should never occur here
+        // because delayed bugs have their level changed to `Bug` when they are
+        // actually printed, so they produce an ICE.
+        //
+        // (Also, even though `level` isn't `pub`, the whole `Diagnostic` could
+        // be overwritten with a new one thanks to `DerefMut`. So this assert
+        // protects against that, too.)
         assert!(
-            diag.is_error(),
-            "emitted non-error ({:?}) diagnostic from `DiagnosticBuilder<ErrorGuaranteed>`",
+            matches!(diag.level, Level::Error | Level::DelayedBug),
+            "invalid diagnostic level ({:?})",
             diag.level,
         );
 
diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs
index 15effd3cbec..e936ebc7185 100644
--- a/compiler/rustc_errors/src/diagnostic_impls.rs
+++ b/compiler/rustc_errors/src/diagnostic_impls.rs
@@ -2,7 +2,7 @@ use crate::diagnostic::DiagnosticLocation;
 use crate::{fluent_generated as fluent, AddToDiagnostic};
 use crate::{
     DiagCtxt, DiagnosticArgValue, DiagnosticBuilder, EmissionGuarantee, ErrCode, IntoDiagnostic,
-    IntoDiagnosticArg, Level,
+    IntoDiagnosticArg, Level, SubdiagnosticMessageOp,
 };
 use rustc_ast as ast;
 use rustc_ast_pretty::pprust;
@@ -299,7 +299,7 @@ pub struct SingleLabelManySpans {
     pub label: &'static str,
 }
 impl AddToDiagnostic for SingleLabelManySpans {
-    fn add_to_diagnostic_with<F>(self, diag: &mut crate::Diagnostic, _: F) {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut crate::Diagnostic, _: F) {
         diag.span_labels(self.spans, self.label);
     }
 }
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 4be5ed923e5..b9e92dbb31c 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -193,7 +193,7 @@ pub type DynEmitter = dyn Emitter + DynSend;
 /// Emitter trait for emitting errors.
 pub trait Emitter: Translate {
     /// Emit a structured diagnostic.
-    fn emit_diagnostic(&mut self, diag: &Diagnostic);
+    fn emit_diagnostic(&mut self, diag: Diagnostic);
 
     /// Emit a notification that an artifact has been output.
     /// Currently only supported for the JSON format.
@@ -230,17 +230,17 @@ pub trait Emitter: Translate {
     ///
     /// * If the current `Diagnostic` has only one visible `CodeSuggestion`,
     ///   we format the `help` suggestion depending on the content of the
-    ///   substitutions. In that case, we return the modified span only.
+    ///   substitutions. In that case, we modify the span and clear the
+    ///   suggestions.
     ///
     /// * If the current `Diagnostic` has multiple suggestions,
-    ///   we return the original `primary_span` and the original suggestions.
-    fn primary_span_formatted<'a>(
+    ///   we leave `primary_span` and the suggestions untouched.
+    fn primary_span_formatted(
         &mut self,
-        diag: &'a Diagnostic,
+        primary_span: &mut MultiSpan,
+        suggestions: &mut Vec<CodeSuggestion>,
         fluent_args: &FluentArgs<'_>,
-    ) -> (MultiSpan, &'a [CodeSuggestion]) {
-        let mut primary_span = diag.span.clone();
-        let suggestions = diag.suggestions.as_deref().unwrap_or(&[]);
+    ) {
         if let Some((sugg, rest)) = suggestions.split_first() {
             let msg = self.translate_message(&sugg.msg, fluent_args).map_err(Report::new).unwrap();
             if rest.is_empty() &&
@@ -287,16 +287,15 @@ pub trait Emitter: Translate {
                 primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg);
 
                 // We return only the modified primary_span
-                (primary_span, &[])
+                suggestions.clear();
             } else {
                 // if there are multiple suggestions, print them all in full
                 // to be consistent. We could try to figure out if we can
                 // make one (or the first one) inline, but that would give
                 // undue importance to a semi-random suggestion
-                (primary_span, suggestions)
             }
         } else {
-            (primary_span, suggestions)
+            // do nothing
         }
     }
 
@@ -518,16 +517,15 @@ impl Emitter for HumanEmitter {
         self.sm.as_ref()
     }
 
-    fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+    fn emit_diagnostic(&mut self, mut diag: Diagnostic) {
         let fluent_args = to_fluent_args(diag.args());
 
-        let mut children = diag.children.clone();
-        let (mut primary_span, suggestions) = self.primary_span_formatted(diag, &fluent_args);
-        debug!("emit_diagnostic: suggestions={:?}", suggestions);
+        let mut suggestions = diag.suggestions.unwrap_or(vec![]);
+        self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args);
 
         self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
-            &mut primary_span,
-            &mut children,
+            &mut diag.span,
+            &mut diag.children,
             &diag.level,
             self.macro_backtrace,
         );
@@ -537,9 +535,9 @@ impl Emitter for HumanEmitter {
             &diag.messages,
             &fluent_args,
             &diag.code,
-            &primary_span,
-            &children,
-            suggestions,
+            &diag.span,
+            &diag.children,
+            &suggestions,
             self.track_diagnostics.then_some(&diag.emitted_at),
         );
     }
@@ -576,9 +574,8 @@ impl Emitter for SilentEmitter {
         None
     }
 
-    fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+    fn emit_diagnostic(&mut self, mut diag: Diagnostic) {
         if diag.level == Level::Fatal {
-            let mut diag = diag.clone();
             diag.note(self.fatal_note.clone());
             self.fatal_dcx.emit_diagnostic(diag);
         }
@@ -2116,6 +2113,7 @@ impl HumanEmitter {
                 }
                 if !self.short_message {
                     for child in children {
+                        assert!(child.level.can_be_top_or_sub().1);
                         let span = &child.span;
                         if let Err(err) = self.emit_messages_default_inner(
                             span,
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 6f922998279..470e3d52452 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -176,7 +176,7 @@ impl Translate for JsonEmitter {
 }
 
 impl Emitter for JsonEmitter {
-    fn emit_diagnostic(&mut self, diag: &crate::Diagnostic) {
+    fn emit_diagnostic(&mut self, diag: crate::Diagnostic) {
         let data = Diagnostic::from_errors_diagnostic(diag, self);
         let result = self.emit(EmitTyped::Diagnostic(data));
         if let Err(e) = result {
@@ -201,7 +201,7 @@ impl Emitter for JsonEmitter {
                 }
                 FutureBreakageItem {
                     diagnostic: EmitTyped::Diagnostic(Diagnostic::from_errors_diagnostic(
-                        &diag, self,
+                        diag, self,
                     )),
                 }
             })
@@ -340,7 +340,7 @@ struct UnusedExterns<'a, 'b, 'c> {
 }
 
 impl Diagnostic {
-    fn from_errors_diagnostic(diag: &crate::Diagnostic, je: &JsonEmitter) -> Diagnostic {
+    fn from_errors_diagnostic(diag: crate::Diagnostic, je: &JsonEmitter) -> Diagnostic {
         let args = to_fluent_args(diag.args());
         let sugg = diag.suggestions.iter().flatten().map(|sugg| {
             let translated_message =
@@ -382,6 +382,28 @@ impl Diagnostic {
                 Ok(())
             }
         }
+
+        let translated_message = je.translate_messages(&diag.messages, &args);
+
+        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(),
+            })
+        } else if let Some(IsLint { name, .. }) = &diag.is_lint {
+            Some(DiagnosticCode { code: name.to_string(), explanation: None })
+        } else {
+            None
+        };
+        let level = diag.level.to_str();
+        let spans = DiagnosticSpan::from_multispan(&diag.span, &args, je);
+        let children = diag
+            .children
+            .iter()
+            .map(|c| Diagnostic::from_sub_diagnostic(c, &args, je))
+            .chain(sugg)
+            .collect();
+
         let buf = BufWriter::default();
         let output = buf.clone();
         je.json_rendered
@@ -398,30 +420,12 @@ impl Diagnostic {
         let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
         let output = String::from_utf8(output).unwrap();
 
-        let translated_message = je.translate_messages(&diag.messages, &args);
-
-        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(),
-            })
-        } else if let Some(IsLint { name, .. }) = &diag.is_lint {
-            Some(DiagnosticCode { code: name.to_string(), explanation: None })
-        } else {
-            None
-        };
-
         Diagnostic {
             message: translated_message.to_string(),
             code,
-            level: diag.level.to_str(),
-            spans: DiagnosticSpan::from_multispan(&diag.span, &args, je),
-            children: diag
-                .children
-                .iter()
-                .map(|c| Diagnostic::from_sub_diagnostic(c, &args, je))
-                .chain(sugg)
-                .collect(),
+            level,
+            spans,
+            children,
             rendered: Some(output),
         }
     }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 9ec636dcc9c..7216fa8f5e4 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -5,6 +5,8 @@
 // tidy-alphabetical-start
 #![allow(incomplete_features)]
 #![allow(internal_features)]
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(array_windows)]
@@ -19,6 +21,7 @@
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
+#![feature(trait_alias)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
 // tidy-alphabetical-end
@@ -35,6 +38,7 @@ pub use codes::*;
 pub use diagnostic::{
     AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgName,
     DiagnosticArgValue, DiagnosticStyledString, IntoDiagnosticArg, StringPart, SubDiagnostic,
+    SubdiagnosticMessageOp,
 };
 pub use diagnostic_builder::{
     BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort, IntoDiagnostic,
@@ -429,6 +433,10 @@ struct DiagCtxtInner {
     /// The number of non-lint errors that have been emitted, including duplicates.
     err_count: usize,
 
+    /// The number of stashed errors. Unlike the other counts, this can go up
+    /// and down, so it doesn't guarantee anything.
+    stashed_err_count: usize,
+
     /// The error count shown to the user at the end.
     deduplicated_err_count: usize,
     /// The warning count shown to the user at the end.
@@ -439,7 +447,7 @@ struct DiagCtxtInner {
     has_printed: bool,
 
     emitter: Box<DynEmitter>,
-    span_delayed_bugs: Vec<DelayedDiagnostic>,
+    delayed_bugs: Vec<DelayedDiagnostic>,
     good_path_delayed_bugs: Vec<DelayedDiagnostic>,
     /// This flag indicates that an expected diagnostic was emitted and suppressed.
     /// This is used for the `good_path_delayed_bugs` check.
@@ -523,8 +531,7 @@ fn default_track_diagnostic(diag: Diagnostic, f: &mut dyn FnMut(Diagnostic)) {
 pub static TRACK_DIAGNOSTIC: AtomicRef<fn(Diagnostic, &mut dyn FnMut(Diagnostic))> =
     AtomicRef::new(&(default_track_diagnostic as _));
 
-#[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)]
-pub enum DelayedBugKind {
+enum DelayedBugKind {
     Normal,
     GoodPath,
 }
@@ -557,11 +564,6 @@ impl Drop for DiagCtxtInner {
             self.flush_delayed(DelayedBugKind::Normal)
         }
 
-        // FIXME(eddyb) this explains what `good_path_delayed_bugs` are!
-        // They're `span_delayed_bugs` but for "require some diagnostic happened"
-        // instead of "require some error happened". Sadly that isn't ideal, as
-        // lints can be `#[allow]`'d, potentially leading to this triggering.
-        // Also, "good path" should be replaced with a better naming.
         if !self.has_printed && !self.suppressed_expected_diag && !std::thread::panicking() {
             self.flush_delayed(DelayedBugKind::GoodPath);
         }
@@ -604,11 +606,12 @@ impl DiagCtxt {
                 flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
                 lint_err_count: 0,
                 err_count: 0,
+                stashed_err_count: 0,
                 deduplicated_err_count: 0,
                 deduplicated_warn_count: 0,
                 has_printed: false,
                 emitter,
-                span_delayed_bugs: Vec::new(),
+                delayed_bugs: Vec::new(),
                 good_path_delayed_bugs: Vec::new(),
                 suppressed_expected_diag: false,
                 taught_diagnostics: Default::default(),
@@ -660,12 +663,13 @@ impl DiagCtxt {
         let mut inner = self.inner.borrow_mut();
         inner.lint_err_count = 0;
         inner.err_count = 0;
+        inner.stashed_err_count = 0;
         inner.deduplicated_err_count = 0;
         inner.deduplicated_warn_count = 0;
         inner.has_printed = false;
 
         // actually free the underlying memory (which `clear` would not do)
-        inner.span_delayed_bugs = Default::default();
+        inner.delayed_bugs = Default::default();
         inner.good_path_delayed_bugs = Default::default();
         inner.taught_diagnostics = Default::default();
         inner.emitted_diagnostic_codes = Default::default();
@@ -681,10 +685,8 @@ impl DiagCtxt {
         let key = (span.with_parent(None), key);
 
         if diag.is_error() {
-            if diag.is_lint.is_some() {
-                inner.lint_err_count += 1;
-            } else {
-                inner.err_count += 1;
+            if diag.is_lint.is_none() {
+                inner.stashed_err_count += 1;
             }
         }
 
@@ -700,10 +702,8 @@ impl DiagCtxt {
         let key = (span.with_parent(None), key);
         let diag = inner.stashed_diagnostics.remove(&key)?;
         if diag.is_error() {
-            if diag.is_lint.is_some() {
-                inner.lint_err_count -= 1;
-            } else {
-                inner.err_count -= 1;
+            if diag.is_lint.is_none() {
+                inner.stashed_err_count -= 1;
             }
         }
         Some(DiagnosticBuilder::new_diagnostic(self, diag))
@@ -714,7 +714,7 @@ impl DiagCtxt {
     }
 
     /// Emit all stashed diagnostics.
-    pub fn emit_stashed_diagnostics(&self) -> Option<ErrorGuaranteed> {
+    pub fn emit_stashed_diagnostics(&self) {
         self.inner.borrow_mut().emit_stashed_diagnostics()
     }
 
@@ -851,6 +851,7 @@ impl DiagCtxt {
         self.struct_span_warn(span, msg).emit()
     }
 
+    #[track_caller]
     pub fn span_bug(&self, span: impl Into<MultiSpan>, msg: impl Into<DiagnosticMessage>) -> ! {
         self.struct_span_bug(span, msg).emit()
     }
@@ -866,8 +867,7 @@ impl DiagCtxt {
     /// directly).
     #[track_caller]
     pub fn delayed_bug(&self, msg: impl Into<DiagnosticMessage>) -> ErrorGuaranteed {
-        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
-            .emit()
+        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).emit()
     }
 
     /// Like `delayed_bug`, but takes an additional span.
@@ -880,15 +880,12 @@ impl DiagCtxt {
         sp: impl Into<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
     ) -> ErrorGuaranteed {
-        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug(DelayedBugKind::Normal), msg)
-            .with_span(sp)
-            .emit()
+        DiagnosticBuilder::<ErrorGuaranteed>::new(self, DelayedBug, msg).with_span(sp).emit()
     }
 
-    // FIXME(eddyb) note the comment inside `impl Drop for DiagCtxtInner`, that's
-    // where the explanation of what "good path" is (also, it should be renamed).
+    /// Ensures that a diagnostic is printed. See `Level::GoodPathDelayedBug`.
     pub fn good_path_delayed_bug(&self, msg: impl Into<DiagnosticMessage>) {
-        DiagnosticBuilder::<()>::new(self, DelayedBug(DelayedBugKind::GoodPath), msg).emit()
+        DiagnosticBuilder::<()>::new(self, GoodPathDelayedBug, msg).emit()
     }
 
     #[track_caller]
@@ -932,40 +929,52 @@ impl DiagCtxt {
         self.struct_bug(msg).emit()
     }
 
-    /// This excludes lint errors and delayed bugs.
+    /// This excludes lint errors, delayed bugs, and stashed errors.
     #[inline]
     pub fn err_count(&self) -> usize {
         self.inner.borrow().err_count
     }
 
-    /// This excludes lint errors and delayed bugs.
+    /// This excludes normal errors, lint errors and delayed bugs. Unless
+    /// absolutely necessary, avoid using this. It's dubious because stashed
+    /// errors can later be cancelled, so the presence of a stashed error at
+    /// some point of time doesn't guarantee anything -- there are no
+    /// `ErrorGuaranteed`s here.
+    pub fn stashed_err_count(&self) -> usize {
+        self.inner.borrow().stashed_err_count
+    }
+
+    /// This excludes lint errors, delayed bugs, and stashed errors.
     pub fn has_errors(&self) -> Option<ErrorGuaranteed> {
         self.inner.borrow().has_errors().then(|| {
+            // FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
             #[allow(deprecated)]
-            ErrorGuaranteed::unchecked_claim_error_was_emitted()
+            ErrorGuaranteed::unchecked_error_guaranteed()
         })
     }
 
-    /// This excludes delayed bugs. Unless absolutely necessary, prefer
-    /// `has_errors` to this method.
+    /// This excludes delayed bugs and stashed errors. Unless absolutely
+    /// necessary, prefer `has_errors` to this method.
     pub fn has_errors_or_lint_errors(&self) -> Option<ErrorGuaranteed> {
         let inner = self.inner.borrow();
         let result = inner.has_errors() || inner.lint_err_count > 0;
         result.then(|| {
+            // FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
             #[allow(deprecated)]
-            ErrorGuaranteed::unchecked_claim_error_was_emitted()
+            ErrorGuaranteed::unchecked_error_guaranteed()
         })
     }
 
-    /// Unless absolutely necessary, prefer `has_errors` or
-    /// `has_errors_or_lint_errors` to this method.
+    /// This excludes stashed errors. Unless absolutely necessary, prefer
+    /// `has_errors` or `has_errors_or_lint_errors` to this method.
     pub fn has_errors_or_lint_errors_or_delayed_bugs(&self) -> Option<ErrorGuaranteed> {
         let inner = self.inner.borrow();
         let result =
-            inner.has_errors() || inner.lint_err_count > 0 || !inner.span_delayed_bugs.is_empty();
+            inner.has_errors() || inner.lint_err_count > 0 || !inner.delayed_bugs.is_empty();
         result.then(|| {
+            // FIXME(nnethercote) find a way to store an `ErrorGuaranteed`.
             #[allow(deprecated)]
-            ErrorGuaranteed::unchecked_claim_error_was_emitted()
+            ErrorGuaranteed::unchecked_error_guaranteed()
         })
     }
 
@@ -991,9 +1000,13 @@ impl DiagCtxt {
 
         match (errors.len(), warnings.len()) {
             (0, 0) => return,
-            (0, _) => inner
-                .emitter
-                .emit_diagnostic(&Diagnostic::new(Warning, DiagnosticMessage::Str(warnings))),
+            (0, _) => {
+                // Use `inner.emitter` directly, otherwise the warning might not be emitted, e.g.
+                // with a configuration like `--cap-lints allow --force-warn bare_trait_objects`.
+                inner
+                    .emitter
+                    .emit_diagnostic(Diagnostic::new(Warning, DiagnosticMessage::Str(warnings)));
+            }
             (_, 0) => {
                 inner.emit_diagnostic(Diagnostic::new(Fatal, errors));
             }
@@ -1057,7 +1070,7 @@ impl DiagCtxt {
     }
 
     pub fn force_print_diagnostic(&self, db: Diagnostic) {
-        self.inner.borrow_mut().emitter.emit_diagnostic(&db);
+        self.inner.borrow_mut().emitter.emit_diagnostic(db);
     }
 
     pub fn emit_diagnostic(&self, diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
@@ -1222,16 +1235,13 @@ impl DiagCtxt {
 // `DiagCtxtInner::foo`.
 impl DiagCtxtInner {
     /// Emit all stashed diagnostics.
-    fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
+    fn emit_stashed_diagnostics(&mut self) {
         let has_errors = self.has_errors();
-        let mut reported = None;
         for (_, diag) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
             // Decrement the count tracking the stash; emitting will increment it.
             if diag.is_error() {
-                if diag.is_lint.is_some() {
-                    self.lint_err_count -= 1;
-                } else {
-                    self.err_count -= 1;
+                if diag.is_lint.is_none() {
+                    self.stashed_err_count -= 1;
                 }
             } else {
                 // Unless they're forced, don't flush stashed warnings when
@@ -1241,50 +1251,25 @@ impl DiagCtxtInner {
                     continue;
                 }
             }
-            let reported_this = self.emit_diagnostic(diag);
-            reported = reported.or(reported_this);
+            self.emit_diagnostic(diag);
         }
-        reported
     }
 
+    // Return value is only `Some` if the level is `Error` or `DelayedBug`.
     fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuaranteed> {
-        // The `LintExpectationId` can be stable or unstable depending on when it was created.
-        // Diagnostics created before the definition of `HirId`s are unstable and can not yet
-        // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by
-        // a stable one by the `LintLevelsBuilder`.
-        if let Some(LintExpectationId::Unstable { .. }) = diagnostic.level.get_expectation_id() {
-            self.unstable_expect_diagnostics.push(diagnostic);
-            return None;
-        }
+        assert!(diagnostic.level.can_be_top_or_sub().0);
 
-        // FIXME(eddyb) this should check for `has_errors` and stop pushing
-        // once *any* errors were emitted (and truncate `span_delayed_bugs`
-        // when an error is first emitted, also), but maybe there's a case
-        // in which that's not sound? otherwise this is really inefficient.
-        match diagnostic.level {
-            DelayedBug(_) if self.flags.eagerly_emit_delayed_bugs => {
-                diagnostic.level = Error;
-            }
-            DelayedBug(DelayedBugKind::Normal) => {
-                let backtrace = std::backtrace::Backtrace::capture();
-                self.span_delayed_bugs
-                    .push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
-                #[allow(deprecated)]
-                return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
-            }
-            DelayedBug(DelayedBugKind::GoodPath) => {
-                let backtrace = std::backtrace::Backtrace::capture();
-                self.good_path_delayed_bugs
-                    .push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
+        if let Some(expectation_id) = diagnostic.level.get_expectation_id() {
+            // The `LintExpectationId` can be stable or unstable depending on when it was created.
+            // Diagnostics created before the definition of `HirId`s are unstable and can not yet
+            // be stored. Instead, they are buffered until the `LintExpectationId` is replaced by
+            // a stable one by the `LintLevelsBuilder`.
+            if let LintExpectationId::Unstable { .. } = expectation_id {
+                self.unstable_expect_diagnostics.push(diagnostic);
                 return None;
             }
-            _ => {}
-        }
-
-        // This must come after the possible promotion of `DelayedBug` to
-        // `Error` above.
-        if matches!(diagnostic.level, Error | Fatal) && self.treat_next_err_as_bug() {
-            diagnostic.level = Bug;
+            self.suppressed_expected_diag = true;
+            self.fulfilled_expectations.insert(expectation_id.normalize());
         }
 
         if diagnostic.has_future_breakage() {
@@ -1295,21 +1280,45 @@ impl DiagCtxtInner {
             self.future_breakage_diagnostics.push(diagnostic.clone());
         }
 
-        if let Some(expectation_id) = diagnostic.level.get_expectation_id() {
-            self.suppressed_expected_diag = true;
-            self.fulfilled_expectations.insert(expectation_id.normalize());
+        if matches!(diagnostic.level, DelayedBug | GoodPathDelayedBug)
+            && self.flags.eagerly_emit_delayed_bugs
+        {
+            diagnostic.level = Error;
         }
 
-        if diagnostic.level == Warning && !self.flags.can_emit_warnings {
-            if diagnostic.has_future_breakage() {
+        match diagnostic.level {
+            // This must come after the possible promotion of `DelayedBug`/`GoodPathDelayedBug` to
+            // `Error` above.
+            Fatal | Error if self.treat_next_err_as_bug() => {
+                diagnostic.level = Bug;
+            }
+            DelayedBug => {
+                // FIXME(eddyb) this should check for `has_errors` and stop pushing
+                // once *any* errors were emitted (and truncate `delayed_bugs`
+                // when an error is first emitted, also), but maybe there's a case
+                // in which that's not sound? otherwise this is really inefficient.
+                let backtrace = std::backtrace::Backtrace::capture();
+                self.delayed_bugs.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
+                #[allow(deprecated)]
+                return Some(ErrorGuaranteed::unchecked_error_guaranteed());
+            }
+            GoodPathDelayedBug => {
+                let backtrace = std::backtrace::Backtrace::capture();
+                self.good_path_delayed_bugs
+                    .push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
+                return None;
+            }
+            Warning if !self.flags.can_emit_warnings => {
+                if diagnostic.has_future_breakage() {
+                    (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {});
+                }
+                return None;
+            }
+            Allow | Expect(_) => {
                 (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {});
+                return None;
             }
-            return None;
-        }
-
-        if matches!(diagnostic.level, Expect(_) | Allow) {
-            (*TRACK_DIAGNOSTIC)(diagnostic, &mut |_| {});
-            return None;
+            _ => {}
         }
 
         let mut guaranteed = None;
@@ -1325,11 +1334,16 @@ impl DiagCtxtInner {
                 !self.emitted_diagnostics.insert(diagnostic_hash)
             };
 
+            let level = diagnostic.level;
+            let is_error = diagnostic.is_error();
+            let is_lint = diagnostic.is_lint.is_some();
+
             // Only emit the diagnostic if we've been asked to deduplicate or
             // haven't already emitted an equivalent diagnostic.
             if !(self.flags.deduplicate_diagnostics && already_emitted) {
                 debug!(?diagnostic);
                 debug!(?self.emitted_diagnostics);
+
                 let already_emitted_sub = |sub: &mut SubDiagnostic| {
                     debug!(?sub);
                     if sub.level != OnceNote && sub.level != OnceHelp {
@@ -1341,7 +1355,6 @@ impl DiagCtxtInner {
                     debug!(?diagnostic_hash);
                     !self.emitted_diagnostics.insert(diagnostic_hash)
                 };
-
                 diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {});
                 if already_emitted {
                     diagnostic.note(
@@ -1349,26 +1362,28 @@ impl DiagCtxtInner {
                     );
                 }
 
-                self.emitter.emit_diagnostic(&diagnostic);
-                if diagnostic.is_error() {
+                if is_error {
                     self.deduplicated_err_count += 1;
                 } else if matches!(diagnostic.level, ForceWarning(_) | Warning) {
                     self.deduplicated_warn_count += 1;
                 }
                 self.has_printed = true;
+
+                self.emitter.emit_diagnostic(diagnostic);
             }
-            if diagnostic.is_error() {
-                if diagnostic.is_lint.is_some() {
+
+            if is_error {
+                if is_lint {
                     self.lint_err_count += 1;
                 } else {
                     self.err_count += 1;
                 }
                 self.panic_if_treat_err_as_bug();
+            }
 
-                #[allow(deprecated)]
-                {
-                    guaranteed = Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
-                }
+            #[allow(deprecated)]
+            if level == Level::Error {
+                guaranteed = Some(ErrorGuaranteed::unchecked_error_guaranteed());
             }
         });
 
@@ -1397,12 +1412,12 @@ impl DiagCtxtInner {
     fn flush_delayed(&mut self, kind: DelayedBugKind) {
         let (bugs, note1) = match kind {
             DelayedBugKind::Normal => (
-                std::mem::take(&mut self.span_delayed_bugs),
-                "no errors encountered even though `span_delayed_bug` issued",
+                std::mem::take(&mut self.delayed_bugs),
+                "no errors encountered even though delayed bugs were created",
             ),
             DelayedBugKind::GoodPath => (
                 std::mem::take(&mut self.good_path_delayed_bugs),
-                "no warnings or errors encountered even though `good_path_delayed_bugs` issued",
+                "no warnings or errors encountered even though good path delayed bugs were created",
             ),
         };
         let note2 = "those delayed bugs will now be shown as internal compiler errors";
@@ -1441,8 +1456,8 @@ impl DiagCtxtInner {
             let mut bug =
                 if backtrace || self.ice_file.is_none() { bug.decorate() } else { bug.inner };
 
-            // "Undelay" the `DelayedBug`s (into plain `Bug`s).
-            if !matches!(bug.level, DelayedBug(_)) {
+            // "Undelay" the delayed bugs (into plain `Bug`s).
+            if !matches!(bug.level, DelayedBug | GoodPathDelayedBug) {
                 // NOTE(eddyb) not panicking here because we're already producing
                 // an ICE, and the more information the merrier.
                 bug.subdiagnostic(InvalidFlushedDelayedDiagnosticLevel {
@@ -1508,35 +1523,59 @@ impl DelayedDiagnostic {
     }
 }
 
+/// Level              is_error  EmissionGuarantee         Top-level  Sub   Used in lints?
+/// -----              --------  -----------------         ---------  ---   --------------
+/// Bug                yes       BugAbort                  yes        -     -
+/// Fatal              yes       FatalAbort/FatalError(*)  yes        -     -
+/// Error              yes       ErrorGuaranteed           yes        -     yes
+/// DelayedBug         yes       ErrorGuaranteed           yes        -     -
+/// GoodPathDelayedBug -         ()                        yes        -     -
+/// ForceWarning       -         ()                        yes        -     lint-only
+/// Warning            -         ()                        yes        yes   yes
+/// Note               -         ()                        rare       yes   -
+/// OnceNote           -         ()                        -          yes   lint-only
+/// Help               -         ()                        rare       yes   -
+/// OnceHelp           -         ()                        -          yes   lint-only
+/// FailureNote        -         ()                        rare       -     -
+/// Allow              -         ()                        yes        -     lint-only
+/// Expect             -         ()                        yes        -     lint-only
+///
+/// (*) `FatalAbort` normally, `FatalError` in the non-aborting "almost fatal" case that is
+///     occasionally used.
+///
 #[derive(Copy, PartialEq, Eq, Clone, Hash, Debug, Encodable, Decodable)]
 pub enum Level {
     /// For bugs in the compiler. Manifests as an ICE (internal compiler error) panic.
-    ///
-    /// Its `EmissionGuarantee` is `BugAbort`.
     Bug,
 
-    /// This is a strange one: lets you register an error without emitting it. If compilation ends
-    /// without any other errors occurring, this will be emitted as a bug. Otherwise, it will be
-    /// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths
-    /// that should only be reached when compiling erroneous code.
-    ///
-    /// Its `EmissionGuarantee` is `ErrorGuaranteed` for `Normal` delayed bugs, and `()` for
-    /// `GoodPath` delayed bugs.
-    DelayedBug(DelayedBugKind),
-
     /// An error that causes an immediate abort. Used for things like configuration errors,
     /// internal overflows, some file operation errors.
-    ///
-    /// Its `EmissionGuarantee` is `FatalAbort`, except in the non-aborting "almost fatal" case
-    /// that is occasionally used, where it is `FatalError`.
     Fatal,
 
     /// An error in the code being compiled, which prevents compilation from finishing. This is the
     /// most common case.
-    ///
-    /// Its `EmissionGuarantee` is `ErrorGuaranteed`.
     Error,
 
+    /// This is a strange one: lets you register an error without emitting it. If compilation ends
+    /// without any other errors occurring, this will be emitted as a bug. Otherwise, it will be
+    /// silently dropped. I.e. "expect other errors are emitted" semantics. Useful on code paths
+    /// that should only be reached when compiling erroneous code.
+    DelayedBug,
+
+    /// Like `DelayedBug`, but weaker: lets you register an error without emitting it. If
+    /// compilation ends without any other diagnostics being emitted (and without an expected lint
+    /// being suppressed), this will be emitted as a bug. Otherwise, it will be silently dropped.
+    /// I.e. "expect other diagnostics are emitted (or suppressed)" semantics. Useful on code paths
+    /// that should only be reached when emitting diagnostics, e.g. for expensive one-time
+    /// diagnostic formatting operations.
+    ///
+    /// FIXME(nnethercote) good path delayed bugs are semantically strange: if printed they produce
+    /// an ICE, but they don't satisfy `is_error` and they don't guarantee an error is emitted.
+    /// Plus there's the extra complication with expected (suppressed) lints. They have limited
+    /// use, and are used in very few places, and "good path" isn't a good name. It would be good
+    /// to remove them.
+    GoodPathDelayedBug,
+
     /// A `force-warn` lint warning about the code being compiled. Does not prevent compilation
     /// from finishing.
     ///
@@ -1545,45 +1584,28 @@ pub enum Level {
     ForceWarning(Option<LintExpectationId>),
 
     /// A warning about the code being compiled. Does not prevent compilation from finishing.
-    ///
-    /// Its `EmissionGuarantee` is `()`.
     Warning,
 
-    /// A message giving additional context. Rare, because notes are more commonly attached to other
-    /// diagnostics such as errors.
-    ///
-    /// Its `EmissionGuarantee` is `()`.
+    /// A message giving additional context.
     Note,
 
-    /// A note that is only emitted once. Rare, mostly used in circumstances relating to lints.
-    ///
-    /// Its `EmissionGuarantee` is `()`.
+    /// A note that is only emitted once.
     OnceNote,
 
-    /// A message suggesting how to fix something. Rare, because help messages are more commonly
-    /// attached to other diagnostics such as errors.
-    ///
-    /// Its `EmissionGuarantee` is `()`.
+    /// A message suggesting how to fix something.
     Help,
 
-    /// A help that is only emitted once. Rare.
-    ///
-    /// Its `EmissionGuarantee` is `()`.
+    /// A help that is only emitted once.
     OnceHelp,
 
-    /// Similar to `Note`, but used in cases where compilation has failed. Rare.
-    ///
-    /// Its `EmissionGuarantee` is `()`.
+    /// Similar to `Note`, but used in cases where compilation has failed. When printed for human
+    /// consumption, it doesn't have any kind of `note:` label.
     FailureNote,
 
     /// Only used for lints.
-    ///
-    /// Its `EmissionGuarantee` is `()`.
     Allow,
 
     /// Only used for lints.
-    ///
-    /// Its `EmissionGuarantee` is `()`.
     Expect(LintExpectationId),
 }
 
@@ -1597,7 +1619,7 @@ impl Level {
     fn color(self) -> ColorSpec {
         let mut spec = ColorSpec::new();
         match self {
-            Bug | DelayedBug(_) | Fatal | Error => {
+            Bug | Fatal | Error | DelayedBug | GoodPathDelayedBug => {
                 spec.set_fg(Some(Color::Red)).set_intense(true);
             }
             ForceWarning(_) | Warning => {
@@ -1617,7 +1639,7 @@ impl Level {
 
     pub fn to_str(self) -> &'static str {
         match self {
-            Bug | DelayedBug(_) => "error: internal compiler error",
+            Bug | DelayedBug | GoodPathDelayedBug => "error: internal compiler error",
             Fatal | Error => "error",
             ForceWarning(_) | Warning => "warning",
             Note | OnceNote => "note",
@@ -1637,6 +1659,19 @@ impl Level {
             _ => None,
         }
     }
+
+    // Can this level be used in a top-level diagnostic message and/or a
+    // subdiagnostic message?
+    fn can_be_top_or_sub(&self) -> (bool, bool) {
+        match self {
+            Bug | DelayedBug | Fatal | Error | GoodPathDelayedBug | ForceWarning(_)
+            | FailureNote | Allow | Expect(_) => (true, false),
+
+            Warning | Note | Help => (true, true),
+
+            OnceNote | OnceHelp => (false, true),
+        }
+    }
 }
 
 // FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite.
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 657e19277a7..cfeb31fc4c8 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-
 use crate::base::ast::NestedMetaItem;
 use crate::errors;
 use crate::expand::{self, AstFragment, Invocation};
diff --git a/compiler/rustc_expand/src/lib.rs b/compiler/rustc_expand/src/lib.rs
index 2cf6a8df7c5..4da86d77dc8 100644
--- a/compiler/rustc_expand/src/lib.rs
+++ b/compiler/rustc_expand/src/lib.rs
@@ -10,7 +10,7 @@
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_span)]
 #![feature(try_blocks)]
-#![deny(rustc::untranslatable_diagnostic)]
+#![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
 
 #[macro_use]
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index 1155366db85..18f6ae35054 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -77,7 +77,7 @@ declare_features! (
     /// Allows empty structs and enum variants with braces.
     (accepted, braced_empty_structs, "1.8.0", Some(29720)),
     /// Allows `c"foo"` literals.
-    (accepted, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723)),
+    (accepted, c_str_literals, "1.77.0", Some(105723)),
     /// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
     (accepted, cfg_attr_multi, "1.33.0", Some(54881)),
     /// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 68b6f69854d..019cc1c847e 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -440,9 +440,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         experimental!(optimize),
     ),
 
-    gated!(
-        ffi_returns_twice, Normal, template!(Word), WarnFollowing, experimental!(ffi_returns_twice)
-    ),
     gated!(ffi_pure, Normal, template!(Word), WarnFollowing, experimental!(ffi_pure)),
     gated!(ffi_const, Normal, template!(Word), WarnFollowing, experimental!(ffi_const)),
     gated!(
diff --git a/compiler/rustc_feature/src/lib.rs b/compiler/rustc_feature/src/lib.rs
index cd1d9b13daa..f1c8f2e2dde 100644
--- a/compiler/rustc_feature/src/lib.rs
+++ b/compiler/rustc_feature/src/lib.rs
@@ -15,8 +15,6 @@
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![feature(lazy_cell)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 mod accepted;
 mod builtin_attrs;
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 85fcf6a9994..008c59e1be3 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -33,7 +33,7 @@ declare_features! (
     // -------------------------------------------------------------------------
 
     /// Allows using the `amdgpu-kernel` ABI.
-    (removed, abi_amdgpu_kernel, "CURRENT_RUSTC_VERSION", Some(51575), None),
+    (removed, abi_amdgpu_kernel, "1.77.0", Some(51575), None),
     (removed, advanced_slice_patterns, "1.0.0", Some(62254),
      Some("merged into `#![feature(slice_patterns)]`")),
     (removed, allocator, "1.0.0", None, None),
@@ -97,6 +97,9 @@ declare_features! (
     /// Allows `#[doc(include = "some-file")]`.
     (removed, external_doc, "1.54.0", Some(44732),
      Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")),
+    /// Allows using `#[ffi_returns_twice]` on foreign functions.
+    (removed, ffi_returns_twice, "CURRENT_RUSTC_VERSION", Some(58314),
+     Some("being investigated by the ffi-unwind project group")),
     /// Allows generators to be cloned.
     (removed, generator_clone, "1.65.0", Some(95360), Some("renamed to `coroutine_clone`")),
     /// Allows defining generators.
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index d00621d8254..42fc24c937b 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -356,7 +356,7 @@ declare_features! (
     /// Allows `#[track_caller]` on async functions.
     (unstable, async_fn_track_caller, "1.73.0", Some(110011)),
     /// Allows `for await` loops.
-    (unstable, async_for_loop, "CURRENT_RUSTC_VERSION", Some(118898)),
+    (unstable, async_for_loop, "1.77.0", Some(118898)),
     /// Allows builtin # foo() syntax
     (unstable, builtin_syntax, "1.71.0", Some(110680)),
     /// Treat `extern "C"` function as nounwind.
@@ -370,7 +370,7 @@ declare_features! (
     /// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.
     (unstable, cfg_sanitize, "1.41.0", Some(39699)),
     /// Allows `cfg(sanitizer_cfi_generalize_pointers)` and `cfg(sanitizer_cfi_normalize_integers)`.
-    (unstable, cfg_sanitizer_cfi, "CURRENT_RUSTC_VERSION", Some(89653)),
+    (unstable, cfg_sanitizer_cfi, "1.77.0", Some(89653)),
     /// Allows `cfg(target_abi = "...")`.
     (unstable, cfg_target_abi, "1.55.0", Some(80970)),
     /// Allows `cfg(target(abi = "..."))`.
@@ -465,8 +465,6 @@ declare_features! (
     (unstable, ffi_const, "1.45.0", Some(58328)),
     /// Allows the use of `#[ffi_pure]` on foreign functions.
     (unstable, ffi_pure, "1.45.0", Some(58329)),
-    /// Allows using `#[ffi_returns_twice]` on foreign functions.
-    (unstable, ffi_returns_twice, "1.34.0", Some(58314)),
     /// Allows using `#[repr(align(...))]` on function items
     (unstable, fn_align, "1.53.0", Some(82232)),
     /// Support delegating implementation of functions to other already implemented functions.
@@ -516,7 +514,7 @@ declare_features! (
     (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)),
+    (incomplete, min_exhaustive_patterns, "1.77.0", Some(119612)),
     /// A minimal, sound subset of specialization intended to be used by the
     /// standard library until the soundness issues with specialization
     /// are fixed.
@@ -552,7 +550,7 @@ declare_features! (
     /// Allows using enums in offset_of!
     (unstable, offset_of_enum, "1.75.0", Some(120141)),
     /// Allows using multiple nested field accesses in offset_of!
-    (unstable, offset_of_nested, "CURRENT_RUSTC_VERSION", Some(120140)),
+    (unstable, offset_of_nested, "1.77.0", Some(120140)),
     /// Allows using `#[optimize(X)]`.
     (unstable, optimize_attribute, "1.34.0", Some(54882)),
     /// Allows macro attributes on expressions, statements and non-inline modules.
diff --git a/compiler/rustc_fluent_macro/src/lib.rs b/compiler/rustc_fluent_macro/src/lib.rs
index fc65d1eb8c4..e3784409af8 100644
--- a/compiler/rustc_fluent_macro/src/lib.rs
+++ b/compiler/rustc_fluent_macro/src/lib.rs
@@ -4,8 +4,6 @@
 #![feature(rustdoc_internals)]
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_span)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::default_hash_types)]
 
 use proc_macro::TokenStream;
diff --git a/compiler/rustc_fs_util/src/lib.rs b/compiler/rustc_fs_util/src/lib.rs
index 81d63338145..3359fef8c1c 100644
--- a/compiler/rustc_fs_util/src/lib.rs
+++ b/compiler/rustc_fs_util/src/lib.rs
@@ -1,6 +1,4 @@
 #![feature(absolute_path)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 use std::ffi::CString;
 use std::fs;
diff --git a/compiler/rustc_graphviz/src/lib.rs b/compiler/rustc_graphviz/src/lib.rs
index eba3215d931..43bee5c4be0 100644
--- a/compiler/rustc_graphviz/src/lib.rs
+++ b/compiler/rustc_graphviz/src/lib.rs
@@ -276,8 +276,6 @@
 #![feature(rustdoc_internals)]
 #![doc(rust_logo)]
 #![allow(internal_features)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 use LabelText::*;
 
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index ff50086ff8f..abf7a695fd2 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -163,10 +163,6 @@ impl Lifetime {
             (LifetimeSuggestionPosition::Normal, self.ident.span)
         }
     }
-
-    pub fn is_static(&self) -> bool {
-        self.res == LifetimeName::Static
-    }
 }
 
 /// A `Path` is essentially Rust's notion of a name; for instance,
@@ -835,7 +831,7 @@ pub struct OwnerNodes<'tcx> {
     // The zeroth node's parent should never be accessed: the owner's parent is computed by the
     // hir_owner_parent query. It is set to `ItemLocalId::INVALID` to force an ICE if accidentally
     // used.
-    pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
+    pub nodes: IndexVec<ItemLocalId, ParentedNode<'tcx>>,
     /// Content of local bodies.
     pub bodies: SortedMap<ItemLocalId, &'tcx Body<'tcx>>,
 }
@@ -843,9 +839,8 @@ pub struct OwnerNodes<'tcx> {
 impl<'tcx> OwnerNodes<'tcx> {
     pub fn node(&self) -> OwnerNode<'tcx> {
         use rustc_index::Idx;
-        let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
-        let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
-        node
+        // Indexing must ensure it is an OwnerNode.
+        self.nodes[ItemLocalId::new(0)].node.as_owner().unwrap()
     }
 }
 
@@ -860,9 +855,7 @@ impl fmt::Debug for OwnerNodes<'_> {
                     .nodes
                     .iter_enumerated()
                     .map(|(id, parented_node)| {
-                        let parented_node = parented_node.as_ref().map(|node| node.parent);
-
-                        debug_fn(move |f| write!(f, "({id:?}, {parented_node:?})"))
+                        debug_fn(move |f| write!(f, "({id:?}, {:?})", parented_node.parent))
                     })
                     .collect::<Vec<_>>(),
             )
@@ -3351,13 +3344,15 @@ impl<'hir> OwnerNode<'hir> {
         }
     }
 
-    pub fn span(&self) -> Span {
+    // Span by reference to pass to `Node::Err`.
+    #[allow(rustc::pass_by_value)]
+    pub fn span(&self) -> &'hir Span {
         match self {
             OwnerNode::Item(Item { span, .. })
             | OwnerNode::ForeignItem(ForeignItem { span, .. })
             | OwnerNode::ImplItem(ImplItem { span, .. })
-            | OwnerNode::TraitItem(TraitItem { span, .. }) => *span,
-            OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => *inner_span,
+            | OwnerNode::TraitItem(TraitItem { span, .. }) => span,
+            OwnerNode::Crate(Mod { spans: ModSpans { inner_span, .. }, .. }) => inner_span,
         }
     }
 
@@ -3486,17 +3481,19 @@ pub enum Node<'hir> {
     Arm(&'hir Arm<'hir>),
     Block(&'hir Block<'hir>),
     Local(&'hir Local<'hir>),
-
     /// `Ctor` refers to the constructor of an enum variant or struct. Only tuple or unit variants
     /// with synthesized constructors.
     Ctor(&'hir VariantData<'hir>),
-
     Lifetime(&'hir Lifetime),
     GenericParam(&'hir GenericParam<'hir>),
-
     Crate(&'hir Mod<'hir>),
-
     Infer(&'hir InferArg),
+    WhereBoundPredicate(&'hir WhereBoundPredicate<'hir>),
+    // FIXME: Merge into `Node::Infer`.
+    ArrayLenInfer(&'hir InferArg),
+    // Span by reference to minimize `Node`'s size
+    #[allow(rustc::pass_by_value)]
+    Err(&'hir Span),
 }
 
 impl<'hir> Node<'hir> {
@@ -3541,7 +3538,10 @@ impl<'hir> Node<'hir> {
             | Node::Crate(..)
             | Node::Ty(..)
             | Node::TraitRef(..)
-            | Node::Infer(..) => None,
+            | Node::Infer(..)
+            | Node::WhereBoundPredicate(..)
+            | Node::ArrayLenInfer(..)
+            | Node::Err(..) => None,
         }
     }
 
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 27c834d848f..52e1109ff92 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -108,8 +108,8 @@ impl<'a> FnKind<'a> {
 
 /// An abstract representation of the HIR `rustc_middle::hir::map::Map`.
 pub trait Map<'hir> {
-    /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
-    fn find(&self, hir_id: HirId) -> Option<Node<'hir>>;
+    /// Retrieves the `Node` corresponding to `id`.
+    fn hir_node(&self, hir_id: HirId) -> Node<'hir>;
     fn body(&self, id: BodyId) -> &'hir Body<'hir>;
     fn item(&self, id: ItemId) -> &'hir Item<'hir>;
     fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>;
@@ -119,7 +119,7 @@ pub trait Map<'hir> {
 
 // Used when no map is actually available, forcing manual implementation of nested visitors.
 impl<'hir> Map<'hir> for ! {
-    fn find(&self, _: HirId) -> Option<Node<'hir>> {
+    fn hir_node(&self, _: HirId) -> Node<'hir> {
         *self;
     }
     fn body(&self, _: BodyId) -> &'hir Body<'hir> {
@@ -669,6 +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 {
+        // FIXME: Use `visit_infer` here.
         ArrayLen::Infer(InferArg { hir_id, span: _ }) => visitor.visit_id(*hir_id),
         ArrayLen::Body(c) => visitor.visit_anon_const(c),
     }
diff --git a/compiler/rustc_hir/src/lib.rs b/compiler/rustc_hir/src/lib.rs
index 6c64d802e68..aff946ac580 100644
--- a/compiler/rustc_hir/src/lib.rs
+++ b/compiler/rustc_hir/src/lib.rs
@@ -9,8 +9,6 @@
 #![feature(never_type)]
 #![feature(rustc_attrs)]
 #![feature(variant_count)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
 
 #[macro_use]
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 54d0fb6ffab..d6f604c180b 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -33,10 +33,6 @@ hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the as
 
 hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
 
-hir_analysis_async_trait_impl_should_be_async =
-    method `{$method_name}` should be async because the method from the trait is async
-    .trait_item_label = required because the trait method is async
-
 hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
     .label = deref recursion limit reached
     .help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
@@ -210,6 +206,9 @@ hir_analysis_manual_implementation =
     .label = manual implementations of `{$trait_name}` are experimental
     .help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
 
+hir_analysis_method_should_return_future = method should be `async` or return a future, but it is synchronous
+    .note = this method is `async` so it expects a future to be returned
+
 hir_analysis_missing_one_of_trait_item = not all trait items implemented, missing one of: `{$missing_items_msg}`
     .label = missing one of `{$missing_items_msg}` in implementation
     .note = required because of this annotation
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index e37119e7d4d..1ae267d1a40 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -243,9 +243,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
         speculative: bool,
         dup_bindings: &mut FxHashMap<DefId, Span>,
         path_span: Span,
-        constness: ty::BoundConstness,
         only_self_bounds: OnlySelfBounds,
-        polarity: ty::ImplPolarity,
     ) -> Result<(), ErrorGuaranteed> {
         // Given something like `U: SomeTrait<T = X>`, we want to produce a
         // predicate like `<U as SomeTrait>::T = X`. This is somewhat
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index e67a44d96ad..3c64b102bae 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -14,6 +14,7 @@ use rustc_errors::{
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_infer::traits::FulfillmentError;
+use rustc_middle::query::Key;
 use rustc_middle::ty::{self, suggest_constraining_type_param, Ty, TyCtxt, TypeVisitableExt};
 use rustc_session::parse::feature_err;
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -859,6 +860,56 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         self.set_tainted_by_errors(err.emit());
     }
+
+    /// On ambiguous associated type, look for an associated function whose name matches the
+    /// extended path and, if found, emit an E0223 error with a structured suggestion.
+    /// e.g. for `String::from::utf8`, suggest `String::from_utf8` (#109195)
+    pub(crate) fn maybe_report_similar_assoc_fn(
+        &self,
+        span: Span,
+        qself_ty: Ty<'tcx>,
+        qself: &hir::Ty<'_>,
+    ) -> Result<(), ErrorGuaranteed> {
+        let tcx = self.tcx();
+        if let Some((_, node)) = tcx.hir().parent_iter(qself.hir_id).skip(1).next()
+            && let hir::Node::Expr(hir::Expr {
+                kind:
+                    hir::ExprKind::Path(hir::QPath::TypeRelative(
+                        hir::Ty {
+                            kind:
+                                hir::TyKind::Path(hir::QPath::TypeRelative(
+                                    _,
+                                    hir::PathSegment { ident: ident2, .. },
+                                )),
+                            ..
+                        },
+                        hir::PathSegment { ident: ident3, .. },
+                    )),
+                ..
+            }) = node
+            && let Some(ty_def_id) = qself_ty.ty_def_id()
+            && let Ok([inherent_impl]) = tcx.inherent_impls(ty_def_id)
+            && let name = format!("{ident2}_{ident3}")
+            && let Some(ty::AssocItem { kind: ty::AssocKind::Fn, .. }) = tcx
+                .associated_items(inherent_impl)
+                .filter_by_name_unhygienic(Symbol::intern(&name))
+                .next()
+        {
+            let reported =
+                struct_span_code_err!(tcx.dcx(), span, E0223, "ambiguous associated type")
+                    .with_span_suggestion_verbose(
+                        ident2.span.to(ident3.span),
+                        format!("there is an associated function with a similar name: `{name}`"),
+                        name,
+                        Applicability::MaybeIncorrect,
+                    )
+                    .emit();
+            self.set_tainted_by_errors(reported);
+            Err(reported)
+        } else {
+            Ok(())
+        }
+    }
 }
 
 /// Emits an error regarding forbidden type binding associations
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 30b10446afc..aa826c1f268 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -16,7 +16,7 @@ use rustc_middle::ty::{
     self, GenericArgsRef, GenericParamDef, GenericParamDefKind, IsSuggestable, Ty, TyCtxt,
 };
 use rustc_session::lint::builtin::LATE_BOUND_LIFETIME_ARGUMENTS;
-use rustc_span::{symbol::kw, Span};
+use rustc_span::symbol::kw;
 use smallvec::SmallVec;
 
 /// Report an error that a generic argument did not match the generic parameter that was
@@ -404,7 +404,6 @@ pub fn create_args_for_parent_generic_args<'tcx: 'a, 'a>(
 /// Used specifically for function calls.
 pub fn check_generic_arg_count_for_call(
     tcx: TyCtxt<'_>,
-    span: Span,
     def_id: DefId,
     generics: &ty::Generics,
     seg: &hir::PathSegment<'_>,
@@ -418,17 +417,7 @@ pub fn check_generic_arg_count_for_call(
     };
     let has_self = generics.parent.is_none() && generics.has_self;
 
-    check_generic_arg_count(
-        tcx,
-        span,
-        def_id,
-        seg,
-        generics,
-        gen_args,
-        gen_pos,
-        has_self,
-        seg.infer_args,
-    )
+    check_generic_arg_count(tcx, def_id, seg, generics, gen_args, gen_pos, has_self, seg.infer_args)
 }
 
 /// Checks that the correct number of generic arguments have been provided.
@@ -436,7 +425,6 @@ pub fn check_generic_arg_count_for_call(
 #[instrument(skip(tcx, gen_pos), level = "debug")]
 pub(crate) fn check_generic_arg_count(
     tcx: TyCtxt<'_>,
-    span: Span,
     def_id: DefId,
     seg: &hir::PathSegment<'_>,
     gen_params: &ty::Generics,
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 89f39897ea8..d438d3e7c60 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -12,7 +12,7 @@ use crate::astconv::errors::prohibit_assoc_ty_binding;
 use crate::astconv::generics::{check_generic_arg_count, create_args_for_parent_generic_args};
 use crate::bounds::Bounds;
 use crate::collect::HirPlaceholderCollector;
-use crate::errors::{AmbiguousLifetimeBound, TypeofReservedKeywordUsed};
+use crate::errors::AmbiguousLifetimeBound;
 use crate::middle::resolve_bound_vars as rbv;
 use crate::require_c_abi_if_c_variadic;
 use rustc_ast::TraitObjectSyntax;
@@ -25,13 +25,13 @@ use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{walk_generics, Visitor as _};
-use rustc_hir::{GenericArg, GenericArgs, OpaqueTyOrigin};
+use rustc_hir::{GenericArg, GenericArgs};
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::middle::stability::AllowUnstable;
 use rustc_middle::ty::{
-    self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, IsSuggestable, ParamEnv, Ty,
-    TyCtxt, TypeVisitableExt,
+    self, Const, GenericArgKind, GenericArgsRef, GenericParamDefKind, ParamEnv, Ty, TyCtxt,
+    TypeVisitableExt,
 };
 use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -379,7 +379,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
         let mut arg_count = check_generic_arg_count(
             tcx,
-            span,
             def_id,
             seg,
             generics,
@@ -773,9 +772,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 speculative,
                 &mut dup_bindings,
                 binding.span,
-                constness,
                 only_self_bounds,
-                polarity,
             );
             // Okay to ignore `Err` because of `ErrorGuaranteed` (see above).
         }
@@ -1373,6 +1370,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     )
                     .emit() // Already reported in an earlier stage.
                 } else {
+                    self.maybe_report_similar_assoc_fn(span, qself_ty, qself)?;
+
                     let traits: Vec<_> =
                         self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident);
 
@@ -2491,7 +2490,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 let opaque_ty = tcx.hir().item(item_id);
 
                 match opaque_ty.kind {
-                    hir::ItemKind::OpaqueTy(&hir::OpaqueTy { origin, .. }) => {
+                    hir::ItemKind::OpaqueTy(&hir::OpaqueTy { .. }) => {
                         let local_def_id = item_id.owner_id.def_id;
                         // If this is an RPITIT and we are using the new RPITIT lowering scheme, we
                         // generate the def_id of an associated type for the trait and return as
@@ -2501,7 +2500,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         } else {
                             local_def_id.to_def_id()
                         };
-                        self.impl_trait_ty_to_ty(def_id, lifetimes, origin, in_trait)
+                        self.impl_trait_ty_to_ty(def_id, lifetimes, in_trait)
                     }
                     ref i => bug!("`impl Trait` pointed to non-opaque type?? {:#?}", i),
                 }
@@ -2537,21 +2536,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
                 Ty::new_array_with_const_len(tcx, self.ast_ty_to_ty(ty), length)
             }
-            hir::TyKind::Typeof(e) => {
-                let ty_erased = tcx.type_of(e.def_id).instantiate_identity();
-                let ty = tcx.fold_regions(ty_erased, |r, _| {
-                    if r.is_erased() { tcx.lifetimes.re_static } else { r }
-                });
-                let span = ast_ty.span;
-                let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false) {
-                    (ty, Some((span, Applicability::MachineApplicable)))
-                } else {
-                    (ty, None)
-                };
-                tcx.dcx().emit_err(TypeofReservedKeywordUsed { span, ty, opt_sugg });
-
-                ty
-            }
+            hir::TyKind::Typeof(e) => tcx.type_of(e.def_id).instantiate_identity(),
             hir::TyKind::Infer => {
                 // Infer also appears as the type of arguments or return
                 // values in an ExprKind::Closure, or as
@@ -2571,7 +2556,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         &self,
         def_id: DefId,
         lifetimes: &[hir::GenericArg<'_>],
-        origin: OpaqueTyOrigin,
         in_trait: bool,
     ) -> Ty<'tcx> {
         debug!("impl_trait_ty_to_ty(def_id={:?}, lifetimes={:?})", def_id, lifetimes);
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 379c1154e5f..6edd68f1bae 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -1,5 +1,5 @@
 use super::potentially_plural_count;
-use crate::errors::LifetimesOrBoundsMismatchOnTrait;
+use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
 use hir::def_id::{DefId, DefIdMap, LocalDefId};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
 use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
@@ -10,7 +10,7 @@ use rustc_hir::{GenericParamKind, ImplItemKind};
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
-use rustc_infer::traits::util;
+use rustc_infer::traits::{util, FulfillmentError};
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::util::ExplicitSelf;
@@ -74,7 +74,6 @@ fn check_method_is_structurally_compatible<'tcx>(
     compare_generic_param_kinds(tcx, impl_m, trait_m, delay)?;
     compare_number_of_method_arguments(tcx, impl_m, trait_m, delay)?;
     compare_synthetic_generics(tcx, impl_m, trait_m, delay)?;
-    compare_asyncness(tcx, impl_m, trait_m, delay)?;
     check_region_bounds_on_impl_item(tcx, impl_m, trait_m, delay)?;
     Ok(())
 }
@@ -414,36 +413,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
     }
 }
 
-fn compare_asyncness<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    impl_m: ty::AssocItem,
-    trait_m: ty::AssocItem,
-    delay: bool,
-) -> Result<(), ErrorGuaranteed> {
-    if tcx.asyncness(trait_m.def_id).is_async() {
-        match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() {
-            ty::Alias(ty::Opaque, ..) => {
-                // allow both `async fn foo()` and `fn foo() -> impl Future`
-            }
-            ty::Error(_) => {
-                // We don't know if it's ok, but at least it's already an error.
-            }
-            _ => {
-                return Err(tcx
-                    .dcx()
-                    .create_err(crate::errors::AsyncTraitImplShouldBeAsync {
-                        span: tcx.def_span(impl_m.def_id),
-                        method_name: trait_m.name,
-                        trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
-                    })
-                    .emit_unless(delay));
-            }
-        };
-    }
-
-    Ok(())
-}
-
 /// Given a method def-id in an impl, compare the method signature of the impl
 /// against the trait that it's implementing. In doing so, infer the hidden types
 /// that this method's signature provides to satisfy each return-position `impl Trait`
@@ -695,8 +664,13 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     // RPITs.
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
-        let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
-        return Err(reported);
+        if let Err(guar) = try_report_async_mismatch(tcx, infcx, &errors, trait_m, impl_m, impl_sig)
+        {
+            return Err(guar);
+        }
+
+        let guar = infcx.err_ctxt().report_fulfillment_errors(errors);
+        return Err(guar);
     }
 
     // Finally, resolve all regions. This catches wily misuses of
@@ -1990,6 +1964,10 @@ pub(super) fn check_type_bounds<'tcx>(
     impl_ty: ty::AssocItem,
     impl_trait_ref: ty::TraitRef<'tcx>,
 ) -> Result<(), ErrorGuaranteed> {
+    // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
+    // other `Foo` impls are incoherent.
+    tcx.ensure().coherent_trait(impl_trait_ref.def_id)?;
+
     let param_env = tcx.param_env(impl_ty.def_id);
     debug!(?param_env);
 
@@ -2248,3 +2226,47 @@ fn assoc_item_kind_str(impl_item: &ty::AssocItem) -> &'static str {
         ty::AssocKind::Type => "type",
     }
 }
+
+/// Manually check here that `async fn foo()` wasn't matched against `fn foo()`,
+/// and extract a better error if so.
+fn try_report_async_mismatch<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    infcx: &InferCtxt<'tcx>,
+    errors: &[FulfillmentError<'tcx>],
+    trait_m: ty::AssocItem,
+    impl_m: ty::AssocItem,
+    impl_sig: ty::FnSig<'tcx>,
+) -> Result<(), ErrorGuaranteed> {
+    if !tcx.asyncness(trait_m.def_id).is_async() {
+        return Ok(());
+    }
+
+    let ty::Alias(ty::Projection, ty::AliasTy { def_id: async_future_def_id, .. }) =
+        *tcx.fn_sig(trait_m.def_id).skip_binder().skip_binder().output().kind()
+    else {
+        bug!("expected `async fn` to return an RPITIT");
+    };
+
+    for error in errors {
+        if let traits::BindingObligation(def_id, _) = *error.root_obligation.cause.code()
+            && def_id == async_future_def_id
+            && let Some(proj) = error.root_obligation.predicate.to_opt_poly_projection_pred()
+            && let Some(proj) = proj.no_bound_vars()
+            && infcx.can_eq(
+                error.root_obligation.param_env,
+                proj.term.ty().unwrap(),
+                impl_sig.output(),
+            )
+        {
+            // FIXME: We should suggest making the fn `async`, but extracting
+            // the right span is a bit difficult.
+            return Err(tcx.sess.dcx().emit_err(MethodShouldReturnFuture {
+                span: tcx.def_span(impl_m.def_id),
+                method_name: trait_m.name,
+                trait_item_span: tcx.hir().span_if_local(trait_m.def_id),
+            }));
+        }
+    }
+
+    Ok(())
+}
diff --git a/compiler/rustc_hir_analysis/src/check/entry.rs b/compiler/rustc_hir_analysis/src/check/entry.rs
index 649ac6c5aeb..3d803258c8e 100644
--- a/compiler/rustc_hir_analysis/src/check/entry.rs
+++ b/compiler/rustc_hir_analysis/src/check/entry.rs
@@ -43,8 +43,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
             return None;
         }
         let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
-        match tcx.opt_hir_node(hir_id) {
-            Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
+        match tcx.hir_node(hir_id) {
+            Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
                 generics.params.is_empty().not().then_some(generics.span)
             }
             _ => {
@@ -58,8 +58,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
             return None;
         }
         let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
-        match tcx.opt_hir_node(hir_id) {
-            Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. })) => {
+        match tcx.hir_node(hir_id) {
+            Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, generics, _), .. }) => {
                 Some(generics.where_clause_span)
             }
             _ => {
@@ -80,8 +80,8 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
             return None;
         }
         let hir_id = tcx.local_def_id_to_hir_id(def_id.expect_local());
-        match tcx.opt_hir_node(hir_id) {
-            Some(Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. })) => {
+        match tcx.hir_node(hir_id) {
+            Node::Item(hir::Item { kind: hir::ItemKind::Fn(fn_sig, _, _), .. }) => {
                 Some(fn_sig.decl.output.span())
             }
             _ => {
@@ -202,7 +202,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
     let start_t = tcx.type_of(start_def_id).instantiate_identity();
     match start_t.kind() {
         ty::FnDef(..) => {
-            if let Some(Node::Item(it)) = tcx.opt_hir_node(start_id) {
+            if let Node::Item(it) = tcx.hir_node(start_id) {
                 if let hir::ItemKind::Fn(sig, generics, _) = &it.kind {
                     let mut error = false;
                     if !generics.params.is_empty() {
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 2d0d6611444..96b0cffc8a3 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -112,7 +112,8 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: DefId) -> hir
         | sym::forget
         | sym::black_box
         | sym::variant_count
-        | sym::ptr_mask => hir::Unsafety::Normal,
+        | sym::ptr_mask
+        | sym::debug_assertions => hir::Unsafety::Normal,
         _ => hir::Unsafety::Unsafe,
     };
 
@@ -461,6 +462,8 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 (0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize)
             }
 
+            sym::debug_assertions => (0, Vec::new(), tcx.types.bool),
+
             other => {
                 tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span: it.span, name: other });
                 return;
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 885cfbd0fe2..646a84b043c 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -1005,6 +1005,11 @@ fn check_associated_item(
     enter_wf_checking_ctxt(tcx, span, item_id, |wfcx| {
         let item = tcx.associated_item(item_id);
 
+        // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
+        // other `Foo` impls are incoherent.
+        tcx.ensure()
+            .coherent_trait(tcx.parent(item.trait_item_def_id.unwrap_or(item_id.into())))?;
+
         let self_ty = match item.container {
             ty::TraitContainer => tcx.types.self_param,
             ty::ImplContainer => tcx.type_of(item.container_id(tcx)).instantiate_identity(),
@@ -1291,6 +1296,9 @@ fn check_impl<'tcx>(
                 // therefore don't need to be WF (the trait's `Self: Trait` predicate
                 // won't hold).
                 let trait_ref = tcx.impl_trait_ref(item.owner_id).unwrap().instantiate_identity();
+                // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
+                // other `Foo` impls are incoherent.
+                tcx.ensure().coherent_trait(trait_ref.def_id)?;
                 let trait_ref = wfcx.normalize(
                     ast_trait_ref.path.span,
                     Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 1dabb6feb5e..4860555de20 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -344,11 +344,18 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
         kind: hir::ExprKind::Closure(hir::Closure { kind, .. }), ..
     }) = node
     {
+        // See `ClosureArgsParts`, `CoroutineArgsParts`, and `CoroutineClosureArgsParts`
+        // for info on the usage of each of these fields.
         let dummy_args = match kind {
             ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..],
-            ClosureKind::Coroutine(_) => {
-                &["<resume_ty>", "<yield_ty>", "<return_ty>", "<witness>", "<upvars>"][..]
-            }
+            ClosureKind::Coroutine(_) => &[
+                "<coroutine_kind>",
+                "<resume_ty>",
+                "<yield_ty>",
+                "<return_ty>",
+                "<witness>",
+                "<upvars>",
+            ][..],
             ClosureKind::CoroutineClosure(_) => &[
                 "<closure_kind>",
                 "<closure_signature_parts>",
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 5cdcc1bb860..20a7663f864 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -9,6 +9,8 @@ use rustc_middle::ty::{self, ImplTraitInTraitData, IsSuggestable, Ty, TyCtxt, Ty
 use rustc_span::symbol::Ident;
 use rustc_span::{Span, DUMMY_SP};
 
+use crate::errors::TypeofReservedKeywordUsed;
+
 use super::bad_placeholder;
 use super::ItemCtxt;
 pub use opaque::test_opaque_hidden_types;
@@ -39,8 +41,18 @@ fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
         {
             return tcx.types.usize;
         }
-        Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => {
-            return tcx.typeck(def_id).node_type(e.hir_id);
+        Node::Ty(&hir::Ty { kind: TyKind::Typeof(ref e), span, .. }) if e.hir_id == hir_id => {
+            let ty = tcx.typeck(def_id).node_type(e.hir_id);
+            let ty = tcx.fold_regions(ty, |r, _| {
+                if r.is_erased() { ty::Region::new_error_misc(tcx) } else { r }
+            });
+            let (ty, opt_sugg) = if let Some(ty) = ty.make_suggestable(tcx, false) {
+                (ty, Some((span, Applicability::MachineApplicable)))
+            } else {
+                (ty, None)
+            };
+            tcx.dcx().emit_err(TypeofReservedKeywordUsed { span, ty, opt_sugg });
+            return ty;
         }
         Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
         | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
@@ -509,6 +521,8 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
             x => bug!("unexpected non-type Node::GenericParam: {:?}", x),
         },
 
+        Node::ArrayLenInfer(_) => tcx.types.usize,
+
         x => {
             bug!("unexpected sort of node in type_of(): {:?}", x);
         }
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 4eba31e327f..bec53693d6c 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -167,17 +167,6 @@ pub struct LifetimesOrBoundsMismatchOnTrait {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_async_trait_impl_should_be_async)]
-pub struct AsyncTraitImplShouldBeAsync {
-    #[primary_span]
-    // #[label]
-    pub span: Span,
-    #[label(hir_analysis_trait_item_label)]
-    pub trait_item_span: Option<Span>,
-    pub method_name: Symbol,
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_analysis_drop_impl_on_wrong_item, code = E0120)]
 pub struct DropImplOnWrongItem {
     #[primary_span]
@@ -1513,6 +1502,16 @@ pub struct NotSupportedDelegation<'a> {
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_analysis_method_should_return_future)]
+pub struct MethodShouldReturnFuture {
+    #[primary_span]
+    pub span: Span,
+    pub method_name: Symbol,
+    #[note]
+    pub trait_item_span: Option<Span>,
+}
+
+#[derive(Diagnostic)]
 #[diag(hir_analysis_unused_generic_parameter)]
 pub(crate) struct UnusedGenericParameter {
     #[primary_span]
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 454cb97ac14..883d416ecd1 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -55,7 +55,9 @@ This API is completely unstable and subject to change.
 
 */
 
+#![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::potential_query_instability)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
@@ -169,11 +171,11 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
 
     tcx.sess.time("coherence_checking", || {
         // Check impls constrain their parameters
-        let mut res =
+        let res =
             tcx.hir().try_par_for_each_module(|module| tcx.ensure().check_mod_impl_wf(module));
 
         for &trait_def_id in tcx.all_local_trait_impls(()).keys() {
-            res = res.and(tcx.ensure().coherent_trait(trait_def_id));
+            let _ = tcx.ensure().coherent_trait(trait_def_id);
         }
         // these queries are executed for side-effects (error reporting):
         res.and(tcx.ensure().crate_inherent_impls(()))
@@ -209,7 +211,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
 
     tcx.ensure().check_unused_traits(());
 
-    if let Some(reported) = tcx.dcx().has_errors() { Err(reported) } else { Ok(()) }
+    Ok(())
 }
 
 /// A quasi-deprecated helper used in rustdoc and clippy to get
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 501915d2e7e..3b1ee2975fd 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
@@ -771,8 +771,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
         );
 
         if let Some(parent_node) = self.tcx.hir().opt_parent_id(self.path_segment.hir_id)
-            && let Some(parent_node) = self.tcx.opt_hir_node(parent_node)
-            && let hir::Node::Expr(expr) = parent_node
+            && let hir::Node::Expr(expr) = self.tcx.hir_node(parent_node)
         {
             match &expr.kind {
                 hir::ExprKind::Path(qpath) => self
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 9d0c5cb0f32..b90fa03a3dc 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2,8 +2,6 @@
 //! the definitions in this file have equivalents in `rustc_ast_pretty`.
 
 #![recursion_limit = "256"]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 use rustc_ast as ast;
 use rustc_ast::util::parser::{self, AssocOp, Fixity};
@@ -23,7 +21,7 @@ use std::cell::Cell;
 use std::vec;
 
 pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId) -> String {
-    to_string(&map, |s| s.print_node(map.find(hir_id).unwrap()))
+    to_string(&map, |s| s.print_node(map.hir_node(hir_id)))
 }
 
 pub enum AnnNode<'a> {
@@ -117,6 +115,13 @@ impl<'a> State<'a> {
             Node::Ctor(..) => panic!("cannot print isolated Ctor"),
             Node::Local(a) => self.print_local_decl(a),
             Node::Crate(..) => panic!("cannot print Crate"),
+            Node::WhereBoundPredicate(pred) => {
+                self.print_formal_generic_params(pred.bound_generic_params);
+                self.print_type(pred.bounded_ty);
+                self.print_bounds(":", pred.bounds);
+            }
+            Node::ArrayLenInfer(_) => self.word("_"),
+            Node::Err(_) => self.word("/*ERROR*/"),
         }
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index cf1f232229d..7ea0469dedd 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -1,7 +1,11 @@
 use crate::coercion::{AsCoercionSite, CoerceMany};
 use crate::{Diverges, Expectation, FnCtxt, Needs};
-use rustc_errors::Diagnostic;
-use rustc_hir::{self as hir, ExprKind};
+use rustc_errors::{Applicability, Diagnostic};
+use rustc_hir::{
+    self as hir,
+    def::{CtorOf, DefKind, Res},
+    ExprKind, PatKind,
+};
 use rustc_hir_pretty::ty_to_string;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::traits::Obligation;
@@ -273,7 +277,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Returns `true` if there was an error forcing the coercion to the `()` type.
     pub(super) fn if_fallback_coercion<T>(
         &self,
-        span: Span,
+        if_span: Span,
+        cond_expr: &'tcx hir::Expr<'tcx>,
         then_expr: &'tcx hir::Expr<'tcx>,
         coercion: &mut CoerceMany<'tcx, '_, T>,
     ) -> bool
@@ -283,29 +288,106 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // If this `if` expr is the parent's function return expr,
         // the cause of the type coercion is the return type, point at it. (#25228)
         let hir_id = self.tcx.hir().parent_id(self.tcx.hir().parent_id(then_expr.hir_id));
-        let ret_reason = self.maybe_get_coercion_reason(hir_id, span);
-        let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse);
+        let ret_reason = self.maybe_get_coercion_reason(hir_id, if_span);
+        let cause = self.cause(if_span, ObligationCauseCode::IfExpressionWithNoElse);
         let mut error = false;
         coercion.coerce_forced_unit(
             self,
             &cause,
-            |err| {
-                if let Some((span, msg)) = &ret_reason {
-                    err.span_label(*span, msg.clone());
-                } else if let ExprKind::Block(block, _) = &then_expr.kind
-                    && let Some(expr) = &block.expr
-                {
-                    err.span_label(expr.span, "found here");
-                }
-                err.note("`if` expressions without `else` evaluate to `()`");
-                err.help("consider adding an `else` block that evaluates to the expected type");
-                error = true;
-            },
+            |err| self.explain_if_expr(err, ret_reason, if_span, cond_expr, then_expr, &mut error),
             false,
         );
         error
     }
 
+    /// Explain why `if` expressions without `else` evaluate to `()` and detect likely irrefutable
+    /// `if let PAT = EXPR {}` expressions that could be turned into `let PAT = EXPR;`.
+    fn explain_if_expr(
+        &self,
+        err: &mut Diagnostic,
+        ret_reason: Option<(Span, String)>,
+        if_span: Span,
+        cond_expr: &'tcx hir::Expr<'tcx>,
+        then_expr: &'tcx hir::Expr<'tcx>,
+        error: &mut bool,
+    ) {
+        if let Some((if_span, msg)) = ret_reason {
+            err.span_label(if_span, msg.clone());
+        } else if let ExprKind::Block(block, _) = then_expr.kind
+            && let Some(expr) = block.expr
+        {
+            err.span_label(expr.span, "found here");
+        }
+        err.note("`if` expressions without `else` evaluate to `()`");
+        err.help("consider adding an `else` block that evaluates to the expected type");
+        *error = true;
+        if let ExprKind::Let(hir::Let { span, pat, init, .. }) = cond_expr.kind
+            && let ExprKind::Block(block, _) = then_expr.kind
+            // Refutability checks occur on the MIR, so we approximate it here by checking
+            // if we have an enum with a single variant or a struct in the pattern.
+            && let PatKind::TupleStruct(qpath, ..) | PatKind::Struct(qpath, ..) = pat.kind
+            && let hir::QPath::Resolved(_, path) = qpath
+        {
+            match path.res {
+                Res::Def(DefKind::Ctor(CtorOf::Struct, _), _) => {
+                    // Structs are always irrefutable. Their fields might not be, but we
+                    // don't check for that here, it's only an approximation.
+                }
+                Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id)
+                    if self
+                        .tcx
+                        .adt_def(self.tcx.parent(self.tcx.parent(def_id)))
+                        .variants()
+                        .len()
+                        == 1 =>
+                {
+                    // There's only a single variant in the `enum`, so we can suggest the
+                    // irrefutable `let` instead of `if let`.
+                }
+                _ => return,
+            }
+
+            let mut sugg = vec![
+                // Remove the `if`
+                (if_span.until(*span), String::new()),
+            ];
+            match (block.stmts, block.expr) {
+                ([first, ..], Some(expr)) => {
+                    let padding = self
+                        .tcx
+                        .sess
+                        .source_map()
+                        .indentation_before(first.span)
+                        .unwrap_or_else(|| String::new());
+                    sugg.extend([
+                        (init.span.between(first.span), format!(";\n{padding}")),
+                        (expr.span.shrink_to_hi().with_hi(block.span.hi()), String::new()),
+                    ]);
+                }
+                ([], Some(expr)) => {
+                    let padding = self
+                        .tcx
+                        .sess
+                        .source_map()
+                        .indentation_before(expr.span)
+                        .unwrap_or_else(|| String::new());
+                    sugg.extend([
+                        (init.span.between(expr.span), format!(";\n{padding}")),
+                        (expr.span.shrink_to_hi().with_hi(block.span.hi()), String::new()),
+                    ]);
+                }
+                // If there's no value in the body, then the `if` expression would already
+                // be of type `()`, so checking for those cases is unnecessary.
+                (_, None) => return,
+            }
+            err.multipart_suggestion(
+                "consider using an irrefutable `let` binding instead",
+                sugg,
+                Applicability::MaybeIncorrect,
+            );
+        }
+    }
+
     pub fn maybe_get_coercion_reason(
         &self,
         hir_id: hir::HirId,
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index bed0d80787f..68add9e27c8 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -41,7 +41,7 @@ pub fn check_legal_trait_for_method_call(
     receiver: Option<Span>,
     expr_span: Span,
     trait_id: DefId,
-) {
+) -> Result<(), ErrorGuaranteed> {
     if tcx.lang_items().drop_trait() == Some(trait_id) {
         let sugg = if let Some(receiver) = receiver.filter(|s| !s.is_empty()) {
             errors::ExplicitDestructorCallSugg::Snippet {
@@ -51,8 +51,9 @@ pub fn check_legal_trait_for_method_call(
         } else {
             errors::ExplicitDestructorCallSugg::Empty(span)
         };
-        tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg });
+        return Err(tcx.dcx().emit_err(errors::ExplicitDestructorCall { span, sugg }));
     }
+    tcx.coherent_trait(trait_id)
 }
 
 #[derive(Debug)]
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 58823ea30ce..f21de1609cb 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -448,13 +448,35 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                             );
                         }
                     }
-                    let msg = "an `as` expression can only be used to convert between primitive \
-                               types or to coerce to a specific trait object";
+
+                    let (msg, note) = if let ty::Adt(adt, _) = self.expr_ty.kind()
+                        && adt.is_enum()
+                        && self.cast_ty.is_numeric()
+                    {
+                        (
+                            "an `as` expression can be used to convert enum types to numeric \
+                             types only if the enum type is unit-only or field-less",
+                            Some(
+                                "see https://doc.rust-lang.org/reference/items/enumerations.html#casting for more information",
+                            ),
+                        )
+                    } else {
+                        (
+                            "an `as` expression can only be used to convert between primitive \
+                             types or to coerce to a specific trait object",
+                            None,
+                        )
+                    };
+
                     if label {
                         err.span_label(self.span, msg);
                     } else {
                         err.note(msg);
                     }
+
+                    if let Some(note) = note {
+                        err.note(note);
+                    }
                 } else {
                     err.span_label(self.span, "invalid cast");
                 }
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index ca636ebcade..2beabc0835d 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -1715,8 +1715,8 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
         let ret_msg = "return a value for the case when the loop has zero elements to iterate on";
         let ret_ty_msg =
             "otherwise consider changing the return type to account for that possibility";
-        if let Some(node) = tcx.opt_hir_node(item.into())
-            && let Some(body_id) = node.body_id()
+        let node = tcx.hir_node(item.into());
+        if let Some(body_id) = node.body_id()
             && let Some(sig) = node.fn_sig()
             && let hir::ExprKind::Block(block, _) = hir.body(body_id).value.kind
             && !ty.is_never()
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index b6dfc34d3ac..d8974251de0 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -561,11 +561,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut parent;
         'outer: loop {
             // Climb the HIR tree to see if the current `Expr` is part of a `break;` statement.
-            let Some(
-                hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. })
-                | hir::Node::Block(hir::Block { expr: Some(&ref p), .. })
-                | hir::Node::Expr(&ref p),
-            ) = self.tcx.opt_hir_node(parent_id)
+            let (hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. })
+            | hir::Node::Block(hir::Block { expr: Some(&ref p), .. })
+            | hir::Node::Expr(&ref p)) = self.tcx.hir_node(parent_id)
             else {
                 break;
             };
@@ -578,20 +576,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let mut direct = false;
             loop {
                 // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to.
-                let parent = match self.tcx.opt_hir_node(parent_id) {
-                    Some(hir::Node::Expr(&ref parent)) => {
+                let parent = match self.tcx.hir_node(parent_id) {
+                    hir::Node::Expr(&ref parent) => {
                         parent_id = self.tcx.hir().parent_id(parent.hir_id);
                         parent
                     }
-                    Some(hir::Node::Stmt(hir::Stmt {
+                    hir::Node::Stmt(hir::Stmt {
                         hir_id,
                         kind: hir::StmtKind::Semi(&ref parent) | hir::StmtKind::Expr(&ref parent),
                         ..
-                    })) => {
+                    }) => {
                         parent_id = self.tcx.hir().parent_id(*hir_id);
                         parent
                     }
-                    Some(hir::Node::Block(_)) => {
+                    hir::Node::Block(_) => {
                         parent_id = self.tcx.hir().parent_id(parent_id);
                         parent
                     }
@@ -680,17 +678,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         error: Option<TypeError<'tcx>>,
     ) {
         let parent = self.tcx.hir().parent_id(expr.hir_id);
-        match (self.tcx.opt_hir_node(parent), error) {
-            (Some(hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. })), _)
+        match (self.tcx.hir_node(parent), error) {
+            (hir::Node::Local(hir::Local { ty: Some(ty), init: Some(init), .. }), _)
                 if init.hir_id == expr.hir_id =>
             {
                 // Point at `let` assignment type.
                 err.span_label(ty.span, "expected due to this");
             }
             (
-                Some(hir::Node::Expr(hir::Expr {
-                    kind: hir::ExprKind::Assign(lhs, rhs, _), ..
-                })),
+                hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }),
                 Some(TypeError::Sorts(ExpectedFound { expected, .. })),
             ) if rhs.hir_id == expr.hir_id && !expected.is_closure() => {
                 // We ignore closures explicitly because we already point at them elsewhere.
@@ -725,7 +721,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         None,
                         hir::Path { res: hir::def::Res::Local(hir_id), .. },
                     )) => {
-                        if let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id) {
+                        if let hir::Node::Pat(pat) = self.tcx.hir_node(*hir_id) {
                             primary_span = pat.span;
                             secondary_span = pat.span;
                             match self.tcx.hir().find_parent(pat.hir_id) {
@@ -774,9 +770,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
             }
             (
-                Some(hir::Node::Expr(hir::Expr {
-                    kind: hir::ExprKind::Binary(_, lhs, rhs), ..
-                })),
+                hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Binary(_, lhs, rhs), .. }),
                 Some(TypeError::Sorts(ExpectedFound { expected, .. })),
             ) if rhs.hir_id == expr.hir_id
                 && self.typeck_results.borrow().expr_ty_adjusted_opt(lhs) == Some(expected) =>
@@ -797,8 +791,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {
             return;
         };
-        let Some(hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. })) =
-            self.tcx.opt_hir_node(parent)
+        let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) =
+            self.tcx.hir_node(parent)
         else {
             return;
         };
@@ -1022,13 +1016,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             hir::Path { res: hir::def::Res::Local(bind_hir_id), .. },
         )) = expr.kind
         {
-            let bind = self.tcx.opt_hir_node(*bind_hir_id);
-            let parent = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*bind_hir_id));
-            if let Some(hir::Node::Pat(hir::Pat {
-                kind: hir::PatKind::Binding(_, _hir_id, _, _),
-                ..
-            })) = bind
-                && let Some(hir::Node::Pat(hir::Pat { default_binding_modes: false, .. })) = parent
+            let bind = self.tcx.hir_node(*bind_hir_id);
+            let parent = self.tcx.hir_node(self.tcx.hir().parent_id(*bind_hir_id));
+            if let hir::Node::Pat(hir::Pat {
+                kind: hir::PatKind::Binding(_, _hir_id, _, _), ..
+            }) = bind
+                && let hir::Node::Pat(hir::Pat { default_binding_modes: false, .. }) = parent
             {
                 return true;
             }
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 70afb042441..10e12d01b1f 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -4,7 +4,7 @@ use std::borrow::Cow;
 use crate::fluent_generated as fluent;
 use rustc_errors::{
     codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg,
-    MultiSpan, SubdiagnosticMessage,
+    MultiSpan, SubdiagnosticMessageOp,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::Ty;
@@ -195,10 +195,7 @@ pub struct TypeMismatchFruTypo {
 }
 
 impl AddToDiagnostic for TypeMismatchFruTypo {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         diag.arg("expr", self.expr.as_deref().unwrap_or("NONE"));
 
         // Only explain that `a ..b` is a range if it's split up
@@ -373,10 +370,7 @@ pub struct RemoveSemiForCoerce {
 }
 
 impl AddToDiagnostic for RemoveSemiForCoerce {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         let mut multispan: MultiSpan = self.semi.into();
         multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr);
         multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret);
@@ -547,14 +541,8 @@ pub enum CastUnknownPointerSub {
     From(Span),
 }
 
-impl rustc_errors::AddToDiagnostic for CastUnknownPointerSub {
-    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, f: F)
-    where
-        F: Fn(
-            &mut Diagnostic,
-            rustc_errors::SubdiagnosticMessage,
-        ) -> rustc_errors::SubdiagnosticMessage,
-    {
+impl AddToDiagnostic for CastUnknownPointerSub {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) {
         match self {
             CastUnknownPointerSub::To(span) => {
                 let msg = f(diag, crate::fluent_generated::hir_typeck_label_to);
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 1adde8c21b8..292b85eb97f 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1017,7 +1017,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         then: impl FnOnce(&hir::Expr<'_>),
     ) {
         let mut parent = self.tcx.hir().parent_id(original_expr_id);
-        while let Some(node) = self.tcx.opt_hir_node(parent) {
+        loop {
+            let node = self.tcx.hir_node(parent);
             match node {
                 hir::Node::Expr(hir::Expr {
                     kind:
@@ -1118,7 +1119,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // We won't diverge unless both branches do (or the condition does).
             self.diverges.set(cond_diverges | then_diverges & else_diverges);
         } else {
-            self.if_fallback_coercion(sp, then_expr, &mut coerce);
+            self.if_fallback_coercion(sp, cond_expr, then_expr, &mut coerce);
 
             // If the condition is false we can't diverge.
             self.diverges.set(cond_diverges);
@@ -1471,8 +1472,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         if let hir::TyKind::Array(_, length) = ty.peel_refs().kind
             && let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
-            && let Some(span) = self.tcx.hir().opt_span(hir_id)
         {
+            let span = self.tcx.hir().span(hir_id);
             match self.dcx().steal_diagnostic(span, StashKey::UnderscoreForArrayLengths) {
                 Some(mut err) => {
                     err.span_suggestion(
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 60eb40bd8fe..36c3eef82fc 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -521,7 +521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// We must not attempt to select obligations after this method has run, or risk query cycle
     /// ICE.
     #[instrument(level = "debug", skip(self))]
-    pub(in super::super) fn resolve_coroutine_interiors(&self, def_id: DefId) {
+    pub(in super::super) fn resolve_coroutine_interiors(&self) {
         // Try selecting all obligations that are not blocked on inference variables.
         // Once we start unifying coroutine witnesses, trying to select obligations on them will
         // trigger query cycle ICEs, as doing so requires MIR.
@@ -1105,13 +1105,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let container_id = assoc_item.container_id(tcx);
                 debug!(?def_id, ?container, ?container_id);
                 match container {
-                    ty::TraitContainer => callee::check_legal_trait_for_method_call(
-                        tcx,
-                        path_span,
-                        None,
-                        span,
-                        container_id,
-                    ),
+                    ty::TraitContainer => {
+                        if let Err(e) = callee::check_legal_trait_for_method_call(
+                            tcx,
+                            path_span,
+                            None,
+                            span,
+                            container_id,
+                        ) {
+                            self.set_tainted_by_errors(e);
+                        }
+                    }
                     ty::ImplContainer => {
                         if segments.len() == 1 {
                             // `<T>::assoc` will end up here, and so
@@ -1175,14 +1179,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // parameter internally, but we don't allow users to specify the
             // parameter's value explicitly, so we have to do some error-
             // checking here.
-            let arg_count = check_generic_arg_count_for_call(
-                tcx,
-                span,
-                def_id,
-                generics,
-                seg,
-                IsMethodCall::No,
-            );
+            let arg_count =
+                check_generic_arg_count_for_call(tcx, def_id, generics, seg, IsMethodCall::No);
 
             if let ExplicitLateBound::Yes = arg_count.explicit_late_bound {
                 explicit_late_bound = ExplicitLateBound::Yes;
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index d30c7a4fb38..35b3f27d791 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -2060,7 +2060,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let node = self
                     .tcx
                     .opt_local_def_id_to_hir_id(self.tcx.hir().get_parent_item(call_expr.hir_id))
-                    .and_then(|hir_id| self.tcx.opt_hir_node(hir_id));
+                    .map(|hir_id| self.tcx.hir_node(hir_id));
                 match node {
                     Some(hir::Node::Item(item)) => call_finder.visit_item(item),
                     Some(hir::Node::TraitItem(item)) => call_finder.visit_trait_item(item),
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 5395ffda1d1..ed0bdb9bdaa 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -682,8 +682,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // is and we were expecting a Box, ergo Pin<Box<expected>>, we
                 // can suggest Box::pin.
                 let parent = self.tcx.hir().parent_id(expr.hir_id);
-                let Some(Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. })) =
-                    self.tcx.opt_hir_node(parent)
+                let Node::Expr(Expr { kind: ExprKind::Call(fn_name, _), .. }) =
+                    self.tcx.hir_node(parent)
                 else {
                     return false;
                 };
@@ -908,9 +908,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let ty::Param(expected_ty_as_param) = expected.kind() else { return };
 
-        let fn_node = self.tcx.opt_hir_node(fn_id);
+        let fn_node = self.tcx.hir_node(fn_id);
 
-        let Some(hir::Node::Item(hir::Item {
+        let hir::Node::Item(hir::Item {
             kind:
                 hir::ItemKind::Fn(
                     hir::FnSig {
@@ -921,7 +921,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     _body_id,
                 ),
             ..
-        })) = fn_node
+        }) = fn_node
         else {
             return;
         };
@@ -1053,9 +1053,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             };
             let ty = self.normalize(expr.span, ty);
             if self.can_coerce(found, ty) {
-                if let Some(node) = self.tcx.opt_hir_node(fn_id)
-                    && let Some(owner_node) = node.as_owner()
-                    && let Some(span) = expr.span.find_ancestor_inside(owner_node.span())
+                if let Some(owner_node) = self.tcx.hir_node(fn_id).as_owner()
+                    && let Some(span) = expr.span.find_ancestor_inside(*owner_node.span())
                 {
                     err.multipart_suggestion(
                         "you might have meant to return this value",
@@ -1684,15 +1683,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 None,
                 hir::Path { segments: [_], res: crate::Res::Local(binding), .. },
             )) => {
-                let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) = self.tcx.opt_hir_node(*binding)
-                else {
-                    return expr;
-                };
-                let Some(parent) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id)) else {
+                let hir::Node::Pat(hir::Pat { hir_id, .. }) = self.tcx.hir_node(*binding) else {
                     return expr;
                 };
 
-                match parent {
+                match self.tcx.hir_node(self.tcx.hir().parent_id(*hir_id)) {
                     // foo.clone()
                     hir::Node::Local(hir::Local { init: Some(init), .. }) => {
                         self.note_type_is_not_clone_inner_expr(init)
@@ -1703,8 +1698,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         kind: hir::PatKind::Tuple(pats, ..),
                         ..
                     }) => {
-                        let Some(hir::Node::Local(hir::Local { init: Some(init), .. })) =
-                            self.tcx.opt_hir_node(self.tcx.hir().parent_id(*pat_hir_id))
+                        let hir::Node::Local(hir::Local { init: Some(init), .. }) =
+                            self.tcx.hir_node(self.tcx.hir().parent_id(*pat_hir_id))
                         else {
                             return expr;
                         };
@@ -1736,10 +1731,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     call_expr_kind
                     && let hir::Path { segments: [_], res: crate::Res::Local(binding), .. } =
                         call_expr_path
-                    && let Some(hir::Node::Pat(hir::Pat { hir_id, .. })) =
-                        self.tcx.opt_hir_node(*binding)
-                    && let Some(closure) = self.tcx.opt_hir_node(self.tcx.hir().parent_id(*hir_id))
-                    && let hir::Node::Local(hir::Local { init: Some(init), .. }) = closure
+                    && let hir::Node::Pat(hir::Pat { hir_id, .. }) = self.tcx.hir_node(*binding)
+                    && let hir::Node::Local(hir::Local { init: Some(init), .. }) =
+                        self.tcx.hir_node(self.tcx.hir().parent_id(*hir_id))
                     && let Expr {
                         kind: hir::ExprKind::Closure(hir::Closure { body: body_id, .. }),
                         ..
@@ -1979,20 +1973,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Unroll desugaring, to make sure this works for `for` loops etc.
                 loop {
                     parent = self.tcx.hir().parent_id(id);
-                    if let Some(parent_span) = self.tcx.hir().opt_span(parent) {
-                        if parent_span.find_ancestor_inside(expr.span).is_some() {
-                            // The parent node is part of the same span, so is the result of the
-                            // same expansion/desugaring and not the 'real' parent node.
-                            id = parent;
-                            continue;
-                        }
+                    let parent_span = self.tcx.hir().span(parent);
+                    if parent_span.find_ancestor_inside(expr.span).is_some() {
+                        // The parent node is part of the same span, so is the result of the
+                        // same expansion/desugaring and not the 'real' parent node.
+                        id = parent;
+                        continue;
                     }
                     break;
                 }
 
-                if let Some(hir::Node::Block(&hir::Block {
-                    span: block_span, expr: Some(e), ..
-                })) = self.tcx.opt_hir_node(parent)
+                if let hir::Node::Block(&hir::Block { span: block_span, expr: Some(e), .. }) =
+                    self.tcx.hir_node(parent)
                 {
                     if e.hir_id == id {
                         if let Some(span) = expr.span.find_ancestor_inside(block_span) {
@@ -2220,30 +2212,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
 
         let local_parent = self.tcx.hir().parent_id(local_id);
-        let Some(Node::Param(hir::Param { hir_id: param_hir_id, .. })) =
-            self.tcx.opt_hir_node(local_parent)
+        let Node::Param(hir::Param { hir_id: param_hir_id, .. }) = self.tcx.hir_node(local_parent)
         else {
             return None;
         };
 
         let param_parent = self.tcx.hir().parent_id(*param_hir_id);
-        let Some(Node::Expr(hir::Expr {
+        let Node::Expr(hir::Expr {
             hir_id: expr_hir_id,
             kind: hir::ExprKind::Closure(hir::Closure { fn_decl: closure_fn_decl, .. }),
             ..
-        })) = self.tcx.opt_hir_node(param_parent)
+        }) = self.tcx.hir_node(param_parent)
         else {
             return None;
         };
 
         let expr_parent = self.tcx.hir().parent_id(*expr_hir_id);
-        let hir = self.tcx.opt_hir_node(expr_parent);
+        let hir = self.tcx.hir_node(expr_parent);
         let closure_params_len = closure_fn_decl.inputs.len();
         let (
-            Some(Node::Expr(hir::Expr {
+            Node::Expr(hir::Expr {
                 kind: hir::ExprKind::MethodCall(method_path, receiver, ..),
                 ..
-            })),
+            }),
             1,
         ) = (hir, closure_params_len)
         else {
@@ -2674,10 +2665,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn is_else_if_block(&self, expr: &hir::Expr<'_>) -> bool {
         if let hir::ExprKind::If(..) = expr.kind {
             let parent_id = self.tcx.hir().parent_id(expr.hir_id);
-            if let Some(Node::Expr(hir::Expr {
-                kind: hir::ExprKind::If(_, _, Some(else_expr)),
-                ..
-            })) = self.tcx.opt_hir_node(parent_id)
+            if let Node::Expr(hir::Expr {
+                kind: hir::ExprKind::If(_, _, Some(else_expr)), ..
+            }) = self.tcx.hir_node(parent_id)
             {
                 return else_expr.hir_id == expr.hir_id;
             }
@@ -3067,7 +3057,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         };
         let parent = self.tcx.hir().parent_id(expr.hir_id);
-        if let Some(hir::Node::ExprField(_)) = self.tcx.opt_hir_node(parent) {
+        if let hir::Node::ExprField(_) = self.tcx.hir_node(parent) {
             // Ignore `Foo { field: a..Default::default() }`
             return;
         }
@@ -3146,7 +3136,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let hir::def::Res::Local(hir_id) = path.res else {
             return;
         };
-        let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(hir_id) else {
+        let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
             return;
         };
         let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) =
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index deb3ad2edc7..315dc4330ad 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -1,3 +1,5 @@
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(try_blocks)]
@@ -286,7 +288,7 @@ fn typeck_with_fallback<'tcx>(
     debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
 
     // This must be the last thing before `report_ambiguity_errors`.
-    fcx.resolve_coroutine_interiors(def_id.to_def_id());
+    fcx.resolve_coroutine_interiors();
 
     debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
 
diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs
index 1ce0240f7b8..f9297550c57 100644
--- a/compiler/rustc_hir_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs
@@ -436,7 +436,8 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
     pub(crate) fn cat_rvalue(
         &self,
         hir_id: hir::HirId,
-        span: Span,
+        // FIXME: remove
+        _span: Span,
         expr_ty: Ty<'tcx>,
     ) -> PlaceWithHirId<'tcx> {
         PlaceWithHirId::new(hir_id, expr_ty, PlaceBase::Rvalue, Vec::new())
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 6f18cc51b11..3a44c6c2410 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -356,7 +356,6 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
 
         let arg_count_correct = check_generic_arg_count_for_call(
             self.tcx,
-            self.span,
             pick.item.def_id,
             generics,
             seg,
@@ -630,13 +629,15 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
     fn enforce_illegal_method_limitations(&self, pick: &probe::Pick<'_>) {
         // Disallow calls to the method `drop` defined in the `Drop` trait.
         if let Some(trait_def_id) = pick.item.trait_container(self.tcx) {
-            callee::check_legal_trait_for_method_call(
+            if let Err(e) = callee::check_legal_trait_for_method_call(
                 self.tcx,
                 self.span,
                 Some(self.self_expr.span),
                 self.call_expr.span,
                 trait_def_id,
-            )
+            ) {
+                self.set_tainted_by_errors(e);
+            }
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 2a1c417a16b..81b82393515 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -230,7 +230,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                         if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = kind
                             && let hir::def::Res::Local(hir_id) = path.res
-                            && let Some(hir::Node::Pat(b)) = self.tcx.opt_hir_node(hir_id)
+                            && let hir::Node::Pat(b) = self.tcx.hir_node(hir_id)
                             && let Some(hir::Node::Param(p)) = self.tcx.hir().find_parent(b.hir_id)
                             && let Some(node) = self.tcx.hir().find_parent(p.hir_id)
                             && let Some(decl) = node.fn_decl()
@@ -541,6 +541,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let mut bound_spans: SortedMap<Span, Vec<String>> = Default::default();
         let mut restrict_type_params = false;
+        let mut suggested_derive = false;
         let mut unsatisfied_bounds = false;
         if item_name.name == sym::count && self.is_slice_ty(rcvr_ty, span) {
             let msg = "consider using `len` instead";
@@ -555,6 +556,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     "`count` is defined on `{iterator_trait}`, which `{rcvr_ty}` does not implement"
                 ));
             }
+        } else if !unsatisfied_predicates.is_empty() && matches!(rcvr_ty.kind(), ty::Param(_)) {
+            // We special case the situation where we are looking for `_` in
+            // `<TypeParam as _>::method` because otherwise the machinery will look for blanket
+            // implementations that have unsatisfied trait bounds to suggest, leading us to claim
+            // things like "we're looking for a trait with method `cmp`, both `Iterator` and `Ord`
+            // have one, in order to implement `Ord` you need to restrict `TypeParam: FnPtr` so
+            // that `impl<T: FnPtr> Ord for T` can apply", which is not what we want. We have a type
+            // parameter, we want to directly say "`Ord::cmp` and `Iterator::cmp` exist, restrict
+            // `TypeParam: Ord` or `TypeParam: Iterator`"". That is done further down when calling
+            // `self.suggest_traits_to_import`, so we ignore the `unsatisfied_predicates`
+            // suggestions.
         } else if !unsatisfied_predicates.is_empty() {
             let mut type_params = FxIndexMap::default();
 
@@ -917,20 +929,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 .enumerate()
                 .collect::<Vec<(usize, String)>>();
 
-            for ((span, add_where_or_comma), obligations) in type_params.into_iter() {
-                restrict_type_params = true;
-                // #74886: Sort here so that the output is always the same.
-                let obligations = obligations.into_sorted_stable_ord();
-                err.span_suggestion_verbose(
-                    span,
-                    format!(
-                        "consider restricting the type parameter{s} to satisfy the \
-                         trait bound{s}",
-                        s = pluralize!(obligations.len())
-                    ),
-                    format!("{} {}", add_where_or_comma, obligations.join(", ")),
-                    Applicability::MaybeIncorrect,
-                );
+            if !matches!(rcvr_ty.peel_refs().kind(), ty::Param(_)) {
+                for ((span, add_where_or_comma), obligations) in type_params.into_iter() {
+                    restrict_type_params = true;
+                    // #74886: Sort here so that the output is always the same.
+                    let obligations = obligations.into_sorted_stable_ord();
+                    err.span_suggestion_verbose(
+                        span,
+                        format!(
+                            "consider restricting the type parameter{s} to satisfy the trait \
+                             bound{s}",
+                            s = pluralize!(obligations.len())
+                        ),
+                        format!("{} {}", add_where_or_comma, obligations.join(", ")),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
             }
 
             bound_list.sort_by(|(_, a), (_, b)| a.cmp(b)); // Sort alphabetically.
@@ -978,7 +992,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         "the following trait bounds were not satisfied:\n{bound_list}"
                     ));
                 }
-                self.suggest_derive(&mut err, unsatisfied_predicates);
+                suggested_derive = self.suggest_derive(&mut err, unsatisfied_predicates);
 
                 unsatisfied_bounds = true;
             }
@@ -1201,7 +1215,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
 
-        if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params {
+        if rcvr_ty.is_numeric() && rcvr_ty.is_fresh() || restrict_type_params || suggested_derive {
         } else {
             self.suggest_traits_to_import(
                 &mut err,
@@ -1211,7 +1225,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 args.map(|args| args.len() + 1),
                 source,
                 no_match_data.out_of_scope_traits.clone(),
-                unsatisfied_predicates,
                 static_candidates,
                 unsatisfied_bounds,
                 expected.only_has_type(self),
@@ -1326,7 +1339,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
         self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
-        return Some(err);
+        Some(err)
     }
 
     fn note_candidates_on_method_error(
@@ -2004,7 +2017,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         visitor.visit_body(body);
 
         let parent = self.tcx.hir().parent_id(seg1.hir_id);
-        if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent)
+        if let Node::Expr(call_expr) = self.tcx.hir_node(parent)
             && let Some(expr) = visitor.result
             && let Some(self_ty) = self.node_ty_opt(expr.hir_id)
         {
@@ -2471,7 +2484,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Option<ty::Predicate<'tcx>>,
             Option<ObligationCause<'tcx>>,
         )],
-    ) {
+    ) -> bool {
         let mut derives = self.note_predicate_source_and_get_derives(err, unsatisfied_predicates);
         derives.sort();
         derives.dedup();
@@ -2496,6 +2509,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 Applicability::MaybeIncorrect,
             );
         }
+        !derives_grouped.is_empty()
     }
 
     fn note_derefed_ty_has_method(
@@ -2698,11 +2712,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         inputs_len: Option<usize>,
         source: SelfSource<'tcx>,
         valid_out_of_scope_traits: Vec<DefId>,
-        unsatisfied_predicates: &[(
-            ty::Predicate<'tcx>,
-            Option<ty::Predicate<'tcx>>,
-            Option<ObligationCause<'tcx>>,
-        )],
         static_candidates: &[CandidateSource],
         unsatisfied_bounds: bool,
         return_type: Option<Ty<'tcx>>,
@@ -2919,19 +2928,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // this isn't perfect (that is, there are cases when
                 // implementing a trait would be legal but is rejected
                 // here).
-                unsatisfied_predicates.iter().all(|(p, _, _)| {
-                    match p.kind().skip_binder() {
-                        // Hide traits if they are present in predicates as they can be fixed without
-                        // having to implement them.
-                        ty::PredicateKind::Clause(ty::ClauseKind::Trait(t)) => {
-                            t.def_id() == info.def_id
-                        }
-                        ty::PredicateKind::Clause(ty::ClauseKind::Projection(p)) => {
-                            p.projection_ty.def_id == info.def_id
-                        }
-                        _ => false,
-                    }
-                }) && (type_is_local || info.def_id.is_local())
+                (type_is_local || info.def_id.is_local())
                     && !self.tcx.trait_is_auto(info.def_id)
                     && self
                         .associated_value(info.def_id, item_name)
@@ -3254,7 +3251,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         let parent = self.tcx.hir().parent_id(expr.hir_id);
-        if let Some(Node::Expr(call_expr)) = self.tcx.opt_hir_node(parent)
+        if let Node::Expr(call_expr) = self.tcx.hir_node(parent)
             && let hir::ExprKind::MethodCall(
                 hir::PathSegment { ident: method_name, .. },
                 self_expr,
diff --git a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
index b9b3ed53dae..34ce0ab1f8b 100644
--- a/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
+++ b/compiler/rustc_hir_typeck/src/rvalue_scopes.rs
@@ -73,9 +73,7 @@ pub fn resolve_rvalue_scopes<'a, 'tcx>(
     debug!("start resolving rvalue scopes, def_id={def_id:?}");
     debug!("rvalue_scope: rvalue_candidates={:?}", scope_tree.rvalue_candidates);
     for (&hir_id, candidate) in &scope_tree.rvalue_candidates {
-        let Some(Node::Expr(expr)) = tcx.opt_hir_node(hir_id) else {
-            bug!("hir node does not exist")
-        };
+        let Node::Expr(expr) = tcx.hir_node(hir_id) else { bug!("hir node does not exist") };
         record_rvalue_scope(&mut rvalue_scopes, expr, candidate);
     }
     rvalue_scopes
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index c4773a88521..211109b5941 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -972,9 +972,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     if let Ok(mut s) = self.tcx.sess.source_map().span_to_snippet(closure_body_span) {
                         if s.starts_with('$') {
                             // Looks like a macro fragment. Try to find the real block.
-                            if let Some(hir::Node::Expr(&hir::Expr {
+                            if let hir::Node::Expr(&hir::Expr {
                                 kind: hir::ExprKind::Block(block, ..), ..
-                            })) = self.tcx.opt_hir_node(body_id.hir_id) {
+                            }) = self.tcx.hir_node(body_id.hir_id) {
                                 // If the body is a block (with `{..}`), we use the span of that block.
                                 // E.g. with a `|| $body` expanded from a `m!({ .. })`, we use `{ .. }`, and not `$body`.
                                 // Since we know it's a block, we know we can insert the `let _ = ..` without
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 3430a5fb00d..94f6c06157e 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -753,10 +753,14 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
     }
 
     fn report_error(&self, p: impl Into<ty::GenericArg<'tcx>>) -> ErrorGuaranteed {
-        match self.fcx.dcx().has_errors() {
-            Some(e) => e,
-            None => self
-                .fcx
+        if let Some(guar) = self.fcx.dcx().has_errors() {
+            guar
+        } else if self.fcx.dcx().stashed_err_count() > 0 {
+            // Without this case we sometimes get uninteresting and extraneous
+            // "type annotations needed" errors.
+            self.fcx.dcx().delayed_bug("error in Resolver")
+        } else {
+            self.fcx
                 .err_ctxt()
                 .emit_inference_failure_err(
                     self.fcx.tcx.hir().body_owner_def_id(self.body.id()),
@@ -765,7 +769,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
                     E0282,
                     false,
                 )
-                .emit(),
+                .emit()
         }
     }
 
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index 82f02b7d47a..0729986f32f 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -5,8 +5,6 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_middle;
diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs
index 854841206b8..6fcb3a024ab 100644
--- a/compiler/rustc_index/src/lib.rs
+++ b/compiler/rustc_index/src/lib.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![cfg_attr(
     feature = "nightly",
     feature(extend_one, min_specialization, new_uninit, step_trait, test)
diff --git a/compiler/rustc_index_macros/src/lib.rs b/compiler/rustc_index_macros/src/lib.rs
index 72567b43a5f..532cac5791e 100644
--- a/compiler/rustc_index_macros/src/lib.rs
+++ b/compiler/rustc_index_macros/src/lib.rs
@@ -31,17 +31,17 @@ mod newtype;
 /// - `#[max = 0xFFFF_FFFD]`: specifies the max value, which allows niche
 ///   optimizations. The default max value is 0xFFFF_FF00.
 /// - `#[gate_rustc_only]`: makes parts of the generated code nightly-only.
-///
-/// `SpecOptionPartialEq` is specialized by this macro, so using it requires enabling
-/// `#![feature(min_specialization)]` for the crate.
 #[proc_macro]
 #[cfg_attr(
     feature = "nightly",
-    allow_internal_unstable(step_trait, rustc_attrs, trusted_step, spec_option_partial_eq)
+    allow_internal_unstable(
+        step_trait,
+        rustc_attrs,
+        trusted_step,
+        spec_option_partial_eq,
+        min_specialization
+    )
 )]
-// FIXME: Remove the above comment about `min_specialization` once bootstrap is bumped,
-// and the corresponding one on SpecOptionPartialEq
-#[cfg_attr(all(feature = "nightly", not(bootstrap)), allow_internal_unstable(min_specialization))]
 pub fn newtype_index(input: TokenStream) -> TokenStream {
     newtype::newtype(input)
 }
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index 0a128218c92..8bfc05d6a96 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::{
     codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage,
-    DiagnosticStyledString, IntoDiagnosticArg, MultiSpan, SubdiagnosticMessage,
+    DiagnosticStyledString, IntoDiagnosticArg, MultiSpan, SubdiagnosticMessageOp,
 };
 use rustc_hir as hir;
 use rustc_hir::FnRetTy;
@@ -225,10 +225,7 @@ pub enum RegionOriginNote<'a> {
 }
 
 impl AddToDiagnostic for RegionOriginNote<'_> {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         let mut label_or_note = |span, msg: DiagnosticMessage| {
             let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
             let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
@@ -289,10 +286,7 @@ pub enum LifetimeMismatchLabels {
 }
 
 impl AddToDiagnostic for LifetimeMismatchLabels {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         match self {
             LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
                 diag.span_label(param_span, fluent::infer_declared_different);
@@ -336,10 +330,7 @@ pub struct AddLifetimeParamsSuggestion<'a> {
 }
 
 impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         let mut mk_suggestion = || {
             let (
                 hir::Ty { kind: hir::TyKind::Ref(lifetime_sub, _), .. },
@@ -437,10 +428,7 @@ pub struct IntroducesStaticBecauseUnmetLifetimeReq {
 }
 
 impl AddToDiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
-    fn add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(mut self, diag: &mut Diagnostic, _: F) {
         self.unmet_requirements
             .push_span_label(self.binding_span, fluent::infer_msl_introduces_static);
         diag.span_note(self.unmet_requirements, fluent::infer_msl_unmet_req);
@@ -755,10 +743,7 @@ pub struct ConsiderBorrowingParamHelp {
 }
 
 impl AddToDiagnostic for ConsiderBorrowingParamHelp {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) {
         let mut type_param_span: MultiSpan = self.spans.clone().into();
         for &span in &self.spans {
             // Seems like we can't call f() here as Into<DiagnosticMessage> is required
@@ -799,10 +784,7 @@ pub struct DynTraitConstraintSuggestion {
 }
 
 impl AddToDiagnostic for DynTraitConstraintSuggestion {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) {
         let mut multi_span: MultiSpan = vec![self.span].into();
         multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label);
         multi_span.push_span_label(self.ident.span, fluent::infer_dtcs_introduces_requirement);
@@ -845,10 +827,7 @@ pub struct ReqIntroducedLocations {
 }
 
 impl AddToDiagnostic for ReqIntroducedLocations {
-    fn add_to_diagnostic_with<F>(mut self, diag: &mut Diagnostic, f: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(mut self, diag: &mut Diagnostic, f: F) {
         for sp in self.spans {
             self.span.push_span_label(sp, fluent::infer_ril_introduced_here);
         }
@@ -867,10 +846,7 @@ pub struct MoreTargeted {
 }
 
 impl AddToDiagnostic for MoreTargeted {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _f: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _f: F) {
         diag.code(E0772);
         diag.primary_message(fluent::infer_more_targeted);
         diag.arg("ident", self.ident);
@@ -1289,10 +1265,7 @@ pub struct SuggestTuplePatternMany {
 }
 
 impl AddToDiagnostic for SuggestTuplePatternMany {
-    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, f: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) {
         diag.arg("path", self.path);
         let message = f(diag, crate::fluent_generated::infer_stp_wrap_many.into());
         diag.multipart_suggestions(
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index 331e3633e90..a59a4df7729 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -1,6 +1,6 @@
 use crate::fluent_generated as fluent;
 use crate::infer::error_reporting::nice_region_error::find_anon_type;
-use rustc_errors::{AddToDiagnostic, Diagnostic, IntoDiagnosticArg, SubdiagnosticMessage};
+use rustc_errors::{AddToDiagnostic, Diagnostic, IntoDiagnosticArg, SubdiagnosticMessageOp};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{symbol::kw, Span};
 
@@ -160,10 +160,7 @@ impl RegionExplanation<'_> {
 }
 
 impl AddToDiagnostic for RegionExplanation<'_> {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, f: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) {
         diag.arg("pref_kind", self.prefix);
         diag.arg("suff_kind", self.suffix);
         diag.arg("desc_kind", self.desc.kind);
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 0f1af81d9f0..859593e1194 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -87,6 +87,7 @@ impl<'tcx> InferCtxt<'tcx> {
             reported_signature_mismatch: self.reported_signature_mismatch.clone(),
             tainted_by_errors: self.tainted_by_errors.clone(),
             err_count_on_creation: self.err_count_on_creation,
+            stashed_err_count_on_creation: self.stashed_err_count_on_creation,
             universe: self.universe.clone(),
             intercrate,
             next_trait_solver: self.next_trait_solver,
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index d825a2920ee..156a4f71017 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -481,7 +481,7 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
             }
             ty::ConstKind::Infer(InferConst::EffectVar(vid)) => {
                 match self.infcx.unwrap().probe_effect_var(vid) {
-                    Some(value) => return self.fold_const(value.as_const(self.tcx)),
+                    Some(value) => return self.fold_const(value),
                     None => {
                         return self.canonicalize_const_var(
                             CanonicalVarInfo { kind: CanonicalVarKind::Effect },
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 386fdb09ba5..1f68a5a9c61 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -24,6 +24,7 @@
 use crate::infer::{ConstVariableOrigin, ConstVariableOriginKind};
 use crate::infer::{InferCtxt, RegionVariableOrigin, TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_index::IndexVec;
+use rustc_middle::infer::unify_key::EffectVarValue;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::GenericArg;
 use rustc_middle::ty::{self, List, Ty, TyCtxt};
@@ -152,7 +153,12 @@ impl<'tcx> InferCtxt<'tcx> {
                 )
                 .into(),
             CanonicalVarKind::Effect => {
-                let vid = self.inner.borrow_mut().effect_unification_table().new_key(None).vid;
+                let vid = self
+                    .inner
+                    .borrow_mut()
+                    .effect_unification_table()
+                    .new_key(EffectVarValue::Unknown)
+                    .vid;
                 ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid), self.tcx.types.bool)
                     .into()
             }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index cf9d9333783..dd9ed80ca72 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -71,6 +71,7 @@ use rustc_hir::lang_items::LangItem;
 use rustc_middle::dep_graph::DepContext;
 use rustc_middle::ty::print::{with_forced_trimmed_paths, PrintError};
 use rustc_middle::ty::relate::{self, RelateResult, TypeRelation};
+use rustc_middle::ty::ToPredicate;
 use rustc_middle::ty::{
     self, error::TypeError, IsSuggestable, List, Region, Ty, TyCtxt, TypeFoldable,
     TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@@ -519,10 +520,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         self.report_placeholder_failure(sup_origin, sub_r, sup_r).emit();
                     }
 
-                    RegionResolutionError::CannotNormalize(ty, origin) => {
+                    RegionResolutionError::CannotNormalize(clause, origin) => {
+                        let clause: ty::Clause<'tcx> =
+                            clause.map_bound(ty::ClauseKind::TypeOutlives).to_predicate(self.tcx);
                         self.tcx
                             .dcx()
-                            .struct_span_err(origin.span(), format!("cannot normalize `{ty}`"))
+                            .struct_span_err(origin.span(), format!("cannot normalize `{clause}`"))
                             .emit();
                     }
                 }
@@ -2179,8 +2182,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         if let Some(tykind) = tykind
             && let hir::TyKind::Array(_, length) = tykind
             && let hir::ArrayLen::Body(hir::AnonConst { hir_id, .. }) = length
-            && let Some(span) = self.tcx.hir().opt_span(*hir_id)
         {
+            let span = self.tcx.hir().span(*hir_id);
             Some(TypeErrorAdditionalDiags::ConsiderSpecifyingLength { span, length: sz.found })
         } else {
             None
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index d256994d8d1..2d5fa1b5c70 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -151,13 +151,8 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
                 self.freshen_const(opt_ct, ty::InferConst::Var(v), ty::InferConst::Fresh, ct.ty())
             }
             ty::ConstKind::Infer(ty::InferConst::EffectVar(v)) => {
-                let opt_ct = self
-                    .infcx
-                    .inner
-                    .borrow_mut()
-                    .effect_unification_table()
-                    .probe_value(v)
-                    .map(|effect| effect.as_const(self.infcx.tcx));
+                let opt_ct =
+                    self.infcx.inner.borrow_mut().effect_unification_table().probe_value(v).known();
                 self.freshen_const(
                     opt_ct,
                     ty::InferConst::EffectVar(v),
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 4a1169e68e0..6137506d4a9 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -99,7 +99,7 @@ pub enum RegionResolutionError<'tcx> {
         Region<'tcx>,          // the placeholder `'b`
     ),
 
-    CannotNormalize(Ty<'tcx>, SubregionOrigin<'tcx>),
+    CannotNormalize(ty::PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>),
 }
 
 impl<'tcx> RegionResolutionError<'tcx> {
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 101735b2961..78ef70398e5 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -8,6 +8,7 @@ pub use self::ValuePairs::*;
 pub use relate::combine::ObligationEmittingRelation;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::undo_log::UndoLogs;
+use rustc_middle::infer::unify_key::EffectVarValue;
 use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
 
 use self::opaque_types::OpaqueTypeStorage;
@@ -25,8 +26,8 @@ use rustc_data_structures::unify as ut;
 use rustc_errors::{DiagCtxt, DiagnosticBuilder, ErrorGuaranteed};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
+use rustc_middle::infer::unify_key::ConstVariableValue;
 use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
-use rustc_middle::infer::unify_key::{ConstVariableValue, EffectVarValue};
 use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::{select, DefiningAnchor};
@@ -305,6 +306,12 @@ pub struct InferCtxt<'tcx> {
     // FIXME(matthewjasper) Merge into `tainted_by_errors`
     err_count_on_creation: usize,
 
+    /// Track how many errors were stashed when this infcx is created.
+    /// Used for the same purpose as `err_count_on_creation`, even
+    /// though it's weaker because the count can go up and down.
+    // FIXME(matthewjasper) Merge into `tainted_by_errors`
+    stashed_err_count_on_creation: usize,
+
     /// What is the innermost universe we have created? Starts out as
     /// `UniverseIndex::root()` but grows from there as we enter
     /// universal quantifiers.
@@ -710,6 +717,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
             reported_signature_mismatch: Default::default(),
             tainted_by_errors: Cell::new(None),
             err_count_on_creation: tcx.dcx().err_count(),
+            stashed_err_count_on_creation: tcx.dcx().stashed_err_count(),
             universe: Cell::new(ty::UniverseIndex::ROOT),
             intercrate,
             next_trait_solver,
@@ -818,7 +826,7 @@ impl<'tcx> InferCtxt<'tcx> {
 
         (0..table.len())
             .map(|i| ty::EffectVid::from_usize(i))
-            .filter(|&vid| table.probe_value(vid).is_none())
+            .filter(|&vid| table.probe_value(vid).is_unknown())
             .map(|v| {
                 ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v), self.tcx.types.bool)
             })
@@ -862,7 +870,7 @@ impl<'tcx> InferCtxt<'tcx> {
     }
 
     #[instrument(skip(self, snapshot), level = "debug")]
-    fn rollback_to(&self, cause: &str, snapshot: CombinedSnapshot<'tcx>) {
+    fn rollback_to(&self, snapshot: CombinedSnapshot<'tcx>) {
         let CombinedSnapshot { undo_snapshot, region_constraints_snapshot, universe } = snapshot;
 
         self.universe.set(universe);
@@ -894,7 +902,7 @@ impl<'tcx> InferCtxt<'tcx> {
                 self.commit_from(snapshot);
             }
             Err(_) => {
-                self.rollback_to("commit_if_ok -- error", snapshot);
+                self.rollback_to(snapshot);
             }
         }
         r
@@ -908,7 +916,7 @@ impl<'tcx> InferCtxt<'tcx> {
     {
         let snapshot = self.start_snapshot();
         let r = f(&snapshot);
-        self.rollback_to("probe", snapshot);
+        self.rollback_to(snapshot);
         r
     }
 
@@ -1031,10 +1039,9 @@ impl<'tcx> InferCtxt<'tcx> {
             _ => {}
         }
 
-        let ty::SubtypePredicate { a_is_expected, a, b } =
-            self.instantiate_binder_with_placeholders(predicate);
-
-        Ok(self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b))
+        self.enter_forall(predicate, |ty::SubtypePredicate { a_is_expected, a, b }| {
+            Ok(self.at(cause, param_env).sub_exp(DefineOpaqueTypes::No, a_is_expected, a, b))
+        })
     }
 
     pub fn region_outlives_predicate(
@@ -1042,10 +1049,12 @@ impl<'tcx> InferCtxt<'tcx> {
         cause: &traits::ObligationCause<'tcx>,
         predicate: ty::PolyRegionOutlivesPredicate<'tcx>,
     ) {
-        let ty::OutlivesPredicate(r_a, r_b) = self.instantiate_binder_with_placeholders(predicate);
-        let origin =
-            SubregionOrigin::from_obligation_cause(cause, || RelateRegionParamBound(cause.span));
-        self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
+        self.enter_forall(predicate, |ty::OutlivesPredicate(r_a, r_b)| {
+            let origin = SubregionOrigin::from_obligation_cause(cause, || {
+                RelateRegionParamBound(cause.span)
+            });
+            self.sub_regions(origin, r_b, r_a); // `b : a` ==> `a <= b`
+        })
     }
 
     /// Number of type variables created so far.
@@ -1236,7 +1245,8 @@ impl<'tcx> InferCtxt<'tcx> {
     }
 
     pub fn var_for_effect(&self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
-        let effect_vid = self.inner.borrow_mut().effect_unification_table().new_key(None).vid;
+        let effect_vid =
+            self.inner.borrow_mut().effect_unification_table().new_key(EffectVarValue::Unknown).vid;
         let ty = self
             .tcx
             .type_of(param.def_id)
@@ -1259,26 +1269,24 @@ impl<'tcx> InferCtxt<'tcx> {
     /// inference variables, regionck errors).
     #[must_use = "this method does not have any side effects"]
     pub fn tainted_by_errors(&self) -> Option<ErrorGuaranteed> {
-        debug!(
-            "is_tainted_by_errors(err_count={}, err_count_on_creation={}, \
-             tainted_by_errors={})",
-            self.dcx().err_count(),
-            self.err_count_on_creation,
-            self.tainted_by_errors.get().is_some()
-        );
-
-        if let Some(e) = self.tainted_by_errors.get() {
-            return Some(e);
-        }
-
-        if self.dcx().err_count() > self.err_count_on_creation {
-            // errors reported since this infcx was made
-            let e = self.dcx().has_errors().unwrap();
-            self.set_tainted_by_errors(e);
-            return Some(e);
+        if let Some(guar) = self.tainted_by_errors.get() {
+            Some(guar)
+        } else if self.dcx().err_count() > self.err_count_on_creation {
+            // Errors reported since this infcx was made.
+            let guar = self.dcx().has_errors().unwrap();
+            self.set_tainted_by_errors(guar);
+            Some(guar)
+        } else if self.dcx().stashed_err_count() > self.stashed_err_count_on_creation {
+            // Errors stashed since this infcx was made. Not entirely reliable
+            // because the count of stashed errors can go down. But without
+            // this case we get a moderate number of uninteresting and
+            // extraneous "type annotations needed" errors.
+            let guar = self.dcx().delayed_bug("tainted_by_errors: stashed bug awaiting emission");
+            self.set_tainted_by_errors(guar);
+            Some(guar)
+        } else {
+            None
         }
-
-        None
     }
 
     /// Set the "tainted by errors" flag to true. We call this when we
@@ -1416,8 +1424,8 @@ impl<'tcx> InferCtxt<'tcx> {
         }
     }
 
-    pub fn probe_effect_var(&self, vid: EffectVid) -> Option<EffectVarValue<'tcx>> {
-        self.inner.borrow_mut().effect_unification_table().probe_value(vid)
+    pub fn probe_effect_var(&self, vid: EffectVid) -> Option<ty::Const<'tcx>> {
+        self.inner.borrow_mut().effect_unification_table().probe_value(vid).known()
     }
 
     /// Attempts to resolve all type/region/const variables in
@@ -1453,7 +1461,7 @@ impl<'tcx> InferCtxt<'tcx> {
     // Use this method if you'd like to find some substitution of the binder's
     // variables (e.g. during a method call). If there isn't a [`BoundRegionConversionTime`]
     // that corresponds to your use case, consider whether or not you should
-    // use [`InferCtxt::instantiate_binder_with_placeholders`] instead.
+    // use [`InferCtxt::enter_forall`] instead.
     pub fn instantiate_binder_with_fresh_vars<T>(
         &self,
         span: Span,
@@ -1897,7 +1905,8 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ShallowResolver<'a, 'tcx> {
                 .borrow_mut()
                 .effect_unification_table()
                 .probe_value(vid)
-                .map_or(ct, |val| val.as_const(self.infcx.tcx)),
+                .known()
+                .unwrap_or(ct),
             _ => ct,
         }
     }
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 5ee0a606a5f..46c4f80cb0c 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -327,7 +327,6 @@ impl<'tcx> InferCtxt<'tcx> {
     #[instrument(level = "debug", skip(self))]
     pub fn register_member_constraints(
         &self,
-        param_env: ty::ParamEnv<'tcx>,
         opaque_type_key: OpaqueTypeKey<'tcx>,
         concrete_ty: Ty<'tcx>,
         span: Span,
@@ -687,7 +686,7 @@ fn may_define_opaque_type(tcx: TyCtxt<'_>, def_id: LocalDefId, opaque_hir_id: hi
     let res = hir_id == scope;
     trace!(
         "may_define_opaque_type(def={:?}, opaque_node={:?}) = {}",
-        tcx.opt_hir_node(hir_id),
+        tcx.hir_node(hir_id),
         tcx.hir_node(opaque_hir_id),
         res
     );
diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs
index 926e198b219..a4f9316b502 100644
--- a/compiler/rustc_infer/src/infer/outlives/mod.rs
+++ b/compiler/rustc_infer/src/infer/outlives/mod.rs
@@ -4,8 +4,8 @@ use super::region_constraints::RegionConstraintData;
 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::{self, Ty};
+use rustc_middle::traits::query::{NoSolution, OutlivesBound};
+use rustc_middle::ty;
 
 pub mod components;
 pub mod env;
@@ -49,12 +49,15 @@ impl<'tcx> InferCtxt<'tcx> {
     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>>,
+        deeply_normalize_ty: impl Fn(
+            ty::PolyTypeOutlivesPredicate<'tcx>,
+            SubregionOrigin<'tcx>,
+        ) -> Result<ty::PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
     ) -> Vec<RegionResolutionError<'tcx>> {
         match self.process_registered_region_obligations(outlives_env, deeply_normalize_ty) {
             Ok(()) => {}
-            Err((ty, origin)) => {
-                return vec![RegionResolutionError::CannotNormalize(ty, origin)];
+            Err((clause, origin)) => {
+                return vec![RegionResolutionError::CannotNormalize(clause, origin)];
             }
         };
 
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index b10bf98e8b5..7208f17fb34 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -68,8 +68,9 @@ use crate::infer::{
 use crate::traits::{ObligationCause, ObligationCauseCode};
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::mir::ConstraintCategory;
-use rustc_middle::ty::GenericArgKind;
+use rustc_middle::traits::query::NoSolution;
 use rustc_middle::ty::{self, GenericArgsRef, Region, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{GenericArgKind, PolyTypeOutlivesPredicate};
 use rustc_span::DUMMY_SP;
 use smallvec::smallvec;
 
@@ -125,11 +126,15 @@ impl<'tcx> InferCtxt<'tcx> {
     /// invoked after all type-inference variables have been bound --
     /// right before lexical region resolution.
     #[instrument(level = "debug", skip(self, outlives_env, deeply_normalize_ty))]
-    pub fn process_registered_region_obligations<E>(
+    pub fn process_registered_region_obligations(
         &self,
         outlives_env: &OutlivesEnvironment<'tcx>,
-        mut deeply_normalize_ty: impl FnMut(Ty<'tcx>, SubregionOrigin<'tcx>) -> Result<Ty<'tcx>, E>,
-    ) -> Result<(), (E, SubregionOrigin<'tcx>)> {
+        mut deeply_normalize_ty: impl FnMut(
+            PolyTypeOutlivesPredicate<'tcx>,
+            SubregionOrigin<'tcx>,
+        )
+            -> Result<PolyTypeOutlivesPredicate<'tcx>, NoSolution>,
+    ) -> Result<(), (PolyTypeOutlivesPredicate<'tcx>, SubregionOrigin<'tcx>)> {
         assert!(!self.in_snapshot(), "cannot process registered region obligations in a snapshot");
 
         let normalized_caller_bounds: Vec<_> = outlives_env
@@ -137,38 +142,53 @@ impl<'tcx> InferCtxt<'tcx> {
             .caller_bounds()
             .iter()
             .filter_map(|clause| {
-                let bound_clause = clause.kind();
-                let ty::ClauseKind::TypeOutlives(outlives) = bound_clause.skip_binder() else {
-                    return None;
-                };
+                let outlives = clause.as_type_outlives_clause()?;
                 Some(
                     deeply_normalize_ty(
-                        outlives.0,
+                        outlives,
                         SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP),
                     )
-                    .map(|ty| bound_clause.rebind(ty::OutlivesPredicate(ty, outlives.1))),
+                    // FIXME(-Znext-solver): How do we accurately report an error span here :(
+                    .map_err(|NoSolution| {
+                        (outlives, SubregionOrigin::AscribeUserTypeProvePredicate(DUMMY_SP))
+                    }),
                 )
             })
-            // 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 outlives = &mut TypeOutlives::new(
-                self,
-                self.tcx,
-                outlives_env.region_bound_pairs(),
-                None,
-                &normalized_caller_bounds,
-            );
-            let category = origin.to_constraint_category();
-            outlives.type_must_outlive(origin, sup_type, sub_region, category);
+            .try_collect()?;
+
+        // Must loop since the process of normalizing may itself register region obligations.
+        for iteration in 0.. {
+            let my_region_obligations = self.take_registered_region_obligations();
+            if my_region_obligations.is_empty() {
+                break;
+            }
+
+            if !self.tcx.recursion_limit().value_within_limit(iteration) {
+                bug!(
+                    "FIXME(-Znext-solver): Overflowed when processing region obligations: {my_region_obligations:#?}"
+                );
+            }
+
+            for RegionObligation { sup_type, sub_region, origin } in my_region_obligations {
+                let outlives = ty::Binder::dummy(ty::OutlivesPredicate(sup_type, sub_region));
+                let ty::OutlivesPredicate(sup_type, sub_region) =
+                    deeply_normalize_ty(outlives, origin.clone())
+                        .map_err(|NoSolution| (outlives, origin.clone()))?
+                        .no_bound_vars()
+                        .expect("started with no bound vars, should end with no bound vars");
+
+                debug!(?sup_type, ?sub_region, ?origin);
+
+                let outlives = &mut TypeOutlives::new(
+                    self,
+                    self.tcx,
+                    outlives_env.region_bound_pairs(),
+                    None,
+                    &normalized_caller_bounds,
+                );
+                let category = origin.to_constraint_category();
+                outlives.type_must_outlive(origin, sup_type, sub_region, category);
+            }
         }
 
         Ok(())
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 1c120646f1f..7edfbf02a68 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -202,11 +202,7 @@ impl<'tcx> InferCtxt<'tcx> {
                 ty::ConstKind::Infer(InferConst::EffectVar(a_vid)),
                 ty::ConstKind::Infer(InferConst::EffectVar(b_vid)),
             ) => {
-                self.inner
-                    .borrow_mut()
-                    .effect_unification_table()
-                    .unify_var_var(a_vid, b_vid)
-                    .map_err(|a| effect_unification_error(self.tcx, relation.a_is_expected(), a))?;
+                self.inner.borrow_mut().effect_unification_table().union(a_vid, b_vid);
                 return Ok(a);
             }
 
@@ -225,27 +221,19 @@ impl<'tcx> InferCtxt<'tcx> {
             }
 
             (ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
-                return self.unify_const_variable(vid, b, relation.param_env());
+                return self.unify_const_variable(vid, b);
             }
 
             (_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
-                return self.unify_const_variable(vid, a, relation.param_env());
+                return self.unify_const_variable(vid, a);
             }
 
             (ty::ConstKind::Infer(InferConst::EffectVar(vid)), _) => {
-                return self.unify_effect_variable(
-                    relation.a_is_expected(),
-                    vid,
-                    EffectVarValue::Const(b),
-                );
+                return Ok(self.unify_effect_variable(vid, b));
             }
 
             (_, ty::ConstKind::Infer(InferConst::EffectVar(vid))) => {
-                return self.unify_effect_variable(
-                    !relation.a_is_expected(),
-                    vid,
-                    EffectVarValue::Const(a),
-                );
+                return Ok(self.unify_effect_variable(vid, a));
             }
 
             (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
@@ -310,7 +298,6 @@ impl<'tcx> InferCtxt<'tcx> {
         &self,
         target_vid: ty::ConstVid,
         ct: ty::Const<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
     ) -> RelateResult<'tcx, ty::Const<'tcx>> {
         let span = match self.inner.borrow_mut().const_unification_table().probe_value(target_vid) {
             ConstVariableValue::Known { value } => {
@@ -366,18 +353,12 @@ impl<'tcx> InferCtxt<'tcx> {
         Ok(Ty::new_float(self.tcx, val))
     }
 
-    fn unify_effect_variable(
-        &self,
-        vid_is_expected: bool,
-        vid: ty::EffectVid,
-        val: EffectVarValue<'tcx>,
-    ) -> RelateResult<'tcx, ty::Const<'tcx>> {
+    fn unify_effect_variable(&self, vid: ty::EffectVid, val: ty::Const<'tcx>) -> ty::Const<'tcx> {
         self.inner
             .borrow_mut()
             .effect_unification_table()
-            .unify_var_value(vid, Some(val))
-            .map_err(|e| effect_unification_error(self.tcx, vid_is_expected, e))?;
-        Ok(val.as_const(self.tcx))
+            .union_value(vid, EffectVarValue::Known(val));
+        val
     }
 }
 
@@ -579,11 +560,3 @@ fn float_unification_error<'tcx>(
     let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
     TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b))
 }
-
-fn effect_unification_error<'tcx>(
-    _tcx: TyCtxt<'tcx>,
-    _a_is_expected: bool,
-    (_a, _b): (EffectVarValue<'tcx>, EffectVarValue<'tcx>),
-) -> TypeError<'tcx> {
-    bug!("unexpected effect unification error")
-}
diff --git a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
index 440df8c8936..90be80f67b4 100644
--- a/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
+++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
@@ -38,24 +38,25 @@ impl<'a, 'tcx> CombineFields<'a, 'tcx> {
         // First, we instantiate each bound region in the supertype with a
         // fresh placeholder region. Note that this automatically creates
         // a new universe if needed.
-        let sup_prime = self.infcx.instantiate_binder_with_placeholders(sup);
+        self.infcx.enter_forall(sup, |sup_prime| {
+            // Next, we instantiate each bound region in the subtype
+            // with a fresh region variable. These region variables --
+            // but no other preexisting region variables -- can name
+            // the placeholders.
+            let sub_prime =
+                self.infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, sub);
+            debug!("a_prime={:?}", sub_prime);
+            debug!("b_prime={:?}", sup_prime);
 
-        // Next, we instantiate each bound region in the subtype
-        // with a fresh region variable. These region variables --
-        // but no other preexisting region variables -- can name
-        // the placeholders.
-        let sub_prime = self.infcx.instantiate_binder_with_fresh_vars(span, HigherRankedType, sub);
-
-        debug!("a_prime={:?}", sub_prime);
-        debug!("b_prime={:?}", sup_prime);
-
-        // Compare types now that bound regions have been replaced.
-        let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime)?;
-
-        debug!("OK result={result:?}");
-        // NOTE: returning the result here would be dangerous as it contains
-        // placeholders which **must not** be named afterwards.
-        Ok(())
+            // Compare types now that bound regions have been replaced.
+            let result = self.sub(sub_is_expected).relate(sub_prime, sup_prime);
+            if result.is_ok() {
+                debug!("OK result={result:?}");
+            }
+            // NOTE: returning the result here would be dangerous as it contains
+            // placeholders which **must not** be named afterwards.
+            result.map(|_| ())
+        })
     }
 }
 
@@ -68,9 +69,11 @@ impl<'tcx> InferCtxt<'tcx> {
     /// This is the first step of checking subtyping when higher-ranked things are involved.
     /// For more details visit the relevant sections of the [rustc dev guide].
     ///
+    /// `fn enter_forall` should be preferred over this method.
+    ///
     /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
     #[instrument(level = "debug", skip(self), ret)]
-    pub fn instantiate_binder_with_placeholders<T>(&self, binder: ty::Binder<'tcx, T>) -> T
+    pub fn enter_forall_and_leak_universe<T>(&self, binder: ty::Binder<'tcx, T>) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
@@ -106,6 +109,31 @@ impl<'tcx> InferCtxt<'tcx> {
         self.tcx.replace_bound_vars_uncached(binder, delegate)
     }
 
+    /// Replaces all bound variables (lifetimes, types, and constants) bound by
+    /// `binder` with placeholder variables in a new universe and then calls the
+    /// closure `f` with the instantiated value. The new placeholders can only be
+    /// named by inference variables created inside of the closure `f` or afterwards.
+    ///
+    /// This is the first step of checking subtyping when higher-ranked things are involved.
+    /// For more details visit the relevant sections of the [rustc dev guide].
+    ///
+    /// This method should be preferred over `fn enter_forall_and_leak_universe`.
+    ///
+    /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
+    #[instrument(level = "debug", skip(self, f))]
+    pub fn enter_forall<T, U>(&self, forall: ty::Binder<'tcx, T>, f: impl FnOnce(T) -> U) -> U
+    where
+        T: TypeFoldable<TyCtxt<'tcx>> + Copy,
+    {
+        // FIXME: currently we do nothing to prevent placeholders with the new universe being
+        // used after exiting `f`. For example region subtyping can result in outlives constraints
+        // that name placeholders created in this function. Nested goals from type relations can
+        // also contain placeholders created by this function.
+        let value = self.enter_forall_and_leak_universe(forall);
+        debug!("?value");
+        f(value)
+    }
+
     /// See [RegionConstraintCollector::leak_check][1]. We only check placeholder
     /// leaking into `outer_universe`, i.e. placeholders which cannot be named by that
     /// universe.
diff --git a/compiler/rustc_infer/src/infer/relate/nll.rs b/compiler/rustc_infer/src/infer/relate/nll.rs
index 8b80646a386..5e2d2af9b85 100644
--- a/compiler/rustc_infer/src/infer/relate/nll.rs
+++ b/compiler/rustc_infer/src/infer/relate/nll.rs
@@ -261,52 +261,55 @@ where
         Ok(a)
     }
 
-    #[instrument(skip(self), level = "debug")]
-    fn instantiate_binder_with_placeholders<T>(&mut self, binder: ty::Binder<'tcx, T>) -> T
+    fn enter_forall<T, U>(
+        &mut self,
+        binder: ty::Binder<'tcx, T>,
+        f: impl FnOnce(&mut Self, T) -> U,
+    ) -> U
     where
         T: ty::TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
-        if let Some(inner) = binder.no_bound_vars() {
-            return inner;
-        }
-
-        let mut next_region = {
-            let nll_delegate = &mut self.delegate;
-            let mut lazy_universe = None;
+        let value = if let Some(inner) = binder.no_bound_vars() {
+            inner
+        } else {
+            let mut next_region = {
+                let nll_delegate = &mut self.delegate;
+                let mut lazy_universe = None;
+
+                move |br: ty::BoundRegion| {
+                    // The first time this closure is called, create a
+                    // new universe for the placeholders we will make
+                    // from here out.
+                    let universe = lazy_universe.unwrap_or_else(|| {
+                        let universe = nll_delegate.create_next_universe();
+                        lazy_universe = Some(universe);
+                        universe
+                    });
+
+                    let placeholder = ty::PlaceholderRegion { universe, bound: br };
+                    debug!(?placeholder);
+                    let placeholder_reg = nll_delegate.next_placeholder_region(placeholder);
+                    debug!(?placeholder_reg);
+
+                    placeholder_reg
+                }
+            };
 
-            move |br: ty::BoundRegion| {
-                // The first time this closure is called, create a
-                // new universe for the placeholders we will make
-                // from here out.
-                let universe = lazy_universe.unwrap_or_else(|| {
-                    let universe = nll_delegate.create_next_universe();
-                    lazy_universe = Some(universe);
-                    universe
-                });
-
-                let placeholder = ty::PlaceholderRegion { universe, bound: br };
-                debug!(?placeholder);
-                let placeholder_reg = nll_delegate.next_placeholder_region(placeholder);
-                debug!(?placeholder_reg);
-
-                placeholder_reg
-            }
-        };
+            let delegate = FnMutDelegate {
+                regions: &mut next_region,
+                types: &mut |_bound_ty: ty::BoundTy| {
+                    unreachable!("we only replace regions in nll_relate, not types")
+                },
+                consts: &mut |_bound_var: ty::BoundVar, _ty| {
+                    unreachable!("we only replace regions in nll_relate, not consts")
+                },
+            };
 
-        let delegate = FnMutDelegate {
-            regions: &mut next_region,
-            types: &mut |_bound_ty: ty::BoundTy| {
-                unreachable!("we only replace regions in nll_relate, not types")
-            },
-            consts: &mut |_bound_var: ty::BoundVar, _ty| {
-                unreachable!("we only replace regions in nll_relate, not consts")
-            },
+            self.infcx.tcx.replace_bound_vars_uncached(binder, delegate)
         };
 
-        let replaced = self.infcx.tcx.replace_bound_vars_uncached(binder, delegate);
-        debug!(?replaced);
-
-        replaced
+        debug!(?value);
+        f(self, value)
     }
 
     #[instrument(skip(self), level = "debug")]
@@ -630,10 +633,10 @@ where
 
             // Note: the order here is important. Create the placeholders first, otherwise
             // we assign the wrong universe to the existential!
-            let b_replaced = self.instantiate_binder_with_placeholders(b);
-            let a_replaced = self.instantiate_binder_with_existentials(a);
-
-            self.relate(a_replaced, b_replaced)?;
+            self.enter_forall(b, |this, b| {
+                let a = this.instantiate_binder_with_existentials(a);
+                this.relate(a, b)
+            })?;
 
             self.ambient_variance = variance;
         }
@@ -650,10 +653,10 @@ where
             let variance =
                 std::mem::replace(&mut self.ambient_variance, ty::Variance::Contravariant);
 
-            let a_replaced = self.instantiate_binder_with_placeholders(a);
-            let b_replaced = self.instantiate_binder_with_existentials(b);
-
-            self.relate(a_replaced, b_replaced)?;
+            self.enter_forall(a, |this, a| {
+                let b = this.instantiate_binder_with_existentials(b);
+                this.relate(a, b)
+            })?;
 
             self.ambient_variance = variance;
         }
diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs
index 959b0903127..d5999331dfa 100644
--- a/compiler/rustc_infer/src/infer/resolve.rs
+++ b/compiler/rustc_infer/src/infer/resolve.rs
@@ -237,14 +237,13 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerResolver<'_, 'tcx> {
             }
             ty::ConstKind::Infer(ty::InferConst::EffectVar(vid)) => {
                 debug_assert_eq!(c.ty(), self.infcx.tcx.types.bool);
-                match self.infcx.probe_effect_var(vid) {
-                    Some(c) => c.as_const(self.infcx.tcx),
-                    None => ty::Const::new_infer(
+                self.infcx.probe_effect_var(vid).unwrap_or_else(|| {
+                    ty::Const::new_infer(
                         self.infcx.tcx,
                         ty::InferConst::EffectVar(self.infcx.root_effect_var(vid)),
                         self.infcx.tcx.types.bool,
-                    ),
-                }
+                    )
+                })
             }
             _ => {
                 if c.has_infer() {
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index e2dd4b49e1a..622cdf0c7b8 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -16,6 +16,8 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
 #![feature(extend_one)]
diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
index 1ceb245dcc7..7401654aea8 100644
--- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs
@@ -5,7 +5,6 @@ use rustc_data_structures::fx::FxIndexSet;
 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;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::Span;
@@ -62,7 +61,7 @@ pub fn report_object_safety_error<'tcx>(
     err.span_label(span, format!("`{trait_str}` cannot be made into an object"));
 
     if let Some(hir_id) = hir_id
-        && let Some(hir::Node::Ty(ty)) = tcx.hir().find(hir_id)
+        && let hir::Node::Ty(ty) = tcx.hir_node(hir_id)
         && let hir::TyKind::TraitObject([trait_ref, ..], ..) = ty.kind
     {
         let mut hir_id = hir_id;
diff --git a/compiler/rustc_interface/src/lib.rs b/compiler/rustc_interface/src/lib.rs
index 69414a13795..7d69e49b209 100644
--- a/compiler/rustc_interface/src/lib.rs
+++ b/compiler/rustc_interface/src/lib.rs
@@ -4,8 +4,6 @@
 #![feature(let_chains)]
 #![feature(thread_spawn_unchecked)]
 #![feature(try_blocks)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 97956404120..50b2bf7da15 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -778,6 +778,10 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
     // kindck is gone now). -nmatsakis
     if let Some(reported) = sess.dcx().has_errors() {
         return Err(reported);
+    } else if sess.dcx().stashed_err_count() > 0 {
+        // Without this case we sometimes get delayed bug ICEs and I don't
+        // understand why. -nnethercote
+        return Err(sess.dcx().delayed_bug("some stashed error is waiting for use"));
     }
 
     sess.time("misc_checking_3", || {
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 2d4963a8b90..bfc4fc07d4c 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -749,6 +749,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(debug_macros, true);
     tracked!(default_hidden_visibility, Some(true));
     tracked!(dep_info_omit_d_target, true);
+    tracked!(direct_access_external_data, Some(true));
     tracked!(dual_proc_macros, true);
     tracked!(dwarf_version, Some(5));
     tracked!(emit_thin_lto, false);
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index f6c9289b529..ca84e930c24 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -18,8 +18,7 @@
 //! lexeme types.
 //!
 //! [`rustc_parse::lexer`]: ../rustc_parse/lexer/index.html
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
+
 // We want to be able to build this crate with a stable compiler,
 // so no `#![feature]` attributes should be added.
 #![deny(unstable_features)]
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index eb42730f69a..0fa61c5d87e 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -188,6 +188,23 @@ pub(super) fn builtin(
             #[allow(rustc::potential_query_instability)]
             let possibilities: Vec<Symbol> =
                 sess.parse_sess.check_config.expecteds.keys().copied().collect();
+
+            let mut names_possibilities: Vec<_> = if value.is_none() {
+                // We later sort and display all the possibilities, so the order here does not matter.
+                #[allow(rustc::potential_query_instability)]
+                sess.parse_sess
+                    .check_config
+                    .expecteds
+                    .iter()
+                    .filter_map(|(k, v)| match v {
+                        ExpectedValues::Some(v) if v.contains(&Some(name)) => Some(k),
+                        _ => None,
+                    })
+                    .collect()
+            } else {
+                Vec::new()
+            };
+
             let is_from_cargo = std::env::var_os("CARGO").is_some();
             let mut is_feature_cfg = name == sym::feature;
 
@@ -262,17 +279,30 @@ pub(super) fn builtin(
                 }
 
                 is_feature_cfg |= best_match == sym::feature;
-            } else if !possibilities.is_empty() {
-                let mut possibilities =
-                    possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>();
-                possibilities.sort();
-                let possibilities = possibilities.join("`, `");
+            } else {
+                if !names_possibilities.is_empty() && names_possibilities.len() <= 3 {
+                    names_possibilities.sort();
+                    for cfg_name in names_possibilities.iter() {
+                        db.span_suggestion(
+                            name_span,
+                            "found config with similar value",
+                            format!("{cfg_name} = \"{name}\""),
+                            Applicability::MaybeIncorrect,
+                        );
+                    }
+                }
+                if !possibilities.is_empty() {
+                    let mut possibilities =
+                        possibilities.iter().map(Symbol::as_str).collect::<Vec<_>>();
+                    possibilities.sort();
+                    let possibilities = possibilities.join("`, `");
 
-                // The list of expected names can be long (even by default) and
-                // so the diagnostic produced can take a lot of space. To avoid
-                // cloging the user output we only want to print that diagnostic
-                // once.
-                db.help_once(format!("expected names are: `{possibilities}`"));
+                    // The list of expected names can be long (even by default) and
+                    // so the diagnostic produced can take a lot of space. To avoid
+                    // cloging the user output we only want to print that diagnostic
+                    // once.
+                    db.help_once(format!("expected names are: `{possibilities}`"));
+                }
             }
 
             let inst = if let Some((value, _value_span)) = value {
diff --git a/compiler/rustc_lint/src/errors.rs b/compiler/rustc_lint/src/errors.rs
index 3bd0c1b8031..21d4b6fa65b 100644
--- a/compiler/rustc_lint/src/errors.rs
+++ b/compiler/rustc_lint/src/errors.rs
@@ -1,5 +1,5 @@
 use crate::fluent_generated as fluent;
-use rustc_errors::{codes::*, AddToDiagnostic, Diagnostic, SubdiagnosticMessage};
+use rustc_errors::{codes::*, AddToDiagnostic, Diagnostic, SubdiagnosticMessageOp};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_session::lint::Level;
 use rustc_span::{Span, Symbol};
@@ -24,10 +24,7 @@ pub enum OverruledAttributeSub {
 }
 
 impl AddToDiagnostic for OverruledAttributeSub {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         match self {
             OverruledAttributeSub::DefaultSource { id } => {
                 diag.note(fluent::lint_default_source);
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index eb2490a47d0..516df14c894 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -345,7 +345,7 @@ declare_tool_lint! {
     ///
     /// More details on translatable diagnostics can be found [here](https://rustc-dev-guide.rust-lang.org/diagnostics/translation.html).
     pub rustc::UNTRANSLATABLE_DIAGNOSTIC,
-    Allow,
+    Deny,
     "prevent creation of diagnostics which cannot be translated",
     report_in_external_macro: true
 }
@@ -357,7 +357,7 @@ declare_tool_lint! {
     ///
     /// More details on diagnostics implementations can be found [here](https://rustc-dev-guide.rust-lang.org/diagnostics/diagnostic-structs.html).
     pub rustc::DIAGNOSTIC_OUTSIDE_OF_IMPL,
-    Allow,
+    Deny,
     "prevent creation of diagnostics outside of `IntoDiagnostic`/`AddToDiagnostic` impls",
     report_in_external_macro: true
 }
diff --git a/compiler/rustc_lint/src/late.rs b/compiler/rustc_lint/src/late.rs
index caa01556591..d3d7698e7f9 100644
--- a/compiler/rustc_lint/src/late.rs
+++ b/compiler/rustc_lint/src/late.rs
@@ -364,14 +364,11 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
     // Note: `passes` is often empty. In that case, it's faster to run
     // `builtin_lints` directly rather than bundling it up into the
     // `RuntimeCombinedLateLintPass`.
-    let mut passes: Vec<_> = unerased_lint_store(tcx.sess)
-        .late_module_passes
-        .iter()
-        .map(|mk_pass| (mk_pass)(tcx))
-        .collect();
-    if passes.is_empty() {
+    let late_module_passes = &unerased_lint_store(tcx.sess).late_module_passes;
+    if late_module_passes.is_empty() {
         late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
     } else {
+        let mut passes: Vec<_> = late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
         passes.push(Box::new(builtin_lints));
         let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] };
         late_lint_mod_inner(tcx, module_def_id, context, pass);
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 0a15671e686..5c2a422a2b7 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -34,11 +34,9 @@
 #![feature(if_let_guard)]
 #![feature(iter_order_by)]
 #![feature(let_chains)]
-#![cfg_attr(not(bootstrap), feature(trait_upcasting))]
+#![feature(trait_upcasting)]
 #![feature(min_specialization)]
 #![feature(rustc_attrs)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
 
 #[macro_use]
@@ -520,6 +518,11 @@ fn register_builtins(store: &mut LintStore) {
         "illegal_floating_point_literal_pattern",
         "no longer a warning, float patterns behave the same as `==`",
     );
+    store.register_removed(
+        "nontrivial_structural_match",
+        "no longer needed, see RFC #3535 \
+         <https://rust-lang.github.io/rfcs/3535-constants-in-patterns.html> for more information",
+    );
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index f916deb4a46..42d9760f8aa 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1,12 +1,13 @@
-#![allow(rustc::untranslatable_diagnostic)]
 #![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
+
 use std::num::NonZeroU32;
 
 use crate::errors::RequestedLevel;
 use crate::fluent_generated as fluent;
 use rustc_errors::{
     codes::*, AddToDiagnostic, Applicability, DecorateLint, Diagnostic, DiagnosticBuilder,
-    DiagnosticMessage, DiagnosticStyledString, SubdiagnosticMessage, SuggestionStyle,
+    DiagnosticMessage, DiagnosticStyledString, SubdiagnosticMessageOp, SuggestionStyle,
 };
 use rustc_hir::def_id::DefId;
 use rustc_macros::{LintDiagnostic, Subdiagnostic};
@@ -268,10 +269,7 @@ pub struct SuggestChangingAssocTypes<'a, 'b> {
 }
 
 impl AddToDiagnostic for SuggestChangingAssocTypes<'_, '_> {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         // Access to associates types should use `<T as Bound>::Assoc`, which does not need a
         // bound. Let's see if this type does that.
 
@@ -323,10 +321,7 @@ pub struct BuiltinTypeAliasGenericBoundsSuggestion {
 }
 
 impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         diag.multipart_suggestion(
             fluent::lint_suggestion,
             self.suggestions,
@@ -443,10 +438,7 @@ pub struct BuiltinUnpermittedTypeInitSub {
 }
 
 impl AddToDiagnostic for BuiltinUnpermittedTypeInitSub {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         let mut err = self.err;
         loop {
             if let Some(span) = err.span {
@@ -497,10 +489,7 @@ pub struct BuiltinClashingExternSub<'a> {
 }
 
 impl AddToDiagnostic for BuiltinClashingExternSub<'_> {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         let mut expected_str = DiagnosticStyledString::new();
         expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
         let mut found_str = DiagnosticStyledString::new();
@@ -766,10 +755,7 @@ pub struct HiddenUnicodeCodepointsDiagLabels {
 }
 
 impl AddToDiagnostic for HiddenUnicodeCodepointsDiagLabels {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         for (c, span) in self.spans {
             diag.span_label(span, format!("{c:?}"));
         }
@@ -783,10 +769,7 @@ pub enum HiddenUnicodeCodepointsDiagSub {
 
 // Used because of multiple multipart_suggestion and note
 impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         match self {
             HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
                 diag.multipart_suggestion_with_style(
@@ -934,10 +917,7 @@ pub struct NonBindingLetSub {
 }
 
 impl AddToDiagnostic for NonBindingLetSub {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         let can_suggest_binding = self.drop_fn_start_end.is_some() || !self.is_assign_desugar;
 
         if can_suggest_binding {
@@ -1217,10 +1197,7 @@ pub enum NonSnakeCaseDiagSub {
 }
 
 impl AddToDiagnostic for NonSnakeCaseDiagSub {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         match self {
             NonSnakeCaseDiagSub::Label { span } => {
                 diag.span_label(span, fluent::lint_label);
@@ -1413,10 +1390,7 @@ pub enum OverflowingBinHexSign {
 }
 
 impl AddToDiagnostic for OverflowingBinHexSign {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         match self {
             OverflowingBinHexSign::Positive => {
                 diag.note(fluent::lint_positive_note);
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index bed5d3c80c0..cf825be7a55 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -77,101 +77,104 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
         for (pred, pred_span) in
             cx.tcx.explicit_item_bounds(def_id).instantiate_identity_iter_copied()
         {
-            let predicate = infcx.instantiate_binder_with_placeholders(pred.kind());
-            let ty::ClauseKind::Projection(proj) = predicate else {
-                continue;
-            };
-            // Only check types, since those are the only things that may
-            // have opaques in them anyways.
-            let Some(proj_term) = proj.term.ty() else { continue };
+            infcx.enter_forall(pred.kind(), |predicate| {
+                let ty::ClauseKind::Projection(proj) = predicate else {
+                    return;
+                };
+                // Only check types, since those are the only things that may
+                // have opaques in them anyways.
+                let Some(proj_term) = proj.term.ty() else { return };
 
-            // HACK: `impl Trait<Assoc = impl Trait2>` from an RPIT is "ok"...
-            if let ty::Alias(ty::Opaque, opaque_ty) = *proj_term.kind()
-                && cx.tcx.parent(opaque_ty.def_id) == def_id
-                && matches!(
-                    opaque.origin,
-                    hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_)
-                )
-            {
-                continue;
-            }
+                // HACK: `impl Trait<Assoc = impl Trait2>` from an RPIT is "ok"...
+                if let ty::Alias(ty::Opaque, opaque_ty) = *proj_term.kind()
+                    && cx.tcx.parent(opaque_ty.def_id) == def_id
+                    && matches!(
+                        opaque.origin,
+                        hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_)
+                    )
+                {
+                    return;
+                }
 
-            // 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;
-            }
+                // 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
+                {
+                    return;
+                }
 
-            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,
-            // replace them with the term we're assigning to the associated
-            // type in our opaque type.
-            let proj_replacer = &mut BottomUpFolder {
-                tcx: cx.tcx,
-                ty_op: |ty| if ty == proj_ty { proj_term } else { ty },
-                lt_op: |lt| lt,
-                ct_op: |ct| ct,
-            };
-            // For example, in `impl Trait<Assoc = impl Send>`, for all of the bounds on `Assoc`,
-            // e.g. `type Assoc: OtherTrait`, replace `<impl Trait as Trait>::Assoc: OtherTrait`
-            // with `impl Send: OtherTrait`.
-            for (assoc_pred, assoc_pred_span) in cx
-                .tcx
-                .explicit_item_bounds(proj.projection_ty.def_id)
-                .iter_instantiated_copied(cx.tcx, proj.projection_ty.args)
-            {
-                let assoc_pred = assoc_pred.fold_with(proj_replacer);
-                let Ok(assoc_pred) = traits::fully_normalize(
-                    infcx,
-                    traits::ObligationCause::dummy(),
-                    cx.param_env,
-                    assoc_pred,
-                ) else {
-                    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,
+                // replace them with the term we're assigning to the associated
+                // type in our opaque type.
+                let proj_replacer = &mut BottomUpFolder {
+                    tcx: cx.tcx,
+                    ty_op: |ty| if ty == proj_ty { proj_term } else { ty },
+                    lt_op: |lt| lt,
+                    ct_op: |ct| ct,
                 };
-                // If that predicate doesn't hold modulo regions (but passed during type-check),
-                // then we must've taken advantage of the hack in `project_and_unify_types` where
-                // we replace opaques with inference vars. Emit a warning!
-                if !infcx.predicate_must_hold_modulo_regions(&traits::Obligation::new(
-                    cx.tcx,
-                    traits::ObligationCause::dummy(),
-                    cx.param_env,
-                    assoc_pred,
-                )) {
-                    // If it's a trait bound and an opaque that doesn't satisfy it,
-                    // then we can emit a suggestion to add the bound.
-                    let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
-                        (
-                            ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }),
-                            ty::ClauseKind::Trait(trait_pred),
-                        ) => Some(AddBound {
-                            suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(),
-                            trait_ref: trait_pred.print_modifiers_and_trait_path(),
-                        }),
-                        _ => None,
+                // For example, in `impl Trait<Assoc = impl Send>`, for all of the bounds on `Assoc`,
+                // e.g. `type Assoc: OtherTrait`, replace `<impl Trait as Trait>::Assoc: OtherTrait`
+                // with `impl Send: OtherTrait`.
+                for (assoc_pred, assoc_pred_span) in cx
+                    .tcx
+                    .explicit_item_bounds(proj.projection_ty.def_id)
+                    .iter_instantiated_copied(cx.tcx, proj.projection_ty.args)
+                {
+                    let assoc_pred = assoc_pred.fold_with(proj_replacer);
+                    let Ok(assoc_pred) = traits::fully_normalize(
+                        infcx,
+                        traits::ObligationCause::dummy(),
+                        cx.param_env,
+                        assoc_pred,
+                    ) else {
+                        continue;
                     };
-                    cx.emit_span_lint(
-                        OPAQUE_HIDDEN_INFERRED_BOUND,
-                        pred_span,
-                        OpaqueHiddenInferredBoundLint {
-                            ty: Ty::new_opaque(
-                                cx.tcx,
-                                def_id,
-                                ty::GenericArgs::identity_for_item(cx.tcx, def_id),
-                            ),
-                            proj_ty: proj_term,
-                            assoc_pred_span,
-                            add_bound,
-                        },
-                    );
+
+                    // If that predicate doesn't hold modulo regions (but passed during type-check),
+                    // then we must've taken advantage of the hack in `project_and_unify_types` where
+                    // we replace opaques with inference vars. Emit a warning!
+                    if !infcx.predicate_must_hold_modulo_regions(&traits::Obligation::new(
+                        cx.tcx,
+                        traits::ObligationCause::dummy(),
+                        cx.param_env,
+                        assoc_pred,
+                    )) {
+                        // If it's a trait bound and an opaque that doesn't satisfy it,
+                        // then we can emit a suggestion to add the bound.
+                        let add_bound = match (proj_term.kind(), assoc_pred.kind().skip_binder()) {
+                            (
+                                ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }),
+                                ty::ClauseKind::Trait(trait_pred),
+                            ) => Some(AddBound {
+                                suggest_span: cx.tcx.def_span(*def_id).shrink_to_hi(),
+                                trait_ref: trait_pred.print_modifiers_and_trait_path(),
+                            }),
+                            _ => None,
+                        };
+
+                        cx.emit_span_lint(
+                            OPAQUE_HIDDEN_INFERRED_BOUND,
+                            pred_span,
+                            OpaqueHiddenInferredBoundLint {
+                                ty: Ty::new_opaque(
+                                    cx.tcx,
+                                    def_id,
+                                    ty::GenericArgs::identity_for_item(cx.tcx, def_id),
+                                ),
+                                proj_ty: proj_term,
+                                assoc_pred_span,
+                                add_bound,
+                            },
+                        );
+                    }
                 }
-            }
+            });
         }
     }
 }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 07c0e75a71c..6a2a2c1e48e 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -3,6 +3,9 @@
 //! These are the built-in lints that are emitted direct in the main
 //! compiler code, rather than using their own custom pass. Those
 //! lints are all available in `rustc_lint::builtin`.
+//!
+//! When removing a lint, make sure to also add a call to `register_removed` in
+//! compiler/rustc_lint/src/lib.rs.
 
 use crate::{declare_lint, declare_lint_pass, FutureIncompatibilityReason};
 use rustc_span::edition::Edition;
@@ -66,7 +69,6 @@ declare_lint_pass! {
         MUST_NOT_SUSPEND,
         NAMED_ARGUMENTS_USED_POSITIONALLY,
         NON_EXHAUSTIVE_OMITTED_PATTERNS,
-        NONTRIVIAL_STRUCTURAL_MATCH,
         ORDER_DEPENDENT_TRAIT_OBJECTS,
         OVERLAPPING_RANGE_ENDPOINTS,
         PATTERNS_IN_FNS_WITHOUT_BODY,
@@ -2280,8 +2282,8 @@ declare_lint! {
     Warn,
     "constant used in pattern contains value of non-structural-match type in a field or a variant",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
-        reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>",
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
+        reference: "issue #120362 <https://github.com/rust-lang/rust/issues/120362>",
     };
 }
 
@@ -2336,47 +2338,8 @@ declare_lint! {
     Warn,
     "pointers are not structural-match",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
-        reference: "issue #62411 <https://github.com/rust-lang/rust/issues/70861>",
-    };
-}
-
-declare_lint! {
-    /// The `nontrivial_structural_match` lint detects constants that are used in patterns,
-    /// whose type is not structural-match and whose initializer body actually uses values
-    /// that are not structural-match. So `Option<NotStructuralMatch>` is ok if the constant
-    /// is just `None`.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,compile_fail
-    /// #![deny(nontrivial_structural_match)]
-    ///
-    /// #[derive(Copy, Clone, Debug)]
-    /// struct NoDerive(u32);
-    /// impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
-    /// impl Eq for NoDerive { }
-    /// fn main() {
-    ///     const INDEX: Option<NoDerive> = [None, Some(NoDerive(10))][0];
-    ///     match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
-    /// }
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// Previous versions of Rust accepted constants in patterns, even if those constants' types
-    /// did not have `PartialEq` derived. Thus the compiler falls back to runtime execution of
-    /// `PartialEq`, which can report that two constants are not equal even if they are
-    /// bit-equivalent.
-    pub NONTRIVIAL_STRUCTURAL_MATCH,
-    Warn,
-    "constant used in pattern of non-structural-match type and the constant's initializer \
-    expression contains values of non-structural-match types",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
-        reference: "issue #73448 <https://github.com/rust-lang/rust/issues/73448>",
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
+        reference: "issue #120362 <https://github.com/rust-lang/rust/issues/120362>",
     };
 }
 
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index eed35326c45..8b7e82d2113 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -1,6 +1,4 @@
 #![feature(min_specialization)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_macros;
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index 5bfffc5d911..6d578c97f3f 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -76,7 +76,6 @@ enum LLVMRustAttribute {
   SanitizeMemory = 22,
   NonLazyBind = 23,
   OptimizeNone = 24,
-  ReturnsTwice = 25,
   ReadNone = 26,
   SanitizeHWAddress = 28,
   WillReturn = 29,
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index 0df7b7eed11..a2dfebec594 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -250,8 +250,6 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
     return Attribute::NonLazyBind;
   case OptimizeNone:
     return Attribute::OptimizeNone;
-  case ReturnsTwice:
-    return Attribute::ReturnsTwice;
   case ReadNone:
     return Attribute::ReadNone;
   case SanitizeHWAddress:
diff --git a/compiler/rustc_llvm/src/lib.rs b/compiler/rustc_llvm/src/lib.rs
index ca0aec71052..6a570c97c88 100644
--- a/compiler/rustc_llvm/src/lib.rs
+++ b/compiler/rustc_llvm/src/lib.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
diff --git a/compiler/rustc_log/src/lib.rs b/compiler/rustc_log/src/lib.rs
index e3464cb8a2d..1a78f9f0f86 100644
--- a/compiler/rustc_log/src/lib.rs
+++ b/compiler/rustc_log/src/lib.rs
@@ -38,9 +38,6 @@
 //! debugging, you can make changes inside those crates and quickly run main.rs
 //! to read the debug logs.
 
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
-
 use std::env::{self, VarError};
 use std::fmt::{self, Display};
 use std::io::{self, IsTerminal};
diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
index c029b931e7d..3a5f289559e 100644
--- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs
@@ -89,10 +89,7 @@ impl SubdiagnosticDeriveBuilder {
             gen impl rustc_errors::AddToDiagnostic for @Self {
                 fn add_to_diagnostic_with<__F>(self, #diag: &mut rustc_errors::Diagnostic, #f: __F)
                 where
-                    __F: core::ops::Fn(
-                        &mut rustc_errors::Diagnostic,
-                        rustc_errors::SubdiagnosticMessage
-                    ) -> rustc_errors::SubdiagnosticMessage,
+                    __F: rustc_errors::SubdiagnosticMessageOp,
                 {
                     #implementation
                 }
diff --git a/compiler/rustc_macros/src/lib.rs b/compiler/rustc_macros/src/lib.rs
index 9e85a59b5b9..af65c908ee6 100644
--- a/compiler/rustc_macros/src/lib.rs
+++ b/compiler/rustc_macros/src/lib.rs
@@ -6,8 +6,6 @@
 #![feature(proc_macro_span)]
 #![feature(proc_macro_tracked_env)]
 #![allow(rustc::default_hash_types)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
 
 use synstructure::decl_derive;
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index bb02a8a1e47..c18f0e7b7b9 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -534,7 +534,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
     ) -> Option<CrateNum> {
         self.used_extern_options.insert(name);
         match self.maybe_resolve_crate(name, dep_kind, None) {
-            Ok(cnum) => Some(cnum),
+            Ok(cnum) => {
+                self.cstore.set_used_recursively(cnum);
+                Some(cnum)
+            }
             Err(err) => {
                 let missing_core =
                     self.maybe_resolve_crate(sym::core, CrateDepKind::Explicit, None).is_err();
@@ -1067,6 +1070,16 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
     pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
         self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
     }
+
+    pub fn unload_unused_crates(&mut self) {
+        for opt_cdata in &mut self.cstore.metas {
+            if let Some(cdata) = opt_cdata
+                && !cdata.used()
+            {
+                *opt_cdata = None;
+            }
+        }
+    }
 }
 
 fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 471425e8017..2e7130f3565 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -15,8 +15,6 @@
 #![feature(try_blocks)]
 #![feature(never_type)]
 #![allow(rustc::potential_query_instability)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 extern crate proc_macro;
 
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 20e3ae3ba94..11cb1bb6d9e 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -106,6 +106,8 @@ pub(crate) struct CrateMetadata {
     private_dep: bool,
     /// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
     host_hash: Option<Svh>,
+    /// The crate was used non-speculatively.
+    used: bool,
 
     /// Additional data used for decoding `HygieneData` (e.g. `SyntaxContext`
     /// and `ExpnId`).
@@ -1811,6 +1813,7 @@ impl CrateMetadata {
             source: Lrc::new(source),
             private_dep,
             host_hash,
+            used: false,
             extern_crate: None,
             hygiene_context: Default::default(),
             def_key_cache: Default::default(),
@@ -1860,6 +1863,10 @@ impl CrateMetadata {
         self.private_dep &= private_dep;
     }
 
+    pub(crate) fn used(&self) -> bool {
+        self.used
+    }
+
     pub(crate) fn required_panic_strategy(&self) -> Option<PanicStrategy> {
         self.root.required_panic_strategy
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 0b352a02b64..7cd2f58779f 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -26,6 +26,7 @@ use rustc_span::symbol::{kw, Symbol};
 use rustc_span::Span;
 
 use std::any::Any;
+use std::mem;
 
 use super::{Decodable, DecodeContext, DecodeIterator};
 
@@ -576,12 +577,24 @@ impl CStore {
         self.get_crate_data(cnum).get_proc_macro_quoted_span(id, sess)
     }
 
+    pub fn set_used_recursively(&mut self, cnum: CrateNum) {
+        let cmeta = self.get_crate_data_mut(cnum);
+        if !cmeta.used {
+            cmeta.used = true;
+            let dependencies = mem::take(&mut cmeta.dependencies);
+            for &dep_cnum in &dependencies {
+                self.set_used_recursively(dep_cnum);
+            }
+            self.get_crate_data_mut(cnum).dependencies = dependencies;
+        }
+    }
+
     pub(crate) fn update_extern_crate(&mut self, cnum: CrateNum, extern_crate: ExternCrate) {
         let cmeta = self.get_crate_data_mut(cnum);
         if cmeta.update_extern_crate(extern_crate) {
             // Propagate the extern crate info to dependencies if it was updated.
             let extern_crate = ExternCrate { dependency_of: cnum, ..extern_crate };
-            let dependencies = std::mem::take(&mut cmeta.dependencies);
+            let dependencies = mem::take(&mut cmeta.dependencies);
             for &dep_cnum in &dependencies {
                 self.update_extern_crate(dep_cnum, extern_crate);
             }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 542caf86223..79aa9a547f7 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -386,7 +386,7 @@ impl<'a, 'tcx> TyEncoder for EncodeContext<'a, 'tcx> {
     }
 }
 
-// Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy_value($value))`, which would
+// Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy($value))`, which would
 // normally need extra variables to avoid errors about multiple mutable borrows.
 macro_rules! record {
     ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{
@@ -398,7 +398,7 @@ macro_rules! record {
     }};
 }
 
-// Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy_value($value))`, which would
+// Shorthand for `$self.$tables.$table.set_some($def_id.index, $self.lazy_array($value))`, which would
 // normally need extra variables to avoid errors about multiple mutable borrows.
 macro_rules! record_array {
     ($self:ident.$tables:ident.$table:ident[$def_id:expr] <- $value:expr) => {{
@@ -1388,13 +1388,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if should_encode_fn_sig(def_kind) {
                 record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id));
             }
-            // FIXME: Some anonymous constants produced by `#[rustc_legacy_const_generics]`
-            // do not have corresponding HIR nodes, so some queries usually making sense for
-            // anonymous constants will not work on them and panic. It's not clear whether it
-            // can cause any observable issues or not.
-            let anon_const_without_hir = def_kind == DefKind::AnonConst
-                && tcx.opt_hir_node(tcx.local_def_id_to_hir_id(local_id)).is_none();
-            if should_encode_generics(def_kind) && !anon_const_without_hir {
+            if should_encode_generics(def_kind) {
                 let g = tcx.generics_of(def_id);
                 record!(self.tables.generics_of[def_id] <- g);
                 record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id));
@@ -1408,7 +1402,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     }
                 }
             }
-            if should_encode_type(tcx, local_id, def_kind) && !anon_const_without_hir {
+            if should_encode_type(tcx, local_id, def_kind) {
                 record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id));
             }
             if should_encode_constness(def_kind) {
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index ba1ae46626b..bf72aac1033 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -158,22 +158,14 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
-    pub fn opt_hir_node(self, id: HirId) -> Option<Node<'tcx>> {
-        let owner = self.hir_owner_nodes(id.owner);
-        let node = owner.nodes[id.local_id].as_ref()?;
-        Some(node.node)
-    }
-
-    /// Retrieves the `hir::Node` corresponding to `id`, returning `None` if cannot be found.
     #[inline]
     pub fn opt_hir_node_by_def_id(self, id: LocalDefId) -> Option<Node<'tcx>> {
-        self.opt_hir_node(self.opt_local_def_id_to_hir_id(id)?)
+        Some(self.hir_node(self.opt_local_def_id_to_hir_id(id)?))
     }
 
-    /// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found.
-    #[track_caller]
+    /// Retrieves the `hir::Node` corresponding to `id`.
     pub fn hir_node(self, id: HirId) -> Node<'tcx> {
-        self.opt_hir_node(id).unwrap_or_else(|| bug!("couldn't find HIR node for hir id {id:?}"))
+        self.hir_owner_nodes(id.owner).nodes[id.local_id].node
     }
 
     /// Retrieves the `hir::Node` corresponding to `id`, panicking if it cannot be found.
@@ -230,10 +222,13 @@ impl<'hir> Map<'hir> {
     /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
     pub fn opt_parent_id(self, id: HirId) -> Option<HirId> {
         if id.local_id == ItemLocalId::from_u32(0) {
+            // FIXME: This function never returns `None` right now, and the parent chain end is
+            // determined by checking for `parent(id) == id`. This function should return `None`
+            // for the crate root instead.
             Some(self.tcx.hir_owner_parent(id.owner))
         } else {
             let owner = self.tcx.hir_owner_nodes(id.owner);
-            let node = owner.nodes[id.local_id].as_ref()?;
+            let node = &owner.nodes[id.local_id];
             let hir_id = HirId { owner: id.owner, local_id: node.parent };
             // HIR indexing should have checked that.
             debug_assert_ne!(id.local_id, node.parent);
@@ -252,11 +247,12 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn find_parent(self, hir_id: HirId) -> Option<Node<'hir>> {
-        self.tcx.opt_hir_node(self.opt_parent_id(hir_id)?)
+        Some(self.tcx.hir_node(self.opt_parent_id(hir_id)?))
     }
 
     pub fn get_if_local(self, id: DefId) -> Option<Node<'hir>> {
-        id.as_local().and_then(|id| self.tcx.opt_hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?))
+        id.as_local()
+            .and_then(|id| Some(self.tcx.hir_node(self.tcx.opt_local_def_id_to_hir_id(id)?)))
     }
 
     pub fn get_generics(self, id: LocalDefId) -> Option<&'hir Generics<'hir>> {
@@ -285,20 +281,12 @@ impl<'hir> Map<'hir> {
 
     #[track_caller]
     pub fn fn_decl_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnDecl<'hir>> {
-        if let Some(node) = self.tcx.opt_hir_node(hir_id) {
-            node.fn_decl()
-        } else {
-            bug!("no node for hir_id `{}`", hir_id)
-        }
+        self.tcx.hir_node(hir_id).fn_decl()
     }
 
     #[track_caller]
     pub fn fn_sig_by_hir_id(self, hir_id: HirId) -> Option<&'hir FnSig<'hir>> {
-        if let Some(node) = self.tcx.opt_hir_node(hir_id) {
-            node.fn_sig()
-        } else {
-            bug!("no node for hir_id `{}`", hir_id)
-        }
+        self.tcx.hir_node(hir_id).fn_sig()
     }
 
     #[track_caller]
@@ -317,10 +305,7 @@ impl<'hir> Map<'hir> {
     /// item (possibly associated), a closure, or a `hir::AnonConst`.
     pub fn body_owner(self, BodyId { hir_id }: BodyId) -> HirId {
         let parent = self.parent_id(hir_id);
-        assert!(
-            self.tcx.opt_hir_node(parent).is_some_and(|n| is_body_owner(n, hir_id)),
-            "{hir_id:?}"
-        );
+        assert!(is_body_owner(self.tcx.hir_node(parent), hir_id), "{hir_id:?}");
         parent
     }
 
@@ -572,7 +557,7 @@ impl<'hir> Map<'hir> {
     /// until the crate root is reached. Prefer this over your own loop using `parent_id`.
     #[inline]
     pub fn parent_iter(self, current_id: HirId) -> impl Iterator<Item = (HirId, Node<'hir>)> {
-        self.parent_id_iter(current_id).filter_map(move |id| Some((id, self.tcx.opt_hir_node(id)?)))
+        self.parent_id_iter(current_id).map(move |id| (id, self.tcx.hir_node(id)))
     }
 
     /// Returns an iterator for the nodes in the ancestor tree of the `current_id`
@@ -624,7 +609,7 @@ impl<'hir> Map<'hir> {
     pub fn get_return_block(self, id: HirId) -> Option<HirId> {
         let mut iter = self.parent_iter(id).peekable();
         let mut ignore_tail = false;
-        if let Some(Node::Expr(Expr { kind: ExprKind::Ret(_), .. })) = self.tcx.opt_hir_node(id) {
+        if let Node::Expr(Expr { kind: ExprKind::Ret(_), .. }) = self.tcx.hir_node(id) {
             // When dealing with `return` statements, we don't care about climbing only tail
             // expressions.
             ignore_tail = true;
@@ -777,8 +762,8 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn expect_variant(self, id: HirId) -> &'hir Variant<'hir> {
-        match self.tcx.opt_hir_node(id) {
-            Some(Node::Variant(variant)) => variant,
+        match self.tcx.hir_node(id) {
+            Node::Variant(variant) => variant,
             _ => bug!("expected variant, found {}", self.node_to_string(id)),
         }
     }
@@ -796,18 +781,18 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn expect_expr(self, id: HirId) -> &'hir Expr<'hir> {
-        match self.tcx.opt_hir_node(id) {
-            Some(Node::Expr(expr)) => expr,
+        match self.tcx.hir_node(id) {
+            Node::Expr(expr) => expr,
             _ => bug!("expected expr, found {}", self.node_to_string(id)),
         }
     }
 
     #[inline]
     fn opt_ident(self, id: HirId) -> Option<Ident> {
-        match self.tcx.opt_hir_node(id)? {
+        match self.tcx.hir_node(id) {
             Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident),
             // A `Ctor` doesn't have an identifier itself, but its parent
-            // struct/variant does. Compare with `hir::Map::opt_span`.
+            // struct/variant does. Compare with `hir::Map::span`.
             Node::Ctor(..) => match self.find_parent(id)? {
                 Node::Item(item) => Some(item.ident),
                 Node::Variant(variant) => Some(variant.ident),
@@ -845,11 +830,6 @@ impl<'hir> Map<'hir> {
     /// Gets the span of the definition of the specified HIR node.
     /// This is used by `tcx.def_span`.
     pub fn span(self, hir_id: HirId) -> Span {
-        self.opt_span(hir_id)
-            .unwrap_or_else(|| bug!("hir::map::Map::span: id not in map: {:?}", hir_id))
-    }
-
-    pub fn opt_span(self, hir_id: HirId) -> Option<Span> {
         fn until_within(outer: Span, end: Span) -> Span {
             if let Some(end) = end.find_ancestor_inside(outer) {
                 outer.with_hi(end.hi())
@@ -873,7 +853,7 @@ impl<'hir> Map<'hir> {
             }
         }
 
-        let span = match self.tcx.opt_hir_node(hir_id)? {
+        let span = match self.tcx.hir_node(hir_id) {
             // Function-like.
             Node::Item(Item { kind: ItemKind::Fn(sig, ..), span: outer_span, .. })
             | Node::TraitItem(TraitItem {
@@ -945,7 +925,7 @@ impl<'hir> Map<'hir> {
                 ForeignItemKind::Fn(decl, _, _) => until_within(item.span, decl.output.span()),
                 _ => named_span(item.span, item.ident, None),
             },
-            Node::Ctor(_) => return self.opt_span(self.parent_id(hir_id)),
+            Node::Ctor(_) => return self.span(self.parent_id(hir_id)),
             Node::Expr(Expr {
                 kind: ExprKind::Closure(Closure { fn_decl_span, .. }),
                 span,
@@ -957,7 +937,7 @@ impl<'hir> Map<'hir> {
             _ => self.span_with_body(hir_id),
         };
         debug_assert_eq!(span.ctxt(), self.span_with_body(hir_id).ctxt());
-        Some(span)
+        span
     }
 
     /// Like `hir.span()`, but includes the body of items
@@ -994,6 +974,9 @@ impl<'hir> Map<'hir> {
             Node::Infer(i) => i.span,
             Node::Local(local) => local.span,
             Node::Crate(item) => item.spans.inner_span,
+            Node::WhereBoundPredicate(pred) => pred.span,
+            Node::ArrayLenInfer(inf) => inf.span,
+            Node::Err(span) => *span,
         }
     }
 
@@ -1057,8 +1040,8 @@ impl<'hir> Map<'hir> {
 }
 
 impl<'hir> intravisit::Map<'hir> for Map<'hir> {
-    fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
-        self.tcx.opt_hir_node(hir_id)
+    fn hir_node(&self, hir_id: HirId) -> Node<'hir> {
+        self.tcx.hir_node(hir_id)
     }
 
     fn body(&self, id: BodyId) -> &'hir Body<'hir> {
@@ -1175,8 +1158,8 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
     let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default();
     let node_str = |prefix| format!("{id} ({prefix} `{}`)", span_str());
 
-    match map.tcx.opt_hir_node(id) {
-        Some(Node::Item(item)) => {
+    match map.tcx.hir_node(id) {
+        Node::Item(item) => {
             let item_str = match item.kind {
                 ItemKind::ExternCrate(..) => "extern crate",
                 ItemKind::Use(..) => "use",
@@ -1204,10 +1187,10 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
             };
             format!("{id} ({item_str} {})", path_str(item.owner_id.def_id))
         }
-        Some(Node::ForeignItem(item)) => {
+        Node::ForeignItem(item) => {
             format!("{id} (foreign item {})", path_str(item.owner_id.def_id))
         }
-        Some(Node::ImplItem(ii)) => {
+        Node::ImplItem(ii) => {
             let kind = match ii.kind {
                 ImplItemKind::Const(..) => "assoc const",
                 ImplItemKind::Fn(..) => "method",
@@ -1215,7 +1198,7 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
             };
             format!("{id} ({kind} `{}` in {})", ii.ident, path_str(ii.owner_id.def_id))
         }
-        Some(Node::TraitItem(ti)) => {
+        Node::TraitItem(ti) => {
             let kind = match ti.kind {
                 TraitItemKind::Const(..) => "assoc constant",
                 TraitItemKind::Fn(..) => "trait method",
@@ -1224,38 +1207,40 @@ fn hir_id_to_string(map: Map<'_>, id: HirId) -> String {
 
             format!("{id} ({kind} `{}` in {})", ti.ident, path_str(ti.owner_id.def_id))
         }
-        Some(Node::Variant(variant)) => {
+        Node::Variant(variant) => {
             format!("{id} (variant `{}` in {})", variant.ident, path_str(variant.def_id))
         }
-        Some(Node::Field(field)) => {
+        Node::Field(field) => {
             format!("{id} (field `{}` in {})", field.ident, path_str(field.def_id))
         }
-        Some(Node::AnonConst(_)) => node_str("const"),
-        Some(Node::ConstBlock(_)) => node_str("const"),
-        Some(Node::Expr(_)) => node_str("expr"),
-        Some(Node::ExprField(_)) => node_str("expr field"),
-        Some(Node::Stmt(_)) => node_str("stmt"),
-        Some(Node::PathSegment(_)) => node_str("path segment"),
-        Some(Node::Ty(_)) => node_str("type"),
-        Some(Node::TypeBinding(_)) => node_str("type binding"),
-        Some(Node::TraitRef(_)) => node_str("trait ref"),
-        Some(Node::Pat(_)) => node_str("pat"),
-        Some(Node::PatField(_)) => node_str("pattern field"),
-        Some(Node::Param(_)) => node_str("param"),
-        Some(Node::Arm(_)) => node_str("arm"),
-        Some(Node::Block(_)) => node_str("block"),
-        Some(Node::Infer(_)) => node_str("infer"),
-        Some(Node::Local(_)) => node_str("local"),
-        Some(Node::Ctor(ctor)) => format!(
+        Node::AnonConst(_) => node_str("const"),
+        Node::ConstBlock(_) => node_str("const"),
+        Node::Expr(_) => node_str("expr"),
+        Node::ExprField(_) => node_str("expr field"),
+        Node::Stmt(_) => node_str("stmt"),
+        Node::PathSegment(_) => node_str("path segment"),
+        Node::Ty(_) => node_str("type"),
+        Node::TypeBinding(_) => node_str("type binding"),
+        Node::TraitRef(_) => node_str("trait ref"),
+        Node::Pat(_) => node_str("pat"),
+        Node::PatField(_) => node_str("pattern field"),
+        Node::Param(_) => node_str("param"),
+        Node::Arm(_) => node_str("arm"),
+        Node::Block(_) => node_str("block"),
+        Node::Infer(_) => node_str("infer"),
+        Node::Local(_) => node_str("local"),
+        Node::Ctor(ctor) => format!(
             "{id} (ctor {})",
             ctor.ctor_def_id().map_or("<missing path>".into(), |def_id| path_str(def_id)),
         ),
-        Some(Node::Lifetime(_)) => node_str("lifetime"),
-        Some(Node::GenericParam(param)) => {
+        Node::Lifetime(_) => node_str("lifetime"),
+        Node::GenericParam(param) => {
             format!("{id} (generic_param {})", path_str(param.def_id))
         }
-        Some(Node::Crate(..)) => String::from("(root_crate)"),
-        None => format!("{id} (unknown node)"),
+        Node::Crate(..) => String::from("(root_crate)"),
+        Node::WhereBoundPredicate(_) => node_str("where bound predicate"),
+        Node::ArrayLenInfer(_) => node_str("array len infer"),
+        Node::Err(_) => node_str("error"),
     }
 }
 
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 94191df30a5..f66cd2370e3 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -12,7 +12,7 @@ use rustc_data_structures::sync::{try_par_for_each_in, DynSend, DynSync};
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
 use rustc_hir::*;
-use rustc_span::{ErrorGuaranteed, ExpnId, DUMMY_SP};
+use rustc_span::{ErrorGuaranteed, ExpnId};
 
 /// Gather the LocalDefId for each item-like within a module, including items contained within
 /// bodies. The Ids are in visitor order. This is used to partition a pass between modules.
@@ -148,10 +148,7 @@ pub fn provide(providers: &mut Providers) {
     providers.hir_attrs = |tcx, id| {
         tcx.hir_crate(()).owners[id.def_id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs)
     };
-    providers.def_span = |tcx, def_id| {
-        let hir_id = tcx.local_def_id_to_hir_id(def_id);
-        tcx.hir().opt_span(hir_id).unwrap_or(DUMMY_SP)
-    };
+    providers.def_span = |tcx, def_id| tcx.hir().span(tcx.local_def_id_to_hir_id(def_id));
     providers.def_ident_span = |tcx, def_id| {
         let hir_id = tcx.local_def_id_to_hir_id(def_id);
         tcx.hir().opt_ident_span(hir_id)
diff --git a/compiler/rustc_middle/src/infer/unify_key.rs b/compiler/rustc_middle/src/infer/unify_key.rs
index c35799ef47f..63c0ebd5f6b 100644
--- a/compiler/rustc_middle/src/infer/unify_key.rs
+++ b/compiler/rustc_middle/src/infer/unify_key.rs
@@ -194,33 +194,37 @@ impl<'tcx> UnifyValue for ConstVariableValue<'tcx> {
 /// values for the effect inference variable
 #[derive(Clone, Copy, Debug)]
 pub enum EffectVarValue<'tcx> {
-    /// The host effect is on, enabling access to syscalls, filesystem access, etc.
-    Host,
-    /// The host effect is off. Execution is restricted to const operations only.
-    NoHost,
-    Const(ty::Const<'tcx>),
+    Unknown,
+    Known(ty::Const<'tcx>),
 }
 
 impl<'tcx> EffectVarValue<'tcx> {
-    pub fn as_const(self, tcx: TyCtxt<'tcx>) -> ty::Const<'tcx> {
+    pub fn known(self) -> Option<ty::Const<'tcx>> {
         match self {
-            EffectVarValue::Host => tcx.consts.true_,
-            EffectVarValue::NoHost => tcx.consts.false_,
-            EffectVarValue::Const(c) => c,
+            EffectVarValue::Unknown => None,
+            EffectVarValue::Known(value) => Some(value),
+        }
+    }
+
+    pub fn is_unknown(self) -> bool {
+        match self {
+            EffectVarValue::Unknown => true,
+            EffectVarValue::Known(_) => false,
         }
     }
 }
 
 impl<'tcx> UnifyValue for EffectVarValue<'tcx> {
-    type Error = (EffectVarValue<'tcx>, EffectVarValue<'tcx>);
+    type Error = NoError;
     fn unify_values(value1: &Self, value2: &Self) -> Result<Self, Self::Error> {
-        match (value1, value2) {
-            (EffectVarValue::Host, EffectVarValue::Host) => Ok(EffectVarValue::Host),
-            (EffectVarValue::NoHost, EffectVarValue::NoHost) => Ok(EffectVarValue::NoHost),
-            (EffectVarValue::NoHost | EffectVarValue::Host, _)
-            | (_, EffectVarValue::NoHost | EffectVarValue::Host) => Err((*value1, *value2)),
-            (EffectVarValue::Const(_), EffectVarValue::Const(_)) => {
-                bug!("equating two const variables, both of which have known values")
+        match (*value1, *value2) {
+            (EffectVarValue::Unknown, EffectVarValue::Unknown) => Ok(EffectVarValue::Unknown),
+            (EffectVarValue::Unknown, EffectVarValue::Known(val))
+            | (EffectVarValue::Known(val), EffectVarValue::Unknown) => {
+                Ok(EffectVarValue::Known(val))
+            }
+            (EffectVarValue::Known(_), EffectVarValue::Known(_)) => {
+                bug!("equating known inference variables: {value1:?} {value2:?}")
             }
         }
     }
@@ -229,7 +233,7 @@ impl<'tcx> UnifyValue for EffectVarValue<'tcx> {
 #[derive(PartialEq, Copy, Clone, Debug)]
 pub struct EffectVidKey<'tcx> {
     pub vid: ty::EffectVid,
-    pub phantom: PhantomData<EffectVarValue<'tcx>>,
+    pub phantom: PhantomData<ty::Const<'tcx>>,
 }
 
 impl<'tcx> From<ty::EffectVid> for EffectVidKey<'tcx> {
@@ -239,7 +243,7 @@ impl<'tcx> From<ty::EffectVid> for EffectVidKey<'tcx> {
 }
 
 impl<'tcx> UnifyKey for EffectVidKey<'tcx> {
-    type Value = Option<EffectVarValue<'tcx>>;
+    type Value = EffectVarValue<'tcx>;
     #[inline]
     fn index(&self) -> u32 {
         self.vid.as_u32()
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index ddfb2ece39f..2aaece1060a 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -30,6 +30,7 @@
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(core_intrinsics)]
+#![feature(const_type_name)]
 #![feature(discriminant_kind)]
 #![feature(exhaustive_patterns)]
 #![feature(coroutines)]
@@ -48,7 +49,7 @@
 #![feature(associated_type_bounds)]
 #![feature(rustc_attrs)]
 #![feature(control_flow_enum)]
-#![cfg_attr(not(bootstrap), feature(trait_upcasting))]
+#![feature(trait_upcasting)]
 #![feature(try_blocks)]
 #![feature(decl_macro)]
 #![feature(extract_if)]
@@ -57,8 +58,10 @@
 #![feature(const_option)]
 #![feature(ptr_alignment_type)]
 #![feature(macro_metavar_expr)]
-#![allow(rustc::potential_query_instability)]
 #![allow(internal_features)]
+#![allow(rustc::potential_query_instability)]
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 
 #[macro_use]
 extern crate bitflags;
diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
index e11c9371118..7d6d39a2a8a 100644
--- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
+++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs
@@ -74,35 +74,32 @@ bitflags! {
         /// `#[used]`: indicates that LLVM can't eliminate this function (but the
         /// linker can!).
         const USED                      = 1 << 9;
-        /// `#[ffi_returns_twice]`, indicates that an extern function can return
-        /// multiple times
-        const FFI_RETURNS_TWICE         = 1 << 10;
         /// `#[track_caller]`: allow access to the caller location
-        const TRACK_CALLER              = 1 << 11;
+        const TRACK_CALLER              = 1 << 10;
         /// #[ffi_pure]: applies clang's `pure` attribute to a foreign function
         /// declaration.
-        const FFI_PURE                  = 1 << 12;
+        const FFI_PURE                  = 1 << 11;
         /// #[ffi_const]: applies clang's `const` attribute to a foreign function
         /// declaration.
-        const FFI_CONST                 = 1 << 13;
+        const FFI_CONST                 = 1 << 12;
         /// #[cmse_nonsecure_entry]: with a TrustZone-M extension, declare a
         /// function as an entry function from Non-Secure code.
-        const CMSE_NONSECURE_ENTRY      = 1 << 14;
+        const CMSE_NONSECURE_ENTRY      = 1 << 13;
         /// `#[coverage(off)]`: indicates that the function should be ignored by
         /// the MIR `InstrumentCoverage` pass and not added to the coverage map
         /// during codegen.
-        const NO_COVERAGE               = 1 << 15;
+        const NO_COVERAGE               = 1 << 14;
         /// `#[used(linker)]`:
         /// indicates that neither LLVM nor the linker will eliminate this function.
-        const USED_LINKER               = 1 << 16;
+        const USED_LINKER               = 1 << 15;
         /// `#[rustc_deallocator]`: a hint to LLVM that the function only deallocates memory.
-        const DEALLOCATOR               = 1 << 17;
+        const DEALLOCATOR               = 1 << 16;
         /// `#[rustc_reallocator]`: a hint to LLVM that the function only reallocates memory.
-        const REALLOCATOR               = 1 << 18;
+        const REALLOCATOR               = 1 << 17;
         /// `#[rustc_allocator_zeroed]`: a hint to LLVM that the function only allocates zeroed memory.
-        const ALLOCATOR_ZEROED          = 1 << 19;
+        const ALLOCATOR_ZEROED          = 1 << 18;
         /// `#[no_builtins]`: indicates that disable implicit builtin knowledge of functions for the function.
-        const NO_BUILTINS               = 1 << 20;
+        const NO_BUILTINS               = 1 << 19;
     }
 }
 rustc_data_structures::external_bitflags_debug! { CodegenFnAttrFlags }
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index 9475b89aa15..e22d5228628 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -140,8 +140,12 @@ fn to_profiler_name(type_name: &'static str) -> &'static str {
 /// loop that goes over each available MIR and applies `run_pass`.
 pub trait MirPass<'tcx> {
     fn name(&self) -> &'static str {
-        let name = std::any::type_name::<Self>();
-        if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }
+        // FIXME Simplify the implementation once more `str` methods get const-stable.
+        // See copypaste in `MirLint`
+        const {
+            let name = std::any::type_name::<Self>();
+            crate::util::common::c_name(name)
+        }
     }
 
     fn profiler_name(&self) -> &'static str {
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 6f587fdd53c..b601b465668 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -907,6 +907,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                     NullOp::SizeOf => write!(fmt, "SizeOf({t})"),
                     NullOp::AlignOf => write!(fmt, "AlignOf({t})"),
                     NullOp::OffsetOf(fields) => write!(fmt, "OffsetOf({t}, {fields:?})"),
+                    NullOp::DebugAssertions => write!(fmt, "cfg!(debug_assertions)"),
                 }
             }
             ThreadLocalRef(did) => ty::tls::with(|tcx| {
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 98642adc190..90b6df1dd1f 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -189,7 +189,7 @@ pub struct BorrowCheckResult<'tcx> {
 
 /// The result of the `mir_const_qualif` query.
 ///
-/// Each field (except `error_occurred`) corresponds to an implementer of the `Qualif` trait in
+/// Each field (except `tainted_by_errors`) corresponds to an implementer of the `Qualif` trait in
 /// `rustc_const_eval/src/transform/check_consts/qualifs.rs`. See that file for more information on each
 /// `Qualif`.
 #[derive(Clone, Copy, Debug, Default, TyEncodable, TyDecodable, HashStable)]
@@ -197,7 +197,6 @@ pub struct ConstQualifs {
     pub has_mut_interior: bool,
     pub needs_drop: bool,
     pub needs_non_const_drop: bool,
-    pub custom_eq: bool,
     pub tainted_by_errors: Option<ErrorGuaranteed>,
 }
 
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index ca56e1fd92c..40af453f6ce 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1361,6 +1361,8 @@ pub enum NullOp<'tcx> {
     AlignOf,
     /// Returns the offset of a field
     OffsetOf(&'tcx List<(VariantIdx, FieldIdx)>),
+    /// cfg!(debug_assertions), but expanded in codegen
+    DebugAssertions,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 4780042a510..5bc151de659 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -194,6 +194,7 @@ impl<'tcx> Rvalue<'tcx> {
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
                 tcx.types.usize
             }
+            Rvalue::NullaryOp(NullOp::DebugAssertions, _) => tcx.types.bool,
             Rvalue::Aggregate(ref ak, ref ops) => match **ak {
                 AggregateKind::Array(ty) => Ty::new_array(tcx, ty, ops.len() as u64),
                 AggregateKind::Tuple => {
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 0fed4ccc62a..e1e5d68148f 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -1038,7 +1038,6 @@ impl<'tcx> PatRangeBoundary<'tcx> {
                 a.partial_cmp(&b)
             }
             ty::Int(ity) => {
-                use rustc_middle::ty::layout::IntegerExt;
                 let size = rustc_target::abi::Integer::from_int_ty(&tcx, *ity).size();
                 let a = size.sign_extend(a) as i128;
                 let b = size.sign_extend(b) as i128;
diff --git a/compiler/rustc_middle/src/traits/util.rs b/compiler/rustc_middle/src/traits/util.rs
index b4054f8ff5e..fd5302dc75b 100644
--- a/compiler/rustc_middle/src/traits/util.rs
+++ b/compiler/rustc_middle/src/traits/util.rs
@@ -1,46 +1,60 @@
 use rustc_data_structures::fx::FxHashSet;
 
-use crate::ty::{PolyTraitRef, TyCtxt};
+use crate::ty::{Clause, PolyTraitRef, ToPolyTraitRef, ToPredicate, TyCtxt};
 
-/// Given a PolyTraitRef, get the PolyTraitRefs of the trait's (transitive) supertraits.
+/// Given a [`PolyTraitRef`], get the [`Clause`]s implied by the trait's definition.
+///
 /// This only exists in `rustc_middle` because the more powerful elaborator depends on
 /// `rustc_infer` for elaborating outlives bounds -- this should only be used for pretty
 /// printing.
+pub fn super_predicates_for_pretty_printing<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    trait_ref: PolyTraitRef<'tcx>,
+) -> impl Iterator<Item = Clause<'tcx>> {
+    let clause = trait_ref.to_predicate(tcx);
+    Elaborator { tcx, visited: FxHashSet::from_iter([clause]), stack: vec![clause] }
+}
+
+/// Like [`super_predicates_for_pretty_printing`], except it only returns traits and filters out
+/// all other [`Clause`]s.
 pub fn supertraits_for_pretty_printing<'tcx>(
     tcx: TyCtxt<'tcx>,
     trait_ref: PolyTraitRef<'tcx>,
 ) -> impl Iterator<Item = PolyTraitRef<'tcx>> {
-    Elaborator { tcx, visited: FxHashSet::from_iter([trait_ref]), stack: vec![trait_ref] }
+    super_predicates_for_pretty_printing(tcx, trait_ref).filter_map(|clause| {
+        clause.as_trait_clause().map(|trait_clause| trait_clause.to_poly_trait_ref())
+    })
 }
 
 struct Elaborator<'tcx> {
     tcx: TyCtxt<'tcx>,
-    visited: FxHashSet<PolyTraitRef<'tcx>>,
-    stack: Vec<PolyTraitRef<'tcx>>,
+    visited: FxHashSet<Clause<'tcx>>,
+    stack: Vec<Clause<'tcx>>,
 }
 
 impl<'tcx> Elaborator<'tcx> {
     fn elaborate(&mut self, trait_ref: PolyTraitRef<'tcx>) {
-        let supertrait_refs = self
-            .tcx
-            .super_predicates_of(trait_ref.def_id())
-            .predicates
-            .into_iter()
-            .flat_map(|(pred, _)| pred.subst_supertrait(self.tcx, &trait_ref).as_trait_clause())
-            .map(|t| t.map_bound(|pred| pred.trait_ref))
-            .filter(|supertrait_ref| self.visited.insert(*supertrait_ref));
-
-        self.stack.extend(supertrait_refs);
+        let super_predicates =
+            self.tcx.super_predicates_of(trait_ref.def_id()).predicates.iter().filter_map(
+                |&(pred, _)| {
+                    let clause = pred.subst_supertrait(self.tcx, &trait_ref);
+                    self.visited.insert(clause).then_some(clause)
+                },
+            );
+
+        self.stack.extend(super_predicates);
     }
 }
 
 impl<'tcx> Iterator for Elaborator<'tcx> {
-    type Item = PolyTraitRef<'tcx>;
+    type Item = Clause<'tcx>;
 
-    fn next(&mut self) -> Option<PolyTraitRef<'tcx>> {
-        if let Some(trait_ref) = self.stack.pop() {
-            self.elaborate(trait_ref);
-            Some(trait_ref)
+    fn next(&mut self) -> Option<Clause<'tcx>> {
+        if let Some(clause) = self.stack.pop() {
+            if let Some(trait_clause) = clause.as_trait_clause() {
+                self.elaborate(trait_clause.to_poly_trait_ref());
+            }
+            Some(clause)
         } else {
             None
         }
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index a2794a100f1..417f1932c6f 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
@@ -55,7 +55,7 @@ impl<'tcx> TypeRelation<'tcx> for MatchAgainstFreshVars<'tcx> {
     fn regions(
         &mut self,
         a: ty::Region<'tcx>,
-        b: ty::Region<'tcx>,
+        _b: ty::Region<'tcx>,
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         Ok(a)
     }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 14d2a93e167..b747f0a4fb6 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1193,7 +1193,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let (suitable_region_binding_scope, bound_region) = loop {
             let def_id = match region.kind() {
                 ty::ReLateParam(fr) => fr.bound_region.get_id()?.as_local()?,
-                ty::ReEarlyParam(ebr) => ebr.def_id.expect_local(),
+                ty::ReEarlyParam(ebr) => ebr.def_id.as_local()?,
                 _ => return None, // not a free region
             };
             let scope = self.local_parent(def_id);
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 8678f388298..13cc5cbed44 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -98,6 +98,7 @@ impl<'tcx, T> IsSuggestable<'tcx> for T
 where
     T: TypeVisitable<TyCtxt<'tcx>> + TypeFoldable<TyCtxt<'tcx>>,
 {
+    #[tracing::instrument(level = "debug", skip(tcx))]
     fn is_suggestable(self, tcx: TyCtxt<'tcx>, infer_suggestable: bool) -> bool {
         self.visit_with(&mut IsSuggestableVisitor { tcx, infer_suggestable }).is_continue()
     }
@@ -533,6 +534,9 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> {
         match c.kind() {
             ConstKind::Infer(InferConst::Var(_)) if self.infer_suggestable => {}
 
+            // effect variables are always suggestable, because they are not visible
+            ConstKind::Infer(InferConst::EffectVar(_)) => {}
+
             ConstKind::Infer(..)
             | ConstKind::Bound(..)
             | ConstKind::Placeholder(..)
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 9c1f4b20d2c..8848d216f5b 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -765,7 +765,14 @@ fn polymorphize<'tcx>(
     let def_id = instance.def_id();
     let upvars_ty = match tcx.type_of(def_id).skip_binder().kind() {
         ty::Closure(..) => Some(args.as_closure().tupled_upvars_ty()),
-        ty::Coroutine(..) => Some(args.as_coroutine().tupled_upvars_ty()),
+        ty::Coroutine(..) => {
+            assert_eq!(
+                args.as_coroutine().kind_ty(),
+                tcx.types.unit,
+                "polymorphization does not support coroutines from async closures"
+            );
+            Some(args.as_coroutine().tupled_upvars_ty())
+        }
         _ => None,
     };
     let has_upvars = upvars_ty.is_some_and(|ty| !ty.tuple_fields().is_empty());
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index c0bfd2380ad..f90703e6184 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1,7 +1,7 @@
 use crate::mir::interpret::{AllocRange, GlobalAlloc, Pointer, Provenance, Scalar};
 use crate::query::IntoQueryParam;
 use crate::query::Providers;
-use crate::traits::util::supertraits_for_pretty_printing;
+use crate::traits::util::{super_predicates_for_pretty_printing, supertraits_for_pretty_printing};
 use crate::ty::GenericArgKind;
 use crate::ty::{
     ConstInt, ParamConst, ScalarInt, Term, TermKind, TypeFoldable, TypeSuperFoldable,
@@ -1255,8 +1255,8 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         // Generate the main trait ref, including associated types.
         let mut first = true;
 
-        if let Some(principal) = predicates.principal() {
-            self.wrap_binder(&principal, |principal, cx| {
+        if let Some(bound_principal) = predicates.principal() {
+            self.wrap_binder(&bound_principal, |principal, cx| {
                 define_scoped_cx!(cx);
                 p!(print_def_path(principal.def_id, &[]));
 
@@ -1281,19 +1281,53 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                 // HACK(eddyb) this duplicates `FmtPrinter`'s `path_generic_args`,
                 // in order to place the projections inside the `<...>`.
                 if !resugared {
-                    // Use a type that can't appear in defaults of type parameters.
-                    let dummy_cx = Ty::new_fresh(cx.tcx(), 0);
-                    let principal = principal.with_self_ty(cx.tcx(), dummy_cx);
+                    let principal_with_self =
+                        principal.with_self_ty(cx.tcx(), cx.tcx().types.trait_object_dummy_self);
 
                     let args = cx
                         .tcx()
-                        .generics_of(principal.def_id)
-                        .own_args_no_defaults(cx.tcx(), principal.args);
-
-                    let mut projections: Vec<_> = predicates.projection_bounds().collect();
-                    projections.sort_by_cached_key(|proj| {
-                        cx.tcx().item_name(proj.item_def_id()).to_string()
-                    });
+                        .generics_of(principal_with_self.def_id)
+                        .own_args_no_defaults(cx.tcx(), principal_with_self.args);
+
+                    let bound_principal_with_self = bound_principal
+                        .with_self_ty(cx.tcx(), cx.tcx().types.trait_object_dummy_self);
+
+                    let super_projections: Vec<_> =
+                        super_predicates_for_pretty_printing(cx.tcx(), bound_principal_with_self)
+                            .filter_map(|clause| clause.as_projection_clause())
+                            .collect();
+
+                    let mut projections: Vec<_> = predicates
+                        .projection_bounds()
+                        .filter(|&proj| {
+                            // Filter out projections that are implied by the super predicates.
+                            let proj_is_implied = super_projections.iter().any(|&super_proj| {
+                                let super_proj = super_proj.map_bound(|super_proj| {
+                                    ty::ExistentialProjection::erase_self_ty(cx.tcx(), super_proj)
+                                });
+
+                                // This function is sometimes called on types with erased and
+                                // anonymized regions, but the super projections can still
+                                // contain named regions. So we erase and anonymize everything
+                                // here to compare the types modulo regions below.
+                                let proj = cx.tcx().erase_regions(proj);
+                                let proj = cx.tcx().anonymize_bound_vars(proj);
+                                let super_proj = cx.tcx().erase_regions(super_proj);
+                                let super_proj = cx.tcx().anonymize_bound_vars(super_proj);
+
+                                proj == super_proj
+                            });
+                            !proj_is_implied
+                        })
+                        .map(|proj| {
+                            // Skip the binder, because we don't want to print the binder in
+                            // front of the associated item.
+                            proj.skip_binder()
+                        })
+                        .collect();
+
+                    projections
+                        .sort_by_cached_key(|proj| cx.tcx().item_name(proj.def_id).to_string());
 
                     if !args.is_empty() || !projections.is_empty() {
                         p!(generic_delimiters(|cx| {
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 927924452f9..f592acd4b6f 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1052,6 +1052,7 @@ impl<'tcx, T> Binder<'tcx, T> {
     where
         T: TypeVisitable<TyCtxt<'tcx>>,
     {
+        // `self.value` is equivalent to `self.skip_binder()`
         if self.value.has_escaping_bound_vars() { None } else { Some(self.skip_binder()) }
     }
 
@@ -1312,6 +1313,7 @@ impl<'tcx> PolyFnSig<'tcx> {
         self.map_bound_ref_unchecked(|fn_sig| fn_sig.inputs())
     }
     #[inline]
+    #[track_caller]
     pub fn input(&self, index: usize) -> ty::Binder<'tcx, Ty<'tcx>> {
         self.map_bound_ref(|fn_sig| fn_sig.inputs()[index])
     }
@@ -2277,12 +2279,12 @@ impl<'tcx> Ty<'tcx> {
     }
 
     /// Returns the type of metadata for (potentially fat) pointers to this type,
-    /// and a boolean signifying if this is conditional on this type being `Sized`.
-    pub fn ptr_metadata_ty(
+    /// or the struct tail if the metadata type cannot be determined.
+    pub fn ptr_metadata_ty_or_tail(
         self,
         tcx: TyCtxt<'tcx>,
         normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
-    ) -> (Ty<'tcx>, bool) {
+    ) -> Result<Ty<'tcx>, Ty<'tcx>> {
         let tail = tcx.struct_tail_with_normalize(self, normalize, || {});
         match tail.kind() {
             // Sized types
@@ -2305,31 +2307,47 @@ impl<'tcx> Ty<'tcx> {
             | ty::Error(_)
             // Extern types have metadata = ().
             | ty::Foreign(..)
-            // `dyn*` has no metadata
+            // `dyn*` has metadata = ().
             | ty::Dynamic(_, _, ty::DynStar)
-            // If returned by `struct_tail_without_normalization` this is a unit struct
+            // If returned by `struct_tail_with_normalize` this is a unit struct
             // without any fields, or not a struct, and therefore is Sized.
             | ty::Adt(..)
-            // If returned by `struct_tail_without_normalization` this is the empty tuple,
+            // If returned by `struct_tail_with_normalize` this is the empty tuple,
             // a.k.a. unit type, which is Sized
-            | ty::Tuple(..) => (tcx.types.unit, false),
+            | ty::Tuple(..) => Ok(tcx.types.unit),
+
+            ty::Str | ty::Slice(_) => Ok(tcx.types.usize),
 
-            ty::Str | ty::Slice(_) => (tcx.types.usize, false),
             ty::Dynamic(_, _, ty::Dyn) => {
                 let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None);
-                (tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]), false)
-            },
+                Ok(tcx.type_of(dyn_metadata).instantiate(tcx, &[tail.into()]))
+            }
 
-            // type parameters only have unit metadata if they're sized, so return true
-            // to make sure we double check this during confirmation
-            ty::Param(_) |  ty::Alias(..) => (tcx.types.unit, true),
+            // We don't know the metadata of `self`, but it must be equal to the
+            // metadata of `tail`.
+            ty::Param(_) | ty::Alias(..) => Err(tail),
 
             ty::Infer(ty::TyVar(_))
             | ty::Bound(..)
             | ty::Placeholder(..)
-            | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => {
-                bug!("`ptr_metadata_ty` applied to unexpected type: {:?} (tail = {:?})", self, tail)
-            }
+            | ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) => bug!(
+                "`ptr_metadata_ty_or_tail` applied to unexpected type: {self:?} (tail = {tail:?})"
+            ),
+        }
+    }
+
+    /// Returns the type of metadata for (potentially fat) pointers to this type.
+    /// Causes an ICE if the metadata type cannot be determined.
+    pub fn ptr_metadata_ty(
+        self,
+        tcx: TyCtxt<'tcx>,
+        normalize: impl FnMut(Ty<'tcx>) -> Ty<'tcx>,
+    ) -> Ty<'tcx> {
+        match self.ptr_metadata_ty_or_tail(tcx, normalize) {
+            Ok(metadata) => metadata,
+            Err(tail) => bug!(
+                "`ptr_metadata_ty` failed to get metadata for type: {self:?} (tail = {tail:?})"
+            ),
         }
     }
 
diff --git a/compiler/rustc_middle/src/util/common.rs b/compiler/rustc_middle/src/util/common.rs
index df101a2f6e4..dd3a36c7bf8 100644
--- a/compiler/rustc_middle/src/util/common.rs
+++ b/compiler/rustc_middle/src/util/common.rs
@@ -65,3 +65,19 @@ pub fn indenter() -> Indenter {
     debug!(">>");
     Indenter { _cannot_construct_outside_of_this_module: () }
 }
+
+// const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
+pub const fn c_name(name: &'static str) -> &'static str {
+    // FIXME Simplify the implementation once more `str` methods get const-stable.
+    // and inline into call site
+    let bytes = name.as_bytes();
+    let mut i = bytes.len();
+    while i > 0 && bytes[i - 1] != b':' {
+        i = i - 1;
+    }
+    let (_, bytes) = bytes.split_at(i);
+    match std::str::from_utf8(bytes) {
+        Ok(name) => name,
+        Err(_) => name,
+    }
+}
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index 065c93e86a8..dba8e8b6499 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -40,43 +40,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         &mut self,
         candidate: &mut Candidate<'pat, 'tcx>,
     ) -> bool {
-        // repeatedly simplify match pairs until fixed point is reached
         debug!("{candidate:#?}");
-
-        // existing_bindings and new_bindings exists to keep the semantics in order.
-        // Reversing the binding order for bindings after `@` changes the binding order in places
-        // it shouldn't be changed, for example `let (Some(a), Some(b)) = (x, y)`
+        // In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
+        // bindings in `pat` before `x`. E.g. (#69971):
+        //
+        // struct NonCopyStruct {
+        //     copy_field: u32,
+        // }
+        //
+        // fn foo1(x: NonCopyStruct) {
+        //     let y @ NonCopyStruct { copy_field: z } = x;
+        //     // the above should turn into
+        //     let z = x.copy_field;
+        //     let y = x;
+        // }
         //
-        // To avoid this, the binding occurs in the following manner:
-        // * the bindings for one iteration of the following loop occurs in order (i.e. left to
-        // right)
-        // * the bindings from the previous iteration of the loop is prepended to the bindings from
-        // the current iteration (in the implementation this is done by mem::swap and extend)
-        // * after all iterations, these new bindings are then appended to the bindings that were
-        // preexisting (i.e. `candidate.binding` when the function was called).
+        // We can't just reverse the binding order, because we must preserve pattern-order
+        // otherwise, e.g. in `let (Some(a), Some(b)) = (x, y)`. Our rule then is: deepest-first,
+        // and bindings at the same depth stay in source order.
+        //
+        // To do this, every time around the loop we prepend the newly found bindings to the
+        // bindings we already had.
         //
         // example:
         // candidate.bindings = [1, 2, 3]
-        // binding in iter 1: [4, 5]
-        // binding in iter 2: [6, 7]
+        // bindings in iter 1: [4, 5]
+        // bindings in iter 2: [6, 7]
         //
-        // final binding: [1, 2, 3, 6, 7, 4, 5]
-        let mut existing_bindings = mem::take(&mut candidate.bindings);
-        let mut new_bindings = Vec::new();
+        // final bindings: [6, 7, 4, 5, 1, 2, 3]
+        let mut accumulated_bindings = mem::take(&mut candidate.bindings);
+        // Repeatedly simplify match pairs until fixed point is reached
         loop {
-            let match_pairs = mem::take(&mut candidate.match_pairs);
-
-            if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place }] =
-                &*match_pairs
-            {
-                existing_bindings.extend_from_slice(&new_bindings);
-                mem::swap(&mut candidate.bindings, &mut existing_bindings);
-                candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats);
-                return true;
-            }
-
             let mut changed = false;
-            for match_pair in match_pairs {
+            for match_pair in mem::take(&mut candidate.match_pairs) {
                 match self.simplify_match_pair(match_pair, candidate) {
                     Ok(()) => {
                         changed = true;
@@ -86,36 +82,39 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     }
                 }
             }
-            // Avoid issue #69971: the binding order should be right to left if there are more
-            // bindings after `@` to please the borrow checker
-            // Ex
-            // struct NonCopyStruct {
-            //     copy_field: u32,
-            // }
-            //
-            // fn foo1(x: NonCopyStruct) {
-            //     let y @ NonCopyStruct { copy_field: z } = x;
-            //     // the above should turn into
-            //     let z = x.copy_field;
-            //     let y = x;
-            // }
-            candidate.bindings.extend_from_slice(&new_bindings);
-            mem::swap(&mut candidate.bindings, &mut new_bindings);
+
+            // This does: accumulated_bindings = candidate.bindings.take() ++ accumulated_bindings
+            candidate.bindings.extend_from_slice(&accumulated_bindings);
+            mem::swap(&mut candidate.bindings, &mut accumulated_bindings);
             candidate.bindings.clear();
 
             if !changed {
-                existing_bindings.extend_from_slice(&new_bindings);
-                mem::swap(&mut candidate.bindings, &mut existing_bindings);
-                // Move or-patterns to the end, because they can result in us
-                // creating additional candidates, so we want to test them as
-                // late as possible.
-                candidate
-                    .match_pairs
-                    .sort_by_key(|pair| matches!(pair.pattern.kind, PatKind::Or { .. }));
-                debug!(simplified = ?candidate, "simplify_candidate");
-                return false; // if we were not able to simplify any, done.
+                // If we were not able to simplify anymore, done.
+                break;
             }
         }
+
+        // Store computed bindings back in `candidate`.
+        mem::swap(&mut candidate.bindings, &mut accumulated_bindings);
+
+        let did_expand_or =
+            if let [MatchPair { pattern: Pat { kind: PatKind::Or { pats }, .. }, place }] =
+                &*candidate.match_pairs
+            {
+                candidate.subcandidates = self.create_or_subcandidates(candidate, place, pats);
+                candidate.match_pairs.clear();
+                true
+            } else {
+                false
+            };
+
+        // Move or-patterns to the end, because they can result in us
+        // creating additional candidates, so we want to test them as
+        // late as possible.
+        candidate.match_pairs.sort_by_key(|pair| matches!(pair.pattern.kind, PatKind::Or { .. }));
+        debug!(simplified = ?candidate, "simplify_candidate");
+
+        did_expand_or
     }
 
     /// Given `candidate` that has a single or-pattern for its match-pairs,
@@ -271,7 +270,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             PatKind::Variant { adt_def, args, variant_index, ref subpatterns } => {
                 let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
                     i == variant_index || {
-                        self.tcx.features().exhaustive_patterns
+                        (self.tcx.features().exhaustive_patterns
+                            || self.tcx.features().min_exhaustive_patterns)
                             && !v
                                 .inhabited_predicate(self.tcx, adt_def)
                                 .instantiate(self.tcx, args)
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 9a2f2ceced1..2b1a9fef360 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -666,7 +666,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
                     let yield_ty = args.yield_ty();
                     let return_ty = args.return_ty();
                     (
-                        vec![closure_ty, args.resume_ty()],
+                        vec![closure_ty, resume_ty],
                         return_ty,
                         Some(Box::new(CoroutineInfo::initial(
                             tcx.coroutine_kind(def_id).unwrap(),
@@ -675,8 +675,39 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
                         ))),
                     )
                 }
-                _ => {
-                    span_bug!(span, "expected type of closure body to be a closure or coroutine");
+                ty::CoroutineClosure(did, args) => {
+                    let args = args.as_coroutine_closure();
+                    let sig = tcx.liberate_late_bound_regions(
+                        def_id.to_def_id(),
+                        args.coroutine_closure_sig(),
+                    );
+                    let self_ty = match args.kind() {
+                        ty::ClosureKind::Fn => {
+                            Ty::new_imm_ref(tcx, tcx.lifetimes.re_erased, closure_ty)
+                        }
+                        ty::ClosureKind::FnMut => {
+                            Ty::new_mut_ref(tcx, tcx.lifetimes.re_erased, closure_ty)
+                        }
+                        ty::ClosureKind::FnOnce => closure_ty,
+                    };
+                    (
+                        [self_ty].into_iter().chain(sig.tupled_inputs_ty.tuple_fields()).collect(),
+                        sig.to_coroutine(
+                            tcx,
+                            args.parent_args(),
+                            args.kind_ty(),
+                            tcx.coroutine_for_closure(*did),
+                            Ty::new_error(tcx, guar),
+                        ),
+                        None,
+                    )
+                }
+                ty::Error(_) => (vec![closure_ty, closure_ty], closure_ty, None),
+                kind => {
+                    span_bug!(
+                        span,
+                        "expected type of closure body to be a closure or coroutine, got {kind:?}"
+                    );
                 }
             }
         }
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index 6827797df37..2d366948771 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -655,7 +655,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let drops = if destination.is_some() {
             &mut self.scopes.breakable_scopes[break_index].break_drops
         } else {
-            self.scopes.breakable_scopes[break_index].continue_drops.as_mut().unwrap()
+            let Some(drops) = self.scopes.breakable_scopes[break_index].continue_drops.as_mut()
+            else {
+                self.tcx.dcx().span_delayed_bug(
+                    source_info.span,
+                    "unlabelled `continue` within labelled block",
+                );
+                self.cfg.terminate(block, source_info, TerminatorKind::Unreachable);
+
+                return self.cfg.start_new_block().unit();
+            };
+            drops
         };
 
         let drop_idx = self.scopes.scopes[scope_index + 1..]
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 232b6033946..0bc5fe6ef89 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -2,7 +2,7 @@ use crate::fluent_generated as fluent;
 use rustc_errors::DiagnosticArgValue;
 use rustc_errors::{
     codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
-    IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessage,
+    IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessageOp,
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::{self, Ty};
@@ -420,10 +420,7 @@ pub struct UnsafeNotInheritedLintNote {
 }
 
 impl AddToDiagnostic for UnsafeNotInheritedLintNote {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         diag.span_note(self.signature_span, fluent::mir_build_unsafe_fn_safe_body);
         let body_start = self.body_span.shrink_to_lo();
         let body_end = self.body_span.shrink_to_hi();
@@ -866,10 +863,7 @@ pub struct Variant {
 }
 
 impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         diag.arg("ty", self.ty);
         let mut spans = MultiSpan::from(self.adt_def_span);
 
diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs
index a3d88b12696..43e44b47e3f 100644
--- a/compiler/rustc_mir_build/src/lib.rs
+++ b/compiler/rustc_mir_build/src/lib.rs
@@ -1,6 +1,9 @@
 //! Construction of MIR from HIR.
 //!
 //! This crate also contains the match exhaustiveness and usefulness checking.
+
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![feature(assert_matches)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
diff --git a/compiler/rustc_mir_build/src/lints.rs b/compiler/rustc_mir_build/src/lints.rs
index 337493d15de..508936be29d 100644
--- a/compiler/rustc_mir_build/src/lints.rs
+++ b/compiler/rustc_mir_build/src/lints.rs
@@ -72,15 +72,14 @@ pub fn check_drop_recursion<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
             tcx.impl_of_method(def_id.to_def_id()).and_then(|def_id| tcx.impl_trait_ref(def_id))
         && let Some(drop_trait) = tcx.lang_items().drop_trait()
         && drop_trait == trait_ref.instantiate_identity().def_id
+        // avoid erroneous `Drop` impls from causing ICEs below
+        && let sig = tcx.fn_sig(def_id).instantiate_identity()
+        && sig.inputs().skip_binder().len() == 1
     {
         // It was. Now figure out for what type `Drop` is implemented and then
         // check for recursion.
-        if let ty::Ref(_, dropped_ty, _) = tcx
-            .liberate_late_bound_regions(
-                def_id.to_def_id(),
-                tcx.fn_sig(def_id).instantiate_identity().input(0),
-            )
-            .kind()
+        if let ty::Ref(_, dropped_ty, _) =
+            tcx.liberate_late_bound_regions(def_id.to_def_id(), sig.input(0)).kind()
         {
             check_recursion(tcx, body, RecursiveDrop { drop_for: *dropped_ty });
         }
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 caf7f4227db..692f4511bb8 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -291,7 +291,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
                 err = err.and(check_never_pattern(cx, pat));
             });
             err?;
-            Ok(cx.pattern_arena.alloc(cx.lower_pat(pat)))
+            Ok(self.pattern_arena.alloc(cx.lower_pat(pat)))
         }
     }
 
@@ -388,7 +388,6 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
             typeck_results: self.typeck_results,
             param_env: self.param_env,
             module: self.tcx.parent_module(self.lint_level).to_def_id(),
-            pattern_arena: self.pattern_arena,
             dropless_arena: self.dropless_arena,
             match_lint_level: self.lint_level,
             whole_match_span,
@@ -666,7 +665,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
 
         // Emit an extra note if the first uncovered witness would be uninhabited
         // if we disregard visibility.
-        let witness_1_is_privately_uninhabited = if self.tcx.features().exhaustive_patterns
+        let witness_1_is_privately_uninhabited = if (self.tcx.features().exhaustive_patterns
+            || self.tcx.features().min_exhaustive_patterns)
             && let Some(witness_1) = witnesses.get(0)
             && let ty::Adt(adt, args) = witness_1.ty().kind()
             && adt.is_enum()
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 9d3a9bf6745..18a00724c3d 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -1,6 +1,5 @@
 use rustc_apfloat::Float;
 use rustc_hir as hir;
-use rustc_hir::def_id::DefId;
 use rustc_index::Idx;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::Obligation;
@@ -17,8 +16,8 @@ use std::cell::Cell;
 
 use super::PatCtxt;
 use crate::errors::{
-    IndirectStructuralMatch, InvalidPattern, NaNPattern, NonPartialEqMatch,
-    NontrivialStructuralMatch, PointerPattern, TypeNotStructural, UnionPattern, UnsizedPattern,
+    IndirectStructuralMatch, InvalidPattern, NaNPattern, NonPartialEqMatch, PointerPattern,
+    TypeNotStructural, UnionPattern, UnsizedPattern,
 };
 
 impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
@@ -33,11 +32,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         cv: mir::Const<'tcx>,
         id: hir::HirId,
         span: Span,
-        check_body_for_struct_match_violation: Option<DefId>,
     ) -> Box<Pat<'tcx>> {
         let infcx = self.tcx.infer_ctxt().build();
         let mut convert = ConstToPat::new(self, id, span, infcx);
-        convert.to_pat(cv, check_body_for_struct_match_violation)
+        convert.to_pat(cv)
     }
 }
 
@@ -103,11 +101,7 @@ impl<'tcx> ConstToPat<'tcx> {
         ty.is_structural_eq_shallow(self.infcx.tcx)
     }
 
-    fn to_pat(
-        &mut self,
-        cv: mir::Const<'tcx>,
-        check_body_for_struct_match_violation: Option<DefId>,
-    ) -> Box<Pat<'tcx>> {
+    fn to_pat(&mut self, cv: mir::Const<'tcx>) -> Box<Pat<'tcx>> {
         trace!(self.treat_byte_string_as_slice);
         // This method is just a wrapper handling a validity check; the heavy lifting is
         // performed by the recursive `recur` method, which is not meant to be
@@ -116,14 +110,6 @@ impl<'tcx> ConstToPat<'tcx> {
         // once indirect_structural_match is a full fledged error, this
         // level of indirection can be eliminated
 
-        let mir_structural_match_violation = check_body_for_struct_match_violation.map(|def_id| {
-            // `mir_const_qualif` must be called with the `DefId` of the item where the const is
-            // defined, not where it is declared. The difference is significant for associated
-            // constants.
-            self.tcx().mir_const_qualif(def_id).custom_eq
-        });
-        debug!(?check_body_for_struct_match_violation, ?mir_structural_match_violation);
-
         let have_valtree =
             matches!(cv, mir::Const::Ty(c) if matches!(c.kind(), ty::ConstKind::Value(_)));
         let inlined_const_as_pat = match cv {
@@ -137,15 +123,15 @@ impl<'tcx> ConstToPat<'tcx> {
                 | ty::ConstKind::Expr(_) => {
                     span_bug!(self.span, "unexpected const in `to_pat`: {:?}", c.kind())
                 }
-                ty::ConstKind::Value(valtree) => self
-                    .recur(valtree, cv.ty(), mir_structural_match_violation.unwrap_or(false))
-                    .unwrap_or_else(|_: FallbackToOpaqueConst| {
+                ty::ConstKind::Value(valtree) => {
+                    self.recur(valtree, cv.ty()).unwrap_or_else(|_: FallbackToOpaqueConst| {
                         Box::new(Pat {
                             span: self.span,
                             ty: cv.ty(),
                             kind: PatKind::Constant { value: cv },
                         })
-                    }),
+                    })
+                }
             },
             mir::Const::Unevaluated(_, _) => {
                 span_bug!(self.span, "unevaluated const in `to_pat`: {cv:?}")
@@ -160,7 +146,12 @@ impl<'tcx> ConstToPat<'tcx> {
         if self.saw_const_match_error.get().is_none() {
             // If we were able to successfully convert the const to some pat (possibly with some
             // lints, but no errors), double-check that all types in the const implement
-            // `Structural` and `PartialEq`.
+            // `PartialEq`. Even if we have a valtree, we may have found something
+            // in there with non-structural-equality, meaning we match using `PartialEq`
+            // and we hence have to check that that impl exists.
+            // This is all messy but not worth cleaning up: at some point we'll emit
+            // a hard error when we don't have a valtree or when we find something in
+            // the valtree that is not structural; then this can all be made a lot simpler.
 
             let structural =
                 traits::search_for_structural_match_violation(self.span, self.tcx(), cv.ty());
@@ -170,19 +161,12 @@ impl<'tcx> ConstToPat<'tcx> {
                 structural
             );
 
-            // This can occur because const qualification treats all associated constants as
-            // opaque, whereas `search_for_structural_match_violation` tries to monomorphize them
-            // before it runs.
-            //
-            // FIXME(#73448): Find a way to bring const qualification into parity with
-            // `search_for_structural_match_violation`.
-            if structural.is_none() && mir_structural_match_violation.unwrap_or(false) {
-                warn!("MIR const-checker found novel structural match violation. See #73448.");
-                return inlined_const_as_pat;
-            }
-
             if let Some(non_sm_ty) = structural {
                 if !self.type_has_partial_eq_impl(cv.ty()) {
+                    // This is reachable and important even if we have a valtree: there might be
+                    // non-structural things in a valtree, in which case we fall back to `PartialEq`
+                    // comparison, in which case we better make sure the trait is implemented for
+                    // each inner type (and not just for the surrounding type).
                     let e = if let ty::Adt(def, ..) = non_sm_ty.kind() {
                         if def.is_union() {
                             let err = UnionPattern { span: self.span };
@@ -201,35 +185,18 @@ impl<'tcx> ConstToPat<'tcx> {
                     // We errored. Signal that in the pattern, so that follow up errors can be silenced.
                     let kind = PatKind::Error(e);
                     return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
-                } else if let ty::Adt(..) = cv.ty().kind()
-                    && matches!(cv, mir::Const::Val(..))
-                {
-                    // This branch is only entered when the current `cv` is `mir::Const::Val`.
-                    // This is because `mir::Const::ty` has already been handled by `Self::recur`
-                    // and the invalid types may be ignored.
+                } else if !have_valtree {
+                    // Not being structural prevented us from constructing a valtree,
+                    // so this is definitely a case we want to reject.
                     let err = TypeNotStructural { span: self.span, non_sm_ty };
                     let e = self.tcx().dcx().emit_err(err);
                     let kind = PatKind::Error(e);
                     return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
-                } else if !self.saw_const_match_lint.get() {
-                    if let Some(mir_structural_match_violation) = mir_structural_match_violation {
-                        match non_sm_ty.kind() {
-                            ty::Adt(..) if mir_structural_match_violation => {
-                                self.tcx().emit_node_span_lint(
-                                    lint::builtin::INDIRECT_STRUCTURAL_MATCH,
-                                    self.id,
-                                    self.span,
-                                    IndirectStructuralMatch { non_sm_ty },
-                                );
-                            }
-                            _ => {
-                                debug!(
-                                    "`search_for_structural_match_violation` found one, but `CustomEq` was \
-                                  not in the qualifs for that `const`"
-                                );
-                            }
-                        }
-                    }
+                } else {
+                    // This could be a violation in an inactive enum variant.
+                    // Since we have a valtree, we trust that we have traversed the full valtree and
+                    // complained about structural match violations there, so we don't
+                    // have to check anything any more.
                 }
             } else if !have_valtree && !self.saw_const_match_lint.get() {
                 // The only way valtree construction can fail without the structural match
@@ -299,7 +266,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 let field = FieldIdx::new(idx);
                 // Patterns can only use monomorphic types.
                 let ty = self.tcx().normalize_erasing_regions(self.param_env, ty);
-                Ok(FieldPat { field, pattern: self.recur(val, ty, false)? })
+                Ok(FieldPat { field, pattern: self.recur(val, ty)? })
             })
             .collect()
     }
@@ -310,7 +277,6 @@ impl<'tcx> ConstToPat<'tcx> {
         &self,
         cv: ValTree<'tcx>,
         ty: Ty<'tcx>,
-        mir_structural_match_violation: bool,
     ) -> Result<Box<Pat<'tcx>>, FallbackToOpaqueConst> {
         let id = self.id;
         let span = self.span;
@@ -395,7 +361,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 prefix: cv
                     .unwrap_branch()
                     .iter()
-                    .map(|val| self.recur(*val, *elem_ty, false))
+                    .map(|val| self.recur(*val, *elem_ty))
                     .collect::<Result<_, _>>()?,
                 slice: None,
                 suffix: Box::new([]),
@@ -404,7 +370,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 prefix: cv
                     .unwrap_branch()
                     .iter()
-                    .map(|val| self.recur(*val, *elem_ty, false))
+                    .map(|val| self.recur(*val, *elem_ty))
                     .collect::<Result<_, _>>()?,
                 slice: None,
                 suffix: Box::new([]),
@@ -471,7 +437,7 @@ impl<'tcx> ConstToPat<'tcx> {
                             _ => *pointee_ty,
                         };
                         // References have the same valtree representation as their pointee.
-                        let subpattern = self.recur(cv, pointee_ty, false)?;
+                        let subpattern = self.recur(cv, pointee_ty)?;
                         self.behind_reference.set(old);
                         PatKind::Deref { subpattern }
                     }
@@ -512,25 +478,6 @@ impl<'tcx> ConstToPat<'tcx> {
             }
         };
 
-        if self.saw_const_match_error.get().is_none()
-            && !self.saw_const_match_lint.get()
-            && mir_structural_match_violation
-            // FIXME(#73448): Find a way to bring const qualification into parity with
-            // `search_for_structural_match_violation` and then remove this condition.
-
-            // Obtain the actual type that isn't annotated. If we just looked at `cv.ty` we
-            // could get `Option<NonStructEq>`, even though `Option` is annotated with derive.
-            && let Some(non_sm_ty) = traits::search_for_structural_match_violation(span, tcx, ty)
-        {
-            self.saw_const_match_lint.set(true);
-            tcx.emit_node_span_lint(
-                lint::builtin::NONTRIVIAL_STRUCTURAL_MATCH,
-                id,
-                span,
-                NontrivialStructuralMatch { non_sm_ty },
-            );
-        }
-
         Ok(Box::new(Pat { span, ty, kind }))
     }
 }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 2190ad14b55..1a5cf13e289 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -542,7 +542,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
 
         match const_value {
             Ok(const_) => {
-                let pattern = self.const_to_pat(const_, id, span, Some(instance.def_id()));
+                let pattern = self.const_to_pat(const_, id, span);
 
                 if !is_associated_const {
                     return pattern;
@@ -612,7 +612,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         };
         if let Some(lit_input) = lit_input {
             match tcx.at(expr.span).lit_to_const(lit_input) {
-                Ok(c) => return self.const_to_pat(Const::Ty(c), id, span, None).kind,
+                Ok(c) => return self.const_to_pat(Const::Ty(c), id, span).kind,
                 // If an error occurred, ignore that it's a literal
                 // and leave reporting the error up to const eval of
                 // the unevaluated constant below.
@@ -635,17 +635,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         if let Ok(Some(valtree)) =
             self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, Some(span))
         {
-            let subpattern = self.const_to_pat(
-                Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)),
-                id,
-                span,
-                None,
-            );
+            let subpattern =
+                self.const_to_pat(Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)), id, span);
             PatKind::InlineConstant { subpattern, def: def_id }
         } else {
             // If that fails, convert it to an opaque constant pattern.
             match tcx.const_eval_resolve(self.param_env, uneval, Some(span)) {
-                Ok(val) => self.const_to_pat(mir::Const::Val(val, ty), id, span, None).kind,
+                Ok(val) => self.const_to_pat(mir::Const::Val(val, ty), id, span).kind,
                 Err(ErrorHandled::TooGeneric(_)) => {
                     // If we land here it means the const can't be evaluated because it's `TooGeneric`.
                     let e = self.tcx.dcx().emit_err(ConstPatternDependsOnGenericParameter { span });
@@ -681,9 +677,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         let lit_input =
             LitToConstInput { lit: &lit.node, ty: self.typeck_results.expr_ty(expr), neg };
         match self.tcx.at(expr.span).lit_to_const(lit_input) {
-            Ok(constant) => {
-                self.const_to_pat(Const::Ty(constant), expr.hir_id, lit.span, None).kind
-            }
+            Ok(constant) => self.const_to_pat(Const::Ty(constant), expr.hir_id, lit.span).kind,
             Err(LitToConstError::Reported(e)) => PatKind::Error(e),
             Err(LitToConstError::TypeError) => bug!("lower_lit: had type error"),
         }
diff --git a/compiler/rustc_mir_dataflow/src/lib.rs b/compiler/rustc_mir_dataflow/src/lib.rs
index 23111cc3199..a4b58e5bfc1 100644
--- a/compiler/rustc_mir_dataflow/src/lib.rs
+++ b/compiler/rustc_mir_dataflow/src/lib.rs
@@ -4,8 +4,6 @@
 #![feature(let_chains)]
 #![feature(min_specialization)]
 #![feature(try_blocks)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 30dd915521c..80e0d0baf57 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -429,7 +429,10 @@ impl<'b, 'a, 'tcx, F: Fn(Ty<'tcx>) -> bool> Gatherer<'b, 'a, 'tcx, F> {
             | Rvalue::AddressOf(..)
             | Rvalue::Discriminant(..)
             | Rvalue::Len(..)
-            | Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {}
+            | Rvalue::NullaryOp(
+                NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..) | NullOp::DebugAssertions,
+                _,
+            ) => {}
         }
     }
 
diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
index 451d3be255f..ba70a4453d6 100644
--- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
+++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
@@ -41,6 +41,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
             ty::Closure(..) => Abi::RustCall,
             ty::CoroutineClosure(..) => Abi::RustCall,
             ty::Coroutine(..) => Abi::Rust,
+            ty::Error(_) => return,
             _ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty),
         };
         let body_can_unwind = layout::fn_can_unwind(tcx, Some(def_id), body_abi);
diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs
index f2448ee3d44..04d0a4f303f 100644
--- a/compiler/rustc_mir_transform/src/const_prop_lint.rs
+++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs
@@ -541,12 +541,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
     }
 
     #[instrument(level = "trace", skip(self), ret)]
-    fn eval_rvalue(
-        &mut self,
-        rvalue: &Rvalue<'tcx>,
-        location: Location,
-        dest: &Place<'tcx>,
-    ) -> Option<()> {
+    fn eval_rvalue(&mut self, rvalue: &Rvalue<'tcx>, dest: &Place<'tcx>) -> Option<()> {
         if !dest.projection.is_empty() {
             return None;
         }
@@ -639,6 +634,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     NullOp::OffsetOf(fields) => {
                         op_layout.offset_of_subfield(self, fields.iter()).bytes()
                     }
+                    NullOp::DebugAssertions => return None,
                 };
                 ImmTy::from_scalar(Scalar::from_target_usize(val, self), layout).into()
             }
@@ -734,7 +730,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
             _ if place.is_indirect() => {}
             ConstPropMode::NoPropagation => self.ensure_not_propagated(place.local),
             ConstPropMode::OnlyInsideOwnBlock | ConstPropMode::FullConstProp => {
-                if self.eval_rvalue(rvalue, location, place).is_none() {
+                if self.eval_rvalue(rvalue, place).is_none() {
                     // Const prop failed, so erase the destination, ensuring that whatever happens
                     // from here on, does not know about the previous value.
                     // This is important in case we have
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index fcd4715b9e8..e40f4520671 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir as hir;
 use rustc_middle::mir::visit::MutVisitor;
 use rustc_middle::mir::{self, dump_mir, MirPass};
-use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt};
+use rustc_middle::ty::{self, InstanceDef, Ty, TyCtxt, TypeVisitableExt};
 use rustc_target::abi::FieldIdx;
 
 pub struct ByMoveBody;
@@ -23,7 +23,10 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
             return;
         };
         let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
-        let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!() };
+        if coroutine_ty.references_error() {
+            return;
+        }
+        let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") };
 
         let coroutine_kind = args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap();
         if coroutine_kind == ty::ClosureKind::FnOnce {
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index 8c11dea5d4e..9a1d8bae6b4 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -1,4 +1,5 @@
-use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::captures::Captures;
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph::WithNumNodes;
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
@@ -38,19 +39,27 @@ impl Debug for BcbCounter {
     }
 }
 
+#[derive(Debug)]
+pub(super) enum CounterIncrementSite {
+    Node { bcb: BasicCoverageBlock },
+    Edge { from_bcb: BasicCoverageBlock, to_bcb: BasicCoverageBlock },
+}
+
 /// Generates and stores coverage counter and coverage expression information
 /// associated with nodes/edges in the BCB graph.
 pub(super) struct CoverageCounters {
-    next_counter_id: CounterId,
+    /// List of places where a counter-increment statement should be injected
+    /// into MIR, each with its corresponding counter ID.
+    counter_increment_sites: IndexVec<CounterId, CounterIncrementSite>,
 
     /// Coverage counters/expressions that are associated with individual BCBs.
     bcb_counters: IndexVec<BasicCoverageBlock, Option<BcbCounter>>,
     /// Coverage counters/expressions that are associated with the control-flow
     /// edge between two BCBs.
     ///
-    /// The iteration order of this map can affect the precise contents of MIR,
-    /// so we use `FxIndexMap` to avoid query stability hazards.
-    bcb_edge_counters: FxIndexMap<(BasicCoverageBlock, BasicCoverageBlock), BcbCounter>,
+    /// We currently don't iterate over this map, but if we do in the future,
+    /// switch it back to `FxIndexMap` to avoid query stability hazards.
+    bcb_edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), BcbCounter>,
     /// Tracks which BCBs have a counter associated with some incoming edge.
     /// Only used by assertions, to verify that BCBs with incoming edge
     /// counters do not have their own physical counters (expressions are allowed).
@@ -71,9 +80,9 @@ impl CoverageCounters {
         let num_bcbs = basic_coverage_blocks.num_nodes();
 
         let mut this = Self {
-            next_counter_id: CounterId::START,
+            counter_increment_sites: IndexVec::new(),
             bcb_counters: IndexVec::from_elem_n(None, num_bcbs),
-            bcb_edge_counters: FxIndexMap::default(),
+            bcb_edge_counters: FxHashMap::default(),
             bcb_has_incoming_edge_counters: BitSet::new_empty(num_bcbs),
             expressions: IndexVec::new(),
         };
@@ -84,8 +93,8 @@ impl CoverageCounters {
         this
     }
 
-    fn make_counter(&mut self) -> BcbCounter {
-        let id = self.next_counter();
+    fn make_counter(&mut self, site: CounterIncrementSite) -> BcbCounter {
+        let id = self.counter_increment_sites.push(site);
         BcbCounter::Counter { id }
     }
 
@@ -103,15 +112,8 @@ impl CoverageCounters {
         self.make_expression(lhs, Op::Add, rhs)
     }
 
-    /// Counter IDs start from one and go up.
-    fn next_counter(&mut self) -> CounterId {
-        let next = self.next_counter_id;
-        self.next_counter_id = self.next_counter_id + 1;
-        next
-    }
-
     pub(super) fn num_counters(&self) -> usize {
-        self.next_counter_id.as_usize()
+        self.counter_increment_sites.len()
     }
 
     #[cfg(test)]
@@ -171,22 +173,26 @@ impl CoverageCounters {
         self.bcb_counters[bcb]
     }
 
-    pub(super) fn bcb_node_counters(
+    /// Returns an iterator over all the nodes/edges in the coverage graph that
+    /// should have a counter-increment statement injected into MIR, along with
+    /// each site's corresponding counter ID.
+    pub(super) fn counter_increment_sites(
         &self,
-    ) -> impl Iterator<Item = (BasicCoverageBlock, &BcbCounter)> {
-        self.bcb_counters
-            .iter_enumerated()
-            .filter_map(|(bcb, counter_kind)| Some((bcb, counter_kind.as_ref()?)))
+    ) -> impl Iterator<Item = (CounterId, &CounterIncrementSite)> {
+        self.counter_increment_sites.iter_enumerated()
     }
 
-    /// For each edge in the BCB graph that has an associated counter, yields
-    /// that edge's *from* and *to* nodes, and its counter.
-    pub(super) fn bcb_edge_counters(
+    /// Returns an iterator over the subset of BCB nodes that have been associated
+    /// with a counter *expression*, along with the ID of that expression.
+    pub(super) fn bcb_nodes_with_coverage_expressions(
         &self,
-    ) -> impl Iterator<Item = (BasicCoverageBlock, BasicCoverageBlock, &BcbCounter)> {
-        self.bcb_edge_counters
-            .iter()
-            .map(|(&(from_bcb, to_bcb), counter_kind)| (from_bcb, to_bcb, counter_kind))
+    ) -> impl Iterator<Item = (BasicCoverageBlock, ExpressionId)> + Captures<'_> {
+        self.bcb_counters.iter_enumerated().filter_map(|(bcb, &counter_kind)| match counter_kind {
+            // Yield the BCB along with its associated expression ID.
+            Some(BcbCounter::Expression { id }) => Some((bcb, id)),
+            // This BCB is associated with a counter or nothing, so skip it.
+            Some(BcbCounter::Counter { .. }) | None => None,
+        })
     }
 
     pub(super) fn into_expressions(self) -> IndexVec<ExpressionId, Expression> {
@@ -339,7 +345,8 @@ impl<'a> MakeBcbCounters<'a> {
         // program results in a tight infinite loop, but it should still compile.
         let one_path_to_target = !self.basic_coverage_blocks.bcb_has_multiple_in_edges(bcb);
         if one_path_to_target || self.bcb_predecessors(bcb).contains(&bcb) {
-            let counter_kind = self.coverage_counters.make_counter();
+            let counter_kind =
+                self.coverage_counters.make_counter(CounterIncrementSite::Node { bcb });
             if one_path_to_target {
                 debug!("{bcb:?} gets a new counter: {counter_kind:?}");
             } else {
@@ -401,7 +408,8 @@ impl<'a> MakeBcbCounters<'a> {
         }
 
         // Make a new counter to count this edge.
-        let counter_kind = self.coverage_counters.make_counter();
+        let counter_kind =
+            self.coverage_counters.make_counter(CounterIncrementSite::Edge { from_bcb, to_bcb });
         debug!("Edge {from_bcb:?}->{to_bcb:?} gets a new counter: {counter_kind:?}");
         self.coverage_counters.set_bcb_edge_counter(from_bcb, to_bcb, counter_kind)
     }
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 3aa41250fd3..4c5be0a3f4b 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -7,7 +7,7 @@ mod spans;
 #[cfg(test)]
 mod tests;
 
-use self::counters::{BcbCounter, CoverageCounters};
+use self::counters::{CounterIncrementSite, CoverageCounters};
 use self::graph::{BasicCoverageBlock, CoverageGraph};
 use self::spans::{BcbMapping, BcbMappingKind, CoverageSpans};
 
@@ -155,61 +155,52 @@ fn inject_coverage_statements<'tcx>(
     bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool,
     coverage_counters: &CoverageCounters,
 ) {
-    // Process the counters associated with BCB nodes.
-    for (bcb, counter_kind) in coverage_counters.bcb_node_counters() {
-        let do_inject = match counter_kind {
-            // Counter-increment statements always need to be injected.
-            BcbCounter::Counter { .. } => true,
-            // The only purpose of expression-used statements is to detect
-            // when a mapping is unreachable, so we only inject them for
-            // expressions with one or more mappings.
-            BcbCounter::Expression { .. } => bcb_has_coverage_spans(bcb),
-        };
-        if do_inject {
-            inject_statement(
-                mir_body,
-                make_mir_coverage_kind(counter_kind),
-                basic_coverage_blocks[bcb].leader_bb(),
-            );
-        }
-    }
-
-    // Process the counters associated with BCB edges.
-    for (from_bcb, to_bcb, counter_kind) in coverage_counters.bcb_edge_counters() {
-        let do_inject = match counter_kind {
-            // Counter-increment statements always need to be injected.
-            BcbCounter::Counter { .. } => true,
-            // BCB-edge expressions never have mappings, so they never need
-            // a corresponding statement.
-            BcbCounter::Expression { .. } => false,
+    // Inject counter-increment statements into MIR.
+    for (id, counter_increment_site) in coverage_counters.counter_increment_sites() {
+        // Determine the block to inject a counter-increment statement into.
+        // For BCB nodes this is just their first block, but for edges we need
+        // to create a new block between the two BCBs, and inject into that.
+        let target_bb = match *counter_increment_site {
+            CounterIncrementSite::Node { bcb } => basic_coverage_blocks[bcb].leader_bb(),
+            CounterIncrementSite::Edge { from_bcb, to_bcb } => {
+                // Create a new block between the last block of `from_bcb` and
+                // the first block of `to_bcb`.
+                let from_bb = basic_coverage_blocks[from_bcb].last_bb();
+                let to_bb = basic_coverage_blocks[to_bcb].leader_bb();
+
+                let new_bb = inject_edge_counter_basic_block(mir_body, from_bb, to_bb);
+                debug!(
+                    "Edge {from_bcb:?} (last {from_bb:?}) -> {to_bcb:?} (leader {to_bb:?}) \
+                    requires a new MIR BasicBlock {new_bb:?} for counter increment {id:?}",
+                );
+                new_bb
+            }
         };
-        if !do_inject {
-            continue;
-        }
-
-        // We need to inject a coverage statement into a new BB between the
-        // last BB of `from_bcb` and the first BB of `to_bcb`.
-        let from_bb = basic_coverage_blocks[from_bcb].last_bb();
-        let to_bb = basic_coverage_blocks[to_bcb].leader_bb();
 
-        let new_bb = inject_edge_counter_basic_block(mir_body, from_bb, to_bb);
-        debug!(
-            "Edge {from_bcb:?} (last {from_bb:?}) -> {to_bcb:?} (leader {to_bb:?}) \
-                requires a new MIR BasicBlock {new_bb:?} for edge counter {counter_kind:?}",
-        );
-
-        // Inject a counter into the newly-created BB.
-        inject_statement(mir_body, make_mir_coverage_kind(counter_kind), new_bb);
+        inject_statement(mir_body, CoverageKind::CounterIncrement { id }, target_bb);
     }
-}
 
-fn make_mir_coverage_kind(counter_kind: &BcbCounter) -> CoverageKind {
-    match *counter_kind {
-        BcbCounter::Counter { id } => CoverageKind::CounterIncrement { id },
-        BcbCounter::Expression { id } => CoverageKind::ExpressionUsed { id },
+    // For each counter expression that is directly associated with at least one
+    // span, we inject an "expression-used" statement, so that coverage codegen
+    // can check whether the injected statement survived MIR optimization.
+    // (BCB edges can't have spans, so we only need to process BCB nodes here.)
+    //
+    // See the code in `rustc_codegen_llvm::coverageinfo::map_data` that deals
+    // with "expressions seen" and "zero terms".
+    for (bcb, expression_id) in coverage_counters
+        .bcb_nodes_with_coverage_expressions()
+        .filter(|&(bcb, _)| bcb_has_coverage_spans(bcb))
+    {
+        inject_statement(
+            mir_body,
+            CoverageKind::ExpressionUsed { id: expression_id },
+            basic_coverage_blocks[bcb].leader_bb(),
+        );
     }
 }
 
+/// Given two basic blocks that have a control-flow edge between them, creates
+/// and returns a new block that sits between those blocks.
 fn inject_edge_counter_basic_block(
     mir_body: &mut mir::Body<'_>,
     from_bb: BasicBlock,
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index b0d758bcbfe..663abbece85 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -59,6 +59,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
         ty::Closure(..) => Abi::RustCall,
         ty::CoroutineClosure(..) => Abi::RustCall,
         ty::Coroutine(..) => Abi::Rust,
+        ty::Error(_) => return false,
         _ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty),
     };
     let body_can_unwind = layout::fn_can_unwind(tcx, Some(def_id), body_abi);
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index f9798bc4e70..36c441a3945 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -489,6 +489,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                     NullOp::OffsetOf(fields) => {
                         layout.offset_of_subfield(&self.ecx, fields.iter()).bytes()
                     }
+                    NullOp::DebugAssertions => return None,
                 };
                 let usize_layout = self.ecx.layout_of(self.tcx.types.usize).unwrap();
                 let imm = ImmTy::try_from_uint(val, usize_layout)?;
@@ -1231,8 +1232,8 @@ impl<'tcx> MutVisitor<'tcx> for StorageRemover<'tcx> {
 
     fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _: Location) {
         if let Operand::Move(place) = *operand
-            && let Some(local) = place.as_local()
-            && self.reused_locals.contains(local)
+            && !place.is_indirect_first_projection()
+            && self.reused_locals.contains(place.local)
         {
             *operand = Operand::Copy(place);
         }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index e77553a03d6..be19bd8349e 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -1027,21 +1027,16 @@ fn try_instance_mir<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: InstanceDef<'tcx>,
 ) -> Result<&'tcx Body<'tcx>, &'static str> {
-    match instance {
-        ty::InstanceDef::DropGlue(_, Some(ty)) => match ty.kind() {
-            ty::Adt(def, args) => {
-                let fields = def.all_fields();
-                for field in fields {
-                    let field_ty = field.ty(tcx, args);
-                    if field_ty.has_param() && field_ty.has_projections() {
-                        return Err("cannot build drop shim for polymorphic type");
-                    }
-                }
-
-                Ok(tcx.instance_mir(instance))
+    if let ty::InstanceDef::DropGlue(_, Some(ty)) = instance
+        && let ty::Adt(def, args) = ty.kind()
+    {
+        let fields = def.all_fields();
+        for field in fields {
+            let field_ty = field.ty(tcx, args);
+            if field_ty.has_param() && field_ty.has_projections() {
+                return Err("cannot build drop shim for polymorphic type");
             }
-            _ => Ok(tcx.instance_mir(instance)),
-        },
-        _ => Ok(tcx.instance_mir(instance)),
+        }
     }
+    Ok(tcx.instance_mir(instance))
 }
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index a28db0defc9..f65eb5cbea9 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -2,10 +2,12 @@
 
 use crate::simplify::simplify_duplicate_switch_targets;
 use rustc_middle::mir::*;
+use rustc_middle::ty::layout;
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::{self, GenericArgsRef, ParamEnv, Ty, TyCtxt};
 use rustc_span::symbol::Symbol;
 use rustc_target::abi::FieldIdx;
+use rustc_target::spec::abi::Abi;
 
 pub struct InstSimplify;
 
@@ -38,6 +40,7 @@ impl<'tcx> MirPass<'tcx> for InstSimplify {
                 block.terminator.as_mut().unwrap(),
                 &mut block.statements,
             );
+            ctx.simplify_nounwind_call(block.terminator.as_mut().unwrap());
             simplify_duplicate_switch_targets(block.terminator.as_mut().unwrap());
         }
     }
@@ -252,6 +255,28 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
         terminator.kind = TerminatorKind::Goto { target: destination_block };
     }
 
+    fn simplify_nounwind_call(&self, terminator: &mut Terminator<'tcx>) {
+        let TerminatorKind::Call { func, unwind, .. } = &mut terminator.kind else {
+            return;
+        };
+
+        let Some((def_id, _)) = func.const_fn_def() else {
+            return;
+        };
+
+        let body_ty = self.tcx.type_of(def_id).skip_binder();
+        let body_abi = match body_ty.kind() {
+            ty::FnDef(..) => body_ty.fn_sig(self.tcx).abi(),
+            ty::Closure(..) => Abi::RustCall,
+            ty::Coroutine(..) => Abi::Rust,
+            _ => bug!("unexpected body ty: {:?}", body_ty),
+        };
+
+        if !layout::fn_can_unwind(self.tcx, Some(def_id), body_abi) {
+            *unwind = UnwindAction::Unreachable;
+        }
+    }
+
     fn simplify_intrinsic_assert(
         &self,
         terminator: &mut Terminator<'tcx>,
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 031515ea958..8e5d69605aa 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -1,5 +1,3 @@
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
 #![feature(const_type_name)]
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index 897375e0e16..f43b85173d4 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -21,6 +21,17 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                     sym::unreachable => {
                         terminator.kind = TerminatorKind::Unreachable;
                     }
+                    sym::debug_assertions => {
+                        let target = target.unwrap();
+                        block.statements.push(Statement {
+                            source_info: terminator.source_info,
+                            kind: StatementKind::Assign(Box::new((
+                                *destination,
+                                Rvalue::NullaryOp(NullOp::DebugAssertions, tcx.types.bool),
+                            ))),
+                        });
+                        terminator.kind = TerminatorKind::Goto { target };
+                    }
                     sym::forget => {
                         if let Some(target) = *target {
                             block.statements.push(Statement {
diff --git a/compiler/rustc_mir_transform/src/pass_manager.rs b/compiler/rustc_mir_transform/src/pass_manager.rs
index 605e1ad46d7..77478cc741d 100644
--- a/compiler/rustc_mir_transform/src/pass_manager.rs
+++ b/compiler/rustc_mir_transform/src/pass_manager.rs
@@ -8,18 +8,10 @@ use crate::{lint::lint_body, validate, MirPass};
 pub trait MirLint<'tcx> {
     fn name(&self) -> &'static str {
         // FIXME Simplify the implementation once more `str` methods get const-stable.
+        // See copypaste in `MirPass`
         const {
             let name = std::any::type_name::<Self>();
-            let bytes = name.as_bytes();
-            let mut i = bytes.len();
-            while i > 0 && bytes[i - 1] != b':' {
-                i = i - 1;
-            }
-            let (_, bytes) = bytes.split_at(i);
-            match std::str::from_utf8(bytes) {
-                Ok(name) => name,
-                Err(_) => name,
-            }
+            rustc_middle::util::common::c_name(name)
         }
     }
 
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index c00093ea27e..577b8f2080f 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -446,6 +446,7 @@ impl<'tcx> Validator<'_, 'tcx> {
                 NullOp::SizeOf => {}
                 NullOp::AlignOf => {}
                 NullOp::OffsetOf(_) => {}
+                NullOp::DebugAssertions => {}
             },
 
             Rvalue::ShallowInitBox(_, _) => return Err(Unpromotable),
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index b0cfa3568ca..7f36ae91f1a 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -1,8 +1,6 @@
 #![feature(array_windows)]
 #![feature(is_sorted)]
 #![allow(rustc::potential_query_instability)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 4f6ea66df7b..5cfebcaa5a5 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -156,7 +156,7 @@ where
         placed
     };
 
-    // Merge until we have at most `max_cgu_count` codegen units.
+    // Merge until we don't exceed the max CGU count.
     // `merge_codegen_units` is responsible for updating the CGU size
     // estimates.
     {
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 86a64d90deb..3c3a8d6fbb9 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -3,8 +3,8 @@ use std::borrow::Cow;
 use rustc_ast::token::Token;
 use rustc_ast::{Path, Visibility};
 use rustc_errors::{
-    codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, IntoDiagnostic, Level,
-    SubdiagnosticMessage,
+    codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
+    IntoDiagnostic, Level, SubdiagnosticMessageOp,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_session::errors::ExprParenthesesNeeded;
@@ -1475,10 +1475,7 @@ pub(crate) struct FnTraitMissingParen {
 }
 
 impl AddToDiagnostic for FnTraitMissingParen {
-    fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
-    where
-        F: Fn(&mut rustc_errors::Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren);
         let applicability = if self.machine_applicable {
             Applicability::MachineApplicable
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index d5fa1108687..5bd8bb72bd6 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -1,11 +1,13 @@
 //! The main parser interface.
 
+#![allow(internal_features)]
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(if_let_guard)]
 #![feature(iter_intersperse)]
 #![feature(let_chains)]
-#![allow(internal_features)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index e36a648e203..1a57474bac2 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2911,12 +2911,22 @@ impl<'a> Parser<'a> {
                 Ok(arm) => arms.push(arm),
                 Err(e) => {
                     // Recover by skipping to the end of the block.
-                    e.emit();
+                    let guar = e.emit();
                     self.recover_stmt();
                     let span = lo.to(self.token.span);
                     if self.token == token::CloseDelim(Delimiter::Brace) {
                         self.bump();
                     }
+                    // Always push at least one arm to make the match non-empty
+                    arms.push(Arm {
+                        attrs: Default::default(),
+                        pat: self.mk_pat(span, ast::PatKind::Err(guar)),
+                        guard: None,
+                        body: Some(self.mk_expr_err(span)),
+                        span,
+                        id: DUMMY_NODE_ID,
+                        is_placeholder: false,
+                    });
                     return Ok(self.mk_expr_with_attrs(
                         span,
                         ExprKind::Match(scrutinee, arms),
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index d76ee161da6..0b65f400825 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -9,8 +9,6 @@
     html_playground_url = "https://play.rust-lang.org/",
     test(attr(deny(warnings)))
 )]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 // We want to be able to build this crate with a stable compiler,
 // so no `#![feature]` attributes should be added.
 #![deny(unstable_features)]
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index d41cc724408..648ef9d51de 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -323,9 +323,6 @@ passes_ffi_const_invalid_target =
 passes_ffi_pure_invalid_target =
     `#[ffi_pure]` may only be used on foreign functions
 
-passes_ffi_returns_twice_invalid_target =
-    `#[ffi_returns_twice]` may only be used on foreign functions
-
 passes_has_incoherent_inherent_impl =
     `rustc_has_incoherent_inherent_impls` attribute should be applied to types or traits.
     .label = only adts, extern types and traits are supported
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 0f0027db01d..ec704dec352 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -192,7 +192,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 }
                 sym::ffi_pure => self.check_ffi_pure(attr.span, attrs, target),
                 sym::ffi_const => self.check_ffi_const(attr.span, target),
-                sym::ffi_returns_twice => self.check_ffi_returns_twice(attr.span, target),
                 sym::rustc_const_unstable
                 | sym::rustc_const_stable
                 | sym::unstable
@@ -828,10 +827,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             self.doc_attr_str_error(meta, "keyword");
             return false;
         }
-        match self.tcx.opt_hir_node(hir_id).and_then(|node| match node {
+        let item_kind = match self.tcx.hir_node(hir_id) {
             hir::Node::Item(item) => Some(&item.kind),
             _ => None,
-        }) {
+        };
+        match item_kind {
             Some(ItemKind::Mod(module)) => {
                 if !module.item_ids.is_empty() {
                     self.dcx().emit_err(errors::DocKeywordEmptyMod { span: meta.span() });
@@ -854,10 +854,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     }
 
     fn check_doc_fake_variadic(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool {
-        match self.tcx.opt_hir_node(hir_id).and_then(|node| match node {
+        let item_kind = match self.tcx.hir_node(hir_id) {
             hir::Node::Item(item) => Some(&item.kind),
             _ => None,
-        }) {
+        };
+        match item_kind {
             Some(ItemKind::Impl(i)) => {
                 let is_valid = matches!(&i.self_ty.kind, hir::TyKind::Tup([_]))
                     || if let hir::TyKind::BareFn(bare_fn_ty) = &i.self_ty.kind {
@@ -1309,15 +1310,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    fn check_ffi_returns_twice(&self, attr_span: Span, target: Target) -> bool {
-        if target == Target::ForeignFn {
-            true
-        } else {
-            self.dcx().emit_err(errors::FfiReturnsTwiceInvalidTarget { attr_span });
-            false
-        }
-    }
-
     /// Warns against some misuses of `#[must_use]`
     fn check_must_use(&self, hir_id: HirId, attr: &Attribute, target: Target) -> bool {
         if !matches!(
@@ -2231,8 +2223,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             }
         } else {
             // special case when `#[macro_export]` is applied to a macro 2.0
-            let (macro_definition, _) =
-                self.tcx.opt_hir_node(hir_id).unwrap().expect_item().expect_macro();
+            let (macro_definition, _) = self.tcx.hir_node(hir_id).expect_item().expect_macro();
             let is_decl_macro = !macro_definition.macro_rules;
 
             if is_decl_macro {
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index d19987cb33c..e11102c459e 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -4,6 +4,7 @@
 // is dead.
 
 use hir::def_id::{LocalDefIdMap, LocalDefIdSet};
+use hir::ItemKind;
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::MultiSpan;
 use rustc_hir as hir;
@@ -14,7 +15,7 @@ use rustc_hir::{Node, PatKind, TyKind};
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::middle::privacy::Level;
 use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt, Visibility};
 use rustc_session::lint;
 use rustc_session::lint::builtin::DEAD_CODE;
 use rustc_span::symbol::{sym, Symbol};
@@ -381,9 +382,46 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
                     intravisit::walk_item(self, item)
                 }
                 hir::ItemKind::ForeignMod { .. } => {}
+                hir::ItemKind::Trait(..) => {
+                    for impl_def_id in self.tcx.all_impls(item.owner_id.to_def_id()) {
+                        if let Some(local_def_id) = impl_def_id.as_local()
+                            && let ItemKind::Impl(impl_ref) =
+                                self.tcx.hir().expect_item(local_def_id).kind
+                        {
+                            // skip items
+                            // mark dependent traits live
+                            intravisit::walk_generics(self, impl_ref.generics);
+                            // mark dependent parameters live
+                            intravisit::walk_path(self, impl_ref.of_trait.unwrap().path);
+                        }
+                    }
+
+                    intravisit::walk_item(self, item)
+                }
                 _ => intravisit::walk_item(self, item),
             },
             Node::TraitItem(trait_item) => {
+                // mark corresponing ImplTerm live
+                let trait_item_id = trait_item.owner_id.to_def_id();
+                if let Some(trait_id) = self.tcx.trait_of_item(trait_item_id) {
+                    // mark the trait live
+                    self.check_def_id(trait_id);
+
+                    for impl_id in self.tcx.all_impls(trait_id) {
+                        if let Some(local_impl_id) = impl_id.as_local()
+                            && let ItemKind::Impl(impl_ref) =
+                                self.tcx.hir().expect_item(local_impl_id).kind
+                        {
+                            // mark self_ty live
+                            intravisit::walk_ty(self, impl_ref.self_ty);
+                            if let Some(&impl_item_id) =
+                                self.tcx.impl_item_implementor_ids(impl_id).get(&trait_item_id)
+                            {
+                                self.check_def_id(impl_item_id);
+                            }
+                        }
+                    }
+                }
                 intravisit::walk_trait_item(self, trait_item);
             }
             Node::ImplItem(impl_item) => {
@@ -636,10 +674,6 @@ fn check_item<'tcx>(
             }
         }
         DefKind::Impl { of_trait } => {
-            if of_trait {
-                worklist.push((id.owner_id.def_id, ComesFromAllowExpect::No));
-            }
-
             // get DefIds from another query
             let local_def_ids = tcx
                 .associated_item_def_ids(id.owner_id)
@@ -648,7 +682,11 @@ fn check_item<'tcx>(
 
             // And we access the Map here to get HirId from LocalDefId
             for id in local_def_ids {
-                if of_trait {
+                // for impl trait blocks, mark associate functions live if the trait is public
+                if of_trait
+                    && (!matches!(tcx.def_kind(id), DefKind::AssocFn)
+                        || tcx.local_visibility(id) == Visibility::Public)
+                {
                     worklist.push((id, ComesFromAllowExpect::No));
                 } else if let Some(comes_from_allow) = has_allow_dead_code_or_lang_attr(tcx, id) {
                     worklist.push((id, comes_from_allow));
@@ -679,7 +717,7 @@ fn check_trait_item(
     use hir::TraitItemKind::{Const, Fn};
     if matches!(tcx.def_kind(id.owner_id), DefKind::AssocConst | DefKind::AssocFn) {
         let trait_item = tcx.hir().trait_item(id);
-        if matches!(trait_item.kind, Const(_, Some(_)) | Fn(_, hir::TraitFn::Provided(_)))
+        if matches!(trait_item.kind, Const(_, Some(_)) | Fn(..))
             && let Some(comes_from_allow) =
                 has_allow_dead_code_or_lang_attr(tcx, trait_item.owner_id.def_id)
         {
@@ -948,7 +986,8 @@ impl<'tcx> DeadVisitor<'tcx> {
             | DefKind::TyAlias
             | DefKind::Enum
             | DefKind::Union
-            | DefKind::ForeignTy => self.warn_dead_code(def_id, "used"),
+            | DefKind::ForeignTy
+            | DefKind::Trait => self.warn_dead_code(def_id, "used"),
             DefKind::Struct => self.warn_dead_code(def_id, "constructed"),
             DefKind::Variant | DefKind::Field => bug!("should be handled specially"),
             _ => {}
@@ -973,18 +1012,33 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
     let module_items = tcx.hir_module_items(module);
 
     for item in module_items.items() {
-        if let hir::ItemKind::Impl(impl_item) = tcx.hir().item(item).kind {
-            let mut dead_items = Vec::new();
-            for item in impl_item.items {
-                let def_id = item.id.owner_id.def_id;
-                if !visitor.is_live_code(def_id) {
-                    let name = tcx.item_name(def_id.to_def_id());
-                    let level = visitor.def_lint_level(def_id);
+        let def_kind = tcx.def_kind(item.owner_id);
 
-                    dead_items.push(DeadItem { def_id, name, level })
+        let mut dead_codes = Vec::new();
+        // if we have diagnosed the trait, do not diagnose unused methods
+        if matches!(def_kind, DefKind::Impl { .. })
+            || (def_kind == DefKind::Trait && live_symbols.contains(&item.owner_id.def_id))
+        {
+            for &def_id in tcx.associated_item_def_ids(item.owner_id.def_id) {
+                // We have diagnosed unused methods in traits
+                if matches!(def_kind, DefKind::Impl { of_trait: true })
+                    && tcx.def_kind(def_id) == DefKind::AssocFn
+                    || def_kind == DefKind::Trait && tcx.def_kind(def_id) != DefKind::AssocFn
+                {
+                    continue;
+                }
+
+                if let Some(local_def_id) = def_id.as_local()
+                    && !visitor.is_live_code(local_def_id)
+                {
+                    let name = tcx.item_name(def_id);
+                    let level = visitor.def_lint_level(local_def_id);
+                    dead_codes.push(DeadItem { def_id: local_def_id, name, level });
                 }
             }
-            visitor.warn_multiple(item.owner_id.def_id, "used", dead_items, ReportOn::NamedField);
+        }
+        if !dead_codes.is_empty() {
+            visitor.warn_multiple(item.owner_id.def_id, "used", dead_codes, ReportOn::NamedField);
         }
 
         if !live_symbols.contains(&item.owner_id.def_id) {
@@ -997,7 +1051,6 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
             continue;
         }
 
-        let def_kind = tcx.def_kind(item.owner_id);
         if let DefKind::Struct | DefKind::Union | DefKind::Enum = def_kind {
             let adt = tcx.adt_def(item.owner_id);
             let mut dead_variants = Vec::new();
@@ -1044,8 +1097,6 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
     for foreign_item in module_items.foreign_items() {
         visitor.check_definition(foreign_item.owner_id.def_id);
     }
-
-    // We do not warn trait items.
 }
 
 pub(crate) fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 77bfe57e370..a732bdbca51 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -8,6 +8,7 @@ use rustc_ast::Label;
 use rustc_errors::{
     codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
     DiagnosticSymbolList, EmissionGuarantee, IntoDiagnostic, Level, MultiSpan,
+    SubdiagnosticMessageOp,
 };
 use rustc_hir::{self as hir, ExprKind, Target};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@@ -390,13 +391,6 @@ pub struct FfiConstInvalidTarget {
     pub attr_span: Span,
 }
 
-#[derive(Diagnostic)]
-#[diag(passes_ffi_returns_twice_invalid_target, code = E0724)]
-pub struct FfiReturnsTwiceInvalidTarget {
-    #[primary_span]
-    pub attr_span: Span,
-}
-
 #[derive(LintDiagnostic)]
 #[diag(passes_must_use_async)]
 pub struct MustUseAsync {
@@ -1739,7 +1733,7 @@ pub struct UnusedVariableTryPrefix {
 
 #[derive(Subdiagnostic)]
 pub enum UnusedVariableSugg {
-    #[multipart_suggestion(passes_suggestion, applicability = "machine-applicable")]
+    #[multipart_suggestion(passes_suggestion, applicability = "maybe-incorrect")]
     TryPrefixSugg {
         #[suggestion_part(code = "_{name}")]
         spans: Vec<Span>,
@@ -1760,7 +1754,7 @@ pub struct UnusedVariableStringInterp {
 }
 
 impl AddToDiagnostic for UnusedVariableStringInterp {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F) {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         diag.span_label(self.lit, crate::fluent_generated::passes_maybe_string_interpolation);
         diag.multipart_suggestion(
             crate::fluent_generated::passes_string_interpolation_only_works,
@@ -1778,7 +1772,7 @@ pub struct UnusedVarTryIgnore {
 }
 
 #[derive(Subdiagnostic)]
-#[multipart_suggestion(passes_suggestion, applicability = "machine-applicable")]
+#[multipart_suggestion(passes_suggestion, applicability = "maybe-incorrect")]
 pub struct UnusedVarTryIgnoreSugg {
     #[suggestion_part(code = "{name}: _")]
     pub shorthands: Vec<Span>,
diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs
index 862b76b1f60..064af5aec35 100644
--- a/compiler/rustc_passes/src/lib.rs
+++ b/compiler/rustc_passes/src/lib.rs
@@ -12,8 +12,6 @@
 #![feature(map_try_insert)]
 #![feature(min_specialization)]
 #![feature(try_blocks)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_middle;
diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs
index f7c382bcd7a..3a8dc377520 100644
--- a/compiler/rustc_passes/src/liveness.rs
+++ b/compiler/rustc_passes/src/liveness.rs
@@ -123,6 +123,7 @@ enum LiveNodeKind {
     VarDefNode(Span, HirId),
     ClosureNode,
     ExitNode,
+    ErrNode,
 }
 
 fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
@@ -133,6 +134,7 @@ fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
         VarDefNode(s, _) => format!("Var def node [{}]", sm.span_to_diagnostic_string(s)),
         ClosureNode => "Closure node".to_owned(),
         ExitNode => "Exit node".to_owned(),
+        ErrNode => "Error node".to_owned(),
     }
 }
 
@@ -967,10 +969,10 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
 
                 // Now that we know the label we're going to,
                 // look it up in the continue loop nodes table
-                self.cont_ln
-                    .get(&sc)
-                    .cloned()
-                    .unwrap_or_else(|| span_bug!(expr.span, "continue to unknown label"))
+                self.cont_ln.get(&sc).cloned().unwrap_or_else(|| {
+                    self.ir.tcx.dcx().span_delayed_bug(expr.span, "continue to unknown label");
+                    self.ir.add_live_node(ErrNode)
+                })
             }
 
             hir::ExprKind::Assign(ref l, ref r, _) => {
diff --git a/compiler/rustc_passes/src/loops.rs b/compiler/rustc_passes/src/loops.rs
index 0f8cc583b03..e10a22cdf31 100644
--- a/compiler/rustc_passes/src/loops.rs
+++ b/compiler/rustc_passes/src/loops.rs
@@ -134,7 +134,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
                     Err(hir::LoopIdError::UnresolvedLabel) => None,
                 };
 
-                if let Some(Node::Block(_)) = loop_id.and_then(|id| self.tcx.opt_hir_node(id)) {
+                if let Some(Node::Block(_)) = loop_id.map(|id| self.tcx.hir_node(id)) {
                     return;
                 }
 
@@ -186,7 +186,7 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
 
                 match destination.target_id {
                     Ok(loop_id) => {
-                        if let Node::Block(block) = self.tcx.opt_hir_node(loop_id).unwrap() {
+                        if let Node::Block(block) = self.tcx.hir_node(loop_id) {
                             self.sess.dcx().emit_err(ContinueLabeledBlock {
                                 span: e.span,
                                 block_span: block.span,
diff --git a/compiler/rustc_pattern_analysis/src/errors.rs b/compiler/rustc_pattern_analysis/src/errors.rs
index 88770b0c43b..2dffdc9846c 100644
--- a/compiler/rustc_pattern_analysis/src/errors.rs
+++ b/compiler/rustc_pattern_analysis/src/errors.rs
@@ -1,4 +1,4 @@
-use rustc_errors::{AddToDiagnostic, Diagnostic, SubdiagnosticMessage};
+use rustc_errors::{AddToDiagnostic, Diagnostic, SubdiagnosticMessageOp};
 use rustc_macros::{LintDiagnostic, Subdiagnostic};
 use rustc_middle::thir::Pat;
 use rustc_middle::ty::Ty;
@@ -23,7 +23,10 @@ impl<'tcx> Uncovered<'tcx> {
         span: Span,
         cx: &RustcMatchCheckCtxt<'p, 'tcx>,
         witnesses: Vec<WitnessPat<'p, 'tcx>>,
-    ) -> Self {
+    ) -> Self
+    where
+        'tcx: 'p,
+    {
         let witness_1 = cx.hoist_witness_pat(witnesses.get(0).unwrap());
         Self {
             span,
@@ -59,10 +62,7 @@ pub struct Overlap<'tcx> {
 }
 
 impl<'tcx> AddToDiagnostic for Overlap<'tcx> {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         let Overlap { span, range } = self;
 
         // FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
diff --git a/compiler/rustc_pattern_analysis/src/lib.rs b/compiler/rustc_pattern_analysis/src/lib.rs
index 8e16d4d7bf4..164dc36b679 100644
--- a/compiler/rustc_pattern_analysis/src/lib.rs
+++ b/compiler/rustc_pattern_analysis/src/lib.rs
@@ -1,5 +1,8 @@
 //! Analysis of patterns, notably match exhaustiveness checking.
 
+#![allow(rustc::untranslatable_diagnostic)]
+#![allow(rustc::diagnostic_outside_of_impl)]
+
 pub mod constructor;
 #[cfg(feature = "rustc")]
 pub mod errors;
@@ -119,7 +122,7 @@ pub trait TypeCx: Sized + fmt::Debug {
     /// `DeconstructedPat`. Only invoqued when `pat.ctor()` is `Struct | Variant(_) | UnionField`.
     fn write_variant_name(
         f: &mut fmt::Formatter<'_>,
-        pat: &crate::pat::DeconstructedPat<'_, Self>,
+        pat: &crate::pat::DeconstructedPat<Self>,
     ) -> fmt::Result;
 
     /// Raise a bug.
@@ -130,9 +133,9 @@ pub trait TypeCx: Sized + fmt::Debug {
     /// The default implementation does nothing.
     fn lint_overlapping_range_endpoints(
         &self,
-        _pat: &DeconstructedPat<'_, Self>,
+        _pat: &DeconstructedPat<Self>,
         _overlaps_on: IntRange,
-        _overlaps_with: &[&DeconstructedPat<'_, Self>],
+        _overlaps_with: &[&DeconstructedPat<Self>],
     ) {
     }
 }
@@ -140,7 +143,7 @@ pub trait TypeCx: Sized + fmt::Debug {
 /// The arm of a match expression.
 #[derive(Debug)]
 pub struct MatchArm<'p, Cx: TypeCx> {
-    pub pat: &'p DeconstructedPat<'p, Cx>,
+    pub pat: &'p DeconstructedPat<Cx>,
     pub has_guard: bool,
     pub arm_data: Cx::ArmData,
 }
diff --git a/compiler/rustc_pattern_analysis/src/lints.rs b/compiler/rustc_pattern_analysis/src/lints.rs
index 3f1497540d2..30e775733de 100644
--- a/compiler/rustc_pattern_analysis/src/lints.rs
+++ b/compiler/rustc_pattern_analysis/src/lints.rs
@@ -10,7 +10,7 @@ use crate::MatchArm;
 /// Traverse the patterns to collect any variants of a non_exhaustive enum that fail to be mentioned
 /// in a given column.
 #[instrument(level = "debug", skip(cx), ret)]
-fn collect_nonexhaustive_missing_variants<'a, 'p, 'tcx>(
+fn collect_nonexhaustive_missing_variants<'p, 'tcx>(
     cx: &RustcMatchCheckCtxt<'p, 'tcx>,
     column: &PatternColumn<'p, RustcMatchCheckCtxt<'p, 'tcx>>,
 ) -> Result<Vec<WitnessPat<'p, 'tcx>>, ErrorGuaranteed> {
diff --git a/compiler/rustc_pattern_analysis/src/pat.rs b/compiler/rustc_pattern_analysis/src/pat.rs
index d419ee46a8e..9bde23c7bf1 100644
--- a/compiler/rustc_pattern_analysis/src/pat.rs
+++ b/compiler/rustc_pattern_analysis/src/pat.rs
@@ -6,7 +6,7 @@ use std::fmt;
 use smallvec::{smallvec, SmallVec};
 
 use crate::constructor::{Constructor, Slice, SliceKind};
-use crate::{Captures, TypeCx};
+use crate::TypeCx;
 
 use self::Constructor::*;
 
@@ -21,9 +21,9 @@ use self::Constructor::*;
 /// This happens if a private or `non_exhaustive` field is uninhabited, because the code mustn't
 /// observe that it is uninhabited. In that case that field is not included in `fields`. Care must
 /// be taken when converting to/from `thir::Pat`.
-pub struct DeconstructedPat<'p, Cx: TypeCx> {
+pub struct DeconstructedPat<Cx: TypeCx> {
     ctor: Constructor<Cx>,
-    fields: &'p [DeconstructedPat<'p, Cx>],
+    fields: Vec<DeconstructedPat<Cx>>,
     ty: Cx::Ty,
     /// Extra data to store in a pattern. `None` if the pattern is a wildcard that does not
     /// correspond to a user-supplied pattern.
@@ -32,14 +32,20 @@ pub struct DeconstructedPat<'p, Cx: TypeCx> {
     useful: Cell<bool>,
 }
 
-impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
+impl<Cx: TypeCx> DeconstructedPat<Cx> {
     pub fn wildcard(ty: Cx::Ty) -> Self {
-        DeconstructedPat { ctor: Wildcard, fields: &[], ty, data: None, useful: Cell::new(false) }
+        DeconstructedPat {
+            ctor: Wildcard,
+            fields: Vec::new(),
+            ty,
+            data: None,
+            useful: Cell::new(false),
+        }
     }
 
     pub fn new(
         ctor: Constructor<Cx>,
-        fields: &'p [DeconstructedPat<'p, Cx>],
+        fields: Vec<DeconstructedPat<Cx>>,
         ty: Cx::Ty,
         data: Cx::PatData,
     ) -> Self {
@@ -62,17 +68,17 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
         self.data.as_ref()
     }
 
-    pub fn iter_fields(&self) -> impl Iterator<Item = &'p DeconstructedPat<'p, Cx>> + Captures<'_> {
+    pub fn iter_fields<'a>(&'a self) -> impl Iterator<Item = &'a DeconstructedPat<Cx>> {
         self.fields.iter()
     }
 
     /// Specialize this pattern with a constructor.
     /// `other_ctor` can be different from `self.ctor`, but must be covered by it.
-    pub(crate) fn specialize(
-        &self,
+    pub(crate) fn specialize<'a>(
+        &'a self,
         other_ctor: &Constructor<Cx>,
         ctor_arity: usize,
-    ) -> SmallVec<[PatOrWild<'p, Cx>; 2]> {
+    ) -> SmallVec<[PatOrWild<'a, Cx>; 2]> {
         let wildcard_sub_tys = || (0..ctor_arity).map(|_| PatOrWild::Wild).collect();
         match (&self.ctor, other_ctor) {
             // Return a wildcard for each field of `other_ctor`.
@@ -139,7 +145,7 @@ impl<'p, Cx: TypeCx> DeconstructedPat<'p, Cx> {
 }
 
 /// This is best effort and not good enough for a `Display` impl.
-impl<'p, Cx: TypeCx> fmt::Debug for DeconstructedPat<'p, Cx> {
+impl<Cx: TypeCx> fmt::Debug for DeconstructedPat<Cx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let pat = self;
         let mut first = true;
@@ -221,7 +227,7 @@ pub(crate) enum PatOrWild<'p, Cx: TypeCx> {
     /// A non-user-provided wildcard, created during specialization.
     Wild,
     /// A user-provided pattern.
-    Pat(&'p DeconstructedPat<'p, Cx>),
+    Pat(&'p DeconstructedPat<Cx>),
 }
 
 impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> {
@@ -236,7 +242,7 @@ impl<'p, Cx: TypeCx> Clone for PatOrWild<'p, Cx> {
 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>> {
+    pub(crate) fn as_pat(&self) -> Option<&'p DeconstructedPat<Cx>> {
         match self {
             PatOrWild::Wild => None,
             PatOrWild::Pat(pat) => Some(pat),
diff --git a/compiler/rustc_pattern_analysis/src/pat_column.rs b/compiler/rustc_pattern_analysis/src/pat_column.rs
index 0339818d61d..ce14fdc364f 100644
--- a/compiler/rustc_pattern_analysis/src/pat_column.rs
+++ b/compiler/rustc_pattern_analysis/src/pat_column.rs
@@ -13,7 +13,7 @@ use crate::{Captures, MatchArm, TypeCx};
 #[derive(Debug)]
 pub struct PatternColumn<'p, Cx: TypeCx> {
     /// This must not contain an or-pattern. `expand_and_push` takes care to expand them.
-    patterns: Vec<&'p DeconstructedPat<'p, Cx>>,
+    patterns: Vec<&'p DeconstructedPat<Cx>>,
 }
 
 impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
@@ -41,7 +41,7 @@ impl<'p, Cx: TypeCx> PatternColumn<'p, Cx> {
     pub fn head_ty(&self) -> Option<&Cx::Ty> {
         self.patterns.first().map(|pat| pat.ty())
     }
-    pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'p DeconstructedPat<'p, Cx>> + Captures<'a> {
+    pub fn iter<'a>(&'a self) -> impl Iterator<Item = &'p DeconstructedPat<Cx>> + Captures<'a> {
         self.patterns.iter().copied()
     }
 
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index b60f32f71c2..a8fe0cb6a1d 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -1,8 +1,7 @@
-use smallvec::SmallVec;
 use std::fmt;
 use std::iter::once;
 
-use rustc_arena::{DroplessArena, TypedArena};
+use rustc_arena::DroplessArena;
 use rustc_hir::def_id::DefId;
 use rustc_hir::HirId;
 use rustc_index::{Idx, IndexVec};
@@ -27,8 +26,7 @@ use crate::constructor::Constructor::*;
 pub type Constructor<'p, 'tcx> = crate::constructor::Constructor<RustcMatchCheckCtxt<'p, 'tcx>>;
 pub type ConstructorSet<'p, 'tcx> =
     crate::constructor::ConstructorSet<RustcMatchCheckCtxt<'p, 'tcx>>;
-pub type DeconstructedPat<'p, 'tcx> =
-    crate::pat::DeconstructedPat<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
+pub type DeconstructedPat<'p, 'tcx> = crate::pat::DeconstructedPat<RustcMatchCheckCtxt<'p, 'tcx>>;
 pub type MatchArm<'p, 'tcx> = crate::MatchArm<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
 pub type Usefulness<'p, 'tcx> = crate::usefulness::Usefulness<'p, RustcMatchCheckCtxt<'p, 'tcx>>;
 pub type UsefulnessReport<'p, 'tcx> =
@@ -64,7 +62,7 @@ impl<'tcx> RevealedTy<'tcx> {
 }
 
 #[derive(Clone)]
-pub struct RustcMatchCheckCtxt<'p, 'tcx> {
+pub struct RustcMatchCheckCtxt<'p, 'tcx: 'p> {
     pub tcx: TyCtxt<'tcx>,
     pub typeck_results: &'tcx ty::TypeckResults<'tcx>,
     /// The module in which the match occurs. This is necessary for
@@ -74,8 +72,6 @@ pub struct RustcMatchCheckCtxt<'p, 'tcx> {
     /// outside its module and should not be matchable with an empty match statement.
     pub module: DefId,
     pub param_env: ty::ParamEnv<'tcx>,
-    /// To allocate lowered patterns
-    pub pattern_arena: &'p TypedArena<DeconstructedPat<'p, 'tcx>>,
     /// To allocate the result of `self.ctor_sub_tys()`
     pub dropless_arena: &'p DroplessArena,
     /// Lint level at the match.
@@ -91,13 +87,13 @@ pub struct RustcMatchCheckCtxt<'p, 'tcx> {
     pub known_valid_scrutinee: bool,
 }
 
-impl<'p, 'tcx> fmt::Debug for RustcMatchCheckCtxt<'p, 'tcx> {
+impl<'p, 'tcx: 'p> fmt::Debug for RustcMatchCheckCtxt<'p, 'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("RustcMatchCheckCtxt").finish()
     }
 }
 
-impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
+impl<'p, 'tcx: 'p> RustcMatchCheckCtxt<'p, 'tcx> {
     /// Type inference occasionally gives us opaque types in places where corresponding patterns
     /// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited
     /// types, we use the corresponding concrete type if possible.
@@ -459,21 +455,20 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
     /// Note: the input patterns must have been lowered through
     /// `rustc_mir_build::thir::pattern::check_match::MatchVisitor::lower_pattern`.
     pub fn lower_pat(&self, pat: &'p Pat<'tcx>) -> DeconstructedPat<'p, 'tcx> {
-        let singleton = |pat| std::slice::from_ref(self.pattern_arena.alloc(pat));
         let cx = self;
         let ty = cx.reveal_opaque_ty(pat.ty);
         let ctor;
-        let fields: &[_];
+        let mut fields: Vec<_>;
         match &pat.kind {
             PatKind::AscribeUserType { subpattern, .. }
             | PatKind::InlineConstant { subpattern, .. } => return self.lower_pat(subpattern),
             PatKind::Binding { subpattern: Some(subpat), .. } => return self.lower_pat(subpat),
             PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
                 ctor = Wildcard;
-                fields = &[];
+                fields = vec![];
             }
             PatKind::Deref { subpattern } => {
-                fields = singleton(self.lower_pat(subpattern));
+                fields = vec![self.lower_pat(subpattern)];
                 ctor = match ty.kind() {
                     // This is a box pattern.
                     ty::Adt(adt, ..) if adt.is_box() => Struct,
@@ -485,15 +480,14 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                 match ty.kind() {
                     ty::Tuple(fs) => {
                         ctor = Struct;
-                        let mut wilds: SmallVec<[_; 2]> = fs
+                        fields = fs
                             .iter()
                             .map(|ty| cx.reveal_opaque_ty(ty))
                             .map(|ty| DeconstructedPat::wildcard(ty))
                             .collect();
                         for pat in subpatterns {
-                            wilds[pat.field.index()] = self.lower_pat(&pat.pattern);
+                            fields[pat.field.index()] = self.lower_pat(&pat.pattern);
                         }
-                        fields = cx.pattern_arena.alloc_from_iter(wilds);
                     }
                     ty::Adt(adt, args) if adt.is_box() => {
                         // The only legal patterns of type `Box` (outside `std`) are `_` and box
@@ -515,7 +509,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                             DeconstructedPat::wildcard(self.reveal_opaque_ty(args.type_at(0)))
                         };
                         ctor = Struct;
-                        fields = singleton(pat);
+                        fields = vec![pat];
                     }
                     ty::Adt(adt, _) => {
                         ctor = match pat.kind {
@@ -535,14 +529,12 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                                 ty
                             },
                         );
-                        let mut wilds: SmallVec<[_; 2]> =
-                            tys.map(|ty| DeconstructedPat::wildcard(ty)).collect();
+                        fields = tys.map(|ty| DeconstructedPat::wildcard(ty)).collect();
                         for pat in subpatterns {
                             if let Some(i) = field_id_to_id[pat.field.index()] {
-                                wilds[i] = self.lower_pat(&pat.pattern);
+                                fields[i] = self.lower_pat(&pat.pattern);
                             }
                         }
-                        fields = cx.pattern_arena.alloc_from_iter(wilds);
                     }
                     _ => bug!("pattern has unexpected type: pat: {:?}, ty: {:?}", pat, ty),
                 }
@@ -554,7 +546,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                             Some(b) => Bool(b),
                             None => Opaque(OpaqueId::new()),
                         };
-                        fields = &[];
+                        fields = vec![];
                     }
                     ty::Char | ty::Int(_) | ty::Uint(_) => {
                         ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
@@ -570,7 +562,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                             }
                             None => Opaque(OpaqueId::new()),
                         };
-                        fields = &[];
+                        fields = vec![];
                     }
                     ty::Float(ty::FloatTy::F32) => {
                         ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
@@ -581,7 +573,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                             }
                             None => Opaque(OpaqueId::new()),
                         };
-                        fields = &[];
+                        fields = vec![];
                     }
                     ty::Float(ty::FloatTy::F64) => {
                         ctor = match value.try_eval_bits(cx.tcx, cx.param_env) {
@@ -592,7 +584,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                             }
                             None => Opaque(OpaqueId::new()),
                         };
-                        fields = &[];
+                        fields = vec![];
                     }
                     ty::Ref(_, t, _) if t.is_str() => {
                         // We want a `&str` constant to behave like a `Deref` pattern, to be compatible
@@ -603,16 +595,16 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                         // subfields.
                         // Note: `t` is `str`, not `&str`.
                         let ty = self.reveal_opaque_ty(*t);
-                        let subpattern = DeconstructedPat::new(Str(*value), &[], ty, pat);
+                        let subpattern = DeconstructedPat::new(Str(*value), Vec::new(), ty, pat);
                         ctor = Ref;
-                        fields = singleton(subpattern)
+                        fields = vec![subpattern]
                     }
                     // All constants that can be structurally matched have already been expanded
                     // into the corresponding `Pat`s by `const_to_pat`. Constants that remain are
                     // opaque.
                     _ => {
                         ctor = Opaque(OpaqueId::new());
-                        fields = &[];
+                        fields = vec![];
                     }
                 }
             }
@@ -649,7 +641,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                     }
                     _ => bug!("invalid type for range pattern: {}", ty.inner()),
                 };
-                fields = &[];
+                fields = vec![];
             }
             PatKind::Array { prefix, slice, suffix } | PatKind::Slice { prefix, slice, suffix } => {
                 let array_len = match ty.kind() {
@@ -665,26 +657,23 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
                     SliceKind::FixedLen(prefix.len() + suffix.len())
                 };
                 ctor = Slice(Slice::new(array_len, kind));
-                fields = cx.pattern_arena.alloc_from_iter(
-                    prefix.iter().chain(suffix.iter()).map(|p| self.lower_pat(&*p)),
-                )
+                fields = prefix.iter().chain(suffix.iter()).map(|p| self.lower_pat(&*p)).collect();
             }
             PatKind::Or { .. } => {
                 ctor = Or;
                 let pats = expand_or_pat(pat);
-                fields =
-                    cx.pattern_arena.alloc_from_iter(pats.into_iter().map(|p| self.lower_pat(p)))
+                fields = pats.into_iter().map(|p| self.lower_pat(p)).collect();
             }
             PatKind::Never => {
                 // A never pattern matches all the values of its type (namely none). Moreover it
                 // must be compatible with other constructors, since we can use `!` on a type like
                 // `Result<!, !>` which has other constructors. Hence we lower it as a wildcard.
                 ctor = Wildcard;
-                fields = &[];
+                fields = vec![];
             }
             PatKind::Error(_) => {
                 ctor = Opaque(OpaqueId::new());
-                fields = &[];
+                fields = vec![];
             }
         }
         DeconstructedPat::new(ctor, fields, ty, pat)
@@ -855,7 +844,7 @@ impl<'p, 'tcx> RustcMatchCheckCtxt<'p, 'tcx> {
     }
 }
 
-impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
+impl<'p, 'tcx: 'p> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
     type Ty = RevealedTy<'tcx>;
     type Error = ErrorGuaranteed;
     type VariantIdx = VariantIdx;
@@ -889,7 +878,7 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
 
     fn write_variant_name(
         f: &mut fmt::Formatter<'_>,
-        pat: &crate::pat::DeconstructedPat<'_, Self>,
+        pat: &crate::pat::DeconstructedPat<Self>,
     ) -> fmt::Result {
         if let ty::Adt(adt, _) = pat.ty().kind() {
             if adt.is_box() {
@@ -908,9 +897,9 @@ impl<'p, 'tcx> TypeCx for RustcMatchCheckCtxt<'p, 'tcx> {
 
     fn lint_overlapping_range_endpoints(
         &self,
-        pat: &crate::pat::DeconstructedPat<'_, Self>,
+        pat: &crate::pat::DeconstructedPat<Self>,
         overlaps_on: IntRange,
-        overlaps_with: &[&crate::pat::DeconstructedPat<'_, Self>],
+        overlaps_with: &[&crate::pat::DeconstructedPat<Self>],
     ) {
         let overlap_as_pat = self.hoist_pat_range(&overlaps_on, *pat.ty());
         let overlaps: Vec<_> = overlaps_with
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index bbb68b353e4..80a807b4f27 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -767,12 +767,6 @@ impl<'a, Cx: TypeCx> PlaceCtxt<'a, Cx> {
     fn ctor_arity(&self, ctor: &Constructor<Cx>) -> usize {
         self.cx.ctor_arity(ctor, self.ty)
     }
-    fn ctor_sub_tys(
-        &'a self,
-        ctor: &'a Constructor<Cx>,
-    ) -> impl Iterator<Item = Cx::Ty> + ExactSizeIterator + Captures<'a> {
-        self.cx.ctor_sub_tys(ctor, self.ty)
-    }
     fn ctors_for_ty(&self) -> Result<ConstructorSet<Cx>, Cx::Error> {
         self.cx.ctors_for_ty(self.ty)
     }
@@ -828,6 +822,38 @@ impl fmt::Display for ValidityConstraint {
     }
 }
 
+/// Data about a place under investigation.
+struct PlaceInfo<Cx: TypeCx> {
+    /// The type of the place.
+    ty: Cx::Ty,
+    /// Whether the place is known to contain valid data.
+    validity: ValidityConstraint,
+    /// Whether the place is the scrutinee itself or a subplace of it.
+    is_scrutinee: bool,
+}
+
+impl<Cx: TypeCx> PlaceInfo<Cx> {
+    fn specialize<'a>(
+        &'a self,
+        cx: &'a Cx,
+        ctor: &'a Constructor<Cx>,
+    ) -> impl Iterator<Item = Self> + ExactSizeIterator + Captures<'a> {
+        let ctor_sub_tys = cx.ctor_sub_tys(ctor, &self.ty);
+        let ctor_sub_validity = self.validity.specialize(ctor);
+        ctor_sub_tys.map(move |ty| PlaceInfo {
+            ty,
+            validity: ctor_sub_validity,
+            is_scrutinee: false,
+        })
+    }
+}
+
+impl<Cx: TypeCx> Clone for PlaceInfo<Cx> {
+    fn clone(&self) -> Self {
+        Self { ty: self.ty.clone(), validity: self.validity, is_scrutinee: self.is_scrutinee }
+    }
+}
+
 /// Represents a pattern-tuple under investigation.
 // The three lifetimes are:
 // - 'p coming from the input
@@ -848,7 +874,7 @@ impl<'p, Cx: TypeCx> Clone for PatStack<'p, Cx> {
 }
 
 impl<'p, Cx: TypeCx> PatStack<'p, Cx> {
-    fn from_pattern(pat: &'p DeconstructedPat<'p, Cx>) -> Self {
+    fn from_pattern(pat: &'p DeconstructedPat<Cx>) -> Self {
         PatStack { pats: smallvec![PatOrWild::Pat(pat)], relevant: true }
     }
 
@@ -1001,10 +1027,9 @@ struct Matrix<'p, Cx: TypeCx> {
     /// each column must have the same type. Each column corresponds to a place within the
     /// scrutinee.
     rows: Vec<MatrixRow<'p, Cx>>,
-    /// Track the type of each column/place.
-    place_ty: SmallVec<[Cx::Ty; 2]>,
-    /// Track for each column/place whether it contains a known valid value.
-    place_validity: SmallVec<[ValidityConstraint; 2]>,
+    /// Track info about each place. Each place corresponds to a column in `rows`, and their types
+    /// must match.
+    place_info: SmallVec<[PlaceInfo<Cx>; 2]>,
     /// Track whether the virtual wildcard row used to compute exhaustiveness is relevant. See top
     /// of the file for details on relevancy.
     wildcard_row_is_relevant: bool,
@@ -1032,10 +1057,10 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
         scrut_ty: Cx::Ty,
         scrut_validity: ValidityConstraint,
     ) -> Self {
+        let place_info = PlaceInfo { ty: scrut_ty, validity: scrut_validity, is_scrutinee: true };
         let mut matrix = Matrix {
             rows: Vec::with_capacity(arms.len()),
-            place_ty: smallvec![scrut_ty],
-            place_validity: smallvec![scrut_validity],
+            place_info: smallvec![place_info],
             wildcard_row_is_relevant: true,
         };
         for (row_id, arm) in arms.iter().enumerate() {
@@ -1051,11 +1076,11 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
         matrix
     }
 
-    fn head_ty(&self) -> Option<&Cx::Ty> {
-        self.place_ty.first()
+    fn head_place(&self) -> Option<&PlaceInfo<Cx>> {
+        self.place_info.first()
     }
     fn column_count(&self) -> usize {
-        self.place_ty.len()
+        self.place_info.len()
     }
 
     fn rows(
@@ -1083,18 +1108,13 @@ impl<'p, Cx: TypeCx> Matrix<'p, Cx> {
         ctor: &Constructor<Cx>,
         ctor_is_relevant: bool,
     ) -> Result<Matrix<'p, Cx>, Cx::Error> {
-        let ctor_sub_tys = pcx.ctor_sub_tys(ctor);
-        let arity = ctor_sub_tys.len();
-        let specialized_place_ty = ctor_sub_tys.chain(self.place_ty[1..].iter().cloned()).collect();
-        let ctor_sub_validity = self.place_validity[0].specialize(ctor);
-        let specialized_place_validity = std::iter::repeat(ctor_sub_validity)
-            .take(arity)
-            .chain(self.place_validity[1..].iter().copied())
-            .collect();
+        let subfield_place_info = self.place_info[0].specialize(pcx.cx, ctor);
+        let arity = subfield_place_info.len();
+        let specialized_place_info =
+            subfield_place_info.chain(self.place_info[1..].iter().cloned()).collect();
         let mut matrix = Matrix {
             rows: Vec::new(),
-            place_ty: specialized_place_ty,
-            place_validity: specialized_place_validity,
+            place_info: specialized_place_info,
             wildcard_row_is_relevant: self.wildcard_row_is_relevant && ctor_is_relevant,
         };
         for (i, row) in self.rows().enumerate() {
@@ -1127,11 +1147,11 @@ impl<'p, Cx: TypeCx> fmt::Debug for Matrix<'p, Cx> {
             .map(|row| row.iter().map(|pat| format!("{pat:?}")).collect())
             .collect();
         pretty_printed_matrix
-            .push(self.place_validity.iter().map(|validity| format!("{validity}")).collect());
+            .push(self.place_info.iter().map(|place| format!("{}", place.validity)).collect());
 
         let column_count = self.column_count();
         assert!(self.rows.iter().all(|row| row.len() == column_count));
-        assert!(self.place_validity.len() == column_count);
+        assert!(self.place_info.len() == column_count);
         let column_widths: Vec<usize> = (0..column_count)
             .map(|col| pretty_printed_matrix.iter().map(|row| row[col].len()).max().unwrap_or(0))
             .collect();
@@ -1432,11 +1452,10 @@ fn collect_overlapping_range_endpoints<'p, Cx: TypeCx>(
 /// - unspecialization, where we lift the results from the previous step into results for this step
 ///     (using `apply_constructor` and by updating `row.useful` for each parent row).
 /// This is all explained at the top of the file.
-#[instrument(level = "debug", skip(mcx, is_top_level), ret)]
+#[instrument(level = "debug", skip(mcx), ret)]
 fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
     mcx: UsefulnessCtxt<'a, Cx>,
     matrix: &mut Matrix<'p, Cx>,
-    is_top_level: bool,
 ) -> Result<WitnessMatrix<Cx>, Cx::Error> {
     debug_assert!(matrix.rows().all(|r| r.len() == matrix.column_count()));
 
@@ -1447,7 +1466,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
         return Ok(WitnessMatrix::empty());
     }
 
-    let Some(ty) = matrix.head_ty().cloned() else {
+    let Some(place) = matrix.head_place() else {
         // The base case: there are no columns in the matrix. We are morally pattern-matching on ().
         // A row is useful iff it has no (unguarded) rows above it.
         let mut useful = true; // Whether the next row is useful.
@@ -1467,18 +1486,17 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
         };
     };
 
-    debug!("ty: {ty:?}");
-    let pcx = &PlaceCtxt { cx: mcx.tycx, ty: &ty };
+    let ty = &place.ty.clone(); // Clone it out so we can mutate `matrix` later.
+    let pcx = &PlaceCtxt { cx: mcx.tycx, ty };
+    debug!("ty: {:?}", pcx.ty);
     let ctors_for_ty = pcx.ctors_for_ty()?;
 
-    // Whether the place/column we are inspecting is known to contain valid data.
-    let place_validity = matrix.place_validity[0];
     // We treat match scrutinees of type `!` or `EmptyEnum` differently.
     let is_toplevel_exception =
-        is_top_level && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
+        place.is_scrutinee && matches!(ctors_for_ty, ConstructorSet::NoConstructors);
     // 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()
+    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());
@@ -1502,11 +1520,9 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
         split_ctors.push(Constructor::Missing);
     }
 
-    // Decide what constructors to report.
-    let is_integers = matches!(ctors_for_ty, ConstructorSet::Integers { .. });
-    let always_report_all = is_top_level && !is_integers;
-    // Whether we should report "Enum::A and Enum::C are missing" or "_ is missing".
-    let report_individual_missing_ctors = always_report_all || !all_missing;
+    // Whether we should report "Enum::A and Enum::C are missing" or "_ is missing". At the top
+    // level we prefer to list all constructors.
+    let report_individual_missing_ctors = place.is_scrutinee || !all_missing;
     // Which constructors are considered missing. We ensure that `!missing_ctors.is_empty() =>
     // split_ctors.contains(Missing)`. The converse usually holds except when
     // `!place_validity.is_known_valid()`.
@@ -1525,7 +1541,7 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: TypeCx>(
         let ctor_is_relevant = matches!(ctor, Constructor::Missing) || missing_ctors.is_empty();
         let mut spec_matrix = matrix.specialize_constructor(pcx, &ctor, ctor_is_relevant)?;
         let mut witnesses = ensure_sufficient_stack(|| {
-            compute_exhaustiveness_and_usefulness(mcx, &mut spec_matrix, false)
+            compute_exhaustiveness_and_usefulness(mcx, &mut spec_matrix)
         })?;
 
         // Transform witnesses for `spec_matrix` into witnesses for `matrix`.
@@ -1575,7 +1591,7 @@ pub enum Usefulness<'p, Cx: TypeCx> {
     /// The arm is useful. This additionally carries a set of or-pattern branches that have been
     /// found to be redundant despite the overall arm being useful. Used only in the presence of
     /// or-patterns, otherwise it stays empty.
-    Useful(Vec<&'p DeconstructedPat<'p, Cx>>),
+    Useful(Vec<&'p DeconstructedPat<Cx>>),
     /// The arm is redundant and can be removed without changing the behavior of the match
     /// expression.
     Redundant,
@@ -1600,8 +1616,7 @@ pub fn compute_match_usefulness<'p, Cx: TypeCx>(
 ) -> Result<UsefulnessReport<'p, Cx>, Cx::Error> {
     let cx = UsefulnessCtxt { tycx };
     let mut matrix = Matrix::new(arms, scrut_ty, scrut_validity);
-    let non_exhaustiveness_witnesses =
-        compute_exhaustiveness_and_usefulness(cx, &mut matrix, true)?;
+    let non_exhaustiveness_witnesses = compute_exhaustiveness_and_usefulness(cx, &mut matrix)?;
 
     let non_exhaustiveness_witnesses: Vec<_> = non_exhaustiveness_witnesses.single_column();
     let arm_usefulness: Vec<_> = arms
diff --git a/compiler/rustc_privacy/Cargo.toml b/compiler/rustc_privacy/Cargo.toml
index 90803c20d43..e7a32771f35 100644
--- a/compiler/rustc_privacy/Cargo.toml
+++ b/compiler/rustc_privacy/Cargo.toml
@@ -16,5 +16,6 @@ rustc_macros = { path = "../rustc_macros" }
 rustc_middle = { path = "../rustc_middle" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
+rustc_ty_utils = { path = "../rustc_ty_utils" }
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index a37d8822480..6d8e7ba937e 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -5,8 +5,6 @@
 #![feature(associated_type_defaults)]
 #![feature(try_blocks)]
 #![feature(let_chains)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate tracing;
@@ -21,7 +19,7 @@ use rustc_hir as hir;
 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_hir::{AssocItemKind, ForeignItemKind, ItemId, ItemKind, PatKind};
 use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::GenericArgs;
@@ -98,9 +96,6 @@ trait DefIdVisitor<'tcx> {
     fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<Self::BreakTy> {
         self.skeleton().visit_trait(trait_ref)
     }
-    fn visit_projection_ty(&mut self, projection: ty::AliasTy<'tcx>) -> ControlFlow<Self::BreakTy> {
-        self.skeleton().visit_projection_ty(projection)
-    }
     fn visit_predicates(
         &mut self,
         predicates: ty::GenericPredicates<'tcx>,
@@ -173,6 +168,10 @@ where
 {
     type BreakTy = V::BreakTy;
 
+    fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
+        self.visit_clause(p.as_clause().unwrap())
+    }
+
     fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<V::BreakTy> {
         let tcx = self.def_id_visitor.tcx();
         // GenericArgs are not visited here because they are visited below
@@ -1076,6 +1075,14 @@ impl<'tcx> TypePrivacyVisitor<'tcx> {
     }
 }
 
+impl<'tcx> rustc_ty_utils::sig_types::SpannedTypeVisitor<'tcx> for TypePrivacyVisitor<'tcx> {
+    type BreakTy = ();
+    fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> ControlFlow<()> {
+        self.span = span;
+        value.visit_with(&mut self.skeleton())
+    }
+}
+
 impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
     fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         let old_maybe_typeck_results =
@@ -1086,18 +1093,15 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
 
     fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) {
         self.span = hir_ty.span;
-        if let Some(typeck_results) = self.maybe_typeck_results {
-            // Types in bodies.
-            if self.visit(typeck_results.node_type(hir_ty.hir_id)).is_break() {
-                return;
-            }
-        } else {
-            // Types in signatures.
-            // FIXME: This is very ineffective. Ideally each HIR type should be converted
-            // into a semantic type only once and the result should be cached somehow.
-            if self.visit(rustc_hir_analysis::hir_ty_to_ty(self.tcx, hir_ty)).is_break() {
-                return;
-            }
+        if self
+            .visit(
+                self.maybe_typeck_results
+                    .unwrap_or_else(|| span_bug!(hir_ty.span, "`hir::Ty` outside of a body"))
+                    .node_type(hir_ty.hir_id),
+            )
+            .is_break()
+        {
+            return;
         }
 
         intravisit::walk_ty(self, hir_ty);
@@ -1105,56 +1109,20 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
 
     fn visit_infer(&mut self, inf: &'tcx hir::InferArg) {
         self.span = inf.span;
-        if let Some(typeck_results) = self.maybe_typeck_results {
-            if let Some(ty) = typeck_results.node_type_opt(inf.hir_id) {
-                if self.visit(ty).is_break() {
-                    return;
-                }
-            } else {
-                // FIXME: check types of const infers here.
+        if let Some(ty) = self
+            .maybe_typeck_results
+            .unwrap_or_else(|| span_bug!(inf.span, "`hir::InferArg` outside of a body"))
+            .node_type_opt(inf.hir_id)
+        {
+            if self.visit(ty).is_break() {
+                return;
             }
         } else {
-            span_bug!(self.span, "`hir::InferArg` outside of a body");
+            // FIXME: check types of const infers here.
         }
         intravisit::walk_inf(self, inf);
     }
 
-    fn visit_trait_ref(&mut self, trait_ref: &'tcx hir::TraitRef<'tcx>) {
-        self.span = trait_ref.path.span;
-        if self.maybe_typeck_results.is_some() {
-            // Privacy of traits in bodies is checked as a part of trait object types.
-        } else {
-            let bounds = rustc_hir_analysis::hir_trait_to_predicates(
-                self.tcx,
-                trait_ref,
-                // NOTE: This isn't really right, but the actual type doesn't matter here. It's
-                // just required by `ty::TraitRef`.
-                self.tcx.types.never,
-            );
-
-            for (clause, _) in bounds.clauses() {
-                match clause.kind().skip_binder() {
-                    ty::ClauseKind::Trait(trait_predicate) => {
-                        if self.visit_trait(trait_predicate.trait_ref).is_break() {
-                            return;
-                        }
-                    }
-                    ty::ClauseKind::Projection(proj_predicate) => {
-                        let term = self.visit(proj_predicate.term);
-                        if term.is_break()
-                            || self.visit_projection_ty(proj_predicate.projection_ty).is_break()
-                        {
-                            return;
-                        }
-                    }
-                    _ => {}
-                }
-            }
-        }
-
-        intravisit::walk_trait_ref(self, trait_ref);
-    }
-
     // Check types of expressions
     fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
         if self.check_expr_pat_type(expr.hir_id, expr.span) {
@@ -1727,7 +1695,26 @@ fn check_mod_privacy(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     // 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);
+
+    let module = tcx.hir_module_items(module_def_id);
+    for def_id in module.definitions() {
+        rustc_ty_utils::sig_types::walk_types(tcx, def_id, &mut visitor);
+
+        if let Some(body_id) = tcx.hir().maybe_body_owned_by(def_id) {
+            visitor.visit_nested_body(body_id);
+        }
+    }
+
+    for id in module.items() {
+        if let ItemKind::Impl(i) = tcx.hir().item(id).kind {
+            if let Some(item) = i.of_trait {
+                let trait_ref = tcx.impl_trait_ref(id.owner_id.def_id).unwrap();
+                let trait_ref = trait_ref.instantiate_identity();
+                visitor.span = item.path.span;
+                visitor.visit_def_id(trait_ref.def_id, "trait", &trait_ref.print_only_trait_path());
+            }
+        }
+    }
 }
 
 fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
diff --git a/compiler/rustc_query_impl/src/lib.rs b/compiler/rustc_query_impl/src/lib.rs
index 818a67a7deb..0fe5b9c664a 100644
--- a/compiler/rustc_query_impl/src/lib.rs
+++ b/compiler/rustc_query_impl/src/lib.rs
@@ -6,8 +6,6 @@
 #![feature(min_specialization)]
 #![feature(rustc_attrs)]
 #![allow(rustc::potential_query_instability, unused_parens)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
 
 #[macro_use]
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 2faa4876798..b6ac54a9ab5 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -52,7 +52,7 @@ impl From<DepNodeIndex> for QueryInvocationId {
     }
 }
 
-pub(crate) struct MarkFrame<'a> {
+pub struct MarkFrame<'a> {
     index: SerializedDepNodeIndex,
     parent: Option<&'a MarkFrame<'a>>,
 }
@@ -754,7 +754,6 @@ impl<D: Deps> DepGraphData<D> {
         &self,
         qcx: Qcx,
         parent_dep_node_index: SerializedDepNodeIndex,
-        dep_node: &DepNode,
         frame: Option<&MarkFrame<'_>>,
     ) -> Option<()> {
         let dep_dep_node_color = self.colors.get(parent_dep_node_index);
@@ -861,7 +860,7 @@ impl<D: Deps> DepGraphData<D> {
         let prev_deps = self.previous.edge_targets_from(prev_dep_node_index);
 
         for dep_dep_node_index in prev_deps {
-            self.try_mark_parent_green(qcx, dep_dep_node_index, dep_node, Some(&frame))?;
+            self.try_mark_parent_green(qcx, dep_dep_node_index, Some(&frame))?;
         }
 
         // If we got here without hitting a `return` that means that all
diff --git a/compiler/rustc_query_system/src/lib.rs b/compiler/rustc_query_system/src/lib.rs
index 9b66b9a48d9..416f556f57d 100644
--- a/compiler/rustc_query_system/src/lib.rs
+++ b/compiler/rustc_query_system/src/lib.rs
@@ -4,8 +4,6 @@
 #![feature(min_specialization)]
 #![feature(let_chains)]
 #![allow(rustc::potential_query_instability, internal_features)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_resolve/messages.ftl b/compiler/rustc_resolve/messages.ftl
index 02847a0f5f9..0747685c35c 100644
--- a/compiler/rustc_resolve/messages.ftl
+++ b/compiler/rustc_resolve/messages.ftl
@@ -118,17 +118,27 @@ resolve_forward_declared_generic_param =
     .label = defaulted generic parameters cannot be forward declared
 
 resolve_generic_params_from_outer_item =
-    can't use generic parameters from outer item
-    .label = use of generic parameter from outer item
+    can't use {$is_self ->
+        [true] `Self`
+        *[false] generic parameters
+    } from outer item
+    .label = use of {$is_self ->
+        [true] `Self`
+        *[false] generic parameter
+    } from outer item
     .refer_to_type_directly = refer to the type directly here instead
     .suggestion = try introducing a local generic parameter here
 
+resolve_generic_params_from_outer_item_const = a `const` is a separate item from the item that contains it
+
 resolve_generic_params_from_outer_item_const_param = const parameter from outer item
 
 resolve_generic_params_from_outer_item_self_ty_alias = `Self` type implicitly declared here, by this `impl`
 
 resolve_generic_params_from_outer_item_self_ty_param = can't use `Self` here
 
+resolve_generic_params_from_outer_item_static = a `static` is a separate item from the item that contains it
+
 resolve_generic_params_from_outer_item_ty_param = type parameter from outer item
 
 
@@ -292,6 +302,9 @@ resolve_underscore_lifetime_name_cannot_be_used_here =
 resolve_unexpected_res_change_ty_to_const_param_sugg =
     you might have meant to write a const parameter here
 
+resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg =
+    if you meant to collect the rest of the slice in `{$ident}`, use the at operator
+
 resolve_unreachable_label =
     use of unreachable label `{$name}`
     .label = unreachable label `{$name}`
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index f3a6eb65a72..d91a865e38a 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -561,13 +561,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         resolution_error: ResolutionError<'a>,
     ) -> DiagnosticBuilder<'_> {
         match resolution_error {
-            ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params) => {
+            ResolutionError::GenericParamsFromOuterItem(outer_res, has_generic_params, def_kind) => {
                 use errs::GenericParamsFromOuterItemLabel as Label;
+                let static_or_const = match def_kind {
+                    DefKind::Static(_) => Some(errs::GenericParamsFromOuterItemStaticOrConst::Static),
+                    DefKind::Const => Some(errs::GenericParamsFromOuterItemStaticOrConst::Const),
+                    _ => None,
+                };
+                let is_self = matches!(outer_res, Res::SelfTyParam { .. } | Res::SelfTyAlias { .. });
                 let mut err = errs::GenericParamsFromOuterItem {
                     span,
                     label: None,
                     refer_to_type_directly: None,
                     sugg: None,
+                    static_or_const,
+                    is_self,
                 };
 
                 let sm = self.tcx.sess.source_map();
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index 655fc9812d7..adc4cd911a7 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -45,6 +45,17 @@ pub(crate) struct GenericParamsFromOuterItem {
     pub(crate) refer_to_type_directly: Option<Span>,
     #[subdiagnostic]
     pub(crate) sugg: Option<GenericParamsFromOuterItemSugg>,
+    #[subdiagnostic]
+    pub(crate) static_or_const: Option<GenericParamsFromOuterItemStaticOrConst>,
+    pub(crate) is_self: bool,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum GenericParamsFromOuterItemStaticOrConst {
+    #[note(resolve_generic_params_from_outer_item_static)]
+    Static,
+    #[note(resolve_generic_params_from_outer_item_const)]
+    Const,
 }
 
 #[derive(Subdiagnostic)]
@@ -800,3 +811,17 @@ pub(crate) struct UnexpectedResChangeTyToConstParamSugg {
     #[applicability]
     pub applicability: Applicability,
 }
+
+#[derive(Subdiagnostic)]
+#[suggestion(
+    resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg,
+    code = "{snippet}",
+    applicability = "maybe-incorrect",
+    style = "verbose"
+)]
+pub(crate) struct UnexpectedResUseAtOpInSlicePatWithRangeSugg {
+    #[primary_span]
+    pub span: Span,
+    pub ident: Ident,
+    pub snippet: String,
+}
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index 7fb9db16e9c..e47f2bdd4d2 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -10,9 +10,7 @@ use rustc_span::symbol::{kw, Ident};
 use rustc_span::Span;
 
 use crate::errors::{ParamKindInEnumDiscriminant, ParamKindInNonTrivialAnonConst};
-use crate::late::{
-    ConstantHasGenerics, HasGenericParams, NoConstantGenericsReason, PathSource, Rib, RibKind,
-};
+use crate::late::{ConstantHasGenerics, NoConstantGenericsReason, PathSource, Rib, RibKind};
 use crate::macros::{sub_namespace_match, MacroRulesScope};
 use crate::BindingKey;
 use crate::{errors, AmbiguityError, AmbiguityErrorMisc, AmbiguityKind, Determinacy, Finalize};
@@ -1090,7 +1088,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         | RibKind::ForwardGenericParamBan => {
                             // Nothing to do. Continue.
                         }
-                        RibKind::Item(_) | RibKind::AssocItem => {
+                        RibKind::Item(..) | RibKind::AssocItem => {
                             // This was an attempt to access an upvar inside a
                             // named function item. This is not allowed, so we
                             // report an error.
@@ -1155,7 +1153,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
             Res::Def(DefKind::TyParam, _) | Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } => {
                 for rib in ribs {
-                    let has_generic_params: HasGenericParams = match rib.kind {
+                    let (has_generic_params, def_kind) = match rib.kind {
                         RibKind::Normal
                         | RibKind::FnOrCoroutine
                         | RibKind::Module(..)
@@ -1213,7 +1211,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                         }
 
                         // This was an attempt to use a type parameter outside its scope.
-                        RibKind::Item(has_generic_params) => has_generic_params,
+                        RibKind::Item(has_generic_params, def_kind) => {
+                            (has_generic_params, def_kind)
+                        }
                         RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
                                 self.report_error(
@@ -1231,7 +1231,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     if let Some(span) = finalize {
                         self.report_error(
                             span,
-                            ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
+                            ResolutionError::GenericParamsFromOuterItem(
+                                res,
+                                has_generic_params,
+                                def_kind,
+                            ),
                         );
                     }
                     return Res::Err;
@@ -1239,7 +1243,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             }
             Res::Def(DefKind::ConstParam, _) => {
                 for rib in ribs {
-                    let has_generic_params = match rib.kind {
+                    let (has_generic_params, def_kind) = match rib.kind {
                         RibKind::Normal
                         | RibKind::FnOrCoroutine
                         | RibKind::Module(..)
@@ -1276,7 +1280,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                             continue;
                         }
 
-                        RibKind::Item(has_generic_params) => has_generic_params,
+                        RibKind::Item(has_generic_params, def_kind) => {
+                            (has_generic_params, def_kind)
+                        }
                         RibKind::ConstParamTy => {
                             if let Some(span) = finalize {
                                 self.report_error(
@@ -1295,7 +1301,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     if let Some(span) = finalize {
                         self.report_error(
                             span,
-                            ResolutionError::GenericParamsFromOuterItem(res, has_generic_params),
+                            ResolutionError::GenericParamsFromOuterItem(
+                                res,
+                                has_generic_params,
+                                def_kind,
+                            ),
                         );
                     }
                     return Res::Err;
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 1f2803d4368..6bd221ff058 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -23,6 +23,7 @@ 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};
 use rustc_hir::{BindingAnnotation, PrimTy, TraitCandidate};
+use rustc_metadata::creader::CStore;
 use rustc_middle::middle::resolve_bound_vars::Set1;
 use rustc_middle::{bug, span_bug};
 use rustc_session::config::{CrateType, ResolveDocLinks};
@@ -185,7 +186,7 @@ pub(crate) enum RibKind<'a> {
     FnOrCoroutine,
 
     /// We passed through an item scope. Disallow upvars.
-    Item(HasGenericParams),
+    Item(HasGenericParams, DefKind),
 
     /// We're in a constant item. Can't refer to dynamic stuff.
     ///
@@ -225,7 +226,7 @@ impl RibKind<'_> {
             | RibKind::MacroDefinition(_)
             | RibKind::ConstParamTy
             | RibKind::InlineAsmSym => false,
-            RibKind::AssocItem | RibKind::Item(_) | RibKind::ForwardGenericParamBan => true,
+            RibKind::AssocItem | RibKind::Item(..) | RibKind::ForwardGenericParamBan => true,
         }
     }
 
@@ -869,11 +870,12 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
     }
     fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
         self.resolve_doc_links(&foreign_item.attrs, MaybeExported::Ok(foreign_item.id));
+        let def_kind = self.r.local_def_kind(foreign_item.id);
         match foreign_item.kind {
             ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    RibKind::Item(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
                     LifetimeRibKind::Generics {
                         binder: foreign_item.id,
                         kind: LifetimeBinderKind::Item,
@@ -885,7 +887,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
             ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    RibKind::Item(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
                     LifetimeRibKind::Generics {
                         binder: foreign_item.id,
                         kind: LifetimeBinderKind::Function,
@@ -895,7 +897,7 @@ impl<'a: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast,
                 );
             }
             ForeignItemKind::Static(..) => {
-                self.with_static_rib(|this| {
+                self.with_static_rib(def_kind, |this| {
                     visit::walk_foreign_item(this, foreign_item);
                 });
             }
@@ -1644,7 +1646,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             debug!(?rib.kind);
             match rib.kind {
                 LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {
-                    let res = self.create_fresh_lifetime(lifetime.id, lifetime.ident, binder);
+                    let res = self.create_fresh_lifetime(lifetime.ident, binder);
                     self.record_lifetime_res(lifetime.id, res, elision_candidate);
                     return;
                 }
@@ -1736,7 +1738,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn create_fresh_lifetime(&mut self, id: NodeId, ident: Ident, binder: NodeId) -> LifetimeRes {
+    fn create_fresh_lifetime(&mut self, ident: Ident, binder: NodeId) -> LifetimeRes {
         debug_assert_eq!(ident.name, kw::UnderscoreLifetime);
         debug!(?ident.span);
 
@@ -1757,7 +1759,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
     #[instrument(level = "debug", skip(self))]
     fn resolve_elided_lifetimes_in_path(
         &mut self,
-        path_id: NodeId,
         partial_res: PartialRes,
         path: &[Segment],
         source: PathSource<'_>,
@@ -1890,7 +1891,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                         // Group all suggestions into the first record.
                         let mut candidate = LifetimeElisionCandidate::Missing(missing_lifetime);
                         for id in node_ids {
-                            let res = self.create_fresh_lifetime(id, ident, binder);
+                            let res = self.create_fresh_lifetime(ident, binder);
                             self.record_lifetime_res(
                                 id,
                                 res,
@@ -2266,10 +2267,11 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
     fn resolve_adt(&mut self, item: &'ast Item, generics: &'ast Generics) {
         debug!("resolve_adt");
+        let kind = self.r.local_def_kind(item.id);
         self.with_current_self_item(item, |this| {
             this.with_generic_param_rib(
                 &generics.params,
-                RibKind::Item(HasGenericParams::Yes(generics.span)),
+                RibKind::Item(HasGenericParams::Yes(generics.span), kind),
                 LifetimeRibKind::Generics {
                     binder: item.id,
                     kind: LifetimeBinderKind::Item,
@@ -2343,11 +2345,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         let name = item.ident.name;
         debug!("(resolving item) resolving {} ({:?})", name, item.kind);
 
+        let def_kind = self.r.local_def_kind(item.id);
         match item.kind {
             ItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    RibKind::Item(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2360,7 +2363,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             ItemKind::Fn(box Fn { ref generics, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    RibKind::Item(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Function,
@@ -2399,7 +2402,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    RibKind::Item(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2420,7 +2423,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 // Create a new rib for the trait-wide type parameters.
                 self.with_generic_param_rib(
                     &generics.params,
-                    RibKind::Item(HasGenericParams::Yes(generics.span)),
+                    RibKind::Item(HasGenericParams::Yes(generics.span), def_kind),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::Item,
@@ -2454,7 +2457,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             }
 
             ItemKind::Static(box ast::StaticItem { ref ty, ref expr, .. }) => {
-                self.with_static_rib(|this| {
+                self.with_static_rib(def_kind, |this| {
                     this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
                         this.visit_ty(ty);
                     });
@@ -2469,11 +2472,14 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             ItemKind::Const(box ast::ConstItem { ref generics, ref ty, ref expr, .. }) => {
                 self.with_generic_param_rib(
                     &generics.params,
-                    RibKind::Item(if self.r.tcx.features().generic_const_items {
-                        HasGenericParams::Yes(generics.span)
-                    } else {
-                        HasGenericParams::No
-                    }),
+                    RibKind::Item(
+                        if self.r.tcx.features().generic_const_items {
+                            HasGenericParams::Yes(generics.span)
+                        } else {
+                            HasGenericParams::No
+                        },
+                        def_kind,
+                    ),
                     LifetimeRibKind::Generics {
                         binder: item.id,
                         kind: LifetimeBinderKind::ConstItem,
@@ -2558,7 +2564,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
             let mut add_bindings_for_ns = |ns| {
                 let parent_rib = self.ribs[ns]
                     .iter()
-                    .rfind(|r| matches!(r.kind, RibKind::Item(_)))
+                    .rfind(|r| matches!(r.kind, RibKind::Item(..)))
                     .expect("associated item outside of an item");
                 seen_bindings.extend(parent_rib.bindings.keys().map(|ident| (*ident, ident.span)));
             };
@@ -2693,8 +2699,8 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         self.label_ribs.pop();
     }
 
-    fn with_static_rib(&mut self, f: impl FnOnce(&mut Self)) {
-        let kind = RibKind::Item(HasGenericParams::No);
+    fn with_static_rib(&mut self, def_kind: DefKind, f: impl FnOnce(&mut Self)) {
+        let kind = RibKind::Item(HasGenericParams::No, def_kind);
         self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
     }
 
@@ -2875,7 +2881,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         // If applicable, create a rib for the type parameters.
         self.with_generic_param_rib(
             &generics.params,
-            RibKind::Item(HasGenericParams::Yes(generics.span)),
+            RibKind::Item(HasGenericParams::Yes(generics.span), self.r.local_def_kind(item_id)),
             LifetimeRibKind::Generics {
                 span: generics.span,
                 binder: item_id,
@@ -3935,7 +3941,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         if record_partial_res == RecordPartialRes::Yes {
             // Avoid recording definition of `A::B` in `<T as A>::B::C`.
             self.r.record_partial_res(node_id, partial_res);
-            self.resolve_elided_lifetimes_in_path(node_id, partial_res, path, source, path_span);
+            self.resolve_elided_lifetimes_in_path(partial_res, path, source, path_span);
         }
 
         partial_res
@@ -4541,14 +4547,20 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 if let Some(res) = res
                     && let Some(def_id) = res.opt_def_id()
                     && !def_id.is_local()
-                    && self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
-                    && matches!(
-                        self.r.tcx.sess.opts.resolve_doc_links,
-                        ResolveDocLinks::ExportedMetadata
-                    )
                 {
-                    // Encoding foreign def ids in proc macro crate metadata will ICE.
-                    return None;
+                    if self.r.tcx.crate_types().contains(&CrateType::ProcMacro)
+                        && matches!(
+                            self.r.tcx.sess.opts.resolve_doc_links,
+                            ResolveDocLinks::ExportedMetadata
+                        )
+                    {
+                        // Encoding foreign def ids in proc macro crate metadata will ICE.
+                        return None;
+                    }
+                    // Doc paths should be resolved speculatively and should not produce any
+                    // diagnostics, but if they are indeed resolved, then we need to keep the
+                    // corresponding crate alive.
+                    CStore::from_tcx_mut(self.r.tcx).set_used_recursively(def_id.krate);
                 }
                 res
             });
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 310c126213a..5d712461993 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -1077,24 +1077,34 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
         err: &mut Diagnostic,
         path: &[Segment],
     ) {
-        if let Some(pat) = self.diagnostic_metadata.current_pat
-            && let ast::PatKind::Range(Some(start), None, range) = &pat.kind
-            && let ExprKind::Path(None, range_path) = &start.kind
+        let Some(pat) = self.diagnostic_metadata.current_pat else { return };
+        let (bound, side, range) = match &pat.kind {
+            ast::PatKind::Range(Some(bound), None, range) => (bound, Side::Start, range),
+            ast::PatKind::Range(None, Some(bound), range) => (bound, Side::End, range),
+            _ => return,
+        };
+        if let ExprKind::Path(None, range_path) = &bound.kind
             && let [segment] = &range_path.segments[..]
             && let [s] = path
             && segment.ident == s.ident
+            && segment.ident.span.eq_ctxt(range.span)
         {
-            // We've encountered `[first, rest..]` where the user might have meant
-            // `[first, rest @ ..]` (#88404).
-            err.span_suggestion_verbose(
-                segment.ident.span.between(range.span),
-                format!(
-                    "if you meant to collect the rest of the slice in `{}`, use the at operator",
-                    segment.ident,
-                ),
-                " @ ",
-                Applicability::MaybeIncorrect,
-            );
+            // We've encountered `[first, rest..]` (#88404) or `[first, ..rest]` (#120591)
+            // where the user might have meant `[first, rest @ ..]`.
+            let (span, snippet) = match side {
+                Side::Start => (segment.ident.span.between(range.span), " @ ".into()),
+                Side::End => (range.span.to(segment.ident.span), format!("{} @ ..", segment.ident)),
+            };
+            err.subdiagnostic(errors::UnexpectedResUseAtOpInSlicePatWithRangeSugg {
+                span,
+                ident: segment.ident,
+                snippet,
+            });
+        }
+
+        enum Side {
+            Start,
+            End,
         }
     }
 
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 9d09d060b59..6c0f2b89347 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -17,7 +17,9 @@
 #![feature(let_chains)]
 #![feature(rustc_attrs)]
 #![allow(rustdoc::private_intra_doc_links)]
+#![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::potential_query_instability)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![allow(internal_features)]
 
 #[macro_use]
@@ -184,7 +186,7 @@ struct BindingError {
 #[derive(Debug)]
 enum ResolutionError<'a> {
     /// Error E0401: can't use type or const parameters from outer item.
-    GenericParamsFromOuterItem(Res, HasGenericParams),
+    GenericParamsFromOuterItem(Res, HasGenericParams, DefKind),
     /// Error E0403: the name is already used for a type or const parameter in this generic
     /// parameter list.
     NameAlreadyUsedInParameterList(Symbol, Span),
@@ -1217,6 +1219,10 @@ impl<'tcx> Resolver<'_, 'tcx> {
         self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`"))
     }
 
+    fn local_def_kind(&self, node: NodeId) -> DefKind {
+        self.tcx.def_kind(self.local_def_id(node))
+    }
+
     /// Adds a definition with a parent definition.
     fn create_def(
         &mut self,
@@ -1625,6 +1631,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             self.tcx
                 .sess
                 .time("resolve_postprocess", || self.crate_loader(|c| c.postprocess(krate)));
+            self.crate_loader(|c| c.unload_unused_crates());
         });
 
         // Make sure we don't mutate the cstore from here on.
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index 9c34aa93957..95833f532f4 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -17,8 +17,6 @@
 #![feature(ptr_sub_ptr)]
 #![cfg_attr(test, feature(test))]
 #![allow(rustc::internal)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 pub use self::serialize::{Decodable, Decoder, Encodable, Encoder};
 
diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs
index 0d6328fbb07..58e1394c090 100644
--- a/compiler/rustc_session/src/lib.rs
+++ b/compiler/rustc_session/src/lib.rs
@@ -4,8 +4,6 @@
 #![feature(rustc_attrs)]
 #![feature(map_many_mut)]
 #![feature(iter_intersperse)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
 
 #[macro_use]
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index d8d201d5f24..ea93ac5841f 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1572,6 +1572,8 @@ options! {
     dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
         "in dep-info output, omit targets for tracking dependencies of the dep-info files \
         themselves (default: no)"),
+    direct_access_external_data: Option<bool> = (None, parse_opt_bool, [TRACKED],
+        "Direct or use GOT indirect to reference external data symbols"),
     dual_proc_macros: bool = (false, parse_bool, [TRACKED],
         "load proc macros for both target and host, but only link to the target (default: no)"),
     dump_dep_graph: bool = (false, parse_bool, [UNTRACKED],
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs
index f6af5a4f87e..0c084660761 100644
--- a/compiler/rustc_session/src/session.rs
+++ b/compiler/rustc_session/src/session.rs
@@ -315,7 +315,7 @@ impl Session {
     pub fn compile_status(&self) -> Result<(), ErrorGuaranteed> {
         // We must include lint errors here.
         if let Some(reported) = self.dcx().has_errors_or_lint_errors() {
-            let _ = self.dcx().emit_stashed_diagnostics();
+            self.dcx().emit_stashed_diagnostics();
             Err(reported)
         } else {
             Ok(())
@@ -767,6 +767,13 @@ impl Session {
         self.opts.unstable_opts.tls_model.unwrap_or(self.target.tls_model)
     }
 
+    pub fn direct_access_external_data(&self) -> Option<bool> {
+        self.opts
+            .unstable_opts
+            .direct_access_external_data
+            .or(self.target.direct_access_external_data)
+    }
+
     pub fn split_debuginfo(&self) -> SplitDebuginfo {
         self.opts.cg.split_debuginfo.unwrap_or(self.target.split_debuginfo)
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 41a4edfc03b..501d6f7d304 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -257,6 +257,7 @@ impl<'tcx> Stable<'tcx> for mir::NullOp<'tcx> {
             OffsetOf(indices) => stable_mir::mir::NullOp::OffsetOf(
                 indices.iter().map(|idx| idx.stable(tables)).collect(),
             ),
+            DebugAssertions => stable_mir::mir::NullOp::DebugAssertions,
         }
     }
 }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index ea6766ea583..7d95a0bc478 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -17,8 +17,6 @@
 
 // tidy-alphabetical-start
 #![allow(internal_features)]
-#![deny(rustc::diagnostic_outside_of_impl)]
-#![deny(rustc::untranslatable_diagnostic)]
 #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
 #![doc(rust_logo)]
 #![feature(array_windows)]
@@ -2477,10 +2475,9 @@ where
 pub struct ErrorGuaranteed(());
 
 impl ErrorGuaranteed {
-    /// To be used only if you really know what you are doing... ideally, we would find a way to
-    /// eliminate all calls to this method.
-    #[deprecated = "`Session::span_delayed_bug` should be preferred over this function"]
-    pub fn unchecked_claim_error_was_emitted() -> Self {
+    /// Don't use this outside of `DiagCtxtInner::emit_diagnostic`!
+    #[deprecated = "should only be used in `DiagCtxtInner::emit_diagnostic`"]
+    pub fn unchecked_error_guaranteed() -> Self {
         ErrorGuaranteed(())
     }
 }
diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs
index 5788d11ed43..51f8aa04e8a 100644
--- a/compiler/rustc_span/src/source_map/tests.rs
+++ b/compiler/rustc_span/src/source_map/tests.rs
@@ -1,5 +1,7 @@
 use super::*;
 
+use rustc_data_structures::sync::FreezeLock;
+
 fn init_source_map() -> SourceMap {
     let sm = SourceMap::new(FilePathMapping::empty());
     sm.new_source_file(PathBuf::from("blork.rs").into(), "first line.\nsecond line".to_string());
@@ -263,53 +265,6 @@ fn t10() {
     );
 }
 
-/// Returns the span corresponding to the `n`th occurrence of `substring` in `source_text`.
-trait SourceMapExtension {
-    fn span_substr(
-        &self,
-        file: &Lrc<SourceFile>,
-        source_text: &str,
-        substring: &str,
-        n: usize,
-    ) -> Span;
-}
-
-impl SourceMapExtension for SourceMap {
-    fn span_substr(
-        &self,
-        file: &Lrc<SourceFile>,
-        source_text: &str,
-        substring: &str,
-        n: usize,
-    ) -> Span {
-        eprintln!(
-            "span_substr(file={:?}/{:?}, substring={:?}, n={})",
-            file.name, file.start_pos, substring, n
-        );
-        let mut i = 0;
-        let mut hi = 0;
-        loop {
-            let offset = source_text[hi..].find(substring).unwrap_or_else(|| {
-                panic!(
-                    "source_text `{}` does not have {} occurrences of `{}`, only {}",
-                    source_text, n, substring, i
-                );
-            });
-            let lo = hi + offset;
-            hi = lo + substring.len();
-            if i == n {
-                let span = Span::with_root_ctxt(
-                    BytePos(lo as u32 + file.start_pos.0),
-                    BytePos(hi as u32 + file.start_pos.0),
-                );
-                assert_eq!(&self.span_to_snippet(span).unwrap()[..], substring);
-                return span;
-            }
-            i += 1;
-        }
-    }
-}
-
 // Takes a unix-style path and returns a platform specific path.
 fn path(p: &str) -> PathBuf {
     path_str(p).into()
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 362aaca6364..02bb1fde75c 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)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_middle;
diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs
index bffb3681f13..b19c5b6f28f 100644
--- a/compiler/rustc_target/src/lib.rs
+++ b/compiler/rustc_target/src/lib.rs
@@ -17,8 +17,6 @@
 #![feature(min_specialization)]
 #![feature(rustc_attrs)]
 #![feature(step_trait)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(internal_features)]
 
 use std::path::{Path, PathBuf};
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 6c698c5b01d..d04bcb2d78a 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1543,6 +1543,7 @@ supported_targets! {
     ("armebv7r-none-eabihf", armebv7r_none_eabihf),
     ("armv7r-none-eabi", armv7r_none_eabi),
     ("armv7r-none-eabihf", armv7r_none_eabihf),
+    ("armv8r-none-eabihf", armv8r_none_eabihf),
 
     ("x86_64-pc-solaris", x86_64_pc_solaris),
     ("sparcv9-sun-solaris", sparcv9_sun_solaris),
@@ -1886,6 +1887,8 @@ pub struct TargetOptions {
     /// passed, and cannot be disabled even via `-C`. Corresponds to `llc
     /// -mattr=$features`.
     pub features: StaticCow<str>,
+    /// Direct or use GOT indirect to reference external data symbols
+    pub direct_access_external_data: Option<bool>,
     /// Whether dynamic linking is available on this target. Defaults to false.
     pub dynamic_linking: bool,
     /// Whether dynamic linking can export TLS globals. Defaults to true.
@@ -2280,6 +2283,7 @@ impl Default for TargetOptions {
             asm_args: cvs![],
             cpu: "generic".into(),
             features: "".into(),
+            direct_access_external_data: None,
             dynamic_linking: false,
             dll_tls_export: true,
             only_cdylib: false,
@@ -2579,6 +2583,12 @@ impl Target {
                     base.$key_name = s as u32;
                 }
             } );
+            ($key_name:ident, Option<bool>) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                if let Some(s) = obj.remove(&name).and_then(|b| b.as_bool()) {
+                    base.$key_name = Some(s);
+                }
+            } );
             ($key_name:ident, Option<u64>) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 if let Some(s) = obj.remove(&name).and_then(|b| b.as_u64()) {
@@ -3007,6 +3017,7 @@ impl Target {
         key!(cpu);
         key!(features);
         key!(dynamic_linking, bool);
+        key!(direct_access_external_data, Option<bool>);
         key!(dll_tls_export, bool);
         key!(only_cdylib, bool);
         key!(executables, bool);
@@ -3261,6 +3272,7 @@ impl ToJson for Target {
         target_option_val!(cpu);
         target_option_val!(features);
         target_option_val!(dynamic_linking);
+        target_option_val!(direct_access_external_data);
         target_option_val!(dll_tls_export);
         target_option_val!(only_cdylib);
         target_option_val!(executables);
diff --git a/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs
new file mode 100644
index 00000000000..28dba4f7f5d
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/armv8r_none_eabihf.rs
@@ -0,0 +1,35 @@
+// Targets the Little-endian Cortex-R52 processor (ARMv8-R)
+
+use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
+
+pub fn target() -> Target {
+    Target {
+        llvm_target: "armv8r-none-eabihf".into(),
+        pointer_width: 32,
+        data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
+        arch: "arm".into(),
+
+        options: TargetOptions {
+            abi: "eabihf".into(),
+            linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
+            linker: Some("rust-lld".into()),
+            relocation_model: RelocModel::Static,
+            panic_strategy: PanicStrategy::Abort,
+            // The Cortex-R52 has two variants with respect to floating-point support:
+            // 1. fp-armv8, SP-only, with 16 DP (32 SP) registers
+            // 2. neon-fp-armv8, SP+DP, with 32 DP registers
+            // Use the lesser of these two options as the default, as it will produce code
+            // compatible with either variant.
+            //
+            // Reference:
+            // Arm Cortex-R52 Processor Technical Reference Manual
+            // - Chapter 15 Advanced SIMD and floating-point support
+            features: "+fp-armv8,-fp64,-d32".into(),
+            max_atomic_width: Some(64),
+            emit_debug_gdb_scripts: false,
+            // GCC defaults to 8 for arm-none here.
+            c_enum_min_bits: Some(8),
+            ..Default::default()
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
index cb24e740c86..f4350708986 100644
--- a/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/loongarch64_unknown_linux_gnu.rs
@@ -12,6 +12,7 @@ pub fn target() -> Target {
             features: "+f,+d".into(),
             llvm_abiname: "lp64d".into(),
             max_atomic_width: Some(64),
+            direct_access_external_data: Some(false),
             ..base::linux_gnu::opts()
         },
     }
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 7894f8dd98f..20cd573f46e 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::{
     codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
-    EmissionGuarantee, IntoDiagnostic, Level, SubdiagnosticMessage,
+    EmissionGuarantee, IntoDiagnostic, Level, SubdiagnosticMessageOp,
 };
 use rustc_macros::Diagnostic;
 use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
@@ -102,10 +102,7 @@ pub enum AdjustSignatureBorrow {
 }
 
 impl AddToDiagnostic for AdjustSignatureBorrow {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         match self {
             AdjustSignatureBorrow::Borrow { to_borrow } => {
                 diag.arg("len", to_borrow.len());
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index 5ec45212bc7..053ecfc681c 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -14,6 +14,8 @@
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![feature(associated_type_bounds)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs
index e8929f114e1..756db7cc206 100644
--- a/compiler/rustc_trait_selection/src/regions.rs
+++ b/compiler/rustc_trait_selection/src/regions.rs
@@ -1,5 +1,6 @@
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{InferCtxt, RegionResolutionError};
+use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::ObligationCause;
 
 pub trait InferCtxtRegionExt<'tcx> {
@@ -31,7 +32,7 @@ impl<'tcx> InferCtxtRegionExt<'tcx> for InferCtxt<'tcx> {
                     ),
                     ty,
                 )
-                .map_err(|_| ty)
+                .map_err(|_| NoSolution)
             } 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 7052fd776b0..81c0cfea85a 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -8,7 +8,7 @@ use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::Reveal;
 use rustc_middle::traits::solve::inspect::ProbeKind;
 use rustc_middle::traits::solve::{
-    CandidateSource, CanonicalResponse, Certainty, Goal, QueryResult,
+    CandidateSource, CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult,
 };
 use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams};
@@ -276,25 +276,16 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         &mut self,
         goal: Goal<'tcx, G>,
     ) -> Vec<Candidate<'tcx>> {
-        let dummy_candidate = |this: &mut EvalCtxt<'_, 'tcx>, certainty| {
-            let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
-            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) });
-            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);
+            return self.forced_ambiguity(MaybeCause::Overflow);
         };
 
         if normalized_self_ty.is_ty_var() {
             debug!("self type has been normalized to infer");
-            return dummy_candidate(self, Certainty::AMBIGUOUS);
+            return self.forced_ambiguity(MaybeCause::Ambiguity);
         }
 
         let goal =
@@ -315,11 +306,26 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
         self.assemble_param_env_candidates(goal, &mut candidates);
 
-        self.assemble_coherence_unknowable_candidates(goal, &mut candidates);
+        match self.solver_mode() {
+            SolverMode::Normal => self.discard_impls_shadowed_by_env(goal, &mut candidates),
+            SolverMode::Coherence => {
+                self.assemble_coherence_unknowable_candidates(goal, &mut candidates)
+            }
+        }
 
         candidates
     }
 
+    fn forced_ambiguity(&mut self, cause: MaybeCause) -> Vec<Candidate<'tcx>> {
+        let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
+        let certainty = Certainty::Maybe(cause);
+        let result = self.evaluate_added_goals_and_make_canonical_response(certainty).unwrap();
+        let mut dummy_probe = self.inspect.new_probe();
+        dummy_probe.probe_kind(ProbeKind::TraitCandidate { source, result: Ok(result) });
+        self.inspect.finish_probe(dummy_probe);
+        vec![Candidate { source, result }]
+    }
+
     #[instrument(level = "debug", skip_all)]
     fn assemble_non_blanket_impl_candidates<G: GoalKind<'tcx>>(
         &mut self,
@@ -542,7 +548,27 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         goal: Goal<'tcx, G>,
         candidates: &mut Vec<Candidate<'tcx>>,
     ) {
-        let alias_ty = match goal.predicate.self_ty().kind() {
+        let () = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
+            ecx.assemble_alias_bound_candidates_recur(goal.predicate.self_ty(), goal, candidates);
+        });
+    }
+
+    /// For some deeply nested `<T>::A::B::C::D` rigid associated type,
+    /// we should explore the item bounds for all levels, since the
+    /// `associated_type_bounds` feature means that a parent associated
+    /// type may carry bounds for a nested associated type.
+    ///
+    /// If we have a projection, check that its self type is a rigid projection.
+    /// If so, continue searching by recursively calling after normalization.
+    // FIXME: This may recurse infinitely, but I can't seem to trigger it without
+    // hitting another overflow error something. Add a depth parameter needed later.
+    fn assemble_alias_bound_candidates_recur<G: GoalKind<'tcx>>(
+        &mut self,
+        self_ty: Ty<'tcx>,
+        goal: Goal<'tcx, G>,
+        candidates: &mut Vec<Candidate<'tcx>>,
+    ) {
+        let (kind, alias_ty) = match *self_ty.kind() {
             ty::Bool
             | ty::Char
             | ty::Int(_)
@@ -567,13 +593,27 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             | ty::Param(_)
             | ty::Placeholder(..)
             | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
-            | ty::Alias(ty::Inherent, _)
-            | ty::Alias(ty::Weak, _)
             | ty::Error(_) => return,
-            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
-            | ty::Bound(..) => bug!("unexpected self type for `{goal:?}`"),
-            // Excluding IATs and type aliases here as they don't have meaningful item bounds.
-            ty::Alias(ty::Projection | ty::Opaque, alias_ty) => alias_ty,
+            ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) | ty::Bound(..) => {
+                bug!("unexpected self type for `{goal:?}`")
+            }
+
+            ty::Infer(ty::TyVar(_)) => {
+                // If we hit infer when normalizing the self type of an alias,
+                // then bail with ambiguity. We should never encounter this on
+                // the *first* iteration of this recursive function.
+                if let Ok(result) =
+                    self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
+                {
+                    candidates.push(Candidate { source: CandidateSource::AliasBound, result });
+                }
+                return;
+            }
+
+            ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
+            ty::Alias(ty::Inherent | ty::Weak, _) => {
+                unreachable!("Weak and Inherent aliases should have been normalized away already")
+            }
         };
 
         for assumption in
@@ -581,9 +621,28 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         {
             match G::consider_alias_bound_candidate(self, goal, assumption) {
                 Ok(result) => {
-                    candidates.push(Candidate { source: CandidateSource::AliasBound, result })
+                    candidates.push(Candidate { source: CandidateSource::AliasBound, result });
+                }
+                Err(NoSolution) => {}
+            }
+        }
+
+        if kind != ty::Projection {
+            return;
+        }
+
+        match self.try_normalize_ty(goal.param_env, alias_ty.self_ty()) {
+            // Recurse on the self type of the projection.
+            Some(next_self_ty) => {
+                self.assemble_alias_bound_candidates_recur(next_self_ty, goal, candidates);
+            }
+            // Bail if we overflow when normalizing, adding an ambiguous candidate.
+            None => {
+                if let Ok(result) =
+                    self.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW)
+                {
+                    candidates.push(Candidate { source: CandidateSource::AliasBound, result });
                 }
-                Err(NoSolution) => (),
             }
         }
     }
@@ -779,6 +838,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
+    /// In coherence we have to not only care about all impls we know about, but
+    /// also consider impls which may get added in a downstream or sibling crate
+    /// or which an upstream impl may add in a minor release.
+    ///
+    /// To do so we add an ambiguous candidate in case such an unknown impl could
+    /// apply to the current goal.
     #[instrument(level = "debug", skip_all)]
     fn assemble_coherence_unknowable_candidates<G: GoalKind<'tcx>>(
         &mut self,
@@ -786,11 +851,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         candidates: &mut Vec<Candidate<'tcx>>,
     ) {
         let tcx = self.tcx();
-        match self.solver_mode() {
-            SolverMode::Normal => return,
-            SolverMode::Coherence => {}
-        };
-
         let result = self.probe_misc_candidate("coherence unknowable").enter(|ecx| {
             let trait_ref = goal.predicate.trait_ref(tcx);
             #[derive(Debug)]
@@ -820,46 +880,65 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
+    /// If there's a where-bound for the current goal, do not use any impl candidates
+    /// to prove the current goal. Most importantly, if there is a where-bound which does
+    /// not specify any associated types, we do not allow normalizing the associated type
+    /// by using an impl, even if it would apply.
+    ///
+    ///  <https://github.com/rust-lang/trait-system-refactor-initiative/issues/76>
+    // FIXME(@lcnr): The current structure here makes me unhappy and feels ugly. idk how
+    // to improve this however. However, this should make it fairly straightforward to refine
+    // the filtering going forward, so it seems alright-ish for now.
+    fn discard_impls_shadowed_by_env<G: GoalKind<'tcx>>(
+        &mut self,
+        goal: Goal<'tcx, G>,
+        candidates: &mut Vec<Candidate<'tcx>>,
+    ) {
+        let tcx = self.tcx();
+        let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> =
+            goal.with(tcx, goal.predicate.trait_ref(tcx));
+        let mut trait_candidates_from_env = Vec::new();
+        self.assemble_param_env_candidates(trait_goal, &mut trait_candidates_from_env);
+        self.assemble_alias_bound_candidates(trait_goal, &mut trait_candidates_from_env);
+        if !trait_candidates_from_env.is_empty() {
+            let trait_env_result = self.merge_candidates(trait_candidates_from_env);
+            match trait_env_result.unwrap().value.certainty {
+                // If proving the trait goal succeeds by using the env,
+                // we freely drop all impl candidates.
+                //
+                // FIXME(@lcnr): It feels like this could easily hide
+                // a forced ambiguity candidate added earlier.
+                // This feels dangerous.
+                Certainty::Yes => {
+                    candidates.retain(|c| match c.source {
+                        CandidateSource::Impl(_) | CandidateSource::BuiltinImpl(_) => false,
+                        CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => true,
+                    });
+                }
+                // If it is still ambiguous we instead just force the whole goal
+                // to be ambig and wait for inference constraints. See
+                // tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs
+                Certainty::Maybe(cause) => {
+                    *candidates = self.forced_ambiguity(cause);
+                }
+            }
+        }
+    }
+
     /// If there are multiple ways to prove a trait or projection goal, we have
     /// to somehow try to merge the candidates into one. If that fails, we return
     /// ambiguity.
     #[instrument(level = "debug", skip(self), ret)]
     pub(super) fn merge_candidates(
         &mut self,
-        mut candidates: Vec<Candidate<'tcx>>,
+        candidates: Vec<Candidate<'tcx>>,
     ) -> QueryResult<'tcx> {
         // First try merging all candidates. This is complete and fully sound.
         let responses = candidates.iter().map(|c| c.result).collect::<Vec<_>>();
         if let Some(result) = self.try_merge_responses(&responses) {
             return Ok(result);
+        } else {
+            self.flounder(&responses)
         }
-
-        // We then check whether we should prioritize `ParamEnv` candidates.
-        //
-        // Doing so is incomplete and would therefore be unsound during coherence.
-        match self.solver_mode() {
-            SolverMode::Coherence => (),
-            // Prioritize `ParamEnv` candidates only if they do not guide inference.
-            //
-            // This is still incomplete as we may add incorrect region bounds.
-            SolverMode::Normal => {
-                let param_env_responses = candidates
-                    .iter()
-                    .filter(|c| {
-                        matches!(
-                            c.source,
-                            CandidateSource::ParamEnv(_) | CandidateSource::AliasBound
-                        )
-                    })
-                    .map(|c| c.result)
-                    .collect::<Vec<_>>();
-                if let Some(result) = self.try_merge_responses(&param_env_responses) {
-                    // We strongly prefer alias and param-env bounds here, even if they affect inference.
-                    // See https://github.com/rust-lang/trait-system-refactor-initiative/issues/11.
-                    return Ok(result);
-                }
-            }
-        }
-        self.flounder(&responses)
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index 4b95d26f9f8..819b070cf8b 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -20,7 +20,7 @@ use crate::solve::EvalCtxt;
 pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
     ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
-) -> Result<Vec<Ty<'tcx>>, NoSolution> {
+) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution> {
     let tcx = ecx.tcx();
     match *ty.kind() {
         ty::Uint(_)
@@ -34,7 +34,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
         | ty::Char => Ok(vec![]),
 
         // Treat `str` like it's defined as `struct str([u8]);`
-        ty::Str => Ok(vec![Ty::new_slice(tcx, tcx.types.u8)]),
+        ty::Str => Ok(vec![ty::Binder::dummy(Ty::new_slice(tcx, tcx.types.u8))]),
 
         ty::Dynamic(..)
         | ty::Param(..)
@@ -47,46 +47,48 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
         }
 
         ty::RawPtr(ty::TypeAndMut { ty: element_ty, .. }) | ty::Ref(_, element_ty, _) => {
-            Ok(vec![element_ty])
+            Ok(vec![ty::Binder::dummy(element_ty)])
         }
 
-        ty::Array(element_ty, _) | ty::Slice(element_ty) => Ok(vec![element_ty]),
+        ty::Array(element_ty, _) | ty::Slice(element_ty) => Ok(vec![ty::Binder::dummy(element_ty)]),
 
         ty::Tuple(tys) => {
             // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
-            Ok(tys.iter().collect())
+            Ok(tys.iter().map(ty::Binder::dummy).collect())
         }
 
-        ty::Closure(_, args) => Ok(vec![args.as_closure().tupled_upvars_ty()]),
+        ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
 
-        ty::CoroutineClosure(_, args) => Ok(vec![args.as_coroutine_closure().tupled_upvars_ty()]),
+        ty::CoroutineClosure(_, args) => {
+            Ok(vec![ty::Binder::dummy(args.as_coroutine_closure().tupled_upvars_ty())])
+        }
 
         ty::Coroutine(_, args) => {
             let coroutine_args = args.as_coroutine();
-            Ok(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()])
+            Ok(vec![
+                ty::Binder::dummy(coroutine_args.tupled_upvars_ty()),
+                ty::Binder::dummy(coroutine_args.witness()),
+            ])
         }
 
         ty::CoroutineWitness(def_id, args) => Ok(ecx
             .tcx()
             .coroutine_hidden_types(def_id)
-            .map(|bty| {
-                ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars(
-                    tcx,
-                    bty.instantiate(tcx, args),
-                ))
-            })
+            .map(|bty| replace_erased_lifetimes_with_bound_vars(tcx, bty.instantiate(tcx, args)))
             .collect()),
 
         // For `PhantomData<T>`, we pass `T`.
-        ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![args.type_at(0)]),
+        ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]),
 
-        ty::Adt(def, args) => Ok(def.all_fields().map(|f| f.ty(tcx, args)).collect()),
+        ty::Adt(def, args) => {
+            Ok(def.all_fields().map(|f| ty::Binder::dummy(f.ty(tcx, args))).collect())
+        }
 
         ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
             // We can resolve the `impl Trait` to its concrete type,
             // which enforces a DAG between the functions requiring
             // the auto trait bounds in question.
-            Ok(vec![tcx.type_of(def_id).instantiate(tcx, args)])
+            Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, args))])
         }
     }
 }
@@ -116,7 +118,7 @@ pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>(
 pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
     ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
-) -> Result<Vec<Ty<'tcx>>, NoSolution> {
+) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution> {
     match *ty.kind() {
         ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
         | ty::Uint(_)
@@ -150,11 +152,11 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
             bug!("unexpected type `{ty}`")
         }
 
-        ty::Tuple(tys) => Ok(tys.to_vec()),
+        ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()),
 
         ty::Adt(def, args) => {
             let sized_crit = def.sized_constraint(ecx.tcx());
-            Ok(sized_crit.iter_instantiated(ecx.tcx(), args).collect())
+            Ok(sized_crit.iter_instantiated(ecx.tcx(), args).map(ty::Binder::dummy).collect())
         }
     }
 }
@@ -163,7 +165,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
 pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
     ecx: &EvalCtxt<'_, 'tcx>,
     ty: Ty<'tcx>,
-) -> Result<Vec<Ty<'tcx>>, NoSolution> {
+) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution> {
     match *ty.kind() {
         ty::FnDef(..) | ty::FnPtr(_) | ty::Error(_) => Ok(vec![]),
 
@@ -194,9 +196,9 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
             bug!("unexpected type `{ty}`")
         }
 
-        ty::Tuple(tys) => Ok(tys.to_vec()),
+        ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()),
 
-        ty::Closure(_, args) => Ok(vec![args.as_closure().tupled_upvars_ty()]),
+        ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
 
         ty::CoroutineClosure(..) => Err(NoSolution),
 
@@ -205,7 +207,10 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
             Movability::Movable => {
                 if ecx.tcx().features().coroutine_clone {
                     let coroutine = args.as_coroutine();
-                    Ok(vec![coroutine.tupled_upvars_ty(), coroutine.witness()])
+                    Ok(vec![
+                        ty::Binder::dummy(coroutine.tupled_upvars_ty()),
+                        ty::Binder::dummy(coroutine.witness()),
+                    ])
                 } else {
                     Err(NoSolution)
                 }
@@ -216,10 +221,10 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
             .tcx()
             .coroutine_hidden_types(def_id)
             .map(|bty| {
-                ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars(
+                replace_erased_lifetimes_with_bound_vars(
                     ecx.tcx(),
                     bty.instantiate(ecx.tcx(), args),
-                ))
+                )
             })
             .collect()),
     }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 76c50a11102..803379af005 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -477,10 +477,11 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 }
             }
         } else {
-            let kind = self.infcx.instantiate_binder_with_placeholders(kind);
-            let goal = goal.with(self.tcx(), ty::Binder::dummy(kind));
-            self.add_goal(GoalSource::Misc, goal);
-            self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            self.infcx.enter_forall(kind, |kind| {
+                let goal = goal.with(self.tcx(), ty::Binder::dummy(kind));
+                self.add_goal(GoalSource::Misc, goal);
+                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            })
         }
     }
 
@@ -801,13 +802,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         )
     }
 
-    pub(super) fn instantiate_binder_with_placeholders<T: TypeFoldable<TyCtxt<'tcx>> + Copy>(
+    pub(super) fn enter_forall<T: TypeFoldable<TyCtxt<'tcx>> + Copy, U>(
         &self,
         value: ty::Binder<'tcx, T>,
-    ) -> T {
-        self.infcx.instantiate_binder_with_placeholders(value)
+        f: impl FnOnce(T) -> U,
+    ) -> U {
+        self.infcx.enter_forall(value, f)
     }
-
     pub(super) fn resolve_vars_if_possible<T>(&self, value: T) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index 315df06be41..69b69930432 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -31,103 +31,108 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
     ) -> SelectionResult<'tcx, Selection<'tcx>> {
         assert!(self.next_trait_solver());
 
-        let trait_goal = Goal::new(
-            self.tcx,
-            obligation.param_env,
-            self.instantiate_binder_with_placeholders(obligation.predicate),
-        );
-
-        let (result, _) = EvalCtxt::enter_root(self, GenerateProofTree::Never, |ecx| {
-            let goal = Goal::new(ecx.tcx(), trait_goal.param_env, trait_goal.predicate);
-            let (orig_values, canonical_goal) = ecx.canonicalize_goal(goal);
-            let mut candidates = ecx.compute_canonical_trait_candidates(canonical_goal);
-
-            // pseudo-winnow
-            if candidates.len() == 0 {
-                return Err(SelectionError::Unimplemented);
-            } else if candidates.len() > 1 {
-                let mut i = 0;
-                while i < candidates.len() {
-                    let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| {
-                        candidate_should_be_dropped_in_favor_of(
-                            ecx.tcx(),
-                            &candidates[i],
-                            &candidates[j],
-                        )
-                    });
-                    if should_drop_i {
-                        candidates.swap_remove(i);
-                    } else {
-                        i += 1;
-                        if i > 1 {
-                            return Ok(None);
+        self.enter_forall(obligation.predicate, |pred| {
+            let trait_goal = Goal::new(self.tcx, obligation.param_env, pred);
+
+            let (result, _) = EvalCtxt::enter_root(self, GenerateProofTree::Never, |ecx| {
+                let goal = Goal::new(ecx.tcx(), trait_goal.param_env, trait_goal.predicate);
+                let (orig_values, canonical_goal) = ecx.canonicalize_goal(goal);
+                let mut candidates = ecx.compute_canonical_trait_candidates(canonical_goal);
+
+                // pseudo-winnow
+                if candidates.len() == 0 {
+                    return Err(SelectionError::Unimplemented);
+                } else if candidates.len() > 1 {
+                    let mut i = 0;
+                    while i < candidates.len() {
+                        let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| {
+                            candidate_should_be_dropped_in_favor_of(
+                                ecx.tcx(),
+                                &candidates[i],
+                                &candidates[j],
+                            )
+                        });
+                        if should_drop_i {
+                            candidates.swap_remove(i);
+                        } else {
+                            i += 1;
+                            if i > 1 {
+                                return Ok(None);
+                            }
                         }
                     }
                 }
-            }
 
-            let candidate = candidates.pop().unwrap();
-            let (certainty, nested_goals) = ecx
-                .instantiate_and_apply_query_response(
-                    trait_goal.param_env,
-                    orig_values,
-                    candidate.result,
-                )
-                .map_err(|_| SelectionError::Unimplemented)?;
-
-            Ok(Some((candidate, certainty, nested_goals)))
-        });
-
-        let (candidate, certainty, nested_goals) = match result {
-            Ok(Some((candidate, certainty, nested_goals))) => (candidate, certainty, nested_goals),
-            Ok(None) => return Ok(None),
-            Err(e) => return Err(e),
-        };
-
-        let nested_obligations: Vec<_> = nested_goals
-            .into_iter()
-            .map(|goal| {
-                Obligation::new(self.tcx, ObligationCause::dummy(), goal.param_env, goal.predicate)
-            })
-            .collect();
-
-        let goal = self.resolve_vars_if_possible(trait_goal);
-        match (certainty, candidate.source) {
-            // Rematching the implementation will instantiate the same nested goals that
-            // would have caused the ambiguity, so we can still make progress here regardless.
-            (_, CandidateSource::Impl(def_id)) => {
-                rematch_impl(self, goal, def_id, nested_obligations)
-            }
+                let candidate = candidates.pop().unwrap();
+                let (certainty, nested_goals) = ecx
+                    .instantiate_and_apply_query_response(
+                        trait_goal.param_env,
+                        orig_values,
+                        candidate.result,
+                    )
+                    .map_err(|_| SelectionError::Unimplemented)?;
+
+                Ok(Some((candidate, certainty, nested_goals)))
+            });
+
+            let (candidate, certainty, nested_goals) = match result {
+                Ok(Some((candidate, certainty, nested_goals))) => {
+                    (candidate, certainty, nested_goals)
+                }
+                Ok(None) => return Ok(None),
+                Err(e) => return Err(e),
+            };
+
+            let nested_obligations: Vec<_> = nested_goals
+                .into_iter()
+                .map(|goal| {
+                    Obligation::new(
+                        self.tcx,
+                        ObligationCause::dummy(),
+                        goal.param_env,
+                        goal.predicate,
+                    )
+                })
+                .collect();
+
+            let goal = self.resolve_vars_if_possible(trait_goal);
+            match (certainty, candidate.source) {
+                // Rematching the implementation will instantiate the same nested goals that
+                // would have caused the ambiguity, so we can still make progress here regardless.
+                (_, CandidateSource::Impl(def_id)) => {
+                    rematch_impl(self, goal, def_id, nested_obligations)
+                }
 
-            // If an unsize goal is ambiguous, then we can manually rematch it to make
-            // selection progress for coercion during HIR typeck. If it is *not* ambiguous,
-            // but is `BuiltinImplSource::Misc`, it may have nested `Unsize` goals,
-            // and we need to rematch those to detect tuple unsizing and trait upcasting.
-            // FIXME: This will be wrong if we have param-env or where-clause bounds
-            // with the unsize goal -- we may need to mark those with different impl
-            // sources.
-            (Certainty::Maybe(_), CandidateSource::BuiltinImpl(src))
-            | (Certainty::Yes, CandidateSource::BuiltinImpl(src @ BuiltinImplSource::Misc))
-                if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) =>
-            {
-                rematch_unsize(self, goal, nested_obligations, src, certainty)
-            }
+                // If an unsize goal is ambiguous, then we can manually rematch it to make
+                // selection progress for coercion during HIR typeck. If it is *not* ambiguous,
+                // but is `BuiltinImplSource::Misc`, it may have nested `Unsize` goals,
+                // and we need to rematch those to detect tuple unsizing and trait upcasting.
+                // FIXME: This will be wrong if we have param-env or where-clause bounds
+                // with the unsize goal -- we may need to mark those with different impl
+                // sources.
+                (Certainty::Maybe(_), CandidateSource::BuiltinImpl(src))
+                | (Certainty::Yes, CandidateSource::BuiltinImpl(src @ BuiltinImplSource::Misc))
+                    if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) =>
+                {
+                    rematch_unsize(self, goal, nested_obligations, src, certainty)
+                }
 
-            // Technically some builtin impls have nested obligations, but if
-            // `Certainty::Yes`, then they should've all been verified and don't
-            // need re-checking.
-            (Certainty::Yes, CandidateSource::BuiltinImpl(src)) => {
-                Ok(Some(ImplSource::Builtin(src, nested_obligations)))
-            }
+                // Technically some builtin impls have nested obligations, but if
+                // `Certainty::Yes`, then they should've all been verified and don't
+                // need re-checking.
+                (Certainty::Yes, CandidateSource::BuiltinImpl(src)) => {
+                    Ok(Some(ImplSource::Builtin(src, nested_obligations)))
+                }
 
-            // It's fine not to do anything to rematch these, since there are no
-            // nested obligations.
-            (Certainty::Yes, CandidateSource::ParamEnv(_) | CandidateSource::AliasBound) => {
-                Ok(Some(ImplSource::Param(nested_obligations)))
-            }
+                // It's fine not to do anything to rematch these, since there are no
+                // nested obligations.
+                (Certainty::Yes, CandidateSource::ParamEnv(_) | CandidateSource::AliasBound) => {
+                    Ok(Some(ImplSource::Param(nested_obligations)))
+                }
 
-            (Certainty::Maybe(_), _) => Ok(None),
-        }
+                (Certainty::Maybe(_), _) => Ok(None),
+            }
+        })
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index f08622816ec..63555a305d8 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -140,7 +140,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
                                     )
                                 }
                                 ty::PredicateKind::Subtype(pred) => {
-                                    let (a, b) = infcx.instantiate_binder_with_placeholders(
+                                    let (a, b) = infcx.enter_forall_and_leak_universe(
                                         goal.predicate.kind().rebind((pred.a, pred.b)),
                                     );
                                     let expected_found = ExpectedFound::new(true, a, b);
@@ -150,7 +150,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
                                     )
                                 }
                                 ty::PredicateKind::Coerce(pred) => {
-                                    let (a, b) = infcx.instantiate_binder_with_placeholders(
+                                    let (a, b) = infcx.enter_forall_and_leak_universe(
                                         goal.predicate.kind().rebind((pred.a, pred.b)),
                                     );
                                     let expected_found = ExpectedFound::new(false, a, b);
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 6984f0ba694..a7330136fe7 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -124,25 +124,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         }
     }
 
-    #[instrument(level = "debug", skip(self))]
-    fn compute_closure_kind_goal(
-        &mut self,
-        goal: Goal<'tcx, (DefId, ty::GenericArgsRef<'tcx>, ty::ClosureKind)>,
-    ) -> QueryResult<'tcx> {
-        let (_, args, expected_kind) = goal.predicate;
-        let found_kind = args.as_closure().kind_ty().to_opt_closure_kind();
-
-        let Some(found_kind) = found_kind else {
-            return self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
-        };
-        if found_kind.extends(expected_kind) {
-            self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-        } else {
-            Err(NoSolution)
-        }
-    }
-
-    #[instrument(level = "debug", skip(self))]
     fn compute_object_safe_goal(&mut self, trait_def_id: DefId) -> QueryResult<'tcx> {
         if self.tcx().check_is_object_safe(trait_def_id) {
             self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
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 47ba549022d..d177109c420 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -491,6 +491,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
         goal: Goal<'tcx, Self>,
     ) -> QueryResult<'tcx> {
         let tcx = ecx.tcx();
+        let metadata_def_id = tcx.require_lang_item(LangItem::Metadata, None);
+        assert_eq!(metadata_def_id, goal.predicate.def_id());
         ecx.probe_misc_candidate("builtin pointee").enter(|ecx| {
             let metadata_ty = match goal.predicate.self_ty().kind() {
                 ty::Bool
@@ -522,7 +524,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                 }
 
                 ty::Alias(_, _) | ty::Param(_) | ty::Placeholder(..) => {
-                    // FIXME(ptr_metadata): It would also be possible to return a `Ok(Ambig)` with no constraints.
+                    // This is the "fallback impl" for type parameters, unnormalizable projections
+                    // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
+                    // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
+                    // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
                     let sized_predicate = ty::TraitRef::from_lang_item(
                         tcx,
                         LangItem::Sized,
@@ -536,30 +541,16 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
 
                 ty::Adt(def, args) if def.is_struct() => match def.non_enum_variant().tail_opt() {
                     None => tcx.types.unit,
-                    Some(field_def) => {
-                        let self_ty = field_def.ty(tcx, args);
-                        // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
-                        ecx.add_goal(
-                            GoalSource::Misc,
-                            goal.with(tcx, goal.predicate.with_self_ty(tcx, self_ty)),
-                        );
-                        return ecx
-                            .evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
+                    Some(tail_def) => {
+                        let tail_ty = tail_def.ty(tcx, args);
+                        Ty::new_projection(tcx, metadata_def_id, [tail_ty])
                     }
                 },
                 ty::Adt(_, _) => tcx.types.unit,
 
                 ty::Tuple(elements) => match elements.last() {
                     None => tcx.types.unit,
-                    Some(&self_ty) => {
-                        // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
-                        ecx.add_goal(
-                            GoalSource::Misc,
-                            goal.with(tcx, goal.predicate.with_self_ty(tcx, self_ty)),
-                        );
-                        return ecx
-                            .evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
-                    }
+                    Some(&tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]),
                 },
 
                 ty::Infer(
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index fd09a6b671d..044832224e5 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -1049,14 +1049,21 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     fn probe_and_evaluate_goal_for_constituent_tys(
         &mut self,
         goal: Goal<'tcx, TraitPredicate<'tcx>>,
-        constituent_tys: impl Fn(&EvalCtxt<'_, 'tcx>, Ty<'tcx>) -> Result<Vec<Ty<'tcx>>, NoSolution>,
+        constituent_tys: impl Fn(
+            &EvalCtxt<'_, 'tcx>,
+            Ty<'tcx>,
+        ) -> Result<Vec<ty::Binder<'tcx, Ty<'tcx>>>, NoSolution>,
     ) -> QueryResult<'tcx> {
         self.probe_misc_candidate("constituent tys").enter(|ecx| {
             ecx.add_goals(
                 GoalSource::ImplWhereBound,
                 constituent_tys(ecx, goal.predicate.self_ty())?
                     .into_iter()
-                    .map(|ty| goal.with(ecx.tcx(), goal.predicate.with_self_ty(ecx.tcx(), ty)))
+                    .map(|ty| {
+                        ecx.enter_forall(ty, |ty| {
+                            goal.with(ecx.tcx(), goal.predicate.with_self_ty(ecx.tcx(), ty))
+                        })
+                    })
                     .collect::<Vec<_>>(),
             );
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 7933654a915..81c72fc4b7b 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);
-        let _ = infcx.process_registered_region_obligations::<!>(&outlives_env, |ty, _| Ok(ty));
+        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();
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 4b20de26219..cbe9a238b1c 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -971,7 +971,7 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
 
         let Goal { param_env, predicate } = goal.goal();
 
-        // For bound predicates we simply call `infcx.instantiate_binder_with_placeholders`
+        // For bound predicates we simply call `infcx.enter_forall`
         // and then prove the resulting predicate as a nested goal.
         let trait_ref = match predicate.kind().no_bound_vars() {
             Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref,
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs
index b246e476bed..c6f5af08013 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs
@@ -21,51 +21,62 @@ pub fn recompute_applicable_impls<'tcx>(
 
     let impl_may_apply = |impl_def_id| {
         let ocx = ObligationCtxt::new(infcx);
-        let placeholder_obligation =
-            infcx.instantiate_binder_with_placeholders(obligation.predicate);
-        let obligation_trait_ref =
-            ocx.normalize(&ObligationCause::dummy(), param_env, placeholder_obligation.trait_ref);
-
-        let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
-        let impl_trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, impl_args);
-        let impl_trait_ref = ocx.normalize(&ObligationCause::dummy(), param_env, impl_trait_ref);
-
-        if let Err(_) =
-            ocx.eq(&ObligationCause::dummy(), param_env, obligation_trait_ref, impl_trait_ref)
-        {
-            return false;
-        }
+        infcx.enter_forall(obligation.predicate, |placeholder_obligation| {
+            let obligation_trait_ref = ocx.normalize(
+                &ObligationCause::dummy(),
+                param_env,
+                placeholder_obligation.trait_ref,
+            );
+
+            let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
+            let impl_trait_ref =
+                tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, impl_args);
+            let impl_trait_ref =
+                ocx.normalize(&ObligationCause::dummy(), param_env, impl_trait_ref);
+
+            if let Err(_) =
+                ocx.eq(&ObligationCause::dummy(), param_env, obligation_trait_ref, impl_trait_ref)
+            {
+                return false;
+            }
 
-        let impl_predicates = tcx.predicates_of(impl_def_id).instantiate(tcx, impl_args);
-        ocx.register_obligations(impl_predicates.predicates.iter().map(|&predicate| {
-            Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
-        }));
+            let impl_predicates = tcx.predicates_of(impl_def_id).instantiate(tcx, impl_args);
+            ocx.register_obligations(impl_predicates.predicates.iter().map(|&predicate| {
+                Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
+            }));
 
-        ocx.select_where_possible().is_empty()
+            ocx.select_where_possible().is_empty()
+        })
     };
 
     let param_env_candidate_may_apply = |poly_trait_predicate: ty::PolyTraitPredicate<'tcx>| {
         let ocx = ObligationCtxt::new(infcx);
-        let placeholder_obligation =
-            infcx.instantiate_binder_with_placeholders(obligation.predicate);
-        let obligation_trait_ref =
-            ocx.normalize(&ObligationCause::dummy(), param_env, placeholder_obligation.trait_ref);
-
-        let param_env_predicate = infcx.instantiate_binder_with_fresh_vars(
-            DUMMY_SP,
-            BoundRegionConversionTime::HigherRankedType,
-            poly_trait_predicate,
-        );
-        let param_env_trait_ref =
-            ocx.normalize(&ObligationCause::dummy(), param_env, param_env_predicate.trait_ref);
-
-        if let Err(_) =
-            ocx.eq(&ObligationCause::dummy(), param_env, obligation_trait_ref, param_env_trait_ref)
-        {
-            return false;
-        }
+        infcx.enter_forall(obligation.predicate, |placeholder_obligation| {
+            let obligation_trait_ref = ocx.normalize(
+                &ObligationCause::dummy(),
+                param_env,
+                placeholder_obligation.trait_ref,
+            );
+
+            let param_env_predicate = infcx.instantiate_binder_with_fresh_vars(
+                DUMMY_SP,
+                BoundRegionConversionTime::HigherRankedType,
+                poly_trait_predicate,
+            );
+            let param_env_trait_ref =
+                ocx.normalize(&ObligationCause::dummy(), param_env, param_env_predicate.trait_ref);
+
+            if let Err(_) = ocx.eq(
+                &ObligationCause::dummy(),
+                param_env,
+                obligation_trait_ref,
+                param_env_trait_ref,
+            ) {
+                return false;
+            }
 
-        ocx.select_where_possible().is_empty()
+            ocx.select_where_possible().is_empty()
+        })
     };
 
     let mut ambiguities = Vec::new();
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 972da180a33..ceff7187646 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
@@ -64,39 +64,44 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     ) -> Option<(DefId, GenericArgsRef<'tcx>)> {
         let tcx = self.tcx;
         let param_env = obligation.param_env;
-        let trait_ref = self.instantiate_binder_with_placeholders(trait_ref);
-        let trait_self_ty = trait_ref.self_ty();
+        self.enter_forall(trait_ref, |trait_ref| {
+            let trait_self_ty = trait_ref.self_ty();
 
-        let mut self_match_impls = vec![];
-        let mut fuzzy_match_impls = vec![];
+            let mut self_match_impls = vec![];
+            let mut fuzzy_match_impls = vec![];
 
-        self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| {
-            let impl_args = self.fresh_args_for_item(obligation.cause.span, def_id);
-            let impl_trait_ref = tcx.impl_trait_ref(def_id).unwrap().instantiate(tcx, impl_args);
+            self.tcx.for_each_relevant_impl(trait_ref.def_id, trait_self_ty, |def_id| {
+                let impl_args = self.fresh_args_for_item(obligation.cause.span, def_id);
+                let impl_trait_ref =
+                    tcx.impl_trait_ref(def_id).unwrap().instantiate(tcx, impl_args);
 
-            let impl_self_ty = impl_trait_ref.self_ty();
+                let impl_self_ty = impl_trait_ref.self_ty();
 
-            if self.can_eq(param_env, trait_self_ty, impl_self_ty) {
-                self_match_impls.push((def_id, impl_args));
+                if self.can_eq(param_env, trait_self_ty, impl_self_ty) {
+                    self_match_impls.push((def_id, impl_args));
 
-                if iter::zip(trait_ref.args.types().skip(1), impl_trait_ref.args.types().skip(1))
+                    if iter::zip(
+                        trait_ref.args.types().skip(1),
+                        impl_trait_ref.args.types().skip(1),
+                    )
                     .all(|(u, v)| self.fuzzy_match_tys(u, v, false).is_some())
-                {
-                    fuzzy_match_impls.push((def_id, impl_args));
+                    {
+                        fuzzy_match_impls.push((def_id, impl_args));
+                    }
                 }
-            }
-        });
+            });
 
-        let impl_def_id_and_args = if self_match_impls.len() == 1 {
-            self_match_impls[0]
-        } else if fuzzy_match_impls.len() == 1 {
-            fuzzy_match_impls[0]
-        } else {
-            return None;
-        };
+            let impl_def_id_and_args = if self_match_impls.len() == 1 {
+                self_match_impls[0]
+            } else if fuzzy_match_impls.len() == 1 {
+                fuzzy_match_impls[0]
+            } else {
+                return None;
+            };
 
-        tcx.has_attr(impl_def_id_and_args.0, sym::rustc_on_unimplemented)
-            .then_some(impl_def_id_and_args)
+            tcx.has_attr(impl_def_id_and_args.0, sym::rustc_on_unimplemented)
+                .then_some(impl_def_id_and_args)
+        })
     }
 
     /// Used to set on_unimplemented's `ItemContext`
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 243f583aed8..f68200b6f4d 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -19,7 +19,7 @@ use rustc_errors::{
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::intravisit::{Map, Visitor};
+use rustc_hir::intravisit::Visitor;
 use rustc_hir::is_range_literal;
 use rustc_hir::lang_items::LangItem;
 use rustc_hir::{CoroutineDesugaring, CoroutineKind, CoroutineSource, Expr, HirId, Node};
@@ -774,7 +774,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         if steps > 0 {
                             // Don't care about `&mut` because `DerefMut` is used less
                             // often and user will not expect that an autoderef happens.
-                            if let Some(hir::Node::Expr(hir::Expr {
+                            if let hir::Node::Expr(hir::Expr {
                                 kind:
                                     hir::ExprKind::AddrOf(
                                         hir::BorrowKind::Ref,
@@ -782,7 +782,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                         expr,
                                     ),
                                 ..
-                            })) = self.tcx.opt_hir_node(*arg_hir_id)
+                            }) = self.tcx.hir_node(*arg_hir_id)
                             {
                                 let derefs = "*".repeat(steps);
                                 err.span_suggestion_verbose(
@@ -1199,7 +1199,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let Res::Local(hir_id) = path.res else {
             return;
         };
-        let Some(hir::Node::Pat(pat)) = self.tcx.opt_hir_node(hir_id) else {
+        let hir::Node::Pat(pat) = self.tcx.hir_node(hir_id) else {
             return;
         };
         let Some(hir::Node::Local(hir::Local { ty: None, init: Some(init), .. })) =
@@ -1248,52 +1248,55 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         trait_pred: ty::PolyTraitPredicate<'tcx>,
     ) -> bool {
         let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
-        let ty = self.instantiate_binder_with_placeholders(self_ty);
-        let Some(generics) = self.tcx.hir().get_generics(obligation.cause.body_id) else {
-            return false;
-        };
-        let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false };
-        let ty::Param(param) = inner_ty.kind() else { return false };
-        let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } =
-            obligation.cause.code()
-        else {
-            return false;
-        };
-        let arg_node = self.tcx.hir_node(*arg_hir_id);
-        let Node::Expr(Expr { kind: hir::ExprKind::Path(_), .. }) = arg_node else { return false };
+        self.enter_forall(self_ty, |ty: Ty<'_>| {
+            let Some(generics) = self.tcx.hir().get_generics(obligation.cause.body_id) else {
+                return false;
+            };
+            let ty::Ref(_, inner_ty, hir::Mutability::Not) = ty.kind() else { return false };
+            let ty::Param(param) = inner_ty.kind() else { return false };
+            let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } =
+                obligation.cause.code()
+            else {
+                return false;
+            };
+            let arg_node = self.tcx.hir_node(*arg_hir_id);
+            let Node::Expr(Expr { kind: hir::ExprKind::Path(_), .. }) = arg_node else {
+                return false;
+            };
 
-        let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None);
-        let has_clone = |ty| {
-            self.type_implements_trait(clone_trait, [ty], obligation.param_env)
-                .must_apply_modulo_regions()
-        };
+            let clone_trait = self.tcx.require_lang_item(LangItem::Clone, None);
+            let has_clone = |ty| {
+                self.type_implements_trait(clone_trait, [ty], obligation.param_env)
+                    .must_apply_modulo_regions()
+            };
 
-        let new_obligation = self.mk_trait_obligation_with_new_self_ty(
-            obligation.param_env,
-            trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)),
-        );
+            let new_obligation = self.mk_trait_obligation_with_new_self_ty(
+                obligation.param_env,
+                trait_pred.map_bound(|trait_pred| (trait_pred, *inner_ty)),
+            );
 
-        if self.predicate_may_hold(&new_obligation) && has_clone(ty) {
-            if !has_clone(param.to_ty(self.tcx)) {
-                suggest_constraining_type_param(
-                    self.tcx,
-                    generics,
-                    err,
-                    param.name.as_str(),
-                    "Clone",
-                    Some(clone_trait),
-                    None,
+            if self.predicate_may_hold(&new_obligation) && has_clone(ty) {
+                if !has_clone(param.to_ty(self.tcx)) {
+                    suggest_constraining_type_param(
+                        self.tcx,
+                        generics,
+                        err,
+                        param.name.as_str(),
+                        "Clone",
+                        Some(clone_trait),
+                        None,
+                    );
+                }
+                err.span_suggestion_verbose(
+                    obligation.cause.span.shrink_to_hi(),
+                    "consider using clone here",
+                    ".clone()".to_string(),
+                    Applicability::MaybeIncorrect,
                 );
+                return true;
             }
-            err.span_suggestion_verbose(
-                obligation.cause.span.shrink_to_hi(),
-                "consider using clone here",
-                ".clone()",
-                Applicability::MaybeIncorrect,
-            );
-            return true;
-        }
-        false
+            false
+        })
     }
 
     /// Extracts information about a callable type for diagnostics. This is a
@@ -1786,7 +1789,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let Res::Local(hir_id) = path.res
-                && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(hir_id)
+                && let hir::Node::Pat(binding) = self.tcx.hir_node(hir_id)
                 && let Some(hir::Node::Local(local)) = self.tcx.hir().find_parent(binding.hir_id)
                 && let None = local.ty
                 && let Some(binding_expr) = local.init
@@ -2198,7 +2201,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let ty::FnPtr(found) = found.kind() else {
             return;
         };
-        let Some(Node::Expr(arg)) = self.tcx.opt_hir_node(*arg_hir_id) else {
+        let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id) else {
             return;
         };
         let hir::ExprKind::Path(path) = arg.kind else {
@@ -3186,8 +3189,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
             ObligationCauseCode::VariableType(hir_id) => {
                 let parent_node = tcx.hir().parent_id(hir_id);
-                match tcx.opt_hir_node(parent_node) {
-                    Some(Node::Local(hir::Local { ty: Some(ty), .. })) => {
+                match tcx.hir_node(parent_node) {
+                    Node::Local(hir::Local { ty: Some(ty), .. }) => {
                         err.span_suggestion_verbose(
                             ty.span.shrink_to_lo(),
                             "consider borrowing here",
@@ -3196,10 +3199,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         );
                         err.note("all local variables must have a statically known size");
                     }
-                    Some(Node::Local(hir::Local {
+                    Node::Local(hir::Local {
                         init: Some(hir::Expr { kind: hir::ExprKind::Index(..), span, .. }),
                         ..
-                    })) => {
+                    }) => {
                         // When encountering an assignment of an unsized trait, like
                         // `let x = ""[..];`, provide a suggestion to borrow the initializer in
                         // order to use have a slice instead.
@@ -3211,7 +3214,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         );
                         err.note("all local variables must have a statically known size");
                     }
-                    Some(Node::Param(param)) => {
+                    Node::Param(param) => {
                         err.span_suggestion_verbose(
                             param.ty_span.shrink_to_lo(),
                             "function arguments must have a statically known size, borrowed types \
@@ -3233,7 +3236,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 let borrowed_msg = "function arguments must have a statically known size, borrowed \
                                     types always have a known size";
                 if let Some(hir_id) = hir_id
-                    && let Some(hir::Node::Param(param)) = self.tcx.hir().find(hir_id)
+                    && let hir::Node::Param(param) = self.tcx.hir_node(hir_id)
                     && let Some(item) = self.tcx.hir().find_parent(hir_id)
                     && let Some(decl) = item.fn_decl()
                     && let Some(t) = decl.inputs.iter().find(|t| param.ty_span.contains(t.span))
@@ -3247,7 +3250,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     //                                 param._ty_span
                     ty = Some(t);
                 } else if let Some(hir_id) = hir_id
-                    && let Some(hir::Node::Ty(t)) = self.tcx.hir().find(hir_id)
+                    && let hir::Node::Ty(t) = self.tcx.hir_node(hir_id)
                 {
                     ty = Some(t);
                 }
@@ -3958,7 +3961,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         call_hir_id: HirId,
     ) {
         let tcx = self.tcx;
-        if let Some(Node::Expr(expr)) = tcx.opt_hir_node(arg_hir_id)
+        if let Node::Expr(expr) = tcx.hir_node(arg_hir_id)
             && let Some(typeck_results) = &self.typeck_results
         {
             if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr {
@@ -4038,26 +4041,27 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 if let Some(where_pred) = where_pred.as_trait_clause()
                     && let Some(failed_pred) = failed_pred.to_opt_poly_trait_pred()
                 {
-                    let where_pred = self.instantiate_binder_with_placeholders(where_pred);
-                    let failed_pred = self.instantiate_binder_with_fresh_vars(
-                        expr.span,
-                        BoundRegionConversionTime::FnCall,
-                        failed_pred,
-                    );
+                    self.enter_forall(where_pred, |where_pred| {
+                        let failed_pred = self.instantiate_binder_with_fresh_vars(
+                            expr.span,
+                            BoundRegionConversionTime::FnCall,
+                            failed_pred,
+                        );
 
-                    let zipped = iter::zip(where_pred.trait_ref.args, failed_pred.trait_ref.args);
-                    for (expected, actual) in zipped {
-                        self.probe(|_| {
-                            match self.at(&ObligationCause::misc(expr.span, body_id), param_env).eq(
-                                DefineOpaqueTypes::No,
-                                expected,
-                                actual,
-                            ) {
-                                Ok(_) => (), // We ignore nested obligations here for now.
-                                Err(err) => type_diffs.push(err),
-                            }
-                        })
-                    }
+                        let zipped =
+                            iter::zip(where_pred.trait_ref.args, failed_pred.trait_ref.args);
+                        for (expected, actual) in zipped {
+                            self.probe(|_| {
+                                match self
+                                    .at(&ObligationCause::misc(expr.span, body_id), param_env)
+                                    .eq(DefineOpaqueTypes::No, expected, actual)
+                                {
+                                    Ok(_) => (), // We ignore nested obligations here for now.
+                                    Err(err) => type_diffs.push(err),
+                                }
+                            })
+                        }
+                    })
                 } else if let Some(where_pred) = where_pred.as_projection_clause()
                     && let Some(failed_pred) = failed_pred.to_opt_poly_projection_pred()
                     && let Some(found) = failed_pred.skip_binder().term.ty()
@@ -4074,9 +4078,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let hir::Path { res: Res::Local(hir_id), .. } = path
-                && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id)
+                && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
                 && let parent_hir_id = self.tcx.hir().parent_id(binding.hir_id)
-                && let Some(hir::Node::Local(local)) = self.tcx.opt_hir_node(parent_hir_id)
+                && let hir::Node::Local(local) = self.tcx.hir_node(parent_hir_id)
                 && let Some(binding_expr) = local.init
             {
                 // If the expression we're calling on is a binding, we want to point at the
@@ -4087,17 +4091,16 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 self.point_at_chain(expr, typeck_results, type_diffs, param_env, err);
             }
         }
-        let call_node = tcx.opt_hir_node(call_hir_id);
-        if let Some(Node::Expr(hir::Expr {
-            kind: hir::ExprKind::MethodCall(path, rcvr, ..), ..
-        })) = call_node
+        let call_node = tcx.hir_node(call_hir_id);
+        if let Node::Expr(hir::Expr { kind: hir::ExprKind::MethodCall(path, rcvr, ..), .. }) =
+            call_node
         {
             if Some(rcvr.span) == err.span.primary_span() {
                 err.replace_span_with(path.ident.span, true);
             }
         }
 
-        if let Some(Node::Expr(expr)) = tcx.opt_hir_node(call_hir_id) {
+        if let Node::Expr(expr) = tcx.hir_node(call_hir_id) {
             if let hir::ExprKind::Call(hir::Expr { span, .. }, _)
             | hir::ExprKind::MethodCall(
                 hir::PathSegment { ident: Ident { span, .. }, .. },
@@ -4334,7 +4337,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let hir::Path { res: Res::Local(hir_id), .. } = path
-                && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id)
+                && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
                 && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
             {
                 // We've reached the root of the method call chain...
@@ -4615,14 +4618,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         {
             self.probe(|_| {
                 let ocx = ObligationCtxt::new(self);
-                let pred = self.instantiate_binder_with_placeholders(pred);
-                let pred = ocx.normalize(&ObligationCause::dummy(), param_env, pred);
-                ocx.register_obligation(Obligation::new(
-                    self.tcx,
-                    ObligationCause::dummy(),
-                    param_env,
-                    pred,
-                ));
+                self.enter_forall(pred, |pred| {
+                    let pred = ocx.normalize(&ObligationCause::dummy(), param_env, pred);
+                    ocx.register_obligation(Obligation::new(
+                        self.tcx,
+                        ObligationCause::dummy(),
+                        param_env,
+                        pred,
+                    ));
+                });
                 if !ocx.select_where_possible().is_empty() {
                     // encountered errors.
                     return;
@@ -4769,13 +4773,13 @@ fn hint_missing_borrow<'tcx>(
     }
 
     let found_args = match found.kind() {
-        ty::FnPtr(f) => infcx.instantiate_binder_with_placeholders(*f).inputs().iter(),
+        ty::FnPtr(f) => infcx.enter_forall(*f, |f| f.inputs().iter()),
         kind => {
             span_bug!(span, "found was converted to a FnPtr above but is now {:?}", kind)
         }
     };
     let expected_args = match expected.kind() {
-        ty::FnPtr(f) => infcx.instantiate_binder_with_placeholders(*f).inputs().iter(),
+        ty::FnPtr(f) => infcx.enter_forall(*f, |f| f.inputs().iter()),
         kind => {
             span_bug!(span, "expected was converted to a FnPtr above but is now {:?}", kind)
         }
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 1ac0f172ef4..07e4fef9dd4 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
@@ -993,13 +993,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, '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)
+            && let Node::Expr(arg) = self.tcx.hir_node(*arg_hir_id)
             && let arg = arg.peel_borrows()
             && let hir::ExprKind::Path(hir::QPath::Resolved(
                 None,
                 hir::Path { res: hir::def::Res::Local(hir_id), .. },
             )) = arg.kind
-            && let Some(Node::Pat(pat)) = self.tcx.opt_hir_node(*hir_id)
+            && let Node::Pat(pat) = self.tcx.hir_node(*hir_id)
             && let Some((preds, guar)) = self.reported_trait_errors.borrow().get(&pat.span)
             && preds.contains(&obligation.predicate)
         {
@@ -1037,10 +1037,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             }
         }
         let hir_id = self.tcx.local_def_id_to_hir_id(obligation.cause.body_id);
-        let body_id = match self.tcx.opt_hir_node(hir_id) {
-            Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. })) => {
-                body_id
-            }
+        let body_id = match self.tcx.hir_node(hir_id) {
+            hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(_, _, body_id), .. }) => body_id,
             _ => return false,
         };
         let mut v = V { search_span: span, found: None };
@@ -1163,7 +1161,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
             if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
                 && let hir::Path { res: hir::def::Res::Local(hir_id), .. } = path
-                && let Some(hir::Node::Pat(binding)) = self.tcx.opt_hir_node(*hir_id)
+                && let hir::Node::Pat(binding) = self.tcx.hir_node(*hir_id)
                 && let Some(parent) = self.tcx.hir().find_parent(binding.hir_id)
             {
                 // We've reached the root of the method call chain...
@@ -1307,12 +1305,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         let mut pred = obligation.predicate.to_opt_poly_trait_pred();
         while let Some((next_code, next_pred)) = code.parent() {
             if let Some(pred) = pred {
-                let pred = self.instantiate_binder_with_placeholders(pred);
-                diag.note(format!(
-                    "`{}` must implement `{}`, but it does not",
-                    pred.self_ty(),
-                    pred.print_modifiers_and_trait_path()
-                ));
+                self.enter_forall(pred, |pred| {
+                    diag.note(format!(
+                        "`{}` must implement `{}`, but it does not",
+                        pred.self_ty(),
+                        pred.print_modifiers_and_trait_path()
+                    ));
+                })
             }
             code = next_code;
             pred = next_pred;
@@ -2017,70 +2016,78 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         if let [single] = &impl_candidates {
             if self.probe(|_| {
                 let ocx = ObligationCtxt::new(self);
-                let obligation_trait_ref = self.instantiate_binder_with_placeholders(trait_ref);
-                let impl_args = self.fresh_args_for_item(DUMMY_SP, single.impl_def_id);
-                let impl_trait_ref = ocx.normalize(
-                    &ObligationCause::dummy(),
-                    param_env,
-                    ty::EarlyBinder::bind(single.trait_ref).instantiate(self.tcx, impl_args),
-                );
 
-                ocx.register_obligations(
-                    self.tcx
-                        .predicates_of(single.impl_def_id)
-                        .instantiate(self.tcx, impl_args)
-                        .into_iter()
-                        .map(|(clause, _)| {
-                            Obligation::new(self.tcx, ObligationCause::dummy(), param_env, clause)
-                        }),
-                );
-                if !ocx.select_where_possible().is_empty() {
-                    return false;
-                }
+                self.enter_forall(trait_ref, |obligation_trait_ref| {
+                    let impl_args = self.fresh_args_for_item(DUMMY_SP, single.impl_def_id);
+                    let impl_trait_ref = ocx.normalize(
+                        &ObligationCause::dummy(),
+                        param_env,
+                        ty::EarlyBinder::bind(single.trait_ref).instantiate(self.tcx, impl_args),
+                    );
 
-                let mut terrs = vec![];
-                for (obligation_arg, impl_arg) in
-                    std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args)
-                {
-                    if let Err(terr) =
-                        ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg)
-                    {
-                        terrs.push(terr);
-                    }
+                    ocx.register_obligations(
+                        self.tcx
+                            .predicates_of(single.impl_def_id)
+                            .instantiate(self.tcx, impl_args)
+                            .into_iter()
+                            .map(|(clause, _)| {
+                                Obligation::new(
+                                    self.tcx,
+                                    ObligationCause::dummy(),
+                                    param_env,
+                                    clause,
+                                )
+                            }),
+                    );
                     if !ocx.select_where_possible().is_empty() {
                         return false;
                     }
-                }
 
-                // Literally nothing unified, just give up.
-                if terrs.len() == impl_trait_ref.args.len() {
-                    return false;
-                }
+                    let mut terrs = vec![];
+                    for (obligation_arg, impl_arg) in
+                        std::iter::zip(obligation_trait_ref.args, impl_trait_ref.args)
+                    {
+                        if let Err(terr) =
+                            ocx.eq(&ObligationCause::dummy(), param_env, impl_arg, obligation_arg)
+                        {
+                            terrs.push(terr);
+                        }
+                        if !ocx.select_where_possible().is_empty() {
+                            return false;
+                        }
+                    }
 
-                let cand =
-                    self.resolve_vars_if_possible(impl_trait_ref).fold_with(&mut BottomUpFolder {
-                        tcx: self.tcx,
-                        ty_op: |ty| ty,
-                        lt_op: |lt| lt,
-                        ct_op: |ct| ct.normalize(self.tcx, ty::ParamEnv::empty()),
-                    });
-                err.highlighted_help(vec![
-                    StringPart::normal(format!("the trait `{}` ", cand.print_trait_sugared())),
-                    StringPart::highlighted("is"),
-                    StringPart::normal(" implemented for `"),
-                    StringPart::highlighted(cand.self_ty().to_string()),
-                    StringPart::normal("`"),
-                ]);
+                    // Literally nothing unified, just give up.
+                    if terrs.len() == impl_trait_ref.args.len() {
+                        return false;
+                    }
 
-                if let [TypeError::Sorts(exp_found)] = &terrs[..] {
-                    let exp_found = self.resolve_vars_if_possible(*exp_found);
-                    err.help(format!(
-                        "for that trait implementation, expected `{}`, found `{}`",
-                        exp_found.expected, exp_found.found
-                    ));
-                }
+                    let cand = self.resolve_vars_if_possible(impl_trait_ref).fold_with(
+                        &mut BottomUpFolder {
+                            tcx: self.tcx,
+                            ty_op: |ty| ty,
+                            lt_op: |lt| lt,
+                            ct_op: |ct| ct.normalize(self.tcx, ty::ParamEnv::empty()),
+                        },
+                    );
+                    err.highlighted_help(vec![
+                        StringPart::normal(format!("the trait `{}` ", cand.print_trait_sugared())),
+                        StringPart::highlighted("is"),
+                        StringPart::normal(" implemented for `"),
+                        StringPart::highlighted(cand.self_ty().to_string()),
+                        StringPart::normal("`"),
+                    ]);
+
+                    if let [TypeError::Sorts(exp_found)] = &terrs[..] {
+                        let exp_found = self.resolve_vars_if_possible(*exp_found);
+                        err.help(format!(
+                            "for that trait implementation, expected `{}`, found `{}`",
+                            exp_found.expected, exp_found.found
+                        ));
+                    }
 
-                true
+                    true
+                })
             }) {
                 return true;
             }
@@ -2371,6 +2378,12 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     return e;
                 }
 
+                if let Err(guar) = self.tcx.ensure().coherent_trait(trait_ref.def_id()) {
+                    // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
+                    // other `Foo` impls are incoherent.
+                    return guar;
+                }
+
                 // This is kind of a hack: it frequently happens that some earlier
                 // error prevents types from being fully inferred, and then we get
                 // a bunch of uninteresting errors saying something like "<generic
@@ -2666,6 +2679,14 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 if let Some(e) = self.tainted_by_errors() {
                     return e;
                 }
+
+                if let Err(guar) =
+                    self.tcx.ensure().coherent_trait(self.tcx.parent(data.projection_ty.def_id))
+                {
+                    // Avoid bogus "type annotations needed `Foo: Bar`" errors on `impl Bar for Foo` in case
+                    // other `Foo` impls are incoherent.
+                    return guar;
+                }
                 let subst = data
                     .projection_ty
                     .args
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 0337672b302..5ef7a202a12 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -358,8 +358,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                 | ty::PredicateKind::Coerce(_)
                 | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
                 | ty::PredicateKind::ConstEquate(..) => {
-                    let pred =
-                        ty::Binder::dummy(infcx.instantiate_binder_with_placeholders(binder));
+                    let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder));
                     ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)]))
                 }
                 ty::PredicateKind::Ambiguous => ProcessResult::Unchanged,
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 0dc11d785c4..054402acb5c 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -40,6 +40,7 @@ use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
 use rustc_span::symbol::sym;
 
 use std::collections::BTreeMap;
+use std::ops::ControlFlow;
 
 pub use rustc_middle::traits::Reveal;
 
@@ -250,8 +251,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
     let infcx = selcx.infcx;
     let r = infcx.commit_if_ok(|_snapshot| {
         let old_universe = infcx.universe();
-        let placeholder_predicate =
-            infcx.instantiate_binder_with_placeholders(obligation.predicate);
+        let placeholder_predicate = infcx.enter_forall_and_leak_universe(obligation.predicate);
         let new_universe = infcx.universe();
 
         let placeholder_obligation = obligation.with(infcx.tcx, placeholder_predicate);
@@ -1615,32 +1615,44 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
     candidate_set: &mut ProjectionCandidateSet<'tcx>,
 ) {
     debug!("assemble_candidates_from_trait_def(..)");
+    let mut ambiguous = false;
+    selcx.for_each_item_bound(
+        obligation.predicate.self_ty(),
+        |selcx, clause, _| {
+            let Some(clause) = clause.as_projection_clause() else {
+                return ControlFlow::Continue(());
+            };
 
-    let tcx = selcx.tcx();
-    // Check whether the self-type is itself a projection.
-    // If so, extract what we know from the trait and try to come up with a good answer.
-    let bounds = match *obligation.predicate.self_ty().kind() {
-        // Excluding IATs and type aliases here as they don't have meaningful item bounds.
-        ty::Alias(ty::Projection | ty::Opaque, ref data) => {
-            tcx.item_bounds(data.def_id).instantiate(tcx, data.args)
-        }
-        ty::Infer(ty::TyVar(_)) => {
-            // If the self-type is an inference variable, then it MAY wind up
-            // being a projected type, so induce an ambiguity.
-            candidate_set.mark_ambiguous();
-            return;
-        }
-        _ => return,
-    };
+            let is_match =
+                selcx.infcx.probe(|_| selcx.match_projection_projections(obligation, clause, true));
 
-    assemble_candidates_from_predicates(
-        selcx,
-        obligation,
-        candidate_set,
-        ProjectionCandidate::TraitDef,
-        bounds.iter(),
-        true,
+            match is_match {
+                ProjectionMatchesProjection::Yes => {
+                    candidate_set.push_candidate(ProjectionCandidate::TraitDef(clause));
+
+                    if !obligation.predicate.has_non_region_infer() {
+                        // HACK: Pick the first trait def candidate for a fully
+                        // inferred predicate. This is to allow duplicates that
+                        // differ only in normalization.
+                        return ControlFlow::Break(());
+                    }
+                }
+                ProjectionMatchesProjection::Ambiguous => {
+                    candidate_set.mark_ambiguous();
+                }
+                ProjectionMatchesProjection::No => {}
+            }
+
+            ControlFlow::Continue(())
+        },
+        // `ProjectionCandidateSet` is borrowed in the above closure,
+        // so just mark ambiguous outside of the closure.
+        || ambiguous = true,
     );
+
+    if ambiguous {
+        candidate_set.mark_ambiguous();
+    }
 }
 
 /// In the case of a trait object like
@@ -1936,10 +1948,11 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                         // Integers and floats are always Sized, and so have unit type metadata.
                         | ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(..)) => true,
 
-                        // type parameters, opaques, and unnormalized projections have pointer
-                        // metadata if they're known (e.g. by the param_env) to be sized
+                        // We normalize from `Wrapper<Tail>::Metadata` to `Tail::Metadata` if able.
+                        // Otherwise, type parameters, opaques, and unnormalized projections have
+                        // unit metadata if they're known (e.g. by the param_env) to be sized.
                         ty::Param(_) | ty::Alias(..)
-                            if selcx.infcx.predicate_must_hold_modulo_regions(
+                            if self_ty != tail || selcx.infcx.predicate_must_hold_modulo_regions(
                                 &obligation.with(
                                     selcx.tcx(),
                                     ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty]),
@@ -2315,7 +2328,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
         assert_eq!(metadata_def_id, item_def_id);
 
         let mut obligations = Vec::new();
-        let (metadata_ty, check_is_sized) = self_ty.ptr_metadata_ty(tcx, |ty| {
+        let normalize = |ty| {
             normalize_with_depth_to(
                 selcx,
                 obligation.param_env,
@@ -2324,16 +2337,27 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
                 ty,
                 &mut obligations,
             )
+        };
+        let metadata_ty = self_ty.ptr_metadata_ty_or_tail(tcx, normalize).unwrap_or_else(|tail| {
+            if tail == self_ty {
+                // This is the "fallback impl" for type parameters, unnormalizable projections
+                // and opaque types: If the `self_ty` is `Sized`, then the metadata is `()`.
+                // FIXME(ptr_metadata): This impl overlaps with the other impls and shouldn't
+                // exist. Instead, `Pointee<Metadata = ()>` should be a supertrait of `Sized`.
+                let sized_predicate = ty::TraitRef::from_lang_item(
+                    tcx,
+                    LangItem::Sized,
+                    obligation.cause.span(),
+                    [self_ty],
+                );
+                obligations.push(obligation.with(tcx, sized_predicate));
+                tcx.types.unit
+            } else {
+                // We know that `self_ty` has the same metadata as `tail`. This allows us
+                // to prove predicates like `Wrapper<Tail>::Metadata == Tail::Metadata`.
+                Ty::new_projection(tcx, metadata_def_id, [tail])
+            }
         });
-        if check_is_sized {
-            let sized_predicate = ty::TraitRef::from_lang_item(
-                tcx,
-                LangItem::Sized,
-                obligation.cause.span(),
-                [self_ty],
-            );
-            obligations.push(obligation.with(tcx, sized_predicate));
-        }
         (metadata_ty.into(), obligations)
     } else {
         bug!("unexpected builtin trait with associated type: {:?}", obligation.predicate);
diff --git a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
index 4c0c57377e0..a050b30317a 100644
--- a/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/evaluate_obligation.rs
@@ -41,7 +41,28 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
     /// not entirely accurate if inference variables are involved.
     ///
     /// This version may conservatively fail when outlives obligations
-    /// are required.
+    /// are required. Therefore, this version should only be used for
+    /// optimizations or diagnostics and be treated as if it can always
+    /// return `false`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # #![allow(dead_code)]
+    /// trait Trait {}
+    ///
+    /// fn check<T: Trait>() {}
+    ///
+    /// fn foo<T: 'static>()
+    /// where
+    ///     &'static T: Trait,
+    /// {
+    ///     // Evaluating `&'?0 T: Trait` adds a `'?0: 'static` outlives obligation,
+    ///     // which means that `predicate_must_hold_considering_regions` will return
+    ///     // `false`.
+    ///     check::<&'_ T>();
+    /// }
+    /// ```
     fn predicate_must_hold_considering_regions(
         &self,
         obligation: &PredicateObligation<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index eb4b3b7a62e..f9a292c2bd7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -6,13 +6,16 @@
 //!
 //! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly
 
+use std::ops::ControlFlow;
+
 use hir::def_id::DefId;
 use hir::LangItem;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
 use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
-use rustc_middle::ty::{self, Ty, TypeVisitableExt};
+use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt};
 
 use crate::traits;
 use crate::traits::query::evaluate_obligation::InferCtxtExt;
@@ -158,11 +161,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             _ => return,
         }
 
-        let result = self
-            .infcx
-            .probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
+        self.infcx.probe(|_| {
+            let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
+            let placeholder_trait_predicate =
+                self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
+            debug!(?placeholder_trait_predicate);
+
+            // The bounds returned by `item_bounds` may contain duplicates after
+            // normalization, so try to deduplicate when possible to avoid
+            // unnecessary ambiguity.
+            let mut distinct_normalized_bounds = FxHashSet::default();
+            self.for_each_item_bound::<!>(
+                placeholder_trait_predicate.self_ty(),
+                |selcx, bound, idx| {
+                    let Some(bound) = bound.as_trait_clause() else {
+                        return ControlFlow::Continue(());
+                    };
+                    if bound.polarity() != placeholder_trait_predicate.polarity {
+                        return ControlFlow::Continue(());
+                    }
 
-        candidates.vec.extend(result.into_iter().map(|idx| ProjectionCandidate(idx)));
+                    selcx.infcx.probe(|_| {
+                        match selcx.match_normalize_trait_ref(
+                            obligation,
+                            bound.to_poly_trait_ref(),
+                            placeholder_trait_predicate.trait_ref,
+                        ) {
+                            Ok(None) => {
+                                candidates.vec.push(ProjectionCandidate(idx));
+                            }
+                            Ok(Some(normalized_trait))
+                                if distinct_normalized_bounds.insert(normalized_trait) =>
+                            {
+                                candidates.vec.push(ProjectionCandidate(idx));
+                            }
+                            _ => {}
+                        }
+                    });
+
+                    ControlFlow::Continue(())
+                },
+                // On ambiguity.
+                || candidates.ambiguous = true,
+            );
+        });
     }
 
     /// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
@@ -775,64 +817,63 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         self.infcx.probe(|_snapshot| {
             let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
-            let placeholder_trait_predicate =
-                self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate);
-
-            let self_ty = placeholder_trait_predicate.self_ty();
-            let principal_trait_ref = match self_ty.kind() {
-                ty::Dynamic(data, ..) => {
-                    if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
-                        debug!(
-                            "assemble_candidates_from_object_ty: matched builtin bound, \
+            self.infcx.enter_forall(poly_trait_predicate, |placeholder_trait_predicate| {
+                let self_ty = placeholder_trait_predicate.self_ty();
+                let principal_trait_ref = match self_ty.kind() {
+                    ty::Dynamic(data, ..) => {
+                        if data.auto_traits().any(|did| did == obligation.predicate.def_id()) {
+                            debug!(
+                                "assemble_candidates_from_object_ty: matched builtin bound, \
                              pushing candidate"
-                        );
-                        candidates.vec.push(BuiltinObjectCandidate);
-                        return;
-                    }
+                            );
+                            candidates.vec.push(BuiltinObjectCandidate);
+                            return;
+                        }
 
-                    if let Some(principal) = data.principal() {
-                        if !self.infcx.tcx.features().object_safe_for_dispatch {
-                            principal.with_self_ty(self.tcx(), self_ty)
-                        } else if self.tcx().check_is_object_safe(principal.def_id()) {
-                            principal.with_self_ty(self.tcx(), self_ty)
+                        if let Some(principal) = data.principal() {
+                            if !self.infcx.tcx.features().object_safe_for_dispatch {
+                                principal.with_self_ty(self.tcx(), self_ty)
+                            } else if self.tcx().check_is_object_safe(principal.def_id()) {
+                                principal.with_self_ty(self.tcx(), self_ty)
+                            } else {
+                                return;
+                            }
                         } else {
+                            // Only auto trait bounds exist.
                             return;
                         }
-                    } else {
-                        // Only auto trait bounds exist.
+                    }
+                    ty::Infer(ty::TyVar(_)) => {
+                        debug!("assemble_candidates_from_object_ty: ambiguous");
+                        candidates.ambiguous = true; // could wind up being an object type
                         return;
                     }
-                }
-                ty::Infer(ty::TyVar(_)) => {
-                    debug!("assemble_candidates_from_object_ty: ambiguous");
-                    candidates.ambiguous = true; // could wind up being an object type
-                    return;
-                }
-                _ => return,
-            };
-
-            debug!(?principal_trait_ref, "assemble_candidates_from_object_ty");
-
-            // Count only those upcast versions that match the trait-ref
-            // we are looking for. Specifically, do not only check for the
-            // correct trait, but also the correct type parameters.
-            // For example, we may be trying to upcast `Foo` to `Bar<i32>`,
-            // but `Foo` is declared as `trait Foo: Bar<u32>`.
-            let candidate_supertraits = util::supertraits(self.tcx(), principal_trait_ref)
-                .enumerate()
-                .filter(|&(_, upcast_trait_ref)| {
-                    self.infcx.probe(|_| {
-                        self.match_normalize_trait_ref(
-                            obligation,
-                            upcast_trait_ref,
-                            placeholder_trait_predicate.trait_ref,
-                        )
-                        .is_ok()
+                    _ => return,
+                };
+
+                debug!(?principal_trait_ref, "assemble_candidates_from_object_ty");
+
+                // Count only those upcast versions that match the trait-ref
+                // we are looking for. Specifically, do not only check for the
+                // correct trait, but also the correct type parameters.
+                // For example, we may be trying to upcast `Foo` to `Bar<i32>`,
+                // but `Foo` is declared as `trait Foo: Bar<u32>`.
+                let candidate_supertraits = util::supertraits(self.tcx(), principal_trait_ref)
+                    .enumerate()
+                    .filter(|&(_, upcast_trait_ref)| {
+                        self.infcx.probe(|_| {
+                            self.match_normalize_trait_ref(
+                                obligation,
+                                upcast_trait_ref,
+                                placeholder_trait_predicate.trait_ref,
+                            )
+                            .is_ok()
+                        })
                     })
-                })
-                .map(|(idx, _)| ObjectCandidate(idx));
+                    .map(|(idx, _)| ObjectCandidate(idx));
 
-            candidates.vec.extend(candidate_supertraits);
+                candidates.vec.extend(candidate_supertraits);
+            })
         })
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index f2dc4b1be73..6ca24933979 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -159,23 +159,29 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         let trait_predicate = self.infcx.shallow_resolve(obligation.predicate);
         let placeholder_trait_predicate =
-            self.infcx.instantiate_binder_with_placeholders(trait_predicate).trait_ref;
+            self.infcx.enter_forall_and_leak_universe(trait_predicate).trait_ref;
         let placeholder_self_ty = placeholder_trait_predicate.self_ty();
         let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
-        let (def_id, args) = match *placeholder_self_ty.kind() {
-            // Excluding IATs and type aliases here as they don't have meaningful item bounds.
-            ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
-                (def_id, args)
-            }
-            _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
-        };
 
-        let candidate_predicate =
-            tcx.item_bounds(def_id).map_bound(|i| i[idx]).instantiate(tcx, args);
+        let candidate_predicate = self
+            .for_each_item_bound(
+                placeholder_self_ty,
+                |_, clause, clause_idx| {
+                    if clause_idx == idx {
+                        ControlFlow::Break(clause)
+                    } else {
+                        ControlFlow::Continue(())
+                    }
+                },
+                || unreachable!(),
+            )
+            .break_value()
+            .expect("expected to index into clause that exists");
         let candidate = candidate_predicate
             .as_trait_clause()
             .expect("projection candidate is not a trait predicate")
             .map_bound(|t| t.trait_ref);
+
         let mut obligations = Vec::new();
         let candidate = normalize_with_depth_to(
             self,
@@ -194,8 +200,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 .map_err(|_| Unimplemented)
         })?);
 
-        if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() {
-            let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, args);
+        // FIXME(compiler-errors): I don't think this is needed.
+        if let ty::Alias(ty::Projection, alias_ty) = placeholder_self_ty.kind() {
+            let predicates = tcx.predicates_of(alias_ty.def_id).instantiate_own(tcx, alias_ty.args);
             for (predicate, _) in predicates {
                 let normalized = normalize_with_depth_to(
                     self,
@@ -402,7 +409,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             let cause = obligation.derived_cause(BuiltinDerivedObligation);
 
             let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
-            let trait_ref = self.infcx.instantiate_binder_with_placeholders(poly_trait_ref);
+            let trait_ref = self.infcx.enter_forall_and_leak_universe(poly_trait_ref);
             let trait_obligations: Vec<PredicateObligation<'_>> = self.impl_or_trait_obligations(
                 &cause,
                 obligation.recursion_depth + 1,
@@ -493,7 +500,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let tcx = self.tcx();
         debug!(?obligation, ?index, "confirm_object_candidate");
 
-        let trait_predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
+        let trait_predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
         let self_ty = self.infcx.shallow_resolve(trait_predicate.self_ty());
         let obligation_trait_ref = ty::Binder::dummy(trait_predicate.trait_ref);
         let ty::Dynamic(data, ..) = *self_ty.kind() else {
@@ -691,7 +698,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let cause = obligation.derived_cause(BuiltinDerivedObligation);
 
         // Confirm the `type Output: Sized;` bound that is present on `FnOnce`
-        let output_ty = self.infcx.instantiate_binder_with_placeholders(sig.output());
+        let output_ty = self.infcx.enter_forall_and_leak_universe(sig.output());
         let output_ty = normalize_with_depth_to(
             self,
             obligation.param_env,
@@ -712,7 +719,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) -> Vec<PredicateObligation<'tcx>> {
         debug!(?obligation, "confirm_trait_alias_candidate");
 
-        let predicate = self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
+        let predicate = self.infcx.enter_forall_and_leak_universe(obligation.predicate);
         let trait_ref = predicate.trait_ref;
         let trait_def_id = trait_ref.def_id;
         let args = trait_ref.args;
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 7f41c73b72f..ac6cfcdeb59 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -52,6 +52,7 @@ use std::cell::{Cell, RefCell};
 use std::cmp;
 use std::fmt::{self, Display};
 use std::iter;
+use std::ops::ControlFlow;
 
 pub use rustc_middle::traits::select::*;
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -483,7 +484,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // Instead, we select the right impl now but report "`Bar` does
         // not implement `Clone`".
         if candidates.len() == 1 {
-            return self.filter_reservation_impls(candidates.pop().unwrap(), stack.obligation);
+            return self.filter_reservation_impls(candidates.pop().unwrap());
         }
 
         // Winnow, but record the exact outcome of evaluation, which
@@ -557,7 +558,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
 
         // Just one candidate left.
-        self.filter_reservation_impls(candidates.pop().unwrap().candidate, stack.obligation)
+        self.filter_reservation_impls(candidates.pop().unwrap().candidate)
     }
 
     ///////////////////////////////////////////////////////////////////////////
@@ -1436,7 +1437,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     fn filter_reservation_impls(
         &mut self,
         candidate: SelectionCandidate<'tcx>,
-        obligation: &PolyTraitObligation<'tcx>,
     ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> {
         let tcx = self.tcx();
         // Treat reservation impls as ambiguity.
@@ -1593,71 +1593,41 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         self.infcx.selection_cache.insert((param_env, pred), dep_node, candidate);
     }
 
-    /// Matches a predicate against the bounds of its self type.
-    ///
-    /// Given an obligation like `<T as Foo>::Bar: Baz` where the self type is
-    /// a projection, look at the bounds of `T::Bar`, see if we can find a
-    /// `Baz` bound. We return indexes into the list returned by
-    /// `tcx.item_bounds` for any applicable bounds.
-    #[instrument(level = "debug", skip(self), ret)]
-    fn match_projection_obligation_against_definition_bounds(
+    /// Looks at the item bounds of the projection or opaque type.
+    /// If this is a nested rigid projection, such as
+    /// `<<T as Tr1>::Assoc as Tr2>::Assoc`, consider the item bounds
+    /// on both `Tr1::Assoc` and `Tr2::Assoc`, since we may encounter
+    /// relative bounds on both via the `associated_type_bounds` feature.
+    pub(super) fn for_each_item_bound<T>(
         &mut self,
-        obligation: &PolyTraitObligation<'tcx>,
-    ) -> smallvec::SmallVec<[usize; 2]> {
-        let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
-        let placeholder_trait_predicate =
-            self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate);
-        debug!(?placeholder_trait_predicate);
-
-        let tcx = self.infcx.tcx;
-        let (def_id, args) = match *placeholder_trait_predicate.trait_ref.self_ty().kind() {
-            ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
-                (def_id, args)
-            }
-            _ => {
-                span_bug!(
-                    obligation.cause.span,
-                    "match_projection_obligation_against_definition_bounds() called \
-                     but self-ty is not a projection: {:?}",
-                    placeholder_trait_predicate.trait_ref.self_ty()
-                );
-            }
-        };
-        let bounds = tcx.item_bounds(def_id).instantiate(tcx, args);
+        mut self_ty: Ty<'tcx>,
+        mut for_each: impl FnMut(&mut Self, ty::Clause<'tcx>, usize) -> ControlFlow<T, ()>,
+        on_ambiguity: impl FnOnce(),
+    ) -> ControlFlow<T, ()> {
+        let mut idx = 0;
+        loop {
+            let (kind, alias_ty) = match *self_ty.kind() {
+                ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
+                ty::Infer(ty::TyVar(_)) => {
+                    on_ambiguity();
+                    return ControlFlow::Continue(());
+                }
+                _ => return ControlFlow::Continue(()),
+            };
 
-        // The bounds returned by `item_bounds` may contain duplicates after
-        // normalization, so try to deduplicate when possible to avoid
-        // unnecessary ambiguity.
-        let mut distinct_normalized_bounds = FxHashSet::default();
+            for bound in
+                self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args)
+            {
+                for_each(self, bound, idx)?;
+                idx += 1;
+            }
 
-        bounds
-            .iter()
-            .enumerate()
-            .filter_map(|(idx, bound)| {
-                let bound_predicate = bound.kind();
-                if let ty::ClauseKind::Trait(pred) = bound_predicate.skip_binder() {
-                    let bound = bound_predicate.rebind(pred.trait_ref);
-                    if self.infcx.probe(|_| {
-                        match self.match_normalize_trait_ref(
-                            obligation,
-                            bound,
-                            placeholder_trait_predicate.trait_ref,
-                        ) {
-                            Ok(None) => true,
-                            Ok(Some(normalized_trait))
-                                if distinct_normalized_bounds.insert(normalized_trait) =>
-                            {
-                                true
-                            }
-                            _ => false,
-                        }
-                    }) {
-                        return Some(idx);
-                    }
-                }
-                None
-            })
-            .collect()
+            if kind == ty::Projection {
+                self_ty = alias_ty.self_ty();
+            } else {
+                return ControlFlow::Continue(());
+            }
+        }
     }
 
     /// Equates the trait in `obligation` with trait bound. If the two traits
@@ -2386,7 +2356,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             .flat_map(|ty| {
                 let ty: ty::Binder<'tcx, Ty<'tcx>> = types.rebind(*ty); // <----/
 
-                let placeholder_ty = self.infcx.instantiate_binder_with_placeholders(ty);
+                let placeholder_ty = self.infcx.enter_forall_and_leak_universe(ty);
                 let Normalized { value: normalized_ty, mut obligations } =
                     ensure_sufficient_stack(|| {
                         project::normalize_with_depth(
@@ -2472,7 +2442,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         obligation: &PolyTraitObligation<'tcx>,
     ) -> Result<Normalized<'tcx, GenericArgsRef<'tcx>>, ()> {
         let placeholder_obligation =
-            self.infcx.instantiate_binder_with_placeholders(obligation.predicate);
+            self.infcx.enter_forall_and_leak_universe(obligation.predicate);
         let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref;
 
         let impl_args = self.infcx.fresh_args_for_item(obligation.cause.span, impl_def_id);
diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs
index c7916ec60bb..e73bbf6048e 100644
--- a/compiler/rustc_traits/src/lib.rs
+++ b/compiler/rustc_traits/src/lib.rs
@@ -1,7 +1,5 @@
 //! Queries that are independent from the main solver code.
 
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![recursion_limit = "256"]
 
 #[macro_use]
diff --git a/compiler/rustc_transmute/src/lib.rs b/compiler/rustc_transmute/src/lib.rs
index c80389a3a4d..ac4f67d1b55 100644
--- a/compiler/rustc_transmute/src/lib.rs
+++ b/compiler/rustc_transmute/src/lib.rs
@@ -1,8 +1,6 @@
 #![feature(alloc_layout_extra)]
 #![feature(never_type)]
 #![allow(dead_code, unused_variables)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate tracing;
diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs
index 51acb99d29b..fd392d11e83 100644
--- a/compiler/rustc_ty_utils/src/lib.rs
+++ b/compiler/rustc_ty_utils/src/lib.rs
@@ -15,8 +15,6 @@
 #![feature(iterator_try_collect)]
 #![feature(let_chains)]
 #![feature(never_type)]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 
 #[macro_use]
 extern crate rustc_middle;
@@ -37,7 +35,7 @@ mod layout_sanity_check;
 mod needs_drop;
 mod opaque_types;
 mod representability;
-mod sig_types;
+pub mod sig_types;
 mod structural_match;
 mod ty;
 
diff --git a/compiler/rustc_ty_utils/src/representability.rs b/compiler/rustc_ty_utils/src/representability.rs
index 3aaa2e73bb8..70f1f099688 100644
--- a/compiler/rustc_ty_utils/src/representability.rs
+++ b/compiler/rustc_ty_utils/src/representability.rs
@@ -1,5 +1,3 @@
-#![allow(rustc::untranslatable_diagnostic, rustc::diagnostic_outside_of_impl)]
-
 use rustc_hir::def::DefKind;
 use rustc_index::bit_set::BitSet;
 use rustc_middle::query::Providers;
diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs
index b155a4ac87b..38cc558380c 100644
--- a/compiler/rustc_ty_utils/src/sig_types.rs
+++ b/compiler/rustc_ty_utils/src/sig_types.rs
@@ -4,11 +4,11 @@
 use std::ops::ControlFlow;
 
 use rustc_hir::{def::DefKind, def_id::LocalDefId};
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::Span;
 use rustc_type_ir::visit::TypeVisitable;
 
-pub(crate) trait SpannedTypeVisitor<'tcx> {
+pub trait SpannedTypeVisitor<'tcx> {
     type BreakTy = !;
     fn visit(
         &mut self,
@@ -17,7 +17,7 @@ pub(crate) trait SpannedTypeVisitor<'tcx> {
     ) -> ControlFlow<Self::BreakTy>;
 }
 
-pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
+pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
     tcx: TyCtxt<'tcx>,
     item: LocalDefId,
     visitor: &mut V,
@@ -42,11 +42,10 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
         DefKind::TyAlias {..} | DefKind::AssocTy |
         // Walk over the type of the item
         DefKind::Static(_) | DefKind::Const | DefKind::AssocConst | DefKind::AnonConst => {
-            let span = match tcx.hir_node_by_def_id(item).ty() {
-                Some(ty) => ty.span,
-                _ => tcx.def_span(item),
-            };
-            visitor.visit(span, tcx.type_of(item).instantiate_identity());
+            if let Some(ty) = tcx.hir_node_by_def_id(item).ty() {
+                // Associated types in traits don't necessarily have a type that we can visit
+                visitor.visit(ty.span, tcx.type_of(item).instantiate_identity())?;
+            }
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
             }
@@ -59,7 +58,16 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
         // Look at field types
         DefKind::Struct | DefKind::Union | DefKind::Enum => {
             let span = tcx.def_ident_span(item).unwrap();
-            visitor.visit(span, tcx.type_of(item).instantiate_identity());
+            let ty = tcx.type_of(item).instantiate_identity();
+            visitor.visit(span, ty);
+            let ty::Adt(def, args) = ty.kind() else {
+                span_bug!(span, "invalid type for {kind:?}: {:#?}", ty.kind())
+            };
+            for field in def.all_fields() {
+                let span = tcx.def_ident_span(field.did).unwrap();
+                let ty = field.ty(tcx, args);
+                visitor.visit(span, ty);
+            }
             for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
                 visitor.visit(span, pred)?;
             }
@@ -89,7 +97,6 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
             }
         }
         | DefKind::Variant
-        | DefKind::ForeignTy
         | DefKind::TyParam
         | DefKind::ConstParam
         | DefKind::Ctor(_, _)
@@ -103,6 +110,7 @@ pub(crate) fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
         // These don't have any types.
         | DefKind::ExternCrate
         | DefKind::ForeignMod
+        | DefKind::ForeignTy
         | DefKind::Macro(_)
         | DefKind::GlobalAsm
         | DefKind::Mod
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index 83efbfb855f..f498c5531fc 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -2,8 +2,6 @@
     feature = "nightly",
     feature(associated_type_defaults, min_specialization, never_type, rustc_attrs)
 )]
-#![deny(rustc::untranslatable_diagnostic)]
-#![deny(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::usage_of_ty_tykind)]
 #![cfg_attr(feature = "nightly", allow(internal_features))]
 
diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs
index 3b5e41e8d85..777c649fabd 100644
--- a/compiler/rustc_type_ir/src/region_kind.rs
+++ b/compiler/rustc_type_ir/src/region_kind.rs
@@ -163,8 +163,7 @@ pub enum RegionKind<I: Interner> {
     /// A placeholder region -- the higher-ranked version of `ReLateParam`.
     /// Should not exist outside of type inference.
     ///
-    /// Used when instantiating a `forall` binder via
-    /// `infcx.instantiate_binder_with_placeholders`.
+    /// Used when instantiating a `forall` binder via `infcx.enter_forall`.
     RePlaceholder(I::PlaceholderRegion),
 
     /// Erased region, used by trait selection, in MIR and during codegen.
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 38877f7a77f..be727f024c6 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -639,6 +639,7 @@ impl Rvalue {
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(..), _) => {
                 Ok(Ty::usize_ty())
             }
+            Rvalue::NullaryOp(NullOp::DebugAssertions, _) => Ok(Ty::bool_ty()),
             Rvalue::Aggregate(ak, ops) => match *ak {
                 AggregateKind::Array(ty) => Ty::try_new_array(ty, ops.len() as u64),
                 AggregateKind::Tuple => Ok(Ty::new_tuple(
@@ -1005,6 +1006,8 @@ pub enum NullOp {
     AlignOf,
     /// Returns the offset of a field.
     OffsetOf(Vec<(VariantIdx, FieldIdx)>),
+    /// cfg!(debug_assertions), but at codegen time
+    DebugAssertions,
 }
 
 impl Operand {
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 94e6924f41a..49f5f53f9b3 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -207,11 +207,7 @@ impl<T, A: Allocator> RawVec<T, A> {
             // Allocators currently return a `NonNull<[u8]>` whose length
             // matches the size requested. If that ever changes, the capacity
             // here should change to `ptr.len() / mem::size_of::<T>()`.
-            Self {
-                ptr: unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) },
-                cap: unsafe { Cap(capacity) },
-                alloc,
-            }
+            Self { ptr: Unique::from(ptr.cast()), cap: unsafe { Cap(capacity) }, alloc }
         }
     }
 
@@ -239,6 +235,11 @@ impl<T, A: Allocator> RawVec<T, A> {
         self.ptr.as_ptr()
     }
 
+    #[inline]
+    pub fn non_null(&self) -> NonNull<T> {
+        NonNull::from(self.ptr)
+    }
+
     /// Gets the capacity of the allocation.
     ///
     /// This will always be `usize::MAX` if `T` is zero-sized.
@@ -398,7 +399,7 @@ impl<T, A: Allocator> RawVec<T, A> {
         // Allocators currently return a `NonNull<[u8]>` whose length matches
         // the size requested. If that ever changes, the capacity here should
         // change to `ptr.len() / mem::size_of::<T>()`.
-        self.ptr = unsafe { Unique::new_unchecked(ptr.cast().as_ptr()) };
+        self.ptr = Unique::from(ptr.cast());
         self.cap = unsafe { Cap(cap) };
     }
 
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 4033f4eb068..f4e392760c8 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -51,7 +51,7 @@ 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")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 pub use core::slice::{ChunkBy, ChunkByMut};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::slice::{Chunks, Windows};
diff --git a/library/alloc/src/vec/cow.rs b/library/alloc/src/vec/cow.rs
index b12910f3690..3fe83242a30 100644
--- a/library/alloc/src/vec/cow.rs
+++ b/library/alloc/src/vec/cow.rs
@@ -15,7 +15,7 @@ impl<'a, T: Clone> From<&'a [T]> for Cow<'a, [T]> {
     }
 }
 
-#[stable(feature = "cow_from_array_ref", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "cow_from_array_ref", since = "1.77.0")]
 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.
diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs
index 654ce09afcd..7800560da94 100644
--- a/library/alloc/src/vec/into_iter.rs
+++ b/library/alloc/src/vec/into_iter.rs
@@ -136,7 +136,7 @@ impl<T, A: Allocator> IntoIter<T, A> {
         // struct and then overwriting &mut self.
         // this creates less assembly
         self.cap = 0;
-        self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) };
+        self.buf = RawVec::NEW.non_null();
         self.ptr = self.buf;
         self.end = self.buf.as_ptr();
 
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index b3e5ecc9240..08e3cdedc66 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -2861,16 +2861,16 @@ impl<T, A: Allocator> IntoIterator for Vec<T, A> {
     #[inline]
     fn into_iter(self) -> Self::IntoIter {
         unsafe {
-            let mut me = ManuallyDrop::new(self);
+            let me = ManuallyDrop::new(self);
             let alloc = ManuallyDrop::new(ptr::read(me.allocator()));
-            let begin = me.as_mut_ptr();
+            let buf = me.buf.non_null();
+            let begin = buf.as_ptr();
             let end = if T::IS_ZST {
                 begin.wrapping_byte_add(me.len())
             } else {
                 begin.add(me.len()) as *const T
             };
             let cap = me.buf.capacity();
-            let buf = NonNull::new_unchecked(begin);
             IntoIter { buf, phantom: PhantomData, cap, alloc, ptr: buf, end }
         }
     }
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 85cce81f2c1..743f07644e3 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -576,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);
     /// ```
-    #[stable(feature = "array_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "array_methods", since = "1.77.0")]
     pub fn each_ref(&self) -> [&T; N] {
         from_trusted_iterator(self.iter())
     }
@@ -595,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]);
     /// ```
-    #[stable(feature = "array_methods", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "array_methods", since = "1.77.0")]
     pub fn each_mut(&mut self) -> [&mut T; N] {
         from_trusted_iterator(self.iter_mut())
     }
diff --git a/library/core/src/async_iter/async_iter.rs b/library/core/src/async_iter/async_iter.rs
index db71a286b6d..489f95bbf10 100644
--- a/library/core/src/async_iter/async_iter.rs
+++ b/library/core/src/async_iter/async_iter.rs
@@ -47,7 +47,7 @@ pub trait AsyncIterator {
     /// Rust's usual rules apply: calls must never cause undefined behavior
     /// (memory corruption, incorrect use of `unsafe` functions, or the like),
     /// regardless of the async iterator's state.
-    #[cfg_attr(not(bootstrap), lang = "async_iterator_poll_next")]
+    #[lang = "async_iterator_poll_next"]
     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
 
     /// Returns the bounds on the remaining length of the async iterator.
@@ -145,7 +145,7 @@ pub trait IntoAsyncIterator {
     type IntoAsyncIter: AsyncIterator<Item = Self::Item>;
 
     /// Converts `self` into an async iterator
-    #[cfg_attr(not(bootstrap), lang = "into_async_iter_into_iter")]
+    #[lang = "into_async_iter_into_iter"]
     fn into_async_iter(self) -> Self::IntoAsyncIter;
 }
 
diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs
index 177f39b59ae..7bd592492a5 100644
--- a/library/core/src/char/convert.rs
+++ b/library/core/src/char/convert.rs
@@ -27,7 +27,7 @@ pub(super) const unsafe fn from_u32_unchecked(i: u32) -> char {
     unsafe {
         assert_unsafe_precondition!(
             "invalid value for `char`",
-            (i: u32) => char_try_from_u32(i).is_ok()
+            (i: u32 = i) => char_try_from_u32(i).is_ok()
         );
         transmute(i)
     }
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 5c44ca69451..97c3c9e6fae 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -148,7 +148,7 @@ pub const unsafe fn assert_unchecked(cond: bool) {
     unsafe {
         intrinsics::assert_unsafe_precondition!(
             "hint::assert_unchecked must never be called when the condition is false",
-            (cond: bool) => cond,
+            (cond: bool = cond) => cond,
         );
         crate::intrinsics::assume(cond);
     }
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 43124535ab5..18c82f97c28 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -56,7 +56,7 @@
 
 use crate::marker::DiscriminantKind;
 use crate::marker::Tuple;
-use crate::mem;
+use crate::mem::{self, align_of};
 
 pub mod mir;
 pub mod simd;
@@ -947,7 +947,7 @@ extern "rust-intrinsic" {
     /// own, or if it does not enable any significant optimizations.
     ///
     /// This intrinsic does not have a stable counterpart.
-    #[rustc_const_stable(feature = "const_assume", since = "CURRENT_RUSTC_VERSION")]
+    #[rustc_const_stable(feature = "const_assume", since = "1.77.0")]
     #[rustc_nounwind]
     pub fn assume(b: bool);
 
@@ -2567,16 +2567,18 @@ extern "rust-intrinsic" {
     /// matter what*.
     #[rustc_const_unstable(feature = "is_val_statically_known", issue = "none")]
     #[rustc_nounwind]
-    #[cfg(not(bootstrap))]
     pub fn is_val_statically_known<T: Copy>(arg: T) -> bool;
+
+    #[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")]
+    #[rustc_safe_intrinsic]
+    #[cfg(not(bootstrap))]
+    pub(crate) fn debug_assertions() -> bool;
 }
 
-// FIXME: Seems using `unstable` here completely ignores `rustc_allow_const_fn_unstable`
-// and thus compiling stage0 core doesn't work.
-#[rustc_const_stable(feature = "is_val_statically_known", since = "0.0.0")]
 #[cfg(bootstrap)]
-pub const unsafe fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
-    false
+#[rustc_const_unstable(feature = "delayed_debug_assertions", issue = "none")]
+pub(crate) const fn debug_assertions() -> bool {
+    cfg!(debug_assertions)
 }
 
 // Some functions are defined here because they accidentally got made
@@ -2587,10 +2589,27 @@ pub const unsafe fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
 /// Check that the preconditions of an unsafe function are followed, if debug_assertions are on,
 /// and only at runtime.
 ///
-/// This macro should be called as `assert_unsafe_precondition!([Generics](name: Type) => Expression)`
-/// where the names specified will be moved into the macro as captured variables, and defines an item
-/// to call `const_eval_select` on. The tokens inside the square brackets are used to denote generics
-/// for the function declarations and can be omitted if there is no generics.
+/// This macro should be called as
+/// `assert_unsafe_precondition!((expr => name: Type, expr => name: Type) => Expression)`
+/// where each `expr` will be evaluated and passed in as function argument `name: Type`. Then all
+/// those arguments are passed to a function via [`const_eval_select`].
+///
+/// These checks are behind a condition which is evaluated at codegen time, not expansion time like
+/// [`debug_assert`]. This means that a standard library built with optimizations and debug
+/// assertions disabled will have these checks optimized out of its monomorphizations, but if a
+/// a caller of the standard library has debug assertions enabled and monomorphizes an expansion of
+/// this macro, that monomorphization will contain the check.
+///
+/// Since these checks cannot be optimized out in MIR, some care must be taken in both call and
+/// implementation to mitigate their compile-time overhead. The runtime function that we
+/// [`const_eval_select`] to is monomorphic, `#[inline(never)]`, and `#[rustc_nounwind]`. That
+/// combination of properties ensures that the code for the checks is only compiled once, and has a
+/// minimal impact on the caller's code size.
+///
+/// Caller should also introducing any other `let` bindings or any code outside this macro in order
+/// to call it. Since the precompiled standard library is built with full debuginfo and these
+/// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough
+/// debuginfo to have a measurable compile-time impact on debug builds.
 ///
 /// # Safety
 ///
@@ -2604,26 +2623,24 @@ pub const unsafe fn is_val_statically_known<T: Copy>(_arg: T) -> bool {
 ///
 /// So in a sense it is UB if this macro is useful, but we expect callers of `unsafe fn` to make
 /// the occasional mistake, and this check should help them figure things out.
-#[allow_internal_unstable(const_eval_select)] // permit this to be called in stably-const fn
+#[allow_internal_unstable(const_eval_select, delayed_debug_assertions)] // permit this to be called in stably-const fn
 macro_rules! assert_unsafe_precondition {
-    ($name:expr, $([$($tt:tt)*])?($($i:ident:$ty:ty),*$(,)?) => $e:expr $(,)?) => {
-        if cfg!(debug_assertions) {
-            // allow non_snake_case to allow capturing const generics
-            #[allow(non_snake_case)]
-            #[inline(always)]
-            fn runtime$(<$($tt)*>)?($($i:$ty),*) {
+    ($message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => {
+        {
+            #[inline(never)]
+            #[rustc_nounwind]
+            fn precondition_check($($name:$ty),*) {
                 if !$e {
-                    // don't unwind to reduce impact on code size
                     ::core::panicking::panic_nounwind(
-                        concat!("unsafe precondition(s) violated: ", $name)
+                        concat!("unsafe precondition(s) violated: ", $message)
                     );
                 }
             }
-            #[allow(non_snake_case)]
-            #[inline]
-            const fn comptime$(<$($tt)*>)?($(_:$ty),*) {}
+            const fn comptime($(_:$ty),*) {}
 
-            ::core::intrinsics::const_eval_select(($($i,)*), comptime, runtime);
+            if ::core::intrinsics::debug_assertions() {
+                ::core::intrinsics::const_eval_select(($($arg,)*), comptime, precondition_check);
+            }
         }
     };
 }
@@ -2632,30 +2649,47 @@ pub(crate) use assert_unsafe_precondition;
 /// Checks whether `ptr` is properly aligned with respect to
 /// `align_of::<T>()`.
 #[inline]
-pub(crate) fn is_aligned_and_not_null<T>(ptr: *const T) -> bool {
-    !ptr.is_null() && ptr.is_aligned()
+pub(crate) fn is_aligned_and_not_null(ptr: *const (), align: usize) -> bool {
+    !ptr.is_null() && ptr.is_aligned_to(align)
 }
 
-/// Checks whether an allocation of `len` instances of `T` exceeds
-/// the maximum allowed allocation size.
 #[inline]
-pub(crate) fn is_valid_allocation_size<T>(len: usize) -> bool {
-    let max_len = const {
-        let size = crate::mem::size_of::<T>();
-        if size == 0 { usize::MAX } else { isize::MAX as usize / size }
-    };
+pub(crate) fn is_valid_allocation_size(size: usize, len: usize) -> bool {
+    let max_len = if size == 0 { usize::MAX } else { isize::MAX as usize / size };
     len <= max_len
 }
 
+pub(crate) fn is_nonoverlapping_mono(
+    src: *const (),
+    dst: *const (),
+    size: usize,
+    count: usize,
+) -> bool {
+    let src_usize = src.addr();
+    let dst_usize = dst.addr();
+    let Some(size) = size.checked_mul(count) else {
+        crate::panicking::panic_nounwind(
+            "is_nonoverlapping: `size_of::<T>() * count` overflows a usize",
+        )
+    };
+    let diff = src_usize.abs_diff(dst_usize);
+    // If the absolute distance between the ptrs is at least as big as the size of the buffer,
+    // they do not overlap.
+    diff >= size
+}
+
 /// Checks whether the regions of memory starting at `src` and `dst` of size
 /// `count * size_of::<T>()` do *not* overlap.
 #[inline]
 pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -> bool {
     let src_usize = src.addr();
     let dst_usize = dst.addr();
-    let size = mem::size_of::<T>()
-        .checked_mul(count)
-        .expect("is_nonoverlapping: `size_of::<T>() * count` overflows a usize");
+    let Some(size) = mem::size_of::<T>().checked_mul(count) else {
+        // Use panic_nounwind instead of Option::expect, so that this function is nounwind.
+        crate::panicking::panic_nounwind(
+            "is_nonoverlapping: `size_of::<T>() * count` overflows a usize",
+        )
+    };
     let diff = src_usize.abs_diff(dst_usize);
     // If the absolute distance between the ptrs is at least as big as the size of the buffer,
     // they do not overlap.
@@ -2749,13 +2783,13 @@ pub(crate) fn is_nonoverlapping<T>(src: *const T, dst: *const T, count: usize) -
 #[doc(alias = "memcpy")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_allowed_through_unstable_modules]
-#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
 #[inline(always)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[rustc_diagnostic_item = "ptr_copy_nonoverlapping"]
 pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize) {
     extern "rust-intrinsic" {
-        #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
         #[rustc_nounwind]
         pub fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: usize);
     }
@@ -2766,10 +2800,16 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
         assert_unsafe_precondition!(
             "ptr::copy_nonoverlapping requires that both pointer arguments are aligned and non-null \
             and the specified memory ranges do not overlap",
-            [T](src: *const T, dst: *mut T, count: usize) =>
-            is_aligned_and_not_null(src)
-                && is_aligned_and_not_null(dst)
-                && is_nonoverlapping(src, dst, count)
+            (
+                src: *const () = src as *const (),
+                dst: *mut () = dst as *mut (),
+                size: usize = size_of::<T>(),
+                align: usize = align_of::<T>(),
+                count: usize = count,
+            ) =>
+            is_aligned_and_not_null(src, align)
+                && is_aligned_and_not_null(dst, align)
+                && is_nonoverlapping_mono(src, dst, size, count)
         );
         copy_nonoverlapping(src, dst, count)
     }
@@ -2845,13 +2885,13 @@ pub const unsafe fn copy_nonoverlapping<T>(src: *const T, dst: *mut T, count: us
 #[doc(alias = "memmove")]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_allowed_through_unstable_modules]
-#[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+#[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
 #[inline(always)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[rustc_diagnostic_item = "ptr_copy"]
 pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
     extern "rust-intrinsic" {
-        #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+        #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
         #[rustc_nounwind]
         fn copy<T>(src: *const T, dst: *mut T, count: usize);
     }
@@ -2859,9 +2899,15 @@ pub const unsafe fn copy<T>(src: *const T, dst: *mut T, count: usize) {
     // SAFETY: the safety contract for `copy` must be upheld by the caller.
     unsafe {
         assert_unsafe_precondition!(
-            "ptr::copy requires that both pointer arguments are aligned and non-null",
-            [T](src: *const T, dst: *mut T) =>
-            is_aligned_and_not_null(src) && is_aligned_and_not_null(dst)
+            "ptr::copy_nonoverlapping requires that both pointer arguments are aligned and non-null \
+            and the specified memory ranges do not overlap",
+            (
+                src: *const () = src as *const (),
+                dst: *mut () = dst as *mut (),
+                align: usize = align_of::<T>(),
+            ) =>
+            is_aligned_and_not_null(src, align)
+                && is_aligned_and_not_null(dst, align)
         );
         copy(src, dst, count)
     }
@@ -2934,7 +2980,10 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
     unsafe {
         assert_unsafe_precondition!(
             "ptr::write_bytes requires that the destination pointer is aligned and non-null",
-            [T](dst: *mut T) => is_aligned_and_not_null(dst)
+            (
+                addr: *const () = dst as *const (),
+                align: usize = align_of::<T>(),
+            ) => is_aligned_and_not_null(addr, align)
         );
         write_bytes(dst, val, count)
     }
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index d348e31609d..02665b2676c 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -105,7 +105,6 @@
 //! }
 //!
 //! #[custom_mir(dialect = "runtime", phase = "optimized")]
-#![cfg_attr(bootstrap, doc = "#[cfg(any())]")] // disable the following function in doctests when `bootstrap` is set
 //! fn push_and_pop<T>(v: &mut Vec<T>, value: T) {
 //!     mir!(
 //!         let _unused;
@@ -357,7 +356,6 @@ define!("mir_unwind_resume",
 
 define!("mir_storage_live", fn StorageLive<T>(local: T));
 define!("mir_storage_dead", fn StorageDead<T>(local: T));
-#[cfg(not(bootstrap))]
 define!("mir_assume", fn Assume(operand: bool));
 define!("mir_deinit", fn Deinit<T>(place: T));
 define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index a3279dcafef..b54680a61b4 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -111,7 +111,6 @@
 //
 // Library features:
 // tidy-alphabetical-start
-#![cfg_attr(not(bootstrap), feature(offset_of_nested))]
 #![feature(char_indices_offset)]
 #![feature(const_align_of_val)]
 #![feature(const_align_of_val_raw)]
@@ -135,6 +134,7 @@
 #![feature(const_hint_assert_unchecked)]
 #![feature(const_index_range_slice_index)]
 #![feature(const_int_unchecked_arith)]
+#![feature(const_intrinsic_copy)]
 #![feature(const_intrinsic_forget)]
 #![feature(const_ipv4)]
 #![feature(const_ipv6)]
@@ -180,6 +180,7 @@
 #![feature(maybe_uninit_uninit_array)]
 #![feature(non_null_convenience)]
 #![feature(offset_of_enum)]
+#![feature(offset_of_nested)]
 #![feature(panic_internals)]
 #![feature(ptr_alignment_type)]
 #![feature(ptr_metadata)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index d6e0e1895cd..2e22129d7b6 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -225,77 +225,6 @@ marker_impls! {
         {T: ?Sized} &T,
 }
 
-/// Required trait for constants used in pattern matches.
-///
-/// Any type that derives `Eq` automatically implements this trait, *regardless*
-/// of whether its type parameters implement `Eq`.
-///
-/// This is a hack to work around a limitation in our type system.
-///
-/// # Background
-///
-/// We want to require that types of consts used in pattern matches
-/// have the attribute `#[derive(PartialEq, Eq)]`.
-///
-/// In a more ideal world, we could check that requirement by just checking that
-/// the given type implements both the `StructuralPartialEq` trait *and*
-/// the `Eq` trait. However, you can have ADTs that *do* `derive(PartialEq, Eq)`,
-/// and be a case that we want the compiler to accept, and yet the constant's
-/// type fails to implement `Eq`.
-///
-/// Namely, a case like this:
-///
-/// ```rust
-/// #[derive(PartialEq, Eq)]
-/// struct Wrap<X>(X);
-///
-/// fn higher_order(_: &()) { }
-///
-/// const CFN: Wrap<fn(&())> = Wrap(higher_order);
-///
-/// #[allow(pointer_structural_match)]
-/// fn main() {
-///     match CFN {
-///         CFN => {}
-///         _ => {}
-///     }
-/// }
-/// ```
-///
-/// (The problem in the above code is that `Wrap<fn(&())>` does not implement
-/// `PartialEq`, nor `Eq`, because `for<'a> fn(&'a _)` does not implement those
-/// traits.)
-///
-/// Therefore, we cannot rely on naive check for `StructuralPartialEq` and
-/// mere `Eq`.
-///
-/// As a hack to work around this, we use two separate traits injected by each
-/// of the two derives (`#[derive(PartialEq)]` and `#[derive(Eq)]`) and check
-/// that both of them are present as part of structural-match checking.
-#[unstable(feature = "structural_match", issue = "31434")]
-#[diagnostic::on_unimplemented(message = "the type `{Self}` does not `#[derive(Eq)]`")]
-#[lang = "structural_teq"]
-#[cfg(bootstrap)]
-pub trait StructuralEq {
-    // Empty.
-}
-
-// FIXME: Remove special cases of these types from the compiler pattern checking code and always check `T: StructuralEq` instead
-marker_impls! {
-    #[unstable(feature = "structural_match", issue = "31434")]
-    #[cfg(bootstrap)]
-    StructuralEq for
-        usize, u8, u16, u32, u64, u128,
-        isize, i8, i16, i32, i64, i128,
-        bool,
-        char,
-        str /* Technically requires `[u8]: StructuralEq` */,
-        (),
-        {T, const N: usize} [T; N],
-        {T} [T],
-        {T: ?Sized} &T,
-}
-
 /// Types whose values can be duplicated simply by copying bits.
 ///
 /// By default, variable bindings have 'move semantics.' In other
@@ -860,10 +789,6 @@ impl<T: ?Sized> Default for PhantomData<T> {
 #[unstable(feature = "structural_match", issue = "31434")]
 impl<T: ?Sized> StructuralPartialEq for PhantomData<T> {}
 
-#[unstable(feature = "structural_match", issue = "31434")]
-#[cfg(bootstrap)]
-impl<T: ?Sized> StructuralEq for PhantomData<T> {}
-
 /// Compiler-internal trait used to indicate the type of enum discriminants.
 ///
 /// This trait is automatically implemented for every type and does not add any
@@ -1041,22 +966,8 @@ pub trait PointerLike {}
 #[unstable(feature = "adt_const_params", issue = "95174")]
 #[diagnostic::on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
 #[allow(multiple_supertrait_upcastable)]
-#[cfg(not(bootstrap))]
 pub trait ConstParamTy: StructuralPartialEq + Eq {}
 
-/// A marker for types which can be used as types of `const` generic parameters.
-///
-/// These types must have a proper equivalence relation (`Eq`) and it must be automatically
-/// derived (`StructuralPartialEq`). There's a hard-coded check in the compiler ensuring
-/// that all fields are also `ConstParamTy`, which implies that recursively, all fields
-/// are `StructuralPartialEq`.
-#[lang = "const_param_ty"]
-#[unstable(feature = "adt_const_params", issue = "95174")]
-#[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
-#[allow(multiple_supertrait_upcastable)]
-#[cfg(bootstrap)]
-pub trait ConstParamTy: StructuralEq + StructuralPartialEq + Eq {}
-
 /// Derive macro generating an impl of the trait `ConstParamTy`.
 #[rustc_builtin_macro]
 #[unstable(feature = "adt_const_params", issue = "95174")]
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 318a99e23ec..e247b9ed83d 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -1393,19 +1393,9 @@ impl<T> SizedTypeProperties for T {}
 ///
 /// assert_eq!(mem::offset_of!(Option<&u8>, Some.0), 0);
 /// ```
-#[cfg(not(bootstrap))]
-#[stable(feature = "offset_of", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "offset_of", since = "1.77.0")]
 #[allow_internal_unstable(builtin_syntax, hint_must_use)]
 pub macro offset_of($Container:ty, $($fields:expr)+ $(,)?) {
     // The `{}` is for better error messages
     crate::hint::must_use({builtin # offset_of($Container, $($fields)+)})
 }
-
-#[cfg(bootstrap)]
-#[stable(feature = "offset_of", since = "CURRENT_RUSTC_VERSION")]
-#[allow_internal_unstable(builtin_syntax, hint_must_use)]
-#[allow(missing_docs)]
-pub macro offset_of($Container:ty, $($fields:tt).+ $(,)?) {
-    // The `{}` is for better error messages
-    crate::hint::must_use({builtin # offset_of($Container, $($fields).+)})
-}
diff --git a/library/core/src/net/mod.rs b/library/core/src/net/mod.rs
index 5bae4d2f0c4..0786165fe9e 100644
--- a/library/core/src/net/mod.rs
+++ b/library/core/src/net/mod.rs
@@ -9,7 +9,7 @@
 //! * [`SocketAddr`] represents socket addresses of either IPv4 or IPv6; [`SocketAddrV4`]
 //!   and [`SocketAddrV6`] are respectively IPv4 and IPv6 socket addresses
 
-#![stable(feature = "ip_in_core", since = "CURRENT_RUSTC_VERSION")]
+#![stable(feature = "ip_in_core", since = "1.77.0")]
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::ip_addr::{IpAddr, Ipv4Addr, Ipv6Addr, Ipv6MulticastScope};
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 1124719fc8d..288ad8e8d87 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -3,15 +3,13 @@
 use crate::cmp::Ordering;
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
-#[cfg(bootstrap)]
-use crate::marker::StructuralEq;
+use crate::intrinsics;
 use crate::marker::StructuralPartialEq;
 use crate::ops::{BitOr, BitOrAssign, Div, Neg, Rem};
 use crate::str::FromStr;
 
 use super::from_str_radix;
 use super::{IntErrorKind, ParseIntError};
-use crate::intrinsics;
 
 mod private {
     #[unstable(
@@ -35,7 +33,7 @@ mod private {
 pub trait ZeroablePrimitive: Sized + Copy + private::Sealed {}
 
 macro_rules! impl_zeroable_primitive {
-    ($NonZero:ident ( $primitive:ty )) => {
+    ($primitive:ty) => {
         #[unstable(
             feature = "nonzero_internals",
             reason = "implementation detail which may disappear or be replaced at any time",
@@ -52,18 +50,18 @@ macro_rules! impl_zeroable_primitive {
     };
 }
 
-impl_zeroable_primitive!(NonZeroU8(u8));
-impl_zeroable_primitive!(NonZeroU16(u16));
-impl_zeroable_primitive!(NonZeroU32(u32));
-impl_zeroable_primitive!(NonZeroU64(u64));
-impl_zeroable_primitive!(NonZeroU128(u128));
-impl_zeroable_primitive!(NonZeroUsize(usize));
-impl_zeroable_primitive!(NonZeroI8(i8));
-impl_zeroable_primitive!(NonZeroI16(i16));
-impl_zeroable_primitive!(NonZeroI32(i32));
-impl_zeroable_primitive!(NonZeroI64(i64));
-impl_zeroable_primitive!(NonZeroI128(i128));
-impl_zeroable_primitive!(NonZeroIsize(isize));
+impl_zeroable_primitive!(u8);
+impl_zeroable_primitive!(u16);
+impl_zeroable_primitive!(u32);
+impl_zeroable_primitive!(u64);
+impl_zeroable_primitive!(u128);
+impl_zeroable_primitive!(usize);
+impl_zeroable_primitive!(i8);
+impl_zeroable_primitive!(i16);
+impl_zeroable_primitive!(i32);
+impl_zeroable_primitive!(i64);
+impl_zeroable_primitive!(i128);
+impl_zeroable_primitive!(isize);
 
 /// A value that is known not to equal zero.
 ///
@@ -83,6 +81,87 @@ impl_zeroable_primitive!(NonZeroIsize(isize));
 #[rustc_diagnostic_item = "NonZero"]
 pub struct NonZero<T: ZeroablePrimitive>(T);
 
+impl<T> NonZero<T>
+where
+    T: ZeroablePrimitive,
+{
+    /// Creates a non-zero if the given value is not zero.
+    #[stable(feature = "nonzero", since = "1.28.0")]
+    #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
+    #[must_use]
+    #[inline]
+    pub const fn new(n: T) -> Option<Self> {
+        // SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has
+        //         the same layout and size as `T`, with `0` representing `None`.
+        unsafe { intrinsics::transmute_unchecked(n) }
+    }
+
+    /// Creates a non-zero without checking whether the value is non-zero.
+    /// This results in undefined behaviour if the value is zero.
+    ///
+    /// # Safety
+    ///
+    /// The value must not be zero.
+    #[stable(feature = "nonzero", since = "1.28.0")]
+    #[rustc_const_stable(feature = "nonzero", since = "1.28.0")]
+    #[must_use]
+    #[inline]
+    pub const unsafe fn new_unchecked(n: T) -> Self {
+        match Self::new(n) {
+            Some(n) => n,
+            None => {
+                // SAFETY: The caller guarantees that `n` is non-zero, so this is unreachable.
+                unsafe {
+                    intrinsics::assert_unsafe_precondition!(
+                      "NonZero::new_unchecked requires the argument to be non-zero",
+                      () => false,
+                    );
+                    intrinsics::unreachable()
+                }
+            }
+        }
+    }
+
+    /// Converts a reference to a non-zero mutable reference
+    /// if the referenced value is not zero.
+    #[unstable(feature = "nonzero_from_mut", issue = "106290")]
+    #[must_use]
+    #[inline]
+    pub fn from_mut(n: &mut T) -> Option<&mut Self> {
+        // SAFETY: Memory layout optimization guarantees that `Option<NonZero<T>>` has
+        //         the same layout and size as `T`, with `0` representing `None`.
+        let opt_n = unsafe { &mut *(n as *mut T as *mut Option<Self>) };
+
+        opt_n.as_mut()
+    }
+
+    /// Converts a mutable reference to a non-zero mutable reference
+    /// without checking whether the referenced value is non-zero.
+    /// This results in undefined behavior if the referenced value is zero.
+    ///
+    /// # Safety
+    ///
+    /// The referenced value must not be zero.
+    #[unstable(feature = "nonzero_from_mut", issue = "106290")]
+    #[must_use]
+    #[inline]
+    pub unsafe fn from_mut_unchecked(n: &mut T) -> &mut Self {
+        match Self::from_mut(n) {
+            Some(n) => n,
+            None => {
+                // SAFETY: The caller guarantees that `n` references a value that is non-zero, so this is unreachable.
+                unsafe {
+                    intrinsics::assert_unsafe_precondition!(
+                      "NonZero::from_mut_unchecked requires the argument to dereference as non-zero",
+                      () => false,
+                    );
+                    intrinsics::unreachable()
+                }
+            }
+        }
+    }
+}
+
 macro_rules! impl_nonzero_fmt {
     ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
         $(
@@ -100,7 +179,6 @@ macro_rules! impl_nonzero_fmt {
 macro_rules! nonzero_integer {
     (
         #[$stability:meta]
-        #[$const_new_unchecked_stability:meta]
         Self = $Ty:ident,
         Primitive = $signedness:ident $Int:ident,
         $(UnsignedNonZero = $UnsignedNonZero:ident,)?
@@ -143,74 +221,6 @@ macro_rules! nonzero_integer {
         pub type $Ty = NonZero<$Int>;
 
         impl $Ty {
-            /// Creates a non-zero without checking whether the value is non-zero.
-            /// This results in undefined behaviour if the value is zero.
-            ///
-            /// # Safety
-            ///
-            /// The value must not be zero.
-            #[$stability]
-            #[$const_new_unchecked_stability]
-            #[must_use]
-            #[inline]
-            pub const unsafe fn new_unchecked(n: $Int) -> Self {
-                crate::panic::debug_assert_nounwind!(
-                    n != 0,
-                    concat!(stringify!($Ty), "::new_unchecked requires a non-zero argument")
-                );
-                // SAFETY: this is guaranteed to be safe by the caller.
-                unsafe {
-                    Self(n)
-                }
-            }
-
-            /// Creates a non-zero if the given value is not zero.
-            #[$stability]
-            #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
-            #[must_use]
-            #[inline]
-            pub const fn new(n: $Int) -> Option<Self> {
-                if n != 0 {
-                    // SAFETY: we just checked that there's no `0`
-                    Some(unsafe { Self(n) })
-                } else {
-                    None
-                }
-            }
-
-            /// Converts a primitive mutable reference to a non-zero mutable reference
-            /// without checking whether the referenced value is non-zero.
-            /// This results in undefined behavior if `*n` is zero.
-            ///
-            /// # Safety
-            /// The referenced value must not be currently zero.
-            #[unstable(feature = "nonzero_from_mut", issue = "106290")]
-            #[must_use]
-            #[inline]
-            pub unsafe fn from_mut_unchecked(n: &mut $Int) -> &mut Self {
-                // SAFETY: Self is repr(transparent), and the value is assumed to be non-zero.
-                unsafe {
-                    let n_alias = &mut *n;
-                    core::intrinsics::assert_unsafe_precondition!(
-                        concat!(stringify!($Ty), "::from_mut_unchecked requires the argument to dereference as non-zero"),
-                        (n_alias: &mut $Int) => *n_alias != 0
-                    );
-                    &mut *(n as *mut $Int as *mut Self)
-                }
-            }
-
-            /// Converts a primitive mutable reference to a non-zero mutable reference
-            /// if the referenced integer is not zero.
-            #[unstable(feature = "nonzero_from_mut", issue = "106290")]
-            #[must_use]
-            #[inline]
-            pub fn from_mut(n: &mut $Int) -> Option<&mut Self> {
-                // SAFETY: Self is repr(transparent), and the value is non-zero.
-                // As long as the returned reference is alive,
-                // the user cannot `*n = 0` directly.
-                (*n != 0).then(|| unsafe { &mut *(n as *mut $Int as *mut Self) })
-            }
-
             /// Returns the value as a primitive type.
             #[$stability]
             #[inline]
@@ -569,10 +579,6 @@ macro_rules! nonzero_integer {
         #[$stability]
         impl Eq for $Ty {}
 
-        #[unstable(feature = "structural_match", issue = "31434")]
-        #[cfg(bootstrap)]
-        impl StructuralEq for $Ty {}
-
         #[$stability]
         impl PartialOrd for $Ty {
             #[inline]
@@ -724,7 +730,6 @@ macro_rules! nonzero_integer {
     (Self = $Ty:ident, Primitive = unsigned $Int:ident $(,)?) => {
         nonzero_integer! {
             #[stable(feature = "nonzero", since = "1.28.0")]
-            #[rustc_const_stable(feature = "nonzero", since = "1.28.0")]
             Self = $Ty,
             Primitive = unsigned $Int,
             UnsignedPrimitive = $Int,
@@ -735,7 +740,6 @@ macro_rules! nonzero_integer {
     (Self = $Ty:ident, Primitive = signed $Int:ident, $($rest:tt)*) => {
         nonzero_integer! {
             #[stable(feature = "signed_nonzero", since = "1.34.0")]
-            #[rustc_const_stable(feature = "signed_nonzero", since = "1.34.0")]
             Self = $Ty,
             Primitive = signed $Int,
             $($rest)*
@@ -757,7 +761,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
             fn div(self, other: $Ty) -> $Int {
                 // SAFETY: div by zero is checked because `other` is a nonzero,
                 // and MIN/-1 is checked because `self` is an unsigned int.
-                unsafe { crate::intrinsics::unchecked_div(self, other.get()) }
+                unsafe { intrinsics::unchecked_div(self, other.get()) }
             }
         }
 
@@ -770,7 +774,7 @@ macro_rules! nonzero_integer_signedness_dependent_impls {
             fn rem(self, other: $Ty) -> $Int {
                 // SAFETY: rem by zero is checked because `other` is a nonzero,
                 // and MIN/-1 is checked because `self` is an unsigned int.
-                unsafe { crate::intrinsics::unchecked_rem(self, other.get()) }
+                unsafe { intrinsics::unchecked_rem(self, other.get()) }
             }
         }
     };
diff --git a/library/core/src/ops/arith.rs b/library/core/src/ops/arith.rs
index bb3cdde66d1..fd50f804748 100644
--- a/library/core/src/ops/arith.rs
+++ b/library/core/src/ops/arith.rs
@@ -73,6 +73,7 @@
     append_const_msg
 )]
 #[doc(alias = "+")]
+#[const_trait]
 pub trait Add<Rhs = Self> {
     /// The resulting type after applying the `+` operator.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -94,7 +95,8 @@ pub trait Add<Rhs = Self> {
 macro_rules! add_impl {
     ($($t:ty)*) => ($(
         #[stable(feature = "rust1", since = "1.0.0")]
-        impl Add for $t {
+        #[rustc_const_unstable(feature = "const_ops", issue = "90080")]
+        impl const Add for $t {
             type Output = $t;
 
             #[inline]
diff --git a/library/core/src/ops/async_function.rs b/library/core/src/ops/async_function.rs
index 19b1220f05e..d6b06ffb7fc 100644
--- a/library/core/src/ops/async_function.rs
+++ b/library/core/src/ops/async_function.rs
@@ -8,7 +8,7 @@ use crate::marker::Tuple;
 #[rustc_paren_sugar]
 #[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
-#[cfg_attr(not(bootstrap), lang = "async_fn")]
+#[lang = "async_fn"]
 pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
     /// Future returned by [`AsyncFn::async_call`].
     #[unstable(feature = "async_fn_traits", issue = "none")]
@@ -28,7 +28,7 @@ pub trait AsyncFn<Args: Tuple>: AsyncFnMut<Args> {
 #[rustc_paren_sugar]
 #[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
-#[cfg_attr(not(bootstrap), lang = "async_fn_mut")]
+#[lang = "async_fn_mut"]
 pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
     /// Future returned by [`AsyncFnMut::async_call_mut`].
     #[unstable(feature = "async_fn_traits", issue = "none")]
@@ -48,7 +48,7 @@ pub trait AsyncFnMut<Args: Tuple>: AsyncFnOnce<Args> {
 #[rustc_paren_sugar]
 #[fundamental]
 #[must_use = "async closures are lazy and do nothing unless called"]
-#[cfg_attr(not(bootstrap), lang = "async_fn_once")]
+#[lang = "async_fn_once"]
 pub trait AsyncFnOnce<Args: Tuple> {
     /// Future returned by [`AsyncFnOnce::async_call_once`].
     #[unstable(feature = "async_fn_traits", issue = "none")]
diff --git a/library/core/src/ops/coroutine.rs b/library/core/src/ops/coroutine.rs
index 6faded76a4a..6e067f95da9 100644
--- a/library/core/src/ops/coroutine.rs
+++ b/library/core/src/ops/coroutine.rs
@@ -111,7 +111,7 @@ pub trait Coroutine<R = ()> {
     /// been returned previously. While coroutine literals in the language are
     /// guaranteed to panic on resuming after `Complete`, this is not guaranteed
     /// for all implementations of the `Coroutine` trait.
-    #[cfg_attr(not(bootstrap), lang = "coroutine_resume")]
+    #[lang = "coroutine_resume"]
     fn resume(self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return>;
 }
 
diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs
index e809273c9ed..727a22e454d 100644
--- a/library/core/src/ops/range.rs
+++ b/library/core/src/ops/range.rs
@@ -726,7 +726,7 @@ impl<T> Bound<T> {
     /// assert_eq!(unbounded_string.map(|s| s.len()), Unbounded);
     /// ```
     #[inline]
-    #[stable(feature = "bound_map", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "bound_map", since = "1.77.0")]
     pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Bound<U> {
         match self {
             Unbounded => Unbounded,
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index c94e7d73a2a..d4c40c49934 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -1033,7 +1033,6 @@ impl<T> Option<T> {
     #[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")]
     #[rustc_const_unstable(feature = "const_option_ext", issue = "91930")]
     pub const unsafe fn unwrap_unchecked(self) -> T {
-        debug_assert!(self.is_some());
         match self {
             Some(val) => val,
             // SAFETY: the safety contract must be upheld by the caller.
@@ -1074,18 +1073,23 @@ impl<T> Option<T> {
         }
     }
 
-    /// Calls the provided closure with a reference to the contained value (if [`Some`]).
+    /// Calls a function with a reference to the contained value if [`Some`].
+    ///
+    /// Returns the original option.
     ///
     /// # Examples
     ///
     /// ```
-    /// let v = vec![1, 2, 3, 4, 5];
+    /// let list = vec![1, 2, 3];
     ///
-    /// // prints "got: 4"
-    /// let x: Option<&usize> = v.get(3).inspect(|x| println!("got: {x}"));
+    /// // prints "got: 2"
+    /// let x = list
+    ///     .get(1)
+    ///     .inspect(|x| println!("got: {x}"))
+    ///     .expect("list should be long enough");
     ///
     /// // prints nothing
-    /// let x: Option<&usize> = v.get(5).inspect(|x| println!("got: {x}"));
+    /// list.get(5).inspect(|x| println!("got: {x}"));
     /// ```
     #[inline]
     #[stable(feature = "result_option_inspect", since = "1.76.0")]
@@ -2155,7 +2159,6 @@ impl<T: PartialEq> PartialEq for Option<T> {
 ///
 /// Once that's fixed, `Option` should go back to deriving `PartialEq`, as
 /// it used to do before <https://github.com/rust-lang/rust/pull/103556>.
-/// The comment regarding this trait on the `newtype_index` macro should be removed if this is done.
 #[unstable(feature = "spec_option_partial_eq", issue = "none", reason = "exposed only for rustc")]
 #[doc(hidden)]
 pub trait SpecOptionPartialEq: Sized {
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index bf47d767a92..85595b059ad 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -448,22 +448,6 @@ mod prim_unit {}
 #[doc(hidden)]
 impl () {}
 
-// Fake impl that's only really used for docs.
-#[cfg(doc)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Clone for () {
-    fn clone(&self) -> Self {
-        loop {}
-    }
-}
-
-// Fake impl that's only really used for docs.
-#[cfg(doc)]
-#[stable(feature = "rust1", since = "1.0.0")]
-impl Copy for () {
-    // empty
-}
-
 #[rustc_doc_primitive = "pointer"]
 #[doc(alias = "ptr")]
 #[doc(alias = "*")]
@@ -1690,23 +1674,3 @@ mod prim_fn {}
 // See src/librustdoc/passes/collect_trait_impls.rs:collect_trait_impls
 #[doc(hidden)]
 impl<Ret, T> fn(T) -> Ret {}
-
-// Fake impl that's only really used for docs.
-#[cfg(doc)]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(fake_variadic)]
-/// This trait is implemented on function pointers with any number of arguments.
-impl<Ret, T> Clone for fn(T) -> Ret {
-    fn clone(&self) -> Self {
-        loop {}
-    }
-}
-
-// Fake impl that's only really used for docs.
-#[cfg(doc)]
-#[stable(feature = "rust1", since = "1.0.0")]
-#[doc(fake_variadic)]
-/// This trait is implemented on function pointers with any number of arguments.
-impl<Ret, T> Copy for fn(T) -> Ret {
-    // empty
-}
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index f3ceadee24c..c5e3df07a1c 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -806,13 +806,15 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        let this = self;
         // SAFETY: The comparison has no side-effects, and the intrinsic
         // does this check internally in the CTFE implementation.
         unsafe {
             assert_unsafe_precondition!(
-                "ptr::sub_ptr requires `this >= origin`",
-                [T](this: *const T, origin: *const T) => this >= origin
+                "ptr::sub_ptr requires `self >= origin`",
+                (
+                    this: *const () = self as *const (),
+                    origin: *const () = origin as *const (),
+                ) => this >= origin
             )
         };
 
@@ -1284,7 +1286,7 @@ impl<T: ?Sized> *const T {
     /// See [`ptr::copy`] for safety concerns and examples.
     ///
     /// [`ptr::copy`]: crate::ptr::copy()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -1304,7 +1306,7 @@ impl<T: ?Sized> *const T {
     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
     ///
     /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index dce7e035fc7..0fb9017e6d9 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -381,11 +381,11 @@ use crate::cmp::Ordering;
 use crate::fmt;
 use crate::hash;
 use crate::intrinsics::{
-    self, assert_unsafe_precondition, is_aligned_and_not_null, is_nonoverlapping,
+    self, assert_unsafe_precondition, is_aligned_and_not_null, is_nonoverlapping_mono,
 };
 use crate::marker::FnPtr;
 
-use crate::mem::{self, MaybeUninit};
+use crate::mem::{self, align_of, size_of, MaybeUninit};
 
 mod alignment;
 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
@@ -967,10 +967,16 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
         assert_unsafe_precondition!(
             "ptr::swap_nonoverlapping requires that both pointer arguments are aligned and non-null \
             and the specified memory ranges do not overlap",
-            [T](x: *mut T, y: *mut T, count: usize) =>
-            is_aligned_and_not_null(x)
-                && is_aligned_and_not_null(y)
-                && is_nonoverlapping(x, y, count)
+            (
+                x: *mut () = x as *mut (),
+                y: *mut () = y as *mut (),
+                size: usize = size_of::<T>(),
+                align: usize = align_of::<T>(),
+                count: usize = count,
+            ) =>
+            is_aligned_and_not_null(x, align)
+                && is_aligned_and_not_null(y, align)
+                && is_nonoverlapping_mono(x, y, size, count)
         );
     }
 
@@ -1061,7 +1067,10 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
     unsafe {
         assert_unsafe_precondition!(
             "ptr::replace requires that the pointer argument is aligned and non-null",
-            [T](dst: *mut T) => is_aligned_and_not_null(dst)
+            (
+                addr: *const () = dst as *const (),
+                align: usize = align_of::<T>(),
+            ) => is_aligned_and_not_null(addr, align)
         );
         mem::swap(&mut *dst, &mut src); // cannot overlap
     }
@@ -1176,7 +1185,6 @@ pub const unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
-#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[rustc_diagnostic_item = "ptr_read"]
 pub const unsafe fn read<T>(src: *const T) -> T {
@@ -1208,9 +1216,13 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 
     // SAFETY: the caller must guarantee that `src` is valid for reads.
     unsafe {
+        #[cfg(debug_assertions)] // Too expensive to always enable (for now?)
         assert_unsafe_precondition!(
             "ptr::read requires that the pointer argument is aligned and non-null",
-            [T](src: *const T) => is_aligned_and_not_null(src)
+            (
+                addr: *const () = src as *const (),
+                align: usize = align_of::<T>(),
+            ) => is_aligned_and_not_null(addr, align)
         );
         crate::intrinsics::read_via_copy(src)
     }
@@ -1294,7 +1306,11 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 #[inline]
 #[stable(feature = "ptr_unaligned", since = "1.17.0")]
 #[rustc_const_stable(feature = "const_ptr_read", since = "1.71.0")]
-#[rustc_allow_const_fn_unstable(const_mut_refs, const_maybe_uninit_as_mut_ptr)]
+#[rustc_allow_const_fn_unstable(
+    const_mut_refs,
+    const_maybe_uninit_as_mut_ptr,
+    const_intrinsic_copy
+)]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 #[rustc_diagnostic_item = "ptr_read_unaligned"]
 pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
@@ -1408,9 +1424,13 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
     // `dst` cannot overlap `src` because the caller has mutable access
     // to `dst` while `src` is owned by this function.
     unsafe {
+        #[cfg(debug_assertions)] // Too expensive to always enable (for now?)
         assert_unsafe_precondition!(
             "ptr::write requires that the pointer argument is aligned and non-null",
-            [T](dst: *mut T) => is_aligned_and_not_null(dst)
+            (
+                addr: *mut () = dst as *mut (),
+                align: usize = align_of::<T>(),
+            ) => is_aligned_and_not_null(addr, align)
         );
         intrinsics::write_via_move(dst, src)
     }
@@ -1578,7 +1598,10 @@ pub unsafe fn read_volatile<T>(src: *const T) -> T {
     unsafe {
         assert_unsafe_precondition!(
             "ptr::read_volatile requires that the pointer argument is aligned and non-null",
-            [T](src: *const T) => is_aligned_and_not_null(src)
+            (
+                addr: *const () = src as *const (),
+                align: usize = align_of::<T>(),
+            ) => is_aligned_and_not_null(addr, align)
         );
         intrinsics::volatile_load(src)
     }
@@ -1653,7 +1676,10 @@ pub unsafe fn write_volatile<T>(dst: *mut T, src: T) {
     unsafe {
         assert_unsafe_precondition!(
             "ptr::write_volatile requires that the pointer argument is aligned and non-null",
-            [T](dst: *mut T) => is_aligned_and_not_null(dst)
+            (
+                addr: *mut () = dst as *mut (),
+                align: usize = align_of::<T>(),
+            ) => is_aligned_and_not_null(addr, align)
         );
         intrinsics::volatile_store(dst, src);
     }
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 3e47c4f440a..376673d67c1 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1385,7 +1385,7 @@ impl<T: ?Sized> *mut T {
     /// See [`ptr::copy`] for safety concerns and examples.
     ///
     /// [`ptr::copy`]: crate::ptr::copy()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -1405,7 +1405,7 @@ impl<T: ?Sized> *mut T {
     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
     ///
     /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -1425,7 +1425,7 @@ impl<T: ?Sized> *mut T {
     /// See [`ptr::copy`] for safety concerns and examples.
     ///
     /// [`ptr::copy`]: crate::ptr::copy()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
@@ -1445,7 +1445,7 @@ impl<T: ?Sized> *mut T {
     /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples.
     ///
     /// [`ptr::copy_nonoverlapping`]: crate::ptr::copy_nonoverlapping()
-    #[rustc_const_stable(feature = "const_intrinsic_copy", since = "1.63.0")]
+    #[rustc_const_unstable(feature = "const_intrinsic_copy", issue = "80697")]
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index d18082c3048..320cd5eb3b2 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -218,7 +218,10 @@ impl<T: ?Sized> NonNull<T> {
     pub const unsafe fn new_unchecked(ptr: *mut T) -> Self {
         // SAFETY: the caller must guarantee that `ptr` is non-null.
         unsafe {
-            assert_unsafe_precondition!("NonNull::new_unchecked requires that the pointer is non-null", [T: ?Sized](ptr: *mut T) => !ptr.is_null());
+            assert_unsafe_precondition!(
+                "NonNull::new_unchecked requires that the pointer is non-null",
+                (ptr: *mut () = ptr as *mut ()) => !ptr.is_null()
+            );
             NonNull { pointer: ptr as _ }
         }
     }
@@ -470,7 +473,7 @@ impl<T: ?Sized> NonNull<T> {
     #[inline]
     pub const fn cast<U>(self) -> NonNull<U> {
         // SAFETY: `self` is a `NonNull` pointer which is necessarily non-null
-        unsafe { NonNull::new_unchecked(self.as_ptr() as *mut U) }
+        unsafe { NonNull { pointer: self.as_ptr() as *mut U } }
     }
 
     /// Calculates the offset from a pointer.
@@ -1588,8 +1591,7 @@ impl<T> NonNull<[T]> {
     #[unstable(feature = "slice_ptr_get", issue = "74265")]
     #[rustc_const_unstable(feature = "slice_ptr_get", issue = "74265")]
     pub const fn as_non_null_ptr(self) -> NonNull<T> {
-        // SAFETY: We know `self` is non-null.
-        unsafe { NonNull::new_unchecked(self.as_ptr().as_mut_ptr()) }
+        self.cast()
     }
 
     /// Returns a raw pointer to the slice's buffer.
@@ -1825,9 +1827,7 @@ impl<T: ?Sized> hash::Hash for NonNull<T> {
 impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
     #[inline]
     fn from(unique: Unique<T>) -> Self {
-        // SAFETY: A Unique pointer cannot be null, so the conditions for
-        // new_unchecked() are respected.
-        unsafe { NonNull::new_unchecked(unique.as_ptr()) }
+        unique.as_non_null_ptr()
     }
 }
 
@@ -1850,8 +1850,7 @@ impl<T: ?Sized> From<&T> for NonNull<T> {
     /// This conversion is safe and infallible since references cannot be null.
     #[inline]
     fn from(reference: &T) -> Self {
-        // SAFETY: A reference cannot be null, so the conditions for
-        // new_unchecked() are respected.
+        // SAFETY: A reference cannot be null.
         unsafe { NonNull { pointer: reference as *const T } }
     }
 }
diff --git a/library/core/src/ptr/unique.rs b/library/core/src/ptr/unique.rs
index 067f1541e31..b74d691e454 100644
--- a/library/core/src/ptr/unique.rs
+++ b/library/core/src/ptr/unique.rs
@@ -106,6 +106,13 @@ impl<T: ?Sized> Unique<T> {
         self.pointer.as_ptr()
     }
 
+    /// Acquires the underlying `*mut` pointer.
+    #[must_use = "`self` will be dropped if the result is not used"]
+    #[inline]
+    pub const fn as_non_null_ptr(self) -> NonNull<T> {
+        self.pointer
+    }
+
     /// Dereferences the content.
     ///
     /// The resulting lifetime is bound to self so this behaves "as if"
@@ -138,7 +145,7 @@ impl<T: ?Sized> Unique<T> {
     pub const fn cast<U>(self) -> Unique<U> {
         // FIXME(const-hack): replace with `From`
         // SAFETY: is `NonNull`
-        unsafe { Unique::new_unchecked(self.pointer.cast().as_ptr()) }
+        Unique { pointer: self.pointer.cast(), _marker: PhantomData }
     }
 }
 
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 1f448984e53..80f7fe75e82 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -830,7 +830,9 @@ impl<T, E> Result<T, E> {
         }
     }
 
-    /// Calls the provided closure with a reference to the contained value (if [`Ok`]).
+    /// Calls a function with a reference to the contained value if [`Ok`].
+    ///
+    /// Returns the original result.
     ///
     /// # Examples
     ///
@@ -851,7 +853,9 @@ impl<T, E> Result<T, E> {
         self
     }
 
-    /// Calls the provided closure with a reference to the contained error (if [`Err`]).
+    /// Calls a function with a reference to the contained value if [`Err`].
+    ///
+    /// Returns the original result.
     ///
     /// # Examples
     ///
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 2d4c7e78aea..1429313c890 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -87,12 +87,13 @@ unsafe impl<T: Sync> Send for Iter<'_, T> {}
 impl<'a, T> Iter<'a, T> {
     #[inline]
     pub(super) fn new(slice: &'a [T]) -> Self {
-        let ptr = slice.as_ptr();
+        let len = slice.len();
+        let ptr: NonNull<T> = NonNull::from(slice).cast();
         // SAFETY: Similar to `IterMut::new`.
         unsafe {
-            let end_or_len = if T::IS_ZST { invalid(slice.len()) } else { ptr.add(slice.len()) };
+            let end_or_len = if T::IS_ZST { invalid(len) } else { ptr.as_ptr().add(len) };
 
-            Self { ptr: NonNull::new_unchecked(ptr as *mut T), end_or_len, _marker: PhantomData }
+            Self { ptr, end_or_len, _marker: PhantomData }
         }
     }
 
@@ -208,7 +209,8 @@ unsafe impl<T: Send> Send for IterMut<'_, T> {}
 impl<'a, T> IterMut<'a, T> {
     #[inline]
     pub(super) fn new(slice: &'a mut [T]) -> Self {
-        let ptr = slice.as_mut_ptr();
+        let len = slice.len();
+        let ptr: NonNull<T> = NonNull::from(slice).cast();
         // SAFETY: There are several things here:
         //
         // `ptr` has been obtained by `slice.as_ptr()` where `slice` is a valid
@@ -226,10 +228,9 @@ impl<'a, T> IterMut<'a, T> {
         // See the `next_unchecked!` and `is_empty!` macros as well as the
         // `post_inc_start` method for more information.
         unsafe {
-            let end_or_len =
-                if T::IS_ZST { invalid_mut(slice.len()) } else { ptr.add(slice.len()) };
+            let end_or_len = if T::IS_ZST { invalid_mut(len) } else { ptr.as_ptr().add(len) };
 
-            Self { ptr: NonNull::new_unchecked(ptr), end_or_len, _marker: PhantomData }
+            Self { ptr, end_or_len, _marker: PhantomData }
         }
     }
 
@@ -3252,21 +3253,21 @@ unsafe impl<'a, T> TrustedRandomAccessNoCoerce for IterMut<'a, T> {
 ///
 /// [`chunk_by`]: slice::chunk_by
 /// [slices]: slice
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 pub struct ChunkBy<'a, T: 'a, P> {
     slice: &'a [T],
     predicate: P,
 }
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> ChunkBy<'a, T, P> {
     pub(super) fn new(slice: &'a [T], predicate: P) -> Self {
         ChunkBy { slice, predicate }
     }
 }
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> Iterator for ChunkBy<'a, T, P>
 where
     P: FnMut(&T, &T) -> bool,
@@ -3300,7 +3301,7 @@ where
     }
 }
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> DoubleEndedIterator for ChunkBy<'a, T, P>
 where
     P: FnMut(&T, &T) -> bool,
@@ -3322,10 +3323,10 @@ where
     }
 }
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> FusedIterator for ChunkBy<'a, T, P> where P: FnMut(&T, &T) -> bool {}
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 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("ChunkBy").field("slice", &self.slice).finish()
@@ -3339,21 +3340,21 @@ impl<'a, T: 'a + fmt::Debug, P> fmt::Debug for ChunkBy<'a, T, P> {
 ///
 /// [`chunk_by_mut`]: slice::chunk_by_mut
 /// [slices]: slice
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 #[must_use = "iterators are lazy and do nothing unless consumed"]
 pub struct ChunkByMut<'a, T: 'a, P> {
     slice: &'a mut [T],
     predicate: P,
 }
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> ChunkByMut<'a, T, P> {
     pub(super) fn new(slice: &'a mut [T], predicate: P) -> Self {
         ChunkByMut { slice, predicate }
     }
 }
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> Iterator for ChunkByMut<'a, T, P>
 where
     P: FnMut(&T, &T) -> bool,
@@ -3388,7 +3389,7 @@ where
     }
 }
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> DoubleEndedIterator for ChunkByMut<'a, T, P>
 where
     P: FnMut(&T, &T) -> bool,
@@ -3411,10 +3412,10 @@ where
     }
 }
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 impl<'a, T: 'a, P> FusedIterator for ChunkByMut<'a, T, P> where P: FnMut(&T, &T) -> bool {}
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 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("ChunkByMut").field("slice", &self.slice).finish()
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 4ed22ede03a..73e92ed1dad 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -68,7 +68,7 @@ pub use iter::{ArrayChunks, ArrayChunksMut};
 #[unstable(feature = "array_windows", issue = "75027")]
 pub use iter::ArrayWindows;
 
-#[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+#[stable(feature = "slice_group_by", since = "1.77.0")]
 pub use iter::{ChunkBy, ChunkByMut};
 
 #[stable(feature = "split_inclusive", since = "1.51.0")]
@@ -334,8 +334,8 @@ impl<T> [T] {
     /// assert_eq!(Some(&[]), w.first_chunk::<0>());
     /// ```
     #[inline]
-    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
+    #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     pub const fn first_chunk<const N: usize>(&self) -> Option<&[T; N]> {
         if self.len() < N {
             None
@@ -364,7 +364,7 @@ impl<T> [T] {
     /// assert_eq!(None, x.first_chunk_mut::<4>());
     /// ```
     #[inline]
-    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn first_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
         if self.len() < N {
@@ -394,8 +394,8 @@ impl<T> [T] {
     /// assert_eq!(None, x.split_first_chunk::<4>());
     /// ```
     #[inline]
-    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
+    #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     pub const fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])> {
         if self.len() < N {
             None
@@ -429,7 +429,7 @@ impl<T> [T] {
     /// assert_eq!(None, x.split_first_chunk_mut::<4>());
     /// ```
     #[inline]
-    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn split_first_chunk_mut<const N: usize>(
         &mut self,
@@ -464,8 +464,8 @@ impl<T> [T] {
     /// assert_eq!(None, x.split_last_chunk::<4>());
     /// ```
     #[inline]
-    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
-    #[rustc_const_stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
+    #[rustc_const_stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     pub const fn split_last_chunk<const N: usize>(&self) -> Option<(&[T], &[T; N])> {
         if self.len() < N {
             None
@@ -499,7 +499,7 @@ impl<T> [T] {
     /// assert_eq!(None, x.split_last_chunk_mut::<4>());
     /// ```
     #[inline]
-    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn split_last_chunk_mut<const N: usize>(
         &mut self,
@@ -534,7 +534,7 @@ impl<T> [T] {
     /// assert_eq!(Some(&[]), w.last_chunk::<0>());
     /// ```
     #[inline]
-    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn last_chunk<const N: usize>(&self) -> Option<&[T; N]> {
         if self.len() < N {
@@ -568,7 +568,7 @@ impl<T> [T] {
     /// assert_eq!(None, x.last_chunk_mut::<4>());
     /// ```
     #[inline]
-    #[stable(feature = "slice_first_last_chunk", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_first_last_chunk", since = "1.77.0")]
     #[rustc_const_unstable(feature = "const_slice_first_last_chunk", issue = "111774")]
     pub const fn last_chunk_mut<const N: usize>(&mut self) -> Option<&mut [T; N]> {
         if self.len() < N {
@@ -1777,7 +1777,7 @@ impl<T> [T] {
     /// assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
     /// assert_eq!(iter.next(), None);
     /// ```
-    #[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_group_by", since = "1.77.0")]
     #[inline]
     pub fn chunk_by<F>(&self, pred: F) -> ChunkBy<'_, T, F>
     where
@@ -1818,7 +1818,7 @@ impl<T> [T] {
     /// assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
     /// assert_eq!(iter.next(), None);
     /// ```
-    #[stable(feature = "slice_group_by", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "slice_group_by", since = "1.77.0")]
     #[inline]
     pub fn chunk_by_mut<F>(&mut self, pred: F) -> ChunkByMut<'_, T, F>
     where
@@ -1951,10 +1951,7 @@ impl<T> [T] {
     /// }
     /// ```
     #[unstable(feature = "slice_split_at_unchecked", reason = "new API", issue = "76014")]
-    #[rustc_const_stable(
-        feature = "const_slice_split_at_unchecked",
-        since = "CURRENT_RUSTC_VERSION"
-    )]
+    #[rustc_const_stable(feature = "const_slice_split_at_unchecked", since = "1.77.0")]
     #[inline]
     #[must_use]
     pub const unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T]) {
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index 9cdf9b68afb..571abc3e999 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -4,6 +4,7 @@ use crate::array;
 use crate::intrinsics::{
     assert_unsafe_precondition, is_aligned_and_not_null, is_valid_allocation_size,
 };
+use crate::mem::{align_of, size_of};
 use crate::ops::Range;
 use crate::ptr;
 
@@ -96,8 +97,14 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
     unsafe {
         assert_unsafe_precondition!(
             "slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`",
-            [T](data: *const T, len: usize) => is_aligned_and_not_null(data)
-                && is_valid_allocation_size::<T>(len)
+            (
+                data: *mut () = data as *mut (),
+                size: usize = size_of::<T>(),
+                align: usize = align_of::<T>(),
+                len: usize = len,
+            ) =>
+                is_aligned_and_not_null(data, align)
+                && is_valid_allocation_size(size, len)
         );
         &*ptr::slice_from_raw_parts(data, len)
     }
@@ -143,8 +150,14 @@ pub const unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a m
     unsafe {
         assert_unsafe_precondition!(
             "slice::from_raw_parts_mut requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`",
-            [T](data: *mut T, len: usize) => is_aligned_and_not_null(data)
-                && is_valid_allocation_size::<T>(len)
+            (
+                data: *mut () = data as *mut (),
+                size: usize = size_of::<T>(),
+                align: usize = align_of::<T>(),
+                len: usize = len,
+            ) =>
+                is_aligned_and_not_null(data, align)
+                && is_valid_allocation_size(size, len)
         );
         &mut *ptr::slice_from_raw_parts_mut(data, len)
     }
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index b677776443f..e4f29942966 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -197,13 +197,18 @@ impl Duration {
     #[must_use]
     #[rustc_const_stable(feature = "duration_consts_2", since = "1.58.0")]
     pub const fn new(secs: u64, nanos: u32) -> Duration {
-        let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
-            Some(secs) => secs,
-            None => panic!("overflow in Duration::new"),
-        };
-        let nanos = nanos % NANOS_PER_SEC;
-        // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
-        Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
+        if nanos < NANOS_PER_SEC {
+            // SAFETY: nanos < NANOS_PER_SEC, therefore nanos is within the valid range
+            Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
+        } else {
+            let secs = match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
+                Some(secs) => secs,
+                None => panic!("overflow in Duration::new"),
+            };
+            let nanos = nanos % NANOS_PER_SEC;
+            // SAFETY: nanos % NANOS_PER_SEC < NANOS_PER_SEC, therefore nanos is within the valid range
+            Duration { secs, nanos: unsafe { Nanoseconds(nanos) } }
+        }
     }
 
     /// Creates a new `Duration` from the specified number of whole seconds.
diff --git a/library/core/src/tuple.rs b/library/core/src/tuple.rs
index 47e27bdc735..44fac589d4c 100644
--- a/library/core/src/tuple.rs
+++ b/library/core/src/tuple.rs
@@ -63,14 +63,6 @@ macro_rules! tuple_impls {
 
         maybe_tuple_doc! {
             $($T)+ @
-            #[unstable(feature = "structural_match", issue = "31434")]
-            #[cfg(bootstrap)]
-            impl<$($T),+> crate::marker::StructuralEq for ($($T,)+)
-            {}
-        }
-
-        maybe_tuple_doc! {
-            $($T)+ @
             #[stable(feature = "rust1", since = "1.0.0")]
             impl<$($T: PartialOrd),+> PartialOrd for ($($T,)+)
             where
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 9a3b477c2d1..6deebc0d263 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -14,6 +14,7 @@
 #![feature(const_cell_into_inner)]
 #![feature(const_hash)]
 #![feature(const_heap)]
+#![feature(const_intrinsic_copy)]
 #![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_nonnull_new)]
 #![feature(const_pointer_is_aligned)]
@@ -58,7 +59,7 @@
 #![feature(noop_waker)]
 #![feature(numfmt)]
 #![feature(num_midpoint)]
-#![cfg_attr(not(bootstrap), feature(offset_of_nested))]
+#![feature(offset_of_nested)]
 #![feature(isqrt)]
 #![feature(step_trait)]
 #![feature(str_internals)]
@@ -111,7 +112,7 @@
 #![feature(slice_flatten)]
 #![feature(error_generic_member_access)]
 #![feature(error_in_core)]
-#![cfg_attr(not(bootstrap), feature(trait_upcasting))]
+#![feature(trait_upcasting)]
 #![feature(utf8_chunks)]
 #![feature(is_ascii_octdigit)]
 #![feature(get_many_mut)]
diff --git a/library/core/tests/macros.rs b/library/core/tests/macros.rs
index eb886def164..09994fbcbdb 100644
--- a/library/core/tests/macros.rs
+++ b/library/core/tests/macros.rs
@@ -1,3 +1,4 @@
+#[allow(dead_code)]
 trait Trait {
     fn blah(&self);
 }
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index ccae406cc28..d3ba546d730 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -262,7 +262,7 @@ cfg_if::cfg_if! {
 }
 
 // FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
-#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
+#[allow(static_mut_ref)]
 pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     use core::intrinsics::atomic_store_seqcst;
 
@@ -325,7 +325,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
 }
 
 // FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
-#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
+#[allow(static_mut_ref)]
 pub unsafe fn cleanup(payload: *mut u8) -> Box<dyn Any + Send> {
     // A null payload here means that we got here from the catch (...) of
     // __rust_try. This happens when a non-Rust foreign exception is caught.
diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs
index 52a08cad911..9255c3abc8a 100644
--- a/library/proc_macro/src/bridge/client.rs
+++ b/library/proc_macro/src/bridge/client.rs
@@ -3,6 +3,7 @@
 use super::*;
 
 use std::marker::PhantomData;
+use std::sync::atomic::AtomicU32;
 
 macro_rules! define_handles {
     (
@@ -12,8 +13,8 @@ macro_rules! define_handles {
         #[repr(C)]
         #[allow(non_snake_case)]
         pub struct HandleCounters {
-            $($oty: AtomicUsize,)*
-            $($ity: AtomicUsize,)*
+            $($oty: AtomicU32,)*
+            $($ity: AtomicU32,)*
         }
 
         impl HandleCounters {
@@ -21,8 +22,8 @@ macro_rules! define_handles {
             // a wrapper `fn` pointer, once `const fn` can reference `static`s.
             extern "C" fn get() -> &'static Self {
                 static COUNTERS: HandleCounters = HandleCounters {
-                    $($oty: AtomicUsize::new(1),)*
-                    $($ity: AtomicUsize::new(1),)*
+                    $($oty: AtomicU32::new(1),)*
+                    $($ity: AtomicU32::new(1),)*
                 };
                 &COUNTERS
             }
diff --git a/library/proc_macro/src/bridge/handle.rs b/library/proc_macro/src/bridge/handle.rs
index 00954107b77..b3a76306997 100644
--- a/library/proc_macro/src/bridge/handle.rs
+++ b/library/proc_macro/src/bridge/handle.rs
@@ -4,7 +4,7 @@ use std::collections::BTreeMap;
 use std::hash::Hash;
 use std::num::NonZeroU32;
 use std::ops::{Index, IndexMut};
-use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::atomic::{AtomicU32, Ordering};
 
 use super::fxhash::FxHashMap;
 
@@ -13,12 +13,12 @@ pub(super) type Handle = NonZeroU32;
 /// A store that associates values of type `T` with numeric handles. A value can
 /// be looked up using its handle.
 pub(super) struct OwnedStore<T: 'static> {
-    counter: &'static AtomicUsize,
+    counter: &'static AtomicU32,
     data: BTreeMap<Handle, T>,
 }
 
 impl<T> OwnedStore<T> {
-    pub(super) fn new(counter: &'static AtomicUsize) -> Self {
+    pub(super) fn new(counter: &'static AtomicU32) -> Self {
         // Ensure the handle counter isn't 0, which would panic later,
         // when `NonZeroU32::new` (aka `Handle::new`) is called in `alloc`.
         assert_ne!(counter.load(Ordering::SeqCst), 0);
@@ -30,7 +30,7 @@ impl<T> OwnedStore<T> {
 impl<T> OwnedStore<T> {
     pub(super) fn alloc(&mut self, x: T) -> Handle {
         let counter = self.counter.fetch_add(1, Ordering::SeqCst);
-        let handle = Handle::new(counter as u32).expect("`proc_macro` handle counter overflowed");
+        let handle = Handle::new(counter).expect("`proc_macro` handle counter overflowed");
         assert!(self.data.insert(handle, x).is_none());
         handle
     }
@@ -60,7 +60,7 @@ pub(super) struct InternedStore<T: 'static> {
 }
 
 impl<T: Copy + Eq + Hash> InternedStore<T> {
-    pub(super) fn new(counter: &'static AtomicUsize) -> Self {
+    pub(super) fn new(counter: &'static AtomicU32) -> Self {
         InternedStore { owned: OwnedStore::new(counter), interner: FxHashMap::default() }
     }
 
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 75bf3329786..55e24b6491c 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -16,7 +16,6 @@ use std::mem;
 use std::ops::Bound;
 use std::ops::Range;
 use std::panic;
-use std::sync::atomic::AtomicUsize;
 use std::sync::Once;
 use std::thread;
 
diff --git a/library/std/src/f32.rs b/library/std/src/f32.rs
index 1b38ba72114..b60d7a72411 100644
--- a/library/std/src/f32.rs
+++ b/library/std/src/f32.rs
@@ -114,7 +114,7 @@ impl f32 {
     /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    #[stable(feature = "round_ties_even", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "round_ties_even", since = "1.77.0")]
     #[inline]
     pub fn round_ties_even(self) -> f32 {
         unsafe { intrinsics::rintf32(self) }
diff --git a/library/std/src/f64.rs b/library/std/src/f64.rs
index f8fc84440ae..88f992b3957 100644
--- a/library/std/src/f64.rs
+++ b/library/std/src/f64.rs
@@ -114,7 +114,7 @@ impl f64 {
     /// ```
     #[rustc_allow_incoherent_impl]
     #[must_use = "method returns a new number and does not mutate the original value"]
-    #[stable(feature = "round_ties_even", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "round_ties_even", since = "1.77.0")]
     #[inline]
     pub fn round_ties_even(self) -> f64 {
         unsafe { intrinsics::rintf64(self) }
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 80d369eb067..3383a8cfa41 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -428,7 +428,7 @@ impl File {
     ///     Ok(())
     /// }
     /// ```
-    #[stable(feature = "file_create_new", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "file_create_new", since = "1.77.0")]
     pub fn create_new<P: AsRef<Path>>(path: P) -> io::Result<File> {
         OpenOptions::new().read(true).write(true).create_new(true).open(path.as_ref())
     }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index f98654e4d18..571e475c336 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -266,12 +266,12 @@
 //
 // Language features:
 // tidy-alphabetical-start
-#![cfg_attr(not(bootstrap), feature(cfg_sanitizer_cfi))]
 #![feature(alloc_error_handler)]
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
 #![feature(c_unwind)]
+#![feature(cfg_sanitizer_cfi)]
 #![feature(cfg_target_thread_local)]
 #![feature(cfi_encoding)]
 #![feature(concat_idents)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index c80f15d8a61..8294160b72c 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -338,7 +338,7 @@ pub mod panic_count {
 #[cfg(not(feature = "panic_immediate_abort"))]
 #[unstable(feature = "update_panic_count", issue = "none")]
 // FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
-#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
+#[allow(static_mut_ref)]
 pub mod panic_count {
     use crate::cell::Cell;
     use crate::sync::atomic::{AtomicUsize, Ordering};
diff --git a/library/std/src/sync/mutex.rs b/library/std/src/sync/mutex.rs
index 184c406e326..920143b7ac7 100644
--- a/library/std/src/sync/mutex.rs
+++ b/library/std/src/sync/mutex.rs
@@ -404,7 +404,7 @@ impl<T: ?Sized> Mutex<T> {
     /// assert_eq!(*x, 1);
     /// ```
     #[inline]
-    #[stable(feature = "mutex_unpoison", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "mutex_unpoison", since = "1.77.0")]
     pub fn clear_poison(&self) {
         self.poison.clear();
     }
diff --git a/library/std/src/sync/rwlock.rs b/library/std/src/sync/rwlock.rs
index 23d3dd0707a..c5d846b85aa 100644
--- a/library/std/src/sync/rwlock.rs
+++ b/library/std/src/sync/rwlock.rs
@@ -408,7 +408,7 @@ impl<T: ?Sized> RwLock<T> {
     /// assert_eq!(*guard, 1);
     /// ```
     #[inline]
-    #[stable(feature = "mutex_unpoison", since = "CURRENT_RUSTC_VERSION")]
+    #[stable(feature = "mutex_unpoison", since = "1.77.0")]
     pub fn clear_poison(&self) {
         self.poison.clear();
     }
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index e03e98b18d2..fae21636897 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -7,6 +7,7 @@ mod personality;
 
 pub mod cmath;
 pub mod os_str;
+pub mod path;
 
 // FIXME(117276): remove this, move feature implementations into individual
 //                submodules.
diff --git a/library/std/src/sys/pal/common/thread_local/fast_local.rs b/library/std/src/sys/pal/common/thread_local/fast_local.rs
index 9206588be06..0fdca27852c 100644
--- a/library/std/src/sys/pal/common/thread_local/fast_local.rs
+++ b/library/std/src/sys/pal/common/thread_local/fast_local.rs
@@ -14,7 +14,7 @@ pub macro thread_local_inner {
         #[inline]
         #[deny(unsafe_op_in_unsafe_fn)]
         // FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
-        #[cfg_attr(not(bootstrap), allow(static_mut_ref))]
+        #[allow(static_mut_ref)]
         unsafe fn __getit(
             _init: $crate::option::Option<&mut $crate::option::Option<$t>>,
         ) -> $crate::option::Option<&'static $t> {
diff --git a/library/std/src/sys/pal/common/thread_local/static_local.rs b/library/std/src/sys/pal/common/thread_local/static_local.rs
index 51cba66fad7..0dde78b14db 100644
--- a/library/std/src/sys/pal/common/thread_local/static_local.rs
+++ b/library/std/src/sys/pal/common/thread_local/static_local.rs
@@ -12,7 +12,7 @@ pub macro thread_local_inner {
         #[inline] // see comments below
         #[deny(unsafe_op_in_unsafe_fn)]
         // FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
-        #[cfg_attr(not(bootstrap), allow(static_mut_ref))]
+        #[allow(static_mut_ref)]
         unsafe fn __getit(
             _init: $crate::option::Option<&mut $crate::option::Option<$t>>,
         ) -> $crate::option::Option<&'static $t> {
diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs
index 3c83afa280b..57cc656e266 100644
--- a/library/std/src/sys/pal/hermit/mod.rs
+++ b/library/std/src/sys/pal/hermit/mod.rs
@@ -28,8 +28,6 @@ pub mod io;
 pub mod memchr;
 pub mod net;
 pub mod os;
-#[path = "../unix/path.rs"]
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs
index a769fc1ef59..46f3e5b401d 100644
--- a/library/std/src/sys/pal/sgx/mod.rs
+++ b/library/std/src/sys/pal/sgx/mod.rs
@@ -22,7 +22,6 @@ pub mod io;
 pub mod memchr;
 pub mod net;
 pub mod os;
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs
index 46699e64169..be8e0033902 100644
--- a/library/std/src/sys/pal/solid/mod.rs
+++ b/library/std/src/sys/pal/solid/mod.rs
@@ -29,7 +29,6 @@ pub mod fs;
 pub mod io;
 pub mod net;
 pub mod os;
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs
index 95a5b97ea42..7953104486c 100644
--- a/library/std/src/sys/pal/teeos/mod.rs
+++ b/library/std/src/sys/pal/teeos/mod.rs
@@ -25,8 +25,6 @@ pub mod net;
 #[path = "../unsupported/once.rs"]
 pub mod once;
 pub mod os;
-#[path = "../unix/path.rs"]
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index 9837cc89f2d..ba53ed88f37 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -146,3 +146,11 @@ pub(crate) fn image_handle_protocol<T>(protocol_guid: Guid) -> Option<NonNull<T>
     let system_handle = uefi::env::try_image_handle()?;
     open_protocol(system_handle, protocol_guid).ok()
 }
+
+/// Get RuntimeServices
+pub(crate) fn runtime_services() -> Option<NonNull<r_efi::efi::RuntimeServices>> {
+    let system_table: NonNull<r_efi::efi::SystemTable> =
+        crate::os::uefi::env::try_system_table()?.cast();
+    let runtime_services = unsafe { (*system_table.as_ptr()).runtime_services };
+    NonNull::new(runtime_services)
+}
diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs
index 9ee753aa1a0..efa4ed67c50 100644
--- a/library/std/src/sys/pal/uefi/mod.rs
+++ b/library/std/src/sys/pal/uefi/mod.rs
@@ -26,7 +26,6 @@ pub mod net;
 #[path = "../unsupported/once.rs"]
 pub mod once;
 pub mod os;
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
@@ -38,7 +37,6 @@ pub mod thread;
 pub mod thread_local_key;
 #[path = "../unsupported/thread_parking.rs"]
 pub mod thread_parking;
-#[path = "../unsupported/time.rs"]
 pub mod time;
 
 mod helpers;
diff --git a/library/std/src/sys/pal/uefi/path.rs b/library/std/src/sys/pal/uefi/path.rs
deleted file mode 100644
index 106682eee56..00000000000
--- a/library/std/src/sys/pal/uefi/path.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-use super::unsupported;
-use crate::ffi::OsStr;
-use crate::io;
-use crate::path::{Path, PathBuf, Prefix};
-
-pub const MAIN_SEP_STR: &str = "\\";
-pub const MAIN_SEP: char = '\\';
-
-#[inline]
-pub fn is_sep_byte(b: u8) -> bool {
-    b == b'\\'
-}
-
-#[inline]
-pub fn is_verbatim_sep(b: u8) -> bool {
-    b == b'\\'
-}
-
-pub fn parse_prefix(_p: &OsStr) -> Option<Prefix<'_>> {
-    None
-}
-
-pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
-    unsupported()
-}
diff --git a/library/std/src/sys/pal/uefi/tests.rs b/library/std/src/sys/pal/uefi/tests.rs
index 8806eda3ac0..5eb36da922b 100644
--- a/library/std/src/sys/pal/uefi/tests.rs
+++ b/library/std/src/sys/pal/uefi/tests.rs
@@ -1,4 +1,6 @@
 use super::alloc::*;
+use super::time::*;
+use crate::time::Duration;
 
 #[test]
 fn align() {
@@ -19,3 +21,21 @@ fn align() {
         }
     }
 }
+
+#[test]
+fn epoch() {
+    let t = r_efi::system::Time {
+        year: 1970,
+        month: 1,
+        day: 1,
+        hour: 0,
+        minute: 0,
+        second: 0,
+        nanosecond: 0,
+        timezone: r_efi::efi::UNSPECIFIED_TIMEZONE,
+        daylight: 0,
+        pad1: 0,
+        pad2: 0,
+    };
+    assert_eq!(system_time_internal::uefi_time_to_duration(t), Duration::new(0, 0));
+}
diff --git a/library/std/src/sys/pal/uefi/time.rs b/library/std/src/sys/pal/uefi/time.rs
new file mode 100644
index 00000000000..68f428c38fb
--- /dev/null
+++ b/library/std/src/sys/pal/uefi/time.rs
@@ -0,0 +1,105 @@
+use crate::time::Duration;
+
+const SECS_IN_MINUTE: u64 = 60;
+const SECS_IN_HOUR: u64 = SECS_IN_MINUTE * 60;
+const SECS_IN_DAY: u64 = SECS_IN_HOUR * 24;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub struct Instant(Duration);
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub struct SystemTime(Duration);
+
+pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
+
+impl Instant {
+    pub fn now() -> Instant {
+        panic!("time not implemented on this platform")
+    }
+
+    pub fn checked_sub_instant(&self, other: &Instant) -> Option<Duration> {
+        self.0.checked_sub(other.0)
+    }
+
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant(self.0.checked_add(*other)?))
+    }
+
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<Instant> {
+        Some(Instant(self.0.checked_sub(*other)?))
+    }
+}
+
+impl SystemTime {
+    pub fn now() -> SystemTime {
+        system_time_internal::now()
+            .unwrap_or_else(|| panic!("time not implemented on this platform"))
+    }
+
+    pub fn sub_time(&self, other: &SystemTime) -> Result<Duration, Duration> {
+        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
+    }
+
+    pub fn checked_add_duration(&self, other: &Duration) -> Option<SystemTime> {
+        Some(SystemTime(self.0.checked_add(*other)?))
+    }
+
+    pub fn checked_sub_duration(&self, other: &Duration) -> Option<SystemTime> {
+        Some(SystemTime(self.0.checked_sub(*other)?))
+    }
+}
+
+pub(crate) mod system_time_internal {
+    use super::super::helpers;
+    use super::*;
+    use crate::mem::MaybeUninit;
+    use crate::ptr::NonNull;
+    use r_efi::efi::{RuntimeServices, Time};
+
+    pub fn now() -> Option<SystemTime> {
+        let runtime_services: NonNull<RuntimeServices> = helpers::runtime_services()?;
+        let mut t: MaybeUninit<Time> = MaybeUninit::uninit();
+        let r = unsafe {
+            ((*runtime_services.as_ptr()).get_time)(t.as_mut_ptr(), crate::ptr::null_mut())
+        };
+
+        if r.is_error() {
+            return None;
+        }
+
+        let t = unsafe { t.assume_init() };
+
+        Some(SystemTime(uefi_time_to_duration(t)))
+    }
+
+    // This algorithm is based on the one described in the post
+    // https://blog.reverberate.org/2020/05/12/optimizing-date-algorithms.html
+    pub const fn uefi_time_to_duration(t: r_efi::system::Time) -> Duration {
+        assert!(t.month <= 12);
+        assert!(t.month != 0);
+
+        const YEAR_BASE: u32 = 4800; /* Before min year, multiple of 400. */
+
+        // Calculate the number of days since 1/1/1970
+        // Use 1 March as the start
+        let (m_adj, overflow): (u32, bool) = (t.month as u32).overflowing_sub(3);
+        let (carry, adjust): (u32, u32) = if overflow { (1, 12) } else { (0, 0) };
+        let y_adj: u32 = (t.year as u32) + YEAR_BASE - carry;
+        let month_days: u32 = (m_adj.wrapping_add(adjust) * 62719 + 769) / 2048;
+        let leap_days: u32 = y_adj / 4 - y_adj / 100 + y_adj / 400;
+        let days: u32 = y_adj * 365 + leap_days + month_days + (t.day as u32 - 1) - 2472632;
+
+        let localtime_epoch: u64 = (days as u64) * SECS_IN_DAY
+            + (t.second as u64)
+            + (t.minute as u64) * SECS_IN_MINUTE
+            + (t.hour as u64) * SECS_IN_HOUR;
+
+        let utc_epoch: u64 = if t.timezone == r_efi::efi::UNSPECIFIED_TIMEZONE {
+            localtime_epoch
+        } else {
+            (localtime_epoch as i64 + (t.timezone as i64) * SECS_IN_MINUTE as i64) as u64
+        };
+
+        Duration::new(utc_epoch, t.nanosecond)
+    }
+}
diff --git a/library/std/src/sys/pal/unix/locks/pthread_mutex.rs b/library/std/src/sys/pal/unix/locks/pthread_mutex.rs
index 8a78bc1fd73..ee0794334fb 100644
--- a/library/std/src/sys/pal/unix/locks/pthread_mutex.rs
+++ b/library/std/src/sys/pal/unix/locks/pthread_mutex.rs
@@ -1,4 +1,5 @@
 use crate::cell::UnsafeCell;
+use crate::io::Error;
 use crate::mem::{forget, MaybeUninit};
 use crate::sys::cvt_nz;
 use crate::sys_common::lazy_box::{LazyBox, LazyInit};
@@ -103,8 +104,24 @@ impl Mutex {
 
     #[inline]
     pub unsafe fn lock(&self) {
+        #[cold]
+        #[inline(never)]
+        fn fail(r: i32) -> ! {
+            let error = Error::from_raw_os_error(r);
+            panic!("failed to lock mutex: {error}");
+        }
+
         let r = libc::pthread_mutex_lock(raw(self));
-        debug_assert_eq!(r, 0);
+        // As we set the mutex type to `PTHREAD_MUTEX_NORMAL` above, we expect
+        // the lock call to never fail. Unfortunately however, some platforms
+        // (Solaris) do not conform to the standard, and instead always provide
+        // deadlock detection. How kind of them! Unfortunately that means that
+        // we need to check the error code here. To save us from UB on other
+        // less well-behaved platforms in the future, we do it even on "good"
+        // platforms like macOS. See #120147 for more context.
+        if r != 0 {
+            fail(r)
+        }
     }
 
     #[inline]
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index 43cb9d89be9..976a437c17f 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -27,7 +27,6 @@ pub mod net;
 #[cfg(target_os = "l4re")]
 pub use self::l4re::net;
 pub mod os;
-pub mod path;
 pub mod pipe;
 pub mod process;
 pub mod rand;
diff --git a/library/std/src/sys/pal/unix/thread_local_dtor.rs b/library/std/src/sys/pal/unix/thread_local_dtor.rs
index 4bf8f20670d..8857f96501c 100644
--- a/library/std/src/sys/pal/unix/thread_local_dtor.rs
+++ b/library/std/src/sys/pal/unix/thread_local_dtor.rs
@@ -11,7 +11,6 @@
 // Note, however, that we run on lots older linuxes, as well as cross
 // compiling from a newer linux to an older linux, so we also have a
 // fallback implementation to use as well.
-#[cfg_attr(bootstrap, allow(unexpected_cfgs))]
 #[cfg(any(
     target_os = "linux",
     target_os = "android",
diff --git a/library/std/src/sys/pal/unsupported/mod.rs b/library/std/src/sys/pal/unsupported/mod.rs
index b56ded8579c..88f939cbab9 100644
--- a/library/std/src/sys/pal/unsupported/mod.rs
+++ b/library/std/src/sys/pal/unsupported/mod.rs
@@ -9,8 +9,6 @@ pub mod locks;
 pub mod net;
 pub mod once;
 pub mod os;
-#[path = "../unix/path.rs"]
-pub mod path;
 pub mod pipe;
 pub mod process;
 pub mod stdio;
diff --git a/library/std/src/sys/pal/wasi/mod.rs b/library/std/src/sys/pal/wasi/mod.rs
index 4ffc8ecdd67..116878ee996 100644
--- a/library/std/src/sys/pal/wasi/mod.rs
+++ b/library/std/src/sys/pal/wasi/mod.rs
@@ -30,8 +30,6 @@ pub mod io;
 
 pub mod net;
 pub mod os;
-#[path = "../unix/path.rs"]
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
diff --git a/library/std/src/sys/pal/wasm/mod.rs b/library/std/src/sys/pal/wasm/mod.rs
index 76306b618d8..567555118d7 100644
--- a/library/std/src/sys/pal/wasm/mod.rs
+++ b/library/std/src/sys/pal/wasm/mod.rs
@@ -28,8 +28,6 @@ pub mod io;
 pub mod net;
 #[path = "../unsupported/os.rs"]
 pub mod os;
-#[path = "../unix/path.rs"]
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index 2bdd3d96fa4..b82a83ae7a3 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -16,8 +16,8 @@ use crate::sys::{c, cvt, Align8};
 use crate::sys_common::{AsInner, FromInner, IntoInner};
 use crate::thread;
 
-use super::path::maybe_verbatim;
 use super::{api, to_u16s, IoResult};
+use crate::sys::path::maybe_verbatim;
 
 pub struct File {
     handle: Handle,
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index 364521dba40..726a4509f28 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -23,7 +23,6 @@ pub mod locks;
 pub mod memchr;
 pub mod net;
 pub mod os;
-pub mod path;
 pub mod pipe;
 pub mod process;
 pub mod rand;
@@ -210,7 +209,7 @@ pub fn to_u16s<S: AsRef<OsStr>>(s: S) -> crate::io::Result<Vec<u16>> {
 // Once the syscall has completed (errors bail out early) the second closure is
 // yielded the data which has been read from the syscall. The return value
 // from this closure is then the return value of the function.
-fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> crate::io::Result<T>
+pub fn fill_utf16_buf<F1, F2, T>(mut f1: F1, f2: F2) -> crate::io::Result<T>
 where
     F1: FnMut(*mut u16, c::DWORD) -> c::DWORD,
     F2: FnOnce(&[u16]) -> T,
@@ -274,7 +273,7 @@ where
     }
 }
 
-fn os2path(s: &[u16]) -> PathBuf {
+pub fn os2path(s: &[u16]) -> PathBuf {
     PathBuf::from(OsString::from_wide(s))
 }
 
diff --git a/library/std/src/sys/pal/xous/mod.rs b/library/std/src/sys/pal/xous/mod.rs
index b4948d7e583..c9bad4ef019 100644
--- a/library/std/src/sys/pal/xous/mod.rs
+++ b/library/std/src/sys/pal/xous/mod.rs
@@ -12,8 +12,6 @@ pub mod io;
 pub mod locks;
 pub mod net;
 pub mod os;
-#[path = "../unix/path.rs"]
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs
index 7f221dc4fd9..e859269831a 100644
--- a/library/std/src/sys/pal/zkvm/mod.rs
+++ b/library/std/src/sys/pal/zkvm/mod.rs
@@ -24,10 +24,6 @@ pub mod net;
 #[path = "../unsupported/once.rs"]
 pub mod once;
 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"]
diff --git a/library/std/src/sys/path/mod.rs b/library/std/src/sys/path/mod.rs
new file mode 100644
index 00000000000..24a94ec7828
--- /dev/null
+++ b/library/std/src/sys/path/mod.rs
@@ -0,0 +1,18 @@
+cfg_if::cfg_if! {
+    if #[cfg(target_os = "windows")] {
+        mod windows;
+        pub use windows::*;
+    } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
+        mod sgx;
+        pub use sgx::*;
+    } else if #[cfg(any(
+        target_os = "uefi",
+        target_os = "solid_asp3",
+    ))] {
+        mod unsupported_backslash;
+        pub use unsupported_backslash::*;
+    } else {
+        mod unix;
+        pub use unix::*;
+    }
+}
diff --git a/library/std/src/sys/pal/sgx/path.rs b/library/std/src/sys/path/sgx.rs
index c805c15e702..c805c15e702 100644
--- a/library/std/src/sys/pal/sgx/path.rs
+++ b/library/std/src/sys/path/sgx.rs
diff --git a/library/std/src/sys/pal/unix/path.rs b/library/std/src/sys/path/unix.rs
index 837f68d3eaf..837f68d3eaf 100644
--- a/library/std/src/sys/pal/unix/path.rs
+++ b/library/std/src/sys/path/unix.rs
diff --git a/library/std/src/sys/pal/solid/path.rs b/library/std/src/sys/path/unsupported_backslash.rs
index 7045c9be25b..7045c9be25b 100644
--- a/library/std/src/sys/pal/solid/path.rs
+++ b/library/std/src/sys/path/unsupported_backslash.rs
diff --git a/library/std/src/sys/pal/windows/path.rs b/library/std/src/sys/path/windows.rs
index d9684f21753..cebc7910231 100644
--- a/library/std/src/sys/pal/windows/path.rs
+++ b/library/std/src/sys/path/windows.rs
@@ -1,8 +1,8 @@
-use super::{c, fill_utf16_buf, to_u16s};
 use crate::ffi::{OsStr, OsString};
 use crate::io;
 use crate::path::{Path, PathBuf, Prefix};
 use crate::ptr;
+use crate::sys::pal::{c, fill_utf16_buf, os2path, to_u16s};
 
 #[cfg(test)]
 mod tests;
@@ -339,6 +339,6 @@ pub(crate) fn absolute(path: &Path) -> io::Result<PathBuf> {
         // `lpfilename` is a pointer to a null terminated string that is not
         // invalidated until after `GetFullPathNameW` returns successfully.
         |buffer, size| unsafe { c::GetFullPathNameW(lpfilename, size, buffer, ptr::null_mut()) },
-        super::os2path,
+        os2path,
     )
 }
diff --git a/library/std/src/sys/pal/windows/path/tests.rs b/library/std/src/sys/path/windows/tests.rs
index 623c6236166..623c6236166 100644
--- a/library/std/src/sys/pal/windows/path/tests.rs
+++ b/library/std/src/sys/path/windows/tests.rs
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 851832a377c..01f83ecb414 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -59,12 +59,14 @@ cfg_if::cfg_if! {
 
 /// A trait for viewing representations from std types
 #[doc(hidden)]
+#[allow(dead_code)] // not used on all platforms
 pub trait AsInner<Inner: ?Sized> {
     fn as_inner(&self) -> &Inner;
 }
 
 /// A trait for viewing representations from std types
 #[doc(hidden)]
+#[allow(dead_code)] // not used on all platforms
 pub trait AsInnerMut<Inner: ?Sized> {
     fn as_inner_mut(&mut self) -> &mut Inner;
 }
diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs
index 2e13f433dcf..83d5d63556f 100644
--- a/library/std/src/thread/local.rs
+++ b/library/std/src/thread/local.rs
@@ -181,7 +181,7 @@ impl<T: 'static> fmt::Debug for LocalKey<T> {
 #[cfg_attr(not(test), rustc_diagnostic_item = "thread_local_macro")]
 #[allow_internal_unstable(thread_local_internals)]
 // FIXME: Use `SyncUnsafeCell` instead of allowing `static_mut_ref` lint
-#[cfg_attr(not(bootstrap), allow(static_mut_ref))]
+#[allow(static_mut_ref)]
 macro_rules! thread_local {
     // empty (base case for the recursion)
     () => {};
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index ddbe18ab838..27b1d311864 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -97,6 +97,20 @@ impl Std {
             is_for_mir_opt_tests: false,
         }
     }
+
+    fn copy_extra_objects(
+        &self,
+        builder: &Builder<'_>,
+        compiler: &Compiler,
+        target: TargetSelection,
+    ) -> Vec<(PathBuf, DependencyType)> {
+        let mut deps = Vec::new();
+        if !self.is_for_mir_opt_tests {
+            deps.extend(copy_third_party_objects(builder, &compiler, target));
+            deps.extend(copy_self_contained_objects(builder, &compiler, target));
+        }
+        deps
+    }
 }
 
 impl Step for Std {
@@ -159,8 +173,9 @@ impl Step for Std {
         {
             builder.info("WARNING: Using a potentially old libstd. This may not behave well.");
 
-            copy_third_party_objects(builder, &compiler, target);
-            copy_self_contained_objects(builder, &compiler, target);
+            builder.ensure(StartupObjects { compiler, target });
+
+            self.copy_extra_objects(builder, &compiler, target);
 
             builder.ensure(StdLink::from_std(self, compiler));
             return;
@@ -193,15 +208,13 @@ impl Step for Std {
 
             // Even if we're not building std this stage, the new sysroot must
             // still contain the third party objects needed by various targets.
-            copy_third_party_objects(builder, &compiler, target);
-            copy_self_contained_objects(builder, &compiler, target);
+            self.copy_extra_objects(builder, &compiler, target);
 
             builder.ensure(StdLink::from_std(self, compiler_to_use));
             return;
         }
 
-        target_deps.extend(copy_third_party_objects(builder, &compiler, target));
-        target_deps.extend(copy_self_contained_objects(builder, &compiler, target));
+        target_deps.extend(self.copy_extra_objects(builder, &compiler, target));
 
         // The LLD wrappers and `rust-lld` are self-contained linking components that can be
         // necessary to link the stdlib on some targets. We'll also need to copy these binaries to
@@ -222,10 +235,13 @@ impl Step for Std {
             }
         }
 
+        // We build a sysroot for mir-opt tests using the same trick that Miri does: A check build
+        // with -Zalways-encode-mir. This frees us from the need to have a target linker, and the
+        // fact that this is a check build integrates nicely with run_cargo.
         let mut cargo = if self.is_for_mir_opt_tests {
-            let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "rustc");
-            cargo.arg("-p").arg("std").arg("--crate-type=lib");
-            std_cargo(builder, target, compiler.stage, &mut cargo);
+            let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "check");
+            cargo.rustflag("-Zalways-encode-mir");
+            cargo.arg("--manifest-path").arg(builder.src.join("library/sysroot/Cargo.toml"));
             cargo
         } else {
             let mut cargo = builder.cargo(compiler, Mode::Std, SourceType::InTree, target, "build");
@@ -257,7 +273,7 @@ impl Step for Std {
             vec![],
             &libstd_stamp(builder, compiler, target),
             target_deps,
-            false,
+            self.is_for_mir_opt_tests, // is_check
             false,
         );
 
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 4b2d3e9ab4b..afbbbb5bd26 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -98,7 +98,7 @@ pub fn prebuilt_llvm_config(
     let out_dir = builder.llvm_out(target);
 
     let mut llvm_config_ret_dir = builder.llvm_out(builder.config.build);
-    if !builder.config.build.is_msvc() || builder.ninja() {
+    if (!builder.config.build.is_msvc() || builder.ninja()) && !builder.config.llvm_from_ci {
         llvm_config_ret_dir.push("build");
     }
     llvm_config_ret_dir.push("bin");
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 04728e2e00d..baf1b5a4a1a 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -25,7 +25,6 @@ use crate::core::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step};
 use crate::core::config::flags::get_completion;
 use crate::core::config::flags::Subcommand;
 use crate::core::config::TargetSelection;
-use crate::utils;
 use crate::utils::cache::{Interned, INTERNER};
 use crate::utils::exec::BootstrapCommand;
 use crate::utils::helpers::{
@@ -38,23 +37,6 @@ use crate::{envify, CLang, DocTests, GitRepo, Mode};
 
 const ADB_TEST_DIR: &str = "/data/local/tmp/work";
 
-// mir-opt tests have different variants depending on whether a target is 32bit or 64bit, and
-// blessing them requires blessing with each target. To aid developers, when blessing the mir-opt
-// test suite the corresponding target of the opposite pointer size is also blessed.
-//
-// This array serves as the known mappings between 32bit and 64bit targets. If you're developing on
-// a target where a target with the opposite pointer size exists, feel free to add it here.
-const MIR_OPT_BLESS_TARGET_MAPPING: &[(&str, &str)] = &[
-    // (32bit, 64bit)
-    ("i686-unknown-linux-gnu", "x86_64-unknown-linux-gnu"),
-    ("i686-unknown-linux-musl", "x86_64-unknown-linux-musl"),
-    ("i686-pc-windows-msvc", "x86_64-pc-windows-msvc"),
-    ("i686-pc-windows-gnu", "x86_64-pc-windows-gnu"),
-    // ARM Macs don't have a corresponding 32-bit target that they can (easily)
-    // build for, so there is no entry for "aarch64-apple-darwin" here.
-    // Likewise, i686 for macOS is no longer possible to build.
-];
-
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
 pub struct CrateBootstrap {
     path: Interned<PathBuf>,
@@ -1487,46 +1469,18 @@ impl Step for MirOpt {
             })
         };
 
-        // We use custom logic to bless the mir-opt suite: mir-opt tests have multiple variants
-        // (32bit vs 64bit, and panic=abort vs panic=unwind), and all of them needs to be blessed.
-        // When blessing, we try best-effort to also bless the other variants, to aid developers.
         if builder.config.cmd.bless() {
-            let targets = MIR_OPT_BLESS_TARGET_MAPPING
-                .iter()
-                .filter(|(target_32bit, target_64bit)| {
-                    *target_32bit == &*self.target.triple || *target_64bit == &*self.target.triple
-                })
-                .next()
-                .map(|(target_32bit, target_64bit)| {
-                    let target_32bit = TargetSelection::from_user(target_32bit);
-                    let target_64bit = TargetSelection::from_user(target_64bit);
-
-                    // Running compiletest requires a C compiler to be available, but it might not
-                    // have been detected by bootstrap if the target we're testing wasn't in the
-                    // --target flags.
-                    if !builder.cc.borrow().contains_key(&target_32bit) {
-                        utils::cc_detect::find_target(builder, target_32bit);
-                    }
-                    if !builder.cc.borrow().contains_key(&target_64bit) {
-                        utils::cc_detect::find_target(builder, target_64bit);
-                    }
+            // All that we really need to do is cover all combinations of 32/64-bit and unwind/abort,
+            // but while we're at it we might as well flex our cross-compilation support. This
+            // selection covers all our tier 1 operating systems and architectures using only tier
+            // 1 targets.
 
-                    vec![target_32bit, target_64bit]
-                })
-                .unwrap_or_else(|| {
-                    eprintln!(
-                        "\
-Note that not all variants of mir-opt tests are going to be blessed, as no mapping between
-a 32bit and a 64bit target was found for {target}.
-You can add that mapping by changing MIR_OPT_BLESS_TARGET_MAPPING in src/bootstrap/test.rs",
-                        target = self.target,
-                    );
-                    vec![self.target]
-                });
-
-            for target in targets {
-                run(target);
+            for target in ["aarch64-unknown-linux-gnu", "i686-pc-windows-msvc"] {
+                run(TargetSelection::from_user(target));
+            }
 
+            for target in ["x86_64-apple-darwin", "i686-unknown-linux-musl"] {
+                let target = TargetSelection::from_user(target);
                 let panic_abort_target = builder.ensure(MirOptPanicAbortSyntheticTarget {
                     compiler: self.compiler,
                     base: target,
@@ -1616,27 +1570,27 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
                 .ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler), host: target });
         }
 
-        if suite == "mir-opt" {
-            builder.ensure(compile::Std::new_for_mir_opt_tests(compiler, target));
-        } else {
-            builder.ensure(compile::Std::new(compiler, target));
-        }
+        // Also provide `rust_test_helpers` for the host.
+        builder.ensure(TestHelpers { target: compiler.host });
 
         // ensure that `libproc_macro` is available on the host.
         builder.ensure(compile::Std::new(compiler, compiler.host));
 
-        // Also provide `rust_test_helpers` for the host.
-        builder.ensure(TestHelpers { target: compiler.host });
-
         // As well as the target, except for plain wasm32, which can't build it
         if suite != "mir-opt" && !target.contains("wasm") && !target.contains("emscripten") {
             builder.ensure(TestHelpers { target });
         }
 
-        builder.ensure(RemoteCopyLibs { compiler, target });
-
         let mut cmd = builder.tool_cmd(Tool::Compiletest);
 
+        if suite == "mir-opt" {
+            builder.ensure(compile::Std::new_for_mir_opt_tests(compiler, target));
+        } else {
+            builder.ensure(compile::Std::new(compiler, target));
+        }
+
+        builder.ensure(RemoteCopyLibs { compiler, target });
+
         // compiletest currently has... a lot of arguments, so let's just pass all
         // of them!
 
@@ -1745,11 +1699,13 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         flags.push(format!("-Cdebuginfo={}", builder.config.rust_debuginfo_level_tests));
         flags.extend(builder.config.cmd.rustc_args().iter().map(|s| s.to_string()));
 
-        if let Some(linker) = builder.linker(target) {
-            cmd.arg("--target-linker").arg(linker);
-        }
-        if let Some(linker) = builder.linker(compiler.host) {
-            cmd.arg("--host-linker").arg(linker);
+        if suite != "mir-opt" {
+            if let Some(linker) = builder.linker(target) {
+                cmd.arg("--target-linker").arg(linker);
+            }
+            if let Some(linker) = builder.linker(compiler.host) {
+                cmd.arg("--host-linker").arg(linker);
+            }
         }
 
         let mut hostflags = flags.clone();
@@ -1936,15 +1892,17 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             cmd.arg("--remote-test-client").arg(builder.tool_exe(Tool::RemoteTestClient));
         }
 
-        // Running a C compiler on MSVC requires a few env vars to be set, to be
-        // sure to set them here.
-        //
-        // Note that if we encounter `PATH` we make sure to append to our own `PATH`
-        // rather than stomp over it.
-        if !builder.config.dry_run() && target.is_msvc() {
-            for &(ref k, ref v) in builder.cc.borrow()[&target].env() {
-                if k != "PATH" {
-                    cmd.env(k, v);
+        if suite != "mir-opt" {
+            // Running a C compiler on MSVC requires a few env vars to be set, to be
+            // sure to set them here.
+            //
+            // Note that if we encounter `PATH` we make sure to append to our own `PATH`
+            // rather than stomp over it.
+            if !builder.config.dry_run() && target.is_msvc() {
+                for &(ref k, ref v) in builder.cc.borrow()[&target].env() {
+                    if k != "PATH" {
+                        cmd.env(k, v);
+                    }
                 }
             }
         }
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index dac8393de6b..83485abfa56 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -732,7 +732,7 @@ impl<'a> Builder<'a> {
                 check::Rls,
                 check::Rustfmt,
                 check::RustAnalyzer,
-                check::Bootstrap
+                check::Bootstrap,
             ),
             Kind::Test => describe!(
                 crate::core::build_steps::toolstate::ToolStateCheck,
@@ -866,7 +866,7 @@ impl<'a> Builder<'a> {
                 install::Miri,
                 install::LlvmTools,
                 install::Src,
-                install::Rustc
+                install::Rustc,
             ),
             Kind::Run => describe!(
                 run::ExpandYamlAnchors,
@@ -1646,76 +1646,12 @@ impl<'a> Builder<'a> {
             cargo.env("RUSTC_WRAPPER_REAL", existing_wrapper);
         }
 
-        // Dealing with rpath here is a little special, so let's go into some
-        // detail. First off, `-rpath` is a linker option on Unix platforms
-        // which adds to the runtime dynamic loader path when looking for
-        // dynamic libraries. We use this by default on Unix platforms to ensure
-        // that our nightlies behave the same on Windows, that is they work out
-        // of the box. This can be disabled by setting `rpath = false` in `[rust]`
-        // table of `config.toml`
-        //
-        // Ok, so the astute might be wondering "why isn't `-C rpath` used
-        // here?" and that is indeed a good question to ask. This codegen
-        // option is the compiler's current interface to generating an rpath.
-        // Unfortunately it doesn't quite suffice for us. The flag currently
-        // takes no value as an argument, so the compiler calculates what it
-        // should pass to the linker as `-rpath`. This unfortunately is based on
-        // the **compile time** directory structure which when building with
-        // Cargo will be very different than the runtime directory structure.
-        //
-        // All that's a really long winded way of saying that if we use
-        // `-Crpath` then the executables generated have the wrong rpath of
-        // something like `$ORIGIN/deps` when in fact the way we distribute
-        // rustc requires the rpath to be `$ORIGIN/../lib`.
-        //
-        // So, all in all, to set up the correct rpath we pass the linker
-        // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
-        // fun to pass a flag to a tool to pass a flag to pass a flag to a tool
-        // to change a flag in a binary?
-        if self.config.rpath_enabled(target) && helpers::use_host_linker(target) {
-            let libdir = self.sysroot_libdir_relative(compiler).to_str().unwrap();
-            let rpath = if target.contains("apple") {
-                // Note that we need to take one extra step on macOS to also pass
-                // `-Wl,-instal_name,@rpath/...` to get things to work right. To
-                // do that we pass a weird flag to the compiler to get it to do
-                // so. Note that this is definitely a hack, and we should likely
-                // flesh out rpath support more fully in the future.
-                rustflags.arg("-Zosx-rpath-install-name");
-                Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
-            } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
-                rustflags.arg("-Clink-args=-Wl,-z,origin");
-                Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
-            } else {
-                None
-            };
-            if let Some(rpath) = rpath {
-                rustflags.arg(&format!("-Clink-args={rpath}"));
-            }
-        }
-
         cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string());
 
         if let Some(stack_protector) = &self.config.rust_stack_protector {
             rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
         }
 
-        for arg in linker_args(self, compiler.host, LldThreads::Yes) {
-            hostflags.arg(&arg);
-        }
-
-        if let Some(target_linker) = self.linker(target) {
-            let target = crate::envify(&target.triple);
-            cargo.env(&format!("CARGO_TARGET_{target}_LINKER"), target_linker);
-        }
-        // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
-        // `linker_args` here.
-        for flag in linker_flags(self, target, LldThreads::Yes) {
-            rustflags.arg(&flag);
-        }
-        for arg in linker_args(self, target, LldThreads::Yes) {
-            rustdocflags.arg(&arg);
-        }
-
         if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
             cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
         }
@@ -1731,10 +1667,6 @@ impl<'a> Builder<'a> {
         if let Some(opt_level) = &self.config.rust_optimize.get_opt_level() {
             cargo.env(profile_var("OPT_LEVEL"), opt_level);
         }
-        if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
-        {
-            rustflags.arg("-Clink-arg=-gz");
-        }
         cargo.env(
             profile_var("DEBUG_ASSERTIONS"),
             if mode == Mode::Std {
@@ -1940,55 +1872,15 @@ impl<'a> Builder<'a> {
             rustflags.arg("-Wrustc::internal");
         }
 
-        // Throughout the build Cargo can execute a number of build scripts
-        // compiling C/C++ code and we need to pass compilers, archivers, flags, etc
-        // obtained previously to those build scripts.
-        // Build scripts use either the `cc` crate or `configure/make` so we pass
-        // the options through environment variables that are fetched and understood by both.
-        //
-        // FIXME: the guard against msvc shouldn't need to be here
-        if target.is_msvc() {
-            if let Some(ref cl) = self.config.llvm_clang_cl {
-                cargo.env("CC", cl).env("CXX", cl);
-            }
-        } else {
-            let ccache = self.config.ccache.as_ref();
-            let ccacheify = |s: &Path| {
-                let ccache = match ccache {
-                    Some(ref s) => s,
-                    None => return s.display().to_string(),
-                };
-                // FIXME: the cc-rs crate only recognizes the literal strings
-                // `ccache` and `sccache` when doing caching compilations, so we
-                // mirror that here. It should probably be fixed upstream to
-                // accept a new env var or otherwise work with custom ccache
-                // vars.
-                match &ccache[..] {
-                    "ccache" | "sccache" => format!("{} {}", ccache, s.display()),
-                    _ => s.display().to_string(),
-                }
-            };
-            let triple_underscored = target.triple.replace("-", "_");
-            let cc = ccacheify(&self.cc(target));
-            cargo.env(format!("CC_{triple_underscored}"), &cc);
-
-            let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
-            cargo.env(format!("CFLAGS_{triple_underscored}"), &cflags);
-
-            if let Some(ar) = self.ar(target) {
-                let ranlib = format!("{} s", ar.display());
-                cargo
-                    .env(format!("AR_{triple_underscored}"), ar)
-                    .env(format!("RANLIB_{triple_underscored}"), ranlib);
-            }
-
-            if let Ok(cxx) = self.cxx(target) {
-                let cxx = ccacheify(&cxx);
-                let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
-                cargo
-                    .env(format!("CXX_{triple_underscored}"), &cxx)
-                    .env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
-            }
+        if cmd != "check" {
+            self.configure_linker(
+                compiler,
+                target,
+                &mut cargo,
+                &mut rustflags,
+                &mut rustdocflags,
+                &mut hostflags,
+            );
         }
 
         // If Control Flow Guard is enabled, pass the `control-flow-guard` flag to rustc
@@ -2142,6 +2034,136 @@ impl<'a> Builder<'a> {
         Cargo { command: cargo, rustflags, rustdocflags, hostflags, allow_features }
     }
 
+    fn configure_linker(
+        &self,
+        compiler: Compiler,
+        target: TargetSelection,
+        cargo: &mut Command,
+        rustflags: &mut Rustflags,
+        rustdocflags: &mut Rustflags,
+        hostflags: &mut HostFlags,
+    ) {
+        // Dealing with rpath here is a little special, so let's go into some
+        // detail. First off, `-rpath` is a linker option on Unix platforms
+        // which adds to the runtime dynamic loader path when looking for
+        // dynamic libraries. We use this by default on Unix platforms to ensure
+        // that our nightlies behave the same on Windows, that is they work out
+        // of the box. This can be disabled by setting `rpath = false` in `[rust]`
+        // table of `config.toml`
+        //
+        // Ok, so the astute might be wondering "why isn't `-C rpath` used
+        // here?" and that is indeed a good question to ask. This codegen
+        // option is the compiler's current interface to generating an rpath.
+        // Unfortunately it doesn't quite suffice for us. The flag currently
+        // takes no value as an argument, so the compiler calculates what it
+        // should pass to the linker as `-rpath`. This unfortunately is based on
+        // the **compile time** directory structure which when building with
+        // Cargo will be very different than the runtime directory structure.
+        //
+        // All that's a really long winded way of saying that if we use
+        // `-Crpath` then the executables generated have the wrong rpath of
+        // something like `$ORIGIN/deps` when in fact the way we distribute
+        // rustc requires the rpath to be `$ORIGIN/../lib`.
+        //
+        // So, all in all, to set up the correct rpath we pass the linker
+        // argument manually via `-C link-args=-Wl,-rpath,...`. Plus isn't it
+        // fun to pass a flag to a tool to pass a flag to pass a flag to a tool
+        // to change a flag in a binary?
+        if self.config.rpath_enabled(target) && helpers::use_host_linker(target) {
+            let libdir = self.sysroot_libdir_relative(compiler).to_str().unwrap();
+            let rpath = if target.contains("apple") {
+                // Note that we need to take one extra step on macOS to also pass
+                // `-Wl,-instal_name,@rpath/...` to get things to work right. To
+                // do that we pass a weird flag to the compiler to get it to do
+                // so. Note that this is definitely a hack, and we should likely
+                // flesh out rpath support more fully in the future.
+                rustflags.arg("-Zosx-rpath-install-name");
+                Some(format!("-Wl,-rpath,@loader_path/../{libdir}"))
+            } else if !target.is_windows() && !target.contains("aix") && !target.contains("xous") {
+                rustflags.arg("-Clink-args=-Wl,-z,origin");
+                Some(format!("-Wl,-rpath,$ORIGIN/../{libdir}"))
+            } else {
+                None
+            };
+            if let Some(rpath) = rpath {
+                rustflags.arg(&format!("-Clink-args={rpath}"));
+            }
+        }
+
+        for arg in linker_args(self, compiler.host, LldThreads::Yes) {
+            hostflags.arg(&arg);
+        }
+
+        if let Some(target_linker) = self.linker(target) {
+            let target = crate::envify(&target.triple);
+            cargo.env(&format!("CARGO_TARGET_{target}_LINKER"), target_linker);
+        }
+        // We want to set -Clinker using Cargo, therefore we only call `linker_flags` and not
+        // `linker_args` here.
+        for flag in linker_flags(self, target, LldThreads::Yes) {
+            rustflags.arg(&flag);
+        }
+        for arg in linker_args(self, target, LldThreads::Yes) {
+            rustdocflags.arg(&arg);
+        }
+
+        if !self.config.dry_run() && self.cc.borrow()[&target].args().iter().any(|arg| arg == "-gz")
+        {
+            rustflags.arg("-Clink-arg=-gz");
+        }
+
+        // Throughout the build Cargo can execute a number of build scripts
+        // compiling C/C++ code and we need to pass compilers, archivers, flags, etc
+        // obtained previously to those build scripts.
+        // Build scripts use either the `cc` crate or `configure/make` so we pass
+        // the options through environment variables that are fetched and understood by both.
+        //
+        // FIXME: the guard against msvc shouldn't need to be here
+        if target.is_msvc() {
+            if let Some(ref cl) = self.config.llvm_clang_cl {
+                cargo.env("CC", cl).env("CXX", cl);
+            }
+        } else {
+            let ccache = self.config.ccache.as_ref();
+            let ccacheify = |s: &Path| {
+                let ccache = match ccache {
+                    Some(ref s) => s,
+                    None => return s.display().to_string(),
+                };
+                // FIXME: the cc-rs crate only recognizes the literal strings
+                // `ccache` and `sccache` when doing caching compilations, so we
+                // mirror that here. It should probably be fixed upstream to
+                // accept a new env var or otherwise work with custom ccache
+                // vars.
+                match &ccache[..] {
+                    "ccache" | "sccache" => format!("{} {}", ccache, s.display()),
+                    _ => s.display().to_string(),
+                }
+            };
+            let triple_underscored = target.triple.replace("-", "_");
+            let cc = ccacheify(&self.cc(target));
+            cargo.env(format!("CC_{triple_underscored}"), &cc);
+
+            let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" ");
+            cargo.env(format!("CFLAGS_{triple_underscored}"), &cflags);
+
+            if let Some(ar) = self.ar(target) {
+                let ranlib = format!("{} s", ar.display());
+                cargo
+                    .env(format!("AR_{triple_underscored}"), ar)
+                    .env(format!("RANLIB_{triple_underscored}"), ranlib);
+            }
+
+            if let Ok(cxx) = self.cxx(target) {
+                let cxx = ccacheify(&cxx);
+                let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ");
+                cargo
+                    .env(format!("CXX_{triple_underscored}"), &cxx)
+                    .env(format!("CXXFLAGS_{triple_underscored}"), cxxflags);
+            }
+        }
+    }
+
     /// Ensure that a given step is built, returning its output. This will
     /// cache the step, so it is safe (and good!) to call this as often as
     /// needed to ensure that all dependencies are built.
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 700ebcf5e37..2cbebbcf4e2 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -525,6 +525,23 @@ mod dist {
     }
 
     #[test]
+    fn llvm_out_behaviour() {
+        let mut config = configure(&["A"], &["B"]);
+        config.llvm_from_ci = true;
+        let build = Build::new(config.clone());
+
+        let target = TargetSelection::from_user("A");
+        assert!(build.llvm_out(target).ends_with("ci-llvm"));
+        let target = TargetSelection::from_user("B");
+        assert!(build.llvm_out(target).ends_with("llvm"));
+
+        config.llvm_from_ci = false;
+        let build = Build::new(config.clone());
+        let target = TargetSelection::from_user("A");
+        assert!(build.llvm_out(target).ends_with("llvm"));
+    }
+
+    #[test]
     fn build_with_empty_host() {
         let config = configure(&[], &["C"]);
         let build = Build::new(config);
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index ec404ab8580..e63d60feff1 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -720,8 +720,10 @@ download-rustc = false
         if !tarball.exists() {
             let help_on_error = "ERROR: failed to download llvm from ci
 
-    HELP: old builds get deleted after a certain time
-    HELP: if trying to compile an old commit of rustc, disable `download-ci-llvm` in config.toml:
+    HELP: There could be two reasons behind this:
+        1) The host triple is not supported for `download-ci-llvm`.
+        2) Old builds get deleted after a certain time.
+    HELP: In either case, disable `download-ci-llvm` in your config.toml:
 
     [llvm]
     download-ci-llvm = false
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 1336abf6c7a..36f9ee6aff6 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -90,10 +90,6 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     /* Extra values not defined in the built-in targets yet, but used in std */
     (Some(Mode::Std), "target_env", Some(&["libnx"])),
     // (Some(Mode::Std), "target_os", Some(&[])),
-    // #[cfg(bootstrap)] zkvm
-    (Some(Mode::Std), "target_os", Some(&["zkvm"])),
-    // #[cfg(bootstrap)] risc0
-    (Some(Mode::Std), "target_vendor", Some(&["risc0"])),
     (Some(Mode::Std), "target_arch", Some(&["spirv", "nvptx", "xtensa"])),
     /* Extra names used by dependencies */
     // FIXME: Used by serde_json, but we should not be triggering on external dependencies.
@@ -796,12 +792,16 @@ impl Build {
         self.stage_out(compiler, mode).join(&*target.triple).join(self.cargo_dir())
     }
 
-    /// Root output directory for LLVM compiled for `target`
+    /// Root output directory of LLVM for `target`
     ///
     /// Note that if LLVM is configured externally then the directory returned
     /// will likely be empty.
     fn llvm_out(&self, target: TargetSelection) -> PathBuf {
-        self.out.join(&*target.triple).join("llvm")
+        if self.config.llvm_from_ci && self.config.build == target {
+            self.config.ci_llvm_root()
+        } else {
+            self.out.join(&*target.triple).join("llvm")
+        }
     }
 
     fn lld_out(&self, target: TargetSelection) -> PathBuf {
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
index cc0c658aabd..f5c426a717f 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
@@ -30,7 +30,7 @@ python3 "$X_PY" test --stage 2 src/tools/rustfmt
 # We set the GC interval to the shortest possible value (0 would be off) to increase the chance
 # that bugs which only surface when the GC runs at a specific time are more likely to cause CI to fail.
 # This significantly increases the runtime of our test suite, or we'd do this in PR CI too.
-if [[ -z "${PR_CI_JOB:-}" ]]; then
+if [ -z "${PR_CI_JOB:-}" ]; then
     MIRIFLAGS=-Zmiri-provenance-gc=1 python3 "$X_PY" test --stage 2 src/tools/miri
 else
     python3 "$X_PY" test --stage 2 src/tools/miri
diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh
index 0db61204f77..bd5447ac835 100755
--- a/src/ci/docker/run.sh
+++ b/src/ci/docker/run.sh
@@ -72,8 +72,12 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
       # Include cache version. Can be used to manually bust the Docker cache.
       echo "2" >> $hash_key
 
+      echo "Image input"
+      cat $hash_key
+
       cksum=$(sha512sum $hash_key | \
         awk '{print $1}')
+      echo "Image input checksum ${cksum}"
     fi
 
     dockerfile="$docker_dir/$image/Dockerfile"
@@ -84,9 +88,6 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then
         context="$script_dir"
     fi
     echo "::group::Building docker image for $image"
-    echo "Image input"
-    cat $hash_key
-    echo "Image input checksum ${cksum}"
 
     # Print docker version
     docker --version
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 1998b008dc8..1f9307203bc 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -26,6 +26,7 @@
     - [armv4t-none-eabi](platform-support/armv4t-none-eabi.md)
     - [armv5te-none-eabi](platform-support/armv5te-none-eabi.md)
     - [armv7r-none-eabi](platform-support/armv7r-none-eabi.md)
+    - [armv8r-none-eabihf](platform-support/armv8r-none-eabihf.md)
     - [armv6k-nintendo-3ds](platform-support/armv6k-nintendo-3ds.md)
     - [armv7-sony-vita-newlibeabihf](platform-support/armv7-sony-vita-newlibeabihf.md)
     - [armv7-unknown-linux-uclibceabi](platform-support/armv7-unknown-linux-uclibceabi.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index f648a60b6c4..80d9dc85f16 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -280,6 +280,7 @@ target | std | host | notes
 [`armv7a-none-eabihf`](platform-support/arm-none-eabi.md) | * |  | Bare ARMv7-A, hardfloat
 [`armv7k-apple-watchos`](platform-support/apple-watchos.md) | ✓ |  | ARMv7-A Apple WatchOS
 `armv7s-apple-ios` | ✓ |  | ARMv7-A Apple-A6 Apple iOS
+[`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * |  | Bare ARMv8-R, hardfloat
 `avr-unknown-gnu-atmega328` | * |  | AVR. Requires `-Z build-std=core`
 `bpfeb-unknown-none` | * |  | BPF (big endian)
 `bpfel-unknown-none` | * |  | BPF (little endian)
diff --git a/src/doc/rustc/src/platform-support/arm-none-eabi.md b/src/doc/rustc/src/platform-support/arm-none-eabi.md
index 4f76d0d7bbc..6335a6405a1 100644
--- a/src/doc/rustc/src/platform-support/arm-none-eabi.md
+++ b/src/doc/rustc/src/platform-support/arm-none-eabi.md
@@ -13,6 +13,7 @@
 - [{arm,thumb}v4t-none-eabi](armv4t-none-eabi.md)
 - [{arm,thumb}v5te-none-eabi](armv5te-none-eabi.md)
 - armv7a-none-eabihf
+- [armv8r-none-eabihf](armv8r-none-eabihf.md)
 
 Bare-metal target for 32-bit ARM CPUs.
 
diff --git a/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
new file mode 100644
index 00000000000..588e5d7c994
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/armv8r-none-eabihf.md
@@ -0,0 +1,40 @@
+# `armv8r-none-eabihf`
+
+**Tier: 3**
+
+Bare-metal target for CPUs in the ARMv8-R architecture family, supporting
+dual ARM/Thumb mode, with ARM mode as the default.
+
+Processors in this family include the Arm [Cortex-R52][cortex-r52]
+and [Cortex-R52+][cortex-r52-plus].
+
+See [`arm-none-eabi`](arm-none-eabi.md) for information applicable to all
+`arm-none-eabi` targets.
+
+[cortex-r52]: https://www.arm.com/products/silicon-ip-cpu/cortex-r/cortex-r52
+[cortex-r52-plus]: https://www.arm.com/products/silicon-ip-cpu/cortex-r/cortex-r52-plus
+
+## Target maintainers
+
+- [Chris Copeland](https://github.com/chrisnc), `chris@chrisnc.net`
+
+## Requirements
+
+The Cortex-R52 family always includes a floating-point unit, so there is no
+non-`hf` version of this target. The floating-point features assumed by this
+target are those of the single-precision-only config of the Cortex-R52, which
+has 16 double-precision registers, accessible as 32 single-precision registers.
+The other variant of Cortex-R52 includes double-precision, 32 double-precision
+registers, and Advanced SIMD (Neon).
+
+The manual refers to this as the "Full Advanced SIMD config". To compile code
+for this variant, use: `-C target-feature=+fp64,+d32,+neon`. See the [Advanced
+SIMD and floating-point support][fpu] section of the Cortex-R52 Processor
+Technical Reference Manual for more details.
+
+[fpu]: https://developer.arm.com/documentation/100026/0104/Advanced-SIMD-and-floating-point-support/About-the-Advanced-SIMD-and-floating-point-support
+
+## Cross-compilation toolchains and C code
+
+This target supports C code compiled with the `arm-none-eabi` target triple and
+`-march=armv8-r` or a suitable `-mcpu` flag.
diff --git a/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md b/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md
new file mode 100644
index 00000000000..c72df437960
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/direct-access-external-data.md
@@ -0,0 +1,16 @@
+# `direct_access_external_data`
+
+The tracking issue for this feature is: https://github.com/rust-lang/compiler-team/issues/707
+
+------------------------
+
+Option `-Z direct-access-external-data` controls how to access symbols of
+external data.
+
+Supported values for this option are:
+
+- `yes` - Don't use GOT indirection to reference external data symbols.
+- `no` - Use GOT indirection to reference external data symbols.
+
+If the option is not explicitly specified, different targets have different
+default values.
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index aab974ad79e..7ca4392233e 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -191,15 +191,36 @@ pub(crate) fn load_attrs<'hir>(cx: &DocContext<'hir>, did: DefId) -> &'hir [ast:
     cx.tcx.get_attrs_unchecked(did)
 }
 
+pub(crate) fn item_relative_path(tcx: TyCtxt<'_>, def_id: DefId) -> Vec<Symbol> {
+    tcx.def_path(def_id)
+        .data
+        .into_iter()
+        .filter_map(|elem| {
+            // extern blocks (and a few others things) have an empty name.
+            match elem.data.get_opt_name() {
+                Some(s) if !s.is_empty() => Some(s),
+                _ => None,
+            }
+        })
+        .collect()
+}
+
 /// Record an external fully qualified name in the external_paths cache.
 ///
 /// These names are used later on by HTML rendering to generate things like
 /// source links back to the original item.
 pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType) {
+    if did.is_local() {
+        if cx.cache.exact_paths.contains_key(&did) {
+            return;
+        }
+    } else if cx.cache.external_paths.contains_key(&did) {
+        return;
+    }
+
     let crate_name = cx.tcx.crate_name(did.krate);
 
-    let relative =
-        cx.tcx.def_path(did).data.into_iter().filter_map(|elem| elem.data.get_opt_name());
+    let relative = item_relative_path(cx.tcx, did);
     let fqn = if let ItemType::Macro = kind {
         // Check to see if it is a macro 2.0 or built-in macro
         if matches!(
@@ -210,7 +231,7 @@ pub(crate) fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemT
         ) {
             once(crate_name).chain(relative).collect()
         } else {
-            vec![crate_name, relative.last().expect("relative was empty")]
+            vec![crate_name, *relative.last().expect("relative was empty")]
         }
     } else {
         once(crate_name).chain(relative).collect()
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 3bac71dbc24..b8e0d75e7dc 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -82,7 +82,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
     // but there's already an item with the same namespace and same name. Rust gives
     // priority to the not-imported one, so we should, too.
     items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| {
-        // First, lower everything other than imports.
+        // First, lower everything other than glob imports.
         if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
             return Vec::new();
         }
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 3f7f9270b2d..c46047aa0db 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -323,20 +323,20 @@ impl Options {
         early_dcx: &mut EarlyDiagCtxt,
         matches: &getopts::Matches,
         args: Vec<String>,
-    ) -> Result<(Options, RenderOptions), i32> {
+    ) -> Option<(Options, RenderOptions)> {
         // Check for unstable options.
         nightly_options::check_nightly_options(early_dcx, matches, &opts());
 
         if args.is_empty() || matches.opt_present("h") || matches.opt_present("help") {
             crate::usage("rustdoc");
-            return Err(0);
+            return None;
         } else if matches.opt_present("version") {
             rustc_driver::version!(&early_dcx, "rustdoc", matches);
-            return Err(0);
+            return None;
         }
 
         if rustc_driver::describe_flag_categories(early_dcx, &matches) {
-            return Err(0);
+            return None;
         }
 
         let color = config::parse_color(early_dcx, matches);
@@ -382,7 +382,7 @@ impl Options {
                 }
             }
 
-            return Err(0);
+            return None;
         }
 
         let mut emit = Vec::new();
@@ -390,10 +390,7 @@ impl Options {
             for kind in list.split(',') {
                 match kind.parse() {
                     Ok(kind) => emit.push(kind),
-                    Err(()) => {
-                        dcx.err(format!("unrecognized emission type: {kind}"));
-                        return Err(1);
-                    }
+                    Err(()) => dcx.fatal(format!("unrecognized emission type: {kind}")),
                 }
             }
         }
@@ -403,7 +400,7 @@ impl Options {
             && !matches.opt_present("show-coverage")
             && !nightly_options::is_unstable_enabled(matches)
         {
-            early_dcx.early_fatal(
+            dcx.fatal(
                 "the -Z unstable-options flag must be passed to enable --output-format for documentation generation (see https://github.com/rust-lang/rust/issues/76578)",
             );
         }
@@ -420,10 +417,7 @@ impl Options {
             }
             let paths = match theme::load_css_paths(content) {
                 Ok(p) => p,
-                Err(e) => {
-                    dcx.err(e);
-                    return Err(1);
-                }
+                Err(e) => dcx.fatal(e),
             };
             let mut errors = 0;
 
@@ -442,9 +436,9 @@ impl Options {
                 }
             }
             if errors != 0 {
-                return Err(1);
+                dcx.fatal("[check-theme] one or more tests failed");
             }
-            return Err(0);
+            return None;
         }
 
         let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
@@ -452,11 +446,9 @@ impl Options {
         let input = PathBuf::from(if describe_lints {
             "" // dummy, this won't be used
         } else if matches.free.is_empty() {
-            dcx.err("missing file operand");
-            return Err(1);
+            dcx.fatal("missing file operand");
         } else if matches.free.len() > 1 {
-            dcx.err("too many file operands");
-            return Err(1);
+            dcx.fatal("too many file operands");
         } else {
             &matches.free[0]
         });
@@ -466,10 +458,7 @@ impl Options {
         let externs = parse_externs(early_dcx, matches, &unstable_opts);
         let extern_html_root_urls = match parse_extern_html_roots(matches) {
             Ok(ex) => ex,
-            Err(err) => {
-                dcx.err(err);
-                return Err(1);
-            }
+            Err(err) => dcx.fatal(err),
         };
 
         let default_settings: Vec<Vec<(String, String)>> = vec![
@@ -526,16 +515,14 @@ impl Options {
         let no_run = matches.opt_present("no-run");
 
         if !should_test && no_run {
-            dcx.err("the `--test` flag must be passed to enable `--no-run`");
-            return Err(1);
+            dcx.fatal("the `--test` flag must be passed to enable `--no-run`");
         }
 
         let out_dir = matches.opt_str("out-dir").map(|s| PathBuf::from(&s));
         let output = matches.opt_str("output").map(|s| PathBuf::from(&s));
         let output = match (out_dir, output) {
             (Some(_), Some(_)) => {
-                dcx.err("cannot use both 'out-dir' and 'output' at once");
-                return Err(1);
+                dcx.fatal("cannot use both 'out-dir' and 'output' at once");
             }
             (Some(out_dir), None) => out_dir,
             (None, Some(output)) => output,
@@ -549,8 +536,7 @@ impl Options {
 
         if let Some(ref p) = extension_css {
             if !p.is_file() {
-                dcx.err("option --extend-css argument must be a file");
-                return Err(1);
+                dcx.fatal("option --extend-css argument must be a file");
             }
         }
 
@@ -566,31 +552,25 @@ impl Options {
             }
             let paths = match theme::load_css_paths(content) {
                 Ok(p) => p,
-                Err(e) => {
-                    dcx.err(e);
-                    return Err(1);
-                }
+                Err(e) => dcx.fatal(e),
             };
 
             for (theme_file, theme_s) in
                 matches.opt_strs("theme").iter().map(|s| (PathBuf::from(&s), s.to_owned()))
             {
                 if !theme_file.is_file() {
-                    dcx.struct_err(format!("invalid argument: \"{theme_s}\""))
+                    dcx.struct_fatal(format!("invalid argument: \"{theme_s}\""))
                         .with_help("arguments to --theme must be files")
                         .emit();
-                    return Err(1);
                 }
                 if theme_file.extension() != Some(OsStr::new("css")) {
-                    dcx.struct_err(format!("invalid argument: \"{theme_s}\""))
+                    dcx.struct_fatal(format!("invalid argument: \"{theme_s}\""))
                         .with_help("arguments to --theme must have a .css extension")
                         .emit();
-                    return Err(1);
                 }
                 let (success, ret) = theme::test_theme_against(&theme_file, &paths, &dcx);
                 if !success {
-                    dcx.err(format!("error loading theme file: \"{theme_s}\""));
-                    return Err(1);
+                    dcx.fatal(format!("error loading theme file: \"{theme_s}\""));
                 } else if !ret.is_empty() {
                     dcx.struct_warn(format!(
                         "theme file \"{theme_s}\" is missing CSS rules from the default theme",
@@ -620,22 +600,18 @@ impl Options {
             edition,
             &None,
         ) else {
-            return Err(3);
+            dcx.fatal("`ExternalHtml::load` failed");
         };
 
         match matches.opt_str("r").as_deref() {
             Some("rust") | None => {}
-            Some(s) => {
-                dcx.err(format!("unknown input format: {s}"));
-                return Err(1);
-            }
+            Some(s) => dcx.fatal(format!("unknown input format: {s}")),
         }
 
         let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s));
         if let Some(ref index_page) = index_page {
             if !index_page.is_file() {
-                dcx.err("option `--index-page` argument must be a file");
-                return Err(1);
+                dcx.fatal("option `--index-page` argument must be a file");
             }
         }
 
@@ -646,8 +622,7 @@ impl Options {
         let crate_types = match parse_crate_types_from_list(matches.opt_strs("crate-type")) {
             Ok(types) => types,
             Err(e) => {
-                dcx.err(format!("unknown crate type: {e}"));
-                return Err(1);
+                dcx.fatal(format!("unknown crate type: {e}"));
             }
         };
 
@@ -655,18 +630,13 @@ impl Options {
             Some(s) => match OutputFormat::try_from(s.as_str()) {
                 Ok(out_fmt) => {
                     if !out_fmt.is_json() && show_coverage {
-                        dcx.struct_err(
+                        dcx.fatal(
                             "html output format isn't supported for the --show-coverage option",
-                        )
-                        .emit();
-                        return Err(1);
+                        );
                     }
                     out_fmt
                 }
-                Err(e) => {
-                    dcx.err(e);
-                    return Err(1);
-                }
+                Err(e) => dcx.fatal(e),
             },
             None => OutputFormat::default(),
         };
@@ -709,16 +679,14 @@ impl Options {
         let html_no_source = matches.opt_present("html-no-source");
 
         if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) {
-            dcx.struct_err(
+            dcx.fatal(
                 "--generate-link-to-definition option can only be used with HTML output format",
-            )
-            .emit();
-            return Err(1);
+            );
         }
 
-        let scrape_examples_options = ScrapeExamplesOptions::new(matches, &dcx)?;
+        let scrape_examples_options = ScrapeExamplesOptions::new(matches, &dcx);
         let with_examples = matches.opt_strs("with-examples");
-        let call_locations = crate::scrape_examples::load_call_locations(with_examples, &dcx)?;
+        let call_locations = crate::scrape_examples::load_call_locations(with_examples, &dcx);
 
         let unstable_features =
             rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
@@ -793,7 +761,7 @@ impl Options {
             no_emit_shared: false,
             html_no_source,
         };
-        Ok((options, render_options))
+        Some((options, render_options))
     }
 
     /// Returns `true` if the file given as `self.input` is a Markdown file.
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index e80da46adb4..f10c829bf4e 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -4,7 +4,7 @@ use std::fmt;
 
 use serde::{Serialize, Serializer};
 
-use rustc_hir::def::DefKind;
+use rustc_hir::def::{CtorOf, DefKind};
 use rustc_span::hygiene::MacroKind;
 
 use crate::clean;
@@ -115,7 +115,15 @@ impl<'a> From<&'a clean::Item> for ItemType {
 
 impl From<DefKind> for ItemType {
     fn from(other: DefKind) -> Self {
-        match other {
+        Self::from_def_kind(other, None)
+    }
+}
+
+impl ItemType {
+    /// Depending on the parent kind, some variants have a different translation (like a `Method`
+    /// becoming a `TyMethod`).
+    pub(crate) fn from_def_kind(kind: DefKind, parent_kind: Option<DefKind>) -> Self {
+        match kind {
             DefKind::Enum => Self::Enum,
             DefKind::Fn => Self::Function,
             DefKind::Mod => Self::Module,
@@ -131,30 +139,35 @@ impl From<DefKind> for ItemType {
                 MacroKind::Attr => ItemType::ProcAttribute,
                 MacroKind::Derive => ItemType::ProcDerive,
             },
-            DefKind::ForeignTy
-            | DefKind::Variant
-            | DefKind::AssocTy
-            | DefKind::TyParam
+            DefKind::ForeignTy => Self::ForeignType,
+            DefKind::Variant => Self::Variant,
+            DefKind::Field => Self::StructField,
+            DefKind::AssocTy => Self::AssocType,
+            DefKind::AssocFn => {
+                if let Some(DefKind::Trait) = parent_kind {
+                    Self::TyMethod
+                } else {
+                    Self::Method
+                }
+            }
+            DefKind::Ctor(CtorOf::Struct, _) => Self::Struct,
+            DefKind::Ctor(CtorOf::Variant, _) => Self::Variant,
+            DefKind::AssocConst => Self::AssocConst,
+            DefKind::TyParam
             | DefKind::ConstParam
-            | DefKind::Ctor(..)
-            | DefKind::AssocFn
-            | DefKind::AssocConst
             | DefKind::ExternCrate
             | DefKind::Use
             | DefKind::ForeignMod
             | DefKind::AnonConst
             | DefKind::InlineConst
             | DefKind::OpaqueTy
-            | DefKind::Field
             | DefKind::LifetimeParam
             | DefKind::GlobalAsm
             | DefKind::Impl { .. }
             | DefKind::Closure => Self::ForeignType,
         }
     }
-}
 
-impl ItemType {
     pub(crate) fn as_str(&self) -> &'static str {
         match *self {
             ItemType::Module => "mod",
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 1923fc15119..4ba1665bdc9 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -32,6 +32,7 @@ use crate::clean::{
     self, types::ExternalLocation, utils::find_nearest_parent_module, ExternalCrate, ItemId,
     PrimitiveType,
 };
+use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
 use crate::html::escape::Escape;
 use crate::html::render::Context;
@@ -581,22 +582,11 @@ fn generate_macro_def_id_path(
     cx: &Context<'_>,
     root_path: Option<&str>,
 ) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
-    let tcx = cx.shared.tcx;
+    let tcx = cx.tcx();
     let crate_name = tcx.crate_name(def_id.krate);
     let cache = cx.cache();
 
-    let fqp: Vec<Symbol> = tcx
-        .def_path(def_id)
-        .data
-        .into_iter()
-        .filter_map(|elem| {
-            // extern blocks (and a few others things) have an empty name.
-            match elem.data.get_opt_name() {
-                Some(s) if !s.is_empty() => Some(s),
-                _ => None,
-            }
-        })
-        .collect();
+    let fqp = clean::inline::item_relative_path(tcx, def_id);
     let mut relative = fqp.iter().copied();
     let cstore = CStore::from_tcx(tcx);
     // We need this to prevent a `panic` when this function is used from intra doc links...
@@ -651,92 +641,168 @@ fn generate_macro_def_id_path(
     Ok((url, ItemType::Macro, fqp))
 }
 
+fn generate_item_def_id_path(
+    mut def_id: DefId,
+    original_def_id: DefId,
+    cx: &Context<'_>,
+    root_path: Option<&str>,
+    original_def_kind: DefKind,
+) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
+    use crate::rustc_trait_selection::infer::TyCtxtInferExt;
+    use crate::rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;
+    use rustc_middle::traits::ObligationCause;
+
+    let tcx = cx.tcx();
+    let crate_name = tcx.crate_name(def_id.krate);
+
+    // No need to try to infer the actual parent item if it's not an associated item from the `impl`
+    // block.
+    if def_id != original_def_id && matches!(tcx.def_kind(def_id), DefKind::Impl { .. }) {
+        let infcx = tcx.infer_ctxt().build();
+        def_id = infcx
+            .at(&ObligationCause::dummy(), tcx.param_env(def_id))
+            .query_normalize(ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()))
+            .map(|resolved| infcx.resolve_vars_if_possible(resolved.value))
+            .ok()
+            .and_then(|normalized| normalized.skip_binder().ty_adt_def())
+            .map(|adt| adt.did())
+            .unwrap_or(def_id);
+    }
+
+    let relative = clean::inline::item_relative_path(tcx, def_id);
+    let fqp: Vec<Symbol> = once(crate_name).chain(relative).collect();
+
+    let def_kind = tcx.def_kind(def_id);
+    let shortty = def_kind.into();
+    let module_fqp = to_module_fqp(shortty, &fqp);
+    let mut is_remote = false;
+
+    let url_parts = url_parts(cx.cache(), def_id, &module_fqp, &cx.current, &mut is_remote)?;
+    let (url_parts, shortty, fqp) = make_href(root_path, shortty, url_parts, &fqp, is_remote)?;
+    if def_id == original_def_id {
+        return Ok((url_parts, shortty, fqp));
+    }
+    let kind = ItemType::from_def_kind(original_def_kind, Some(def_kind));
+    Ok((format!("{url_parts}#{kind}.{}", tcx.item_name(original_def_id)), shortty, fqp))
+}
+
+fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
+    if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
+}
+
+fn url_parts(
+    cache: &Cache,
+    def_id: DefId,
+    module_fqp: &[Symbol],
+    relative_to: &[Symbol],
+    is_remote: &mut bool,
+) -> Result<UrlPartsBuilder, HrefError> {
+    match cache.extern_locations[&def_id.krate] {
+        ExternalLocation::Remote(ref s) => {
+            *is_remote = true;
+            let s = s.trim_end_matches('/');
+            let mut builder = UrlPartsBuilder::singleton(s);
+            builder.extend(module_fqp.iter().copied());
+            Ok(builder)
+        }
+        ExternalLocation::Local => Ok(href_relative_parts(module_fqp, relative_to).collect()),
+        ExternalLocation::Unknown => Err(HrefError::DocumentationNotBuilt),
+    }
+}
+
+fn make_href(
+    root_path: Option<&str>,
+    shortty: ItemType,
+    mut url_parts: UrlPartsBuilder,
+    fqp: &[Symbol],
+    is_remote: bool,
+) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
+    if !is_remote && let Some(root_path) = root_path {
+        let root = root_path.trim_end_matches('/');
+        url_parts.push_front(root);
+    }
+    debug!(?url_parts);
+    match shortty {
+        ItemType::Module => {
+            url_parts.push("index.html");
+        }
+        _ => {
+            let prefix = shortty.as_str();
+            let last = fqp.last().unwrap();
+            url_parts.push_fmt(format_args!("{prefix}.{last}.html"));
+        }
+    }
+    Ok((url_parts.finish(), shortty, fqp.to_vec()))
+}
+
 pub(crate) fn href_with_root_path(
-    did: DefId,
+    original_did: DefId,
     cx: &Context<'_>,
     root_path: Option<&str>,
 ) -> Result<(String, ItemType, Vec<Symbol>), HrefError> {
     let tcx = cx.tcx();
-    let def_kind = tcx.def_kind(did);
+    let def_kind = tcx.def_kind(original_did);
     let did = match def_kind {
         DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => {
             // documented on their parent's page
-            tcx.parent(did)
+            tcx.parent(original_did)
         }
+        // If this a constructor, we get the parent (either a struct or a variant) and then
+        // generate the link for this item.
+        DefKind::Ctor(..) => return href_with_root_path(tcx.parent(original_did), cx, root_path),
         DefKind::ExternCrate => {
             // Link to the crate itself, not the `extern crate` item.
-            if let Some(local_did) = did.as_local() {
+            if let Some(local_did) = original_did.as_local() {
                 tcx.extern_mod_stmt_cnum(local_did).unwrap_or(LOCAL_CRATE).as_def_id()
             } else {
-                did
+                original_did
             }
         }
-        _ => did,
+        _ => original_did,
     };
     let cache = cx.cache();
     let relative_to = &cx.current;
-    fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
-        if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
-    }
 
-    if !did.is_local()
-        && !cache.effective_visibilities.is_directly_public(tcx, did)
-        && !cache.document_private
-        && !cache.primitive_locations.values().any(|&id| id == did)
-    {
-        return Err(HrefError::Private);
+    if !original_did.is_local() {
+        // If we are generating an href for the "jump to def" feature, then the only case we want
+        // to ignore is if the item is `doc(hidden)` because we can't link to it.
+        if root_path.is_some() {
+            if tcx.is_doc_hidden(original_did) {
+                return Err(HrefError::Private);
+            }
+        } else if !cache.effective_visibilities.is_directly_public(tcx, did)
+            && !cache.document_private
+            && !cache.primitive_locations.values().any(|&id| id == did)
+        {
+            return Err(HrefError::Private);
+        }
     }
 
     let mut is_remote = false;
-    let (fqp, shortty, mut url_parts) = match cache.paths.get(&did) {
+    let (fqp, shortty, url_parts) = match cache.paths.get(&did) {
         Some(&(ref fqp, shortty)) => (fqp, shortty, {
             let module_fqp = to_module_fqp(shortty, fqp.as_slice());
             debug!(?fqp, ?shortty, ?module_fqp);
             href_relative_parts(module_fqp, relative_to).collect()
         }),
         None => {
-            if let Some(&(ref fqp, shortty)) = cache.external_paths.get(&did) {
+            // Associated items are handled differently with "jump to def". The anchor is generated
+            // directly here whereas for intra-doc links, we have some extra computation being
+            // performed there.
+            let def_id_to_get = if root_path.is_some() { original_did } else { did };
+            if let Some(&(ref fqp, shortty)) = cache.external_paths.get(&def_id_to_get) {
                 let module_fqp = to_module_fqp(shortty, fqp);
-                (
-                    fqp,
-                    shortty,
-                    match cache.extern_locations[&did.krate] {
-                        ExternalLocation::Remote(ref s) => {
-                            is_remote = true;
-                            let s = s.trim_end_matches('/');
-                            let mut builder = UrlPartsBuilder::singleton(s);
-                            builder.extend(module_fqp.iter().copied());
-                            builder
-                        }
-                        ExternalLocation::Local => {
-                            href_relative_parts(module_fqp, relative_to).collect()
-                        }
-                        ExternalLocation::Unknown => return Err(HrefError::DocumentationNotBuilt),
-                    },
-                )
+                (fqp, shortty, url_parts(cache, did, module_fqp, relative_to, &mut is_remote)?)
             } else if matches!(def_kind, DefKind::Macro(_)) {
                 return generate_macro_def_id_path(did, cx, root_path);
+            } else if did.is_local() {
+                return Err(HrefError::Private);
             } else {
-                return Err(HrefError::NotInExternalCache);
+                return generate_item_def_id_path(did, original_did, cx, root_path, def_kind);
             }
         }
     };
-    if !is_remote && let Some(root_path) = root_path {
-        let root = root_path.trim_end_matches('/');
-        url_parts.push_front(root);
-    }
-    debug!(?url_parts);
-    match shortty {
-        ItemType::Module => {
-            url_parts.push("index.html");
-        }
-        _ => {
-            let prefix = shortty.as_str();
-            let last = fqp.last().unwrap();
-            url_parts.push_fmt(format_args!("{prefix}.{last}.html"));
-        }
-    }
-    Ok((url_parts.finish(), shortty, fqp.to_vec()))
+    make_href(root_path, shortty, url_parts, fqp, is_remote)
 }
 
 pub(crate) fn href(
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index b055e355b78..8ee35db56f8 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -94,7 +94,7 @@ impl<'tcx> SpanMapVisitor<'tcx> {
 
     /// Used to generate links on items' definition to go to their documentation page.
     pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) {
-        if let Some(Node::Item(item)) = self.tcx.opt_hir_node(hir_id) {
+        if let Node::Item(item) = self.tcx.hir_node(hir_id) {
             if let Some(span) = self.tcx.def_ident_span(item.owner_id) {
                 let cspan = clean::Span::new(span);
                 // If the span isn't from the current crate, we ignore it.
@@ -199,7 +199,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
         if !span.overlaps(m.spans.inner_span) {
             // Now that we confirmed it's a file import, we want to get the span for the module
             // name only and not all the "mod foo;".
-            if let Some(Node::Item(item)) = self.tcx.opt_hir_node(id) {
+            if let Node::Item(item) = self.tcx.hir_node(id) {
                 self.matches.insert(
                     item.ident.span,
                     LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)),
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 8c10f14116a..18ea49c5baf 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -18,7 +18,9 @@
 #![recursion_limit = "256"]
 #![warn(rustc::internal)]
 #![allow(clippy::collapsible_if, clippy::collapsible_else_if)]
+#![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::potential_query_instability)]
+#![allow(rustc::untranslatable_diagnostic)]
 
 extern crate thin_vec;
 #[macro_use]
@@ -177,13 +179,16 @@ pub fn main() {
     init_logging(&early_dcx);
     rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG"));
 
-    let exit_code = rustc_driver::catch_with_exit_code(|| match get_args(&early_dcx) {
-        Some(args) => main_args(&mut early_dcx, &args, using_internal_features),
-        _ =>
-        {
-            #[allow(deprecated)]
-            Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
-        }
+    let exit_code = rustc_driver::catch_with_exit_code(|| {
+        let args = env::args_os()
+            .enumerate()
+            .map(|(i, arg)| {
+                arg.into_string().unwrap_or_else(|arg| {
+                    early_dcx.early_fatal(format!("argument {i} is not valid Unicode: {arg:?}"))
+                })
+            })
+            .collect::<Vec<_>>();
+        main_args(&mut early_dcx, &args, using_internal_features)
     });
     process::exit(exit_code);
 }
@@ -219,19 +224,6 @@ fn init_logging(early_dcx: &EarlyDiagCtxt) {
     tracing::subscriber::set_global_default(subscriber).unwrap();
 }
 
-fn get_args(early_dcx: &EarlyDiagCtxt) -> Option<Vec<String>> {
-    env::args_os()
-        .enumerate()
-        .map(|(i, arg)| {
-            arg.into_string()
-                .map_err(|arg| {
-                    early_dcx.early_warn(format!("Argument {i} is not valid Unicode: {arg:?}"));
-                })
-                .ok()
-        })
-        .collect()
-}
-
 fn opts() -> Vec<RustcOptGroup> {
     let stable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::stable;
     let unstable: fn(_, fn(&mut getopts::Options) -> &mut _) -> _ = RustcOptGroup::unstable;
@@ -730,15 +722,8 @@ fn main_args(
     // Note that we discard any distinction between different non-zero exit
     // codes from `from_matches` here.
     let (options, render_options) = match config::Options::from_matches(early_dcx, &matches, args) {
-        Ok(opts) => opts,
-        Err(code) => {
-            return if code == 0 {
-                Ok(())
-            } else {
-                #[allow(deprecated)]
-                Err(ErrorGuaranteed::unchecked_claim_error_was_emitted())
-            };
-        }
+        Some(opts) => opts,
+        None => return Ok(()),
     };
 
     let diag =
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index e73649c7224..6649894f9c2 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -156,7 +156,7 @@ impl Translate for BufferEmitter {
 }
 
 impl Emitter for BufferEmitter {
-    fn emit_diagnostic(&mut self, diag: &Diagnostic) {
+    fn emit_diagnostic(&mut self, diag: Diagnostic) {
         let mut buffer = self.buffer.borrow_mut();
 
         let fluent_args = to_fluent_args(diag.args());
diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs
index 9069098bf1a..f7bc5464707 100644
--- a/src/librustdoc/passes/lint/redundant_explicit_links.rs
+++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs
@@ -7,6 +7,7 @@ use rustc_hir::def::{DefKind, DocLinkResMap, Namespace, Res};
 use rustc_hir::HirId;
 use rustc_lint_defs::Applicability;
 use rustc_resolve::rustdoc::source_span_for_markdown_range;
+use rustc_span::def_id::DefId;
 use rustc_span::Symbol;
 
 use crate::clean::utils::find_nearest_parent_module;
@@ -33,17 +34,22 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
         return;
     }
 
-    if item.link_names(&cx.cache).is_empty() {
-        // If there's no link names in this item,
-        // then we skip resolution querying to
-        // avoid from panicking.
-        return;
+    if let Some(item_id) = item.def_id() {
+        check_redundant_explicit_link_for_did(cx, item, item_id, hir_id, &doc);
     }
+    if let Some(item_id) = item.inline_stmt_id {
+        check_redundant_explicit_link_for_did(cx, item, item_id, hir_id, &doc);
+    }
+}
 
-    let Some(item_id) = item.def_id() else {
-        return;
-    };
-    let Some(local_item_id) = item_id.as_local() else {
+fn check_redundant_explicit_link_for_did<'md>(
+    cx: &DocContext<'_>,
+    item: &Item,
+    did: DefId,
+    hir_id: HirId,
+    doc: &'md str,
+) {
+    let Some(local_item_id) = did.as_local() else {
         return;
     };
 
@@ -53,12 +59,26 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
         return;
     }
     let is_private = !cx.render_options.document_private
-        && !cx.cache.effective_visibilities.is_directly_public(cx.tcx, item_id);
+        && !cx.cache.effective_visibilities.is_directly_public(cx.tcx, did);
     if is_private {
         return;
     }
 
-    check_redundant_explicit_link(cx, item, hir_id, &doc);
+    let module_id = match cx.tcx.def_kind(did) {
+        DefKind::Mod if item.inner_docs(cx.tcx) => did,
+        _ => find_nearest_parent_module(cx.tcx, did).unwrap(),
+    };
+
+    let Some(resolutions) =
+        cx.tcx.resolutions(()).doc_link_resolutions.get(&module_id.expect_local())
+    else {
+        // If there's no resolutions in this module,
+        // then we skip resolution querying to
+        // avoid from panicking.
+        return;
+    };
+
+    check_redundant_explicit_link(cx, item, hir_id, &doc, &resolutions);
 }
 
 fn check_redundant_explicit_link<'md>(
@@ -66,6 +86,7 @@ fn check_redundant_explicit_link<'md>(
     item: &Item,
     hir_id: HirId,
     doc: &'md str,
+    resolutions: &DocLinkResMap,
 ) -> Option<()> {
     let mut broken_line_callback = |link: BrokenLink<'md>| Some((link.reference, "".into()));
     let mut offset_iter = Parser::new_with_broken_link_callback(
@@ -74,12 +95,6 @@ fn check_redundant_explicit_link<'md>(
         Some(&mut broken_line_callback),
     )
     .into_offset_iter();
-    let item_id = item.def_id()?;
-    let module_id = match cx.tcx.def_kind(item_id) {
-        DefKind::Mod if item.inner_docs(cx.tcx) => item_id,
-        _ => find_nearest_parent_module(cx.tcx, item_id).unwrap(),
-    };
-    let resolutions = cx.tcx.doc_link_resolutions(module_id);
 
     while let Some((event, link_range)) = offset_iter.next() {
         match event {
diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs
index b7d9c16f348..9c9b386edda 100644
--- a/src/librustdoc/scrape_examples.rs
+++ b/src/librustdoc/scrape_examples.rs
@@ -38,28 +38,23 @@ pub(crate) struct ScrapeExamplesOptions {
 }
 
 impl ScrapeExamplesOptions {
-    pub(crate) fn new(
-        matches: &getopts::Matches,
-        dcx: &rustc_errors::DiagCtxt,
-    ) -> Result<Option<Self>, i32> {
+    pub(crate) fn new(matches: &getopts::Matches, dcx: &rustc_errors::DiagCtxt) -> Option<Self> {
         let output_path = matches.opt_str("scrape-examples-output-path");
         let target_crates = matches.opt_strs("scrape-examples-target-crate");
         let scrape_tests = matches.opt_present("scrape-tests");
         match (output_path, !target_crates.is_empty(), scrape_tests) {
-            (Some(output_path), true, _) => Ok(Some(ScrapeExamplesOptions {
+            (Some(output_path), true, _) => Some(ScrapeExamplesOptions {
                 output_path: PathBuf::from(output_path),
                 target_crates,
                 scrape_tests,
-            })),
+            }),
             (Some(_), false, _) | (None, true, _) => {
-                dcx.err("must use --scrape-examples-output-path and --scrape-examples-target-crate together");
-                Err(1)
+                dcx.fatal("must use --scrape-examples-output-path and --scrape-examples-target-crate together");
             }
             (None, false, true) => {
-                dcx.err("must use --scrape-examples-output-path and --scrape-examples-target-crate with --scrape-tests");
-                Err(1)
+                dcx.fatal("must use --scrape-examples-output-path and --scrape-examples-target-crate with --scrape-tests");
             }
-            (None, false, false) => Ok(None),
+            (None, false, false) => None,
         }
     }
 }
@@ -342,24 +337,20 @@ pub(crate) fn run(
 pub(crate) fn load_call_locations(
     with_examples: Vec<String>,
     dcx: &rustc_errors::DiagCtxt,
-) -> Result<AllCallLocations, i32> {
-    let inner = || {
-        let mut all_calls: AllCallLocations = FxHashMap::default();
-        for path in with_examples {
-            let bytes = fs::read(&path).map_err(|e| format!("{e} (for path {path})"))?;
-            let mut decoder = MemDecoder::new(&bytes, 0);
-            let calls = AllCallLocations::decode(&mut decoder);
-
-            for (function, fn_calls) in calls.into_iter() {
-                all_calls.entry(function).or_default().extend(fn_calls.into_iter());
-            }
-        }
+) -> AllCallLocations {
+    let mut all_calls: AllCallLocations = FxHashMap::default();
+    for path in with_examples {
+        let bytes = match fs::read(&path) {
+            Ok(bytes) => bytes,
+            Err(e) => dcx.fatal(format!("failed to load examples: {e}")),
+        };
+        let mut decoder = MemDecoder::new(&bytes, 0);
+        let calls = AllCallLocations::decode(&mut decoder);
 
-        Ok(all_calls)
-    };
+        for (function, fn_calls) in calls.into_iter() {
+            all_calls.entry(function).or_default().extend(fn_calls.into_iter());
+        }
+    }
 
-    inner().map_err(|e: String| {
-        dcx.err(format!("failed to load examples: {e}"));
-        1
-    })
+    all_calls
 }
diff --git a/src/stage0.json b/src/stage0.json
index 1297eb1f8ec..0b6d6e2a138 100644
--- a/src/stage0.json
+++ b/src/stage0.json
@@ -18,423 +18,423 @@
     "tool is executed."
   ],
   "compiler": {
-    "date": "2023-12-22",
+    "date": "2024-02-04",
     "version": "beta"
   },
   "rustfmt": {
-    "date": "2023-12-22",
+    "date": "2024-02-04",
     "version": "nightly"
   },
   "checksums_sha256": {
-    "dist/2023-12-22/cargo-beta-aarch64-apple-darwin.tar.gz": "80a4c4d72f7f436105084047a5806c5665749ecb84ff06bb25e759b56049e610",
-    "dist/2023-12-22/cargo-beta-aarch64-apple-darwin.tar.xz": "0290ccea9da40123cb5ce9d8c22721e015de77525e267003faaca4a161179da0",
-    "dist/2023-12-22/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "85c79d51b2d8480343546a6164fea3f1992a4b8de3c6a45a4952b0eb2ee467ab",
-    "dist/2023-12-22/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "f9174eac9ee6dcd60c24ce5ac5341f16ebb5d704f79bef585e963576a7c7c624",
-    "dist/2023-12-22/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "76fdafa72f31538fe1747da8ff63a16af91affddc0564a8a3bc1d96bed242466",
-    "dist/2023-12-22/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "22ae3c0460073037beee67f0bd9d86af0b72c90d9ee6bf14bb6f09e9cbdf2471",
-    "dist/2023-12-22/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "8731388fe7335a9c31b33ed3bbd5a4e29402e0bfd0ee4b0842974a9416859c8b",
-    "dist/2023-12-22/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "38f8907aab9795465b8be1d0e38ad3b812ea6ea6e3672773b43e4312677916ea",
-    "dist/2023-12-22/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "19e329bd134d01c73dd74a10ee63e35782692cb54ee9dd81556b3920fc055b3b",
-    "dist/2023-12-22/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "b3f4fab444cb5bd462a36f8fb3d90a20042389a5f809bf431dc51645430b6dfa",
-    "dist/2023-12-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "cdc61bec25e556c6d0ef1150c1a01225eae4e325bce94bd49d43ff1d2b2f4049",
-    "dist/2023-12-22/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "082ed52b5bc4e8b4ac16e9a7af81ad774827e41af63532599ee41724b6907378",
-    "dist/2023-12-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "7624915c4adfb8af8d294f581a3ca4796d53a76f7ccb6546c858e0f785adb252",
-    "dist/2023-12-22/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "c224a28f4ffec2b820ac26e21e4bf1e6ecc67f47598e91d34a4e922c21cd967a",
-    "dist/2023-12-22/cargo-beta-i686-pc-windows-gnu.tar.gz": "d936b84681f2b5fd7da75c99eab6c40ae5464b1ac97733cf5774ae7783fad941",
-    "dist/2023-12-22/cargo-beta-i686-pc-windows-gnu.tar.xz": "fa2864c6cbbe940a81a497fcb307afbd7c6c0551346676daf2fa0b488dc72489",
-    "dist/2023-12-22/cargo-beta-i686-pc-windows-msvc.tar.gz": "1b6ed32c7f3b3c0b2f09e43ab04ecf62aa11c778911b860ee0a82cd22fa8ef0c",
-    "dist/2023-12-22/cargo-beta-i686-pc-windows-msvc.tar.xz": "35cf7cf47a49af4b68171264943adcee5c907d8d4fbb021a0716e10ba946655c",
-    "dist/2023-12-22/cargo-beta-i686-unknown-linux-gnu.tar.gz": "cc993cf80d125d5ac25210dee1706bd23aa94f949fb94aa22409f434bafe3c35",
-    "dist/2023-12-22/cargo-beta-i686-unknown-linux-gnu.tar.xz": "60e2bcf98f9969bae7f61987bc30e2358c832033ea98be6f8e08e8b95e8b2409",
-    "dist/2023-12-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "08dbad235465958534802c1609f881561767a63a3373033678caa29b7384e1af",
-    "dist/2023-12-22/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "cbb79d6e06e12b7bc278d6b3a220380e1d4e863c60eed3462ca4f310b25bf247",
-    "dist/2023-12-22/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "f25b99291e3d7ed8891ec1196a3bd747cfc755b3c0bb27cbef0fb1aabeecd950",
-    "dist/2023-12-22/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "0c496d22b1f641ea4bef847a1efe7b69737b0c1d7ca2920ae0a1e87ca99c00e1",
-    "dist/2023-12-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "9d9800913636d33b9976416fa128d6e734c98978c91fdb846a16c9f2b014a77e",
-    "dist/2023-12-22/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "668dda14116c4d54f43653efccdd2a4d211dfea1a08ae5fe02fd69d21b6d9783",
-    "dist/2023-12-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "ec8b813a83d0999a2181c3e026cc43c0004bcdef621ef07c9741b71ed60858a7",
-    "dist/2023-12-22/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "dda9fac6999682ad9bfbeca1cc26b4b083c99558c531e2137bca4b22331527a1",
-    "dist/2023-12-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "ff1153a92dbdf499e6cbcea37d6be513e1c844d303032f9f1f2c9af45dd43b26",
-    "dist/2023-12-22/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "3b8247891ac28674ff4d647da93e267e2400f948b60c870227683463466bc983",
-    "dist/2023-12-22/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "239486637406a61f1aa25925f82131a31d133972e7926dfa54152285ed83917f",
-    "dist/2023-12-22/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "7e9d66d61387aa45a1141187806bc181251b1164bbc48e6b52d8770d746507b6",
-    "dist/2023-12-22/cargo-beta-x86_64-apple-darwin.tar.gz": "3d47e067fedaa2f96cbb33b23315d52d7f5a3379cccca560db312e6cfbbcab39",
-    "dist/2023-12-22/cargo-beta-x86_64-apple-darwin.tar.xz": "7d7b2239cdf1e946ee97ee81ce69f2fe2f3695a82c0434a4a853218547ee58b3",
-    "dist/2023-12-22/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "34b195423b12f4253dbcb47fe9bd55e1bdb302c86096ee9f8248e65c218c5ebc",
-    "dist/2023-12-22/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "d7ebbe5c54ee55ee320e7a57e323d7277afe7c56ec31465fb8012cd436412ef4",
-    "dist/2023-12-22/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "41c1b391e8f132d8bb18d79e52cf2c7e0443417854943608383073cbb977b1ce",
-    "dist/2023-12-22/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "f75987c83543c4994dffc7dfb0bfb57390fbbdf79165360d94fd6513b3bf8abd",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-freebsd.tar.gz": "56d4ada9b370a6fb3b1a654aebd710194eab8e6a2f7f46df9f191a4ae2d75d9e",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-freebsd.tar.xz": "5337096841f04ba7337e8b35df5197fe078832fc417cbe7b4de454c45ae797bc",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-illumos.tar.gz": "e1ad1e2044a8b3329349a33a70400491cb79f5e7c847a626c96415f240e6720a",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-illumos.tar.xz": "f3546d9d207dc59c67dc8e13ccb0abc3fba14ca5feed4f75e0f3c28e31c9ad5f",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "0497f21e775ab847657c6815275d2a8cf03e4d9b4e75975eaa5eeef7fa84b62e",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "5fc2c06ff83063e7c992729f2dc5dc62771c5e0adeb04b0fb4e12f73b166d29c",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "ce5cdea30636dcb14385ead3ca2d31ded9d3f243234c82b3326551c0cf03d599",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "086662482440baad1b5cb738301a186de41ba6512bae1d77369d65e37c56d818",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-netbsd.tar.gz": "b59d49075a3a3fa2aaa8264d3a0c4444400dffe4780bb5efb350d9d558dfe5a9",
-    "dist/2023-12-22/cargo-beta-x86_64-unknown-netbsd.tar.xz": "bd940fc6505c603a2d0e4743af3aa1df6ef903676f31bf4f06083cf86ba0f4d4",
-    "dist/2023-12-22/clippy-beta-aarch64-apple-darwin.tar.gz": "42e4c7e85b516b54bc9a92fdcbaf31a280121a6264ffc00bc4330bb3f3d1ef09",
-    "dist/2023-12-22/clippy-beta-aarch64-apple-darwin.tar.xz": "1858bb5aa212dc68c694e044dd138f58a94ef236e29623b46c275cb9765d1433",
-    "dist/2023-12-22/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "8ec1c0c20dd3381bb2177e3ff28c777a7de6aff5fa557cf3b4e7ebc6aee7de84",
-    "dist/2023-12-22/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "cfa8fd15c5b0ff1570a99ea15004f88a8ddd50f6d367082cf6464523355666c1",
-    "dist/2023-12-22/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "eb81038f1cc56601719a6165da2ba71f357f00ea3380e46f0a1283174efaa9d2",
-    "dist/2023-12-22/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "dc4c69b81fd186e40b6df3900d0c555214b999f3c1ca5a2697d93503357c7194",
-    "dist/2023-12-22/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "e2fde1d65c46011d3ce80e1e46e13dcf7b5673009398296cd4126b1e4a9b2cb0",
-    "dist/2023-12-22/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "b6a422245e574c149b984655f023ca3721c1b5d5a08245292872d86e4b77980d",
-    "dist/2023-12-22/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "4b3ece564b22857b0741080ce20f190dedbd72fa8c7a284921e4c3c481fdd264",
-    "dist/2023-12-22/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "bab8dbbf290576dd9f77c9685f5f1bab114215c85c83512d87839a08a3adce6e",
-    "dist/2023-12-22/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "732adcc6849929efa239a8f5c638fd68324d8f05330b518b8b0804351ae6889a",
-    "dist/2023-12-22/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "5d726d8da3909f1ca58e1b5b50067205b90bf1a7689c516abce66a14b68fd524",
-    "dist/2023-12-22/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "c939f4d6675dfbe0ed0d0353fd9a26b0f96f53c0118257d306eb46c883438b8d",
-    "dist/2023-12-22/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "fa1a7abcdaa6f0347811849dd4dbdcd438d0e47824541b22b1c64fba8c6c1482",
-    "dist/2023-12-22/clippy-beta-i686-pc-windows-gnu.tar.gz": "c1b16be465960d03658eb10c6d65ba363ecb75d17eee49e2da0d055a97d1ebfc",
-    "dist/2023-12-22/clippy-beta-i686-pc-windows-gnu.tar.xz": "e5997892281f08da9445b53c564edd678b7b768624bd29ef55a0bfa6a2022cc6",
-    "dist/2023-12-22/clippy-beta-i686-pc-windows-msvc.tar.gz": "92400c8693ba05a186c6913f69e838cd6668eec60864e5ff857e1da2cd8469dd",
-    "dist/2023-12-22/clippy-beta-i686-pc-windows-msvc.tar.xz": "550430a61f5e17fc30207b843f99a0f56d6fa07c6c458ab560149027b69599cf",
-    "dist/2023-12-22/clippy-beta-i686-unknown-linux-gnu.tar.gz": "a99bd3961497a6266e3fc9d4109a0c1304a6759f6d7062a5175afb5459658346",
-    "dist/2023-12-22/clippy-beta-i686-unknown-linux-gnu.tar.xz": "b8471bfaaf94b61523ac88db9c91c20f67bf24a16367795b2c925abff783fab7",
-    "dist/2023-12-22/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "601760057229682f332e4b005441111eb1573c7c9a9e286f0699019df3b2d4fa",
-    "dist/2023-12-22/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "45b7f4d75ed4838d3de0ed8c70d2ce6a248881c609bc4b883a549f11d12067fa",
-    "dist/2023-12-22/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "6c4fd05f37c0e95046dc87c24734820920a3ec62f3507643f42691ba349f2418",
-    "dist/2023-12-22/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "0aab738f846ad507138c0a5d40823a0db7d89ff130f24e550f337e085dc3ea8e",
-    "dist/2023-12-22/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "007d761b7eb5d5ed5911090ac55af2288e9a97cc4affc5ca488ebde7cc3ab0e6",
-    "dist/2023-12-22/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "ba9ecc14573a882641685cd6570e515a31fa9f3a9973dcef58f3db809b932fa0",
-    "dist/2023-12-22/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "efcf9a7bc03f8e984c6ab3fa2bc269fa5387168992c9fd2b8ab09bbd7111c6c9",
-    "dist/2023-12-22/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "1df14e1f3cf785c9cf5477b584fdf11f1f7e12431a5092cc5cdf6c2878bf4275",
-    "dist/2023-12-22/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "8527bf2c96fba74c09d7b1051616631d0b4e6bace8fe44c8c76f295c9a4eb55e",
-    "dist/2023-12-22/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "cc58fbe8d4d7d0011045f64025bf75e2042b7967b7fb1f297cfe8a0175197258",
-    "dist/2023-12-22/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "c1e41ba2a77f6c0d33751b12522310bed37a032fc01947b9d78e8492a2c74ca2",
-    "dist/2023-12-22/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "a90903f78305533e5315b3dcb26218a91e1733cda5e2fadcada80fe06b3e1a17",
-    "dist/2023-12-22/clippy-beta-x86_64-apple-darwin.tar.gz": "73839c078dbc472a8c5d87686eb7e09db0030d567079359f9a750a52d1d300b8",
-    "dist/2023-12-22/clippy-beta-x86_64-apple-darwin.tar.xz": "fbc52b8be57b032d04e885b325deb3c2d61bce1773fdd68e7b0889a1ba9a167e",
-    "dist/2023-12-22/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "5a618cf8c09bec0e593449648bced16153b6783f98e41d685e5912418710fff6",
-    "dist/2023-12-22/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "f6a7c30cb183c8cecf22d95487250c121d5fe1cacf2bc4e64bc160b4c4cdd566",
-    "dist/2023-12-22/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "58b5ae0e2f46d4f7e64491a4ffcc9180e8616cc82b095526546942b0c6e43583",
-    "dist/2023-12-22/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "aa146f4c9357bd167e4aed6919a1dc780fb57ddb9e83a4332442cb779cc61e1c",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-freebsd.tar.gz": "56b1d7fbdc1e47e8a31243cbbac747b1980b61d45f2daf260d49362f1413f3e2",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-freebsd.tar.xz": "c0e5ca26067fbd0279a36c03f68e07757817aa2207a69250224f6cb44cb9711c",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-illumos.tar.gz": "404cb75b4ae6f2f0f456f77b4e639ddd692c3f47d6f32b168b275dcc999db4c3",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-illumos.tar.xz": "b6c156a01ce3f64fd781669c351df169c0c0485b0282ec33d1c541e7990e1ef7",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "6a2e75e81a2678cb97a47e695b74dbbf0737cf615bb94d1679318bcbe77a0fff",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "6273b5b834766a93c2f65a3cf2283bf1669c1dd9b9f1cbbab497ea250532ef43",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "bf4ec57ca170ccb4ab3fc4d42907418011e5dce9ff3fbbfc341e70744e9f0c8e",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "d875bfbdc53bcca521707e3d08fe3b2c2c2dfeab81634c285228ca91278fd659",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-netbsd.tar.gz": "43ae50703b81f0fdf726b4790afd539f2d5a1dc56507df2726bee693f121550b",
-    "dist/2023-12-22/clippy-beta-x86_64-unknown-netbsd.tar.xz": "894acb6cf32ef66d2b79f24ebdbf37dc8d51f36d9ec326a294cbf4be3128ce77",
-    "dist/2023-12-22/rust-std-beta-aarch64-apple-darwin.tar.gz": "81e9bbeea89702fa3843a5e6bed8b5d3d5bb035d94adb335dfa91d084842fe17",
-    "dist/2023-12-22/rust-std-beta-aarch64-apple-darwin.tar.xz": "1457fbc52b8e8e6c751b69b6b5b3401bbac86f5aed500885fd86128963e6f8ca",
-    "dist/2023-12-22/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "e2574432b2b7e8b056f8d9864142be20fb83ec516bd27f7f937c04c2d9648218",
-    "dist/2023-12-22/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "91fb8193d61c741ee39e1429c8c6e7dc51cb10d5ed1d5f63c4572dd1941f26e1",
-    "dist/2023-12-22/rust-std-beta-aarch64-apple-ios.tar.gz": "6a1b2b7d583e105daca8294fbd4e3f17bcf345ab536eb4e74962a2efc65c9eef",
-    "dist/2023-12-22/rust-std-beta-aarch64-apple-ios.tar.xz": "3c54c2a8b24186c5100898a33837141119d77cfd5363acbb8508630752198208",
-    "dist/2023-12-22/rust-std-beta-aarch64-linux-android.tar.gz": "c9534e00a3b99390a80f23fe580bcca0eb17b8bf5c0731158e8e719ab17bef74",
-    "dist/2023-12-22/rust-std-beta-aarch64-linux-android.tar.xz": "bbb5bdcd5c698d2b089cf57dc071814aa91e51e76fae5a321b0f3bee837dcbc1",
-    "dist/2023-12-22/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "c862de6118465dbc356c69c23d1a755243d86945522cb6a87bd25321a5cf1346",
-    "dist/2023-12-22/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "f8fe6f868c007b3a32b2e20fa397d2aeaa18c1af52bfbf90d181b0dede6235cb",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "3ef167b633f128d5e8b28480169fdaa559c742db7091445b33b7225dd0ab6b17",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "d6027f6826ee84962b4f516204c5e48c4d11a738349d20071d71eb249ab19294",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "2885ebe19250cc078804941bd33d71ac0ba52c8f55c03db0a9d2f7b4b86501b4",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "fe587aec91d8586f5ea93783541b3b1dc005cc9fa92d07a42e93c6cf3570224e",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "b2278c605233768efdbf272b6c1c64b5770330603f0d6ad2e9fc725790c65593",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "40cfe524fc6a97a894d8fab0bcab8a00b72781ed1f8c3273d26e784162959d1f",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "77d9010f59baee9e88fc883cc085f04282b731cdabaf2e3eeb4ccbb8e950c526",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "4b633e678448b03b868dcd038a2a2c4dc78cb600324283b38ed942ee439174cc",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-none.tar.gz": "901d032bf3dac71e52c727264daf42c923adcb12c771f135aef0aaa7784a9c63",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-none.tar.xz": "dd7856ab1d91d92c09f65c8e6fdcada0ffaf63890c656e9bf5e7fe1c5f83cf32",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-uefi.tar.gz": "c64dbbdd967193c3ed53c58e0545a93411e63c83bf0274d40691d1c5e5c58a2c",
-    "dist/2023-12-22/rust-std-beta-aarch64-unknown-uefi.tar.xz": "bf28490141ed88753548a96615742e7dd13efb6bf7ed98e7cc548409a79100df",
-    "dist/2023-12-22/rust-std-beta-arm-linux-androideabi.tar.gz": "aa84489eaaf4ae64a56f64a4f7e2240d41ae77e6532bdaf35eb2163632afd051",
-    "dist/2023-12-22/rust-std-beta-arm-linux-androideabi.tar.xz": "a3cf5b44498c85fbd8f66a776e5947e9b552a8b8110b19b4611ff042d040294f",
-    "dist/2023-12-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "aa4f3fa1994f51228853c8abd1080ac0804d7fe782a2c9a533427555c1ed5db7",
-    "dist/2023-12-22/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "72340fd4f0110ef21cea8e7a54182cf65b616e6c4834624b7971ad8a9c00b4b2",
-    "dist/2023-12-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "5b0b9392fcf9673e69954141470bd4eca00867a303b4f24354f27cf09da1cb8c",
-    "dist/2023-12-22/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "326ea10b82742012a648cf5eb9eb7b6e09087a324e3ff9955df5031233f45d6d",
-    "dist/2023-12-22/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "a7b7a2cde45cfc3d4d74031c36dcb8ea8214f4517e96b5a09bc46f898faf967e",
-    "dist/2023-12-22/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "b178e41c2ad6089e3448209cab7808e93aba7700aa3571f062dcdab74e4753b9",
-    "dist/2023-12-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "0de36da3bec6c34a6e56162b92f88b42ed76e596459a6d1416748b9fa8e8225e",
-    "dist/2023-12-22/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "381006c411b222254b5bc55302096678a47fd085de06615558dce5085da47f22",
-    "dist/2023-12-22/rust-std-beta-armebv7r-none-eabi.tar.gz": "464271fe1c2fe699167afbfe9cdb2ed2bb3a38671d616f6f28d6b7fd4fc72cf4",
-    "dist/2023-12-22/rust-std-beta-armebv7r-none-eabi.tar.xz": "13dc946ac5dd45104c51010bc8a0bf5af64d549cf6b59f8b8b0ac9b06dc5d0f1",
-    "dist/2023-12-22/rust-std-beta-armebv7r-none-eabihf.tar.gz": "2e01997df04b9635d840ca177e4ef379232955cc586e2196c26ea1e18b66f883",
-    "dist/2023-12-22/rust-std-beta-armebv7r-none-eabihf.tar.xz": "a11c1e8c52ba653e5c58baf886b6b1383c622632959d09321ba1dddc2a91caf2",
-    "dist/2023-12-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "b036abe1c19e3f86b80ee670196194ccddf0bfa5261d4ba9fc7994aecb5a487d",
-    "dist/2023-12-22/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "a9b90e4b43353feba58dfab424ae36441077fbb6b8469bc071c058f0bd85aa81",
-    "dist/2023-12-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "0faac13a81d60fd9315c6ea6c929b1fcb9366b23119b658dc05f10a0b4b2e2b6",
-    "dist/2023-12-22/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "62023710833973795681275bf34c45a309327f6e76934603c58b07f204e67a20",
-    "dist/2023-12-22/rust-std-beta-armv7-linux-androideabi.tar.gz": "f48e6eb32ae56fb09a9860f529cb65ca4168d068b6bfa6b1b3164590628ef635",
-    "dist/2023-12-22/rust-std-beta-armv7-linux-androideabi.tar.xz": "dad3d32a6314f7c9de8003476f9667d19f452a331e6363bf25c2ed255a8b0063",
-    "dist/2023-12-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "b8d045889b709783387752e6275c6818c353431bb7b9599e9aa88c6e373072c8",
-    "dist/2023-12-22/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "4750a55e19b27b34e59daa2d1b0f6655ba9d8c491780c785a7adbcc160eda425",
-    "dist/2023-12-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "829c608b0f7f4f6bf73688a30e51d69228b69a9487137751e0bf641f7e8e227a",
-    "dist/2023-12-22/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "4e4d1b1d10b1b7931e2a801cc3d3edb68c91d5f58baaf99fa2f88b9174f2b294",
-    "dist/2023-12-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "cab9b7f30fd074005c59ab5dd4d59c498367671373f5662047c8e16c19236141",
-    "dist/2023-12-22/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "b281e7c3a32523de34c2f7ed646d19f4f32b1db905a222aa1301f8bc57e312f2",
-    "dist/2023-12-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "ebed7143f8cbbf5eb2b99328c6246ecdc51905a90c4c832a13d76f6467e2014a",
-    "dist/2023-12-22/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "6c06418750cabc38f46e434890c2422df9be5177ed1f4b04dc7f67e45cad307b",
-    "dist/2023-12-22/rust-std-beta-armv7a-none-eabi.tar.gz": "06d20a34ef000ab381025c0458bd327d3a2bb13a77f3485334cdb63e51a7354f",
-    "dist/2023-12-22/rust-std-beta-armv7a-none-eabi.tar.xz": "741edc509d401328adcf462aba08744614ad655fa42f89c9818aa1dc715e2d3e",
-    "dist/2023-12-22/rust-std-beta-armv7r-none-eabi.tar.gz": "0a5c38d1a7a9d653e32750a5f600f1887422d4e90360b6f1d98df45084436822",
-    "dist/2023-12-22/rust-std-beta-armv7r-none-eabi.tar.xz": "ae960df5549284a7976129da79916287d84f1d9dece2bb8ada6a3f3cc3246509",
-    "dist/2023-12-22/rust-std-beta-armv7r-none-eabihf.tar.gz": "9280fff8012234559ad644edbe9827c2ef6931d95fa96b5f6a4aa7321215f5d2",
-    "dist/2023-12-22/rust-std-beta-armv7r-none-eabihf.tar.xz": "3bed6d2a89baf609089c431e73d36b73417541f63c8f2bbb190bdf706cd85e93",
-    "dist/2023-12-22/rust-std-beta-i586-pc-windows-msvc.tar.gz": "b8bb7b950134f5e3ba3257ffc55d2b0e4b483955e74f6a146017c1c818359ab4",
-    "dist/2023-12-22/rust-std-beta-i586-pc-windows-msvc.tar.xz": "3c3b4771cd51159d35cf5de21e9bf625453972a53207ca3e6a027901b3eeb7c8",
-    "dist/2023-12-22/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "ed89e574db830d882f1f12f9b570bbc5f4c89776808ec05cbfcb498eb947e6d2",
-    "dist/2023-12-22/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "8c32678710cec0971aa6f740cbb525c0c174f6552d181466b7d49d5822d671c5",
-    "dist/2023-12-22/rust-std-beta-i586-unknown-linux-musl.tar.gz": "2ebc2381b980637844cca7be78a01d204472328897bb02c28b8b5c32bd8d20bc",
-    "dist/2023-12-22/rust-std-beta-i586-unknown-linux-musl.tar.xz": "df48e6af6cc9df2fba7af56b4cccd07e53a0030de964c11e83b7cdaff1bff4f1",
-    "dist/2023-12-22/rust-std-beta-i686-linux-android.tar.gz": "25e6cadd083ba7f02525e411677ebf8470bebae19c0f5fdba453140ddf97a3d1",
-    "dist/2023-12-22/rust-std-beta-i686-linux-android.tar.xz": "bdc722479c73b6fcc6ba401d6f747acbfbdebb074e911bd44a20c8c3ce8192b3",
-    "dist/2023-12-22/rust-std-beta-i686-pc-windows-gnu.tar.gz": "6a8b46606ecb46d16f2d45ae82faaf155ad617b1b81259eed93b77a267b5265c",
-    "dist/2023-12-22/rust-std-beta-i686-pc-windows-gnu.tar.xz": "97c58f4e4cee06dd38ad9e3a56ce505434ee77f0f0db30432d04739d301a194b",
-    "dist/2023-12-22/rust-std-beta-i686-pc-windows-msvc.tar.gz": "1012704d42aaaddbf0679013ea578245e88200afd55d1d510dbe58bdd14b8ef9",
-    "dist/2023-12-22/rust-std-beta-i686-pc-windows-msvc.tar.xz": "cdb291df9fc41e038b38a3a421b791a2c39be3bc9686c5d6e93cbaef95c2ff6b",
-    "dist/2023-12-22/rust-std-beta-i686-unknown-freebsd.tar.gz": "20df3466ef1a82ca986a3239efba9d984535c64d5663f2b3b92b9d6ec2972b25",
-    "dist/2023-12-22/rust-std-beta-i686-unknown-freebsd.tar.xz": "6a63dcb9f7312432c6bf290dc3fea10d56a17472cab65c7d82fde30c800d8b5e",
-    "dist/2023-12-22/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "8d3ae5e37ab866b93bee661773301956d8e6e2294910d0ff04f782f2c7271dd6",
-    "dist/2023-12-22/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "9963bba2883125aded9c6639dda498c3effd574fa032d2268455948df3243979",
-    "dist/2023-12-22/rust-std-beta-i686-unknown-linux-musl.tar.gz": "64e13948dc71571be5c3a4e367d961bcc0bc38167680e86a55b2d1357a45b7ba",
-    "dist/2023-12-22/rust-std-beta-i686-unknown-linux-musl.tar.xz": "ca54983531703de8f7350e00bad2cde13dc996d9de1c0ca1728b50a015dcb344",
-    "dist/2023-12-22/rust-std-beta-i686-unknown-uefi.tar.gz": "a4e3c395607d9ca189c130e371c49ba0a08d1974c56c656a23870d0ca08f0cf7",
-    "dist/2023-12-22/rust-std-beta-i686-unknown-uefi.tar.xz": "20e6ceea5246322840b3fc76b01b16ef32d829ae4e587a052512c39c3c3babca",
-    "dist/2023-12-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "6e4dd7fa56112a879917ea24bfbd45dca625ee812908867e427f23d56deb910b",
-    "dist/2023-12-22/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "23862a72211645d29557d3a1dda63948335d15a9796c139a0676124905e72906",
-    "dist/2023-12-22/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "6abd7c64f58bbcbf04b643a9787f0fef1fe80b89b82143b6251b57afa560cff0",
-    "dist/2023-12-22/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "53fa4d33241b73653523810e441bed53dcac8c3fb7b7de88c125cb8ab8eb66df",
-    "dist/2023-12-22/rust-std-beta-loongarch64-unknown-none.tar.gz": "bb94b1d2391e11f268c0e4c127c06b356e9d79aaa6c68862dd7f97a8fd756e61",
-    "dist/2023-12-22/rust-std-beta-loongarch64-unknown-none.tar.xz": "663d531002d8be8e61fe4b9353a53b3a44056056b18bbd76749762a40416f7fa",
-    "dist/2023-12-22/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "3a25dd389b4501e9fe76057b70cb120e1d1d3caacdce82abc834297c487e50ce",
-    "dist/2023-12-22/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "6be12fd4e79600805cd6d04a5bd1d236dd7f12832d4407d3fcd72ce6bd84101f",
-    "dist/2023-12-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "6edc5d7fb15d71cbd097a09eb264b92f5b1e55f7ef0426c5c8399731f4ebb70d",
-    "dist/2023-12-22/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "beb17c9ca9e789ced8c4046135cde5b613a0b41c9b5aeefb3b7ee5d25701add6",
-    "dist/2023-12-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "6f13eb2dac5f4d59dbe44a4d862f94f763fce0bf4ea0f128c0006c04b922f294",
-    "dist/2023-12-22/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "75e629ca2f90c7e8a78fc16d13cab337816feba3e30564e26b3d38f13b7dffd0",
-    "dist/2023-12-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "e2ffac9803e2c604c56649096e734cff0a53632883c05cb9f1fd79f6ce420162",
-    "dist/2023-12-22/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "85e0193a7bfa284ac4dae84f4079605ba5c2f7c7c2e4f57ac74721aff44d05b8",
-    "dist/2023-12-22/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "41c57fa6eafdc2bc4389da8257b57e48af4250377b02760d06ebc38c83086534",
-    "dist/2023-12-22/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "02d46a445f52d078982866ee9430f8020e15d82f58d8f1edfedcd2f0ade51f36",
-    "dist/2023-12-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "6fdfd4e5ce8dc13cbce7cfb1543dafb54e80ffee0ed40935c3734787519a9673",
-    "dist/2023-12-22/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "5a645c8703ba10256605770ffdbb8abbef62746171f19edbbc069d02be501529",
-    "dist/2023-12-22/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "0cdefa18bc524ef66ddabf83fa2efceced02ad1a5271c9d95f91ec01178055e7",
-    "dist/2023-12-22/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "388dc6fba431953f581388d95cd860224e2d1203811ec86e66aca391650ce053",
-    "dist/2023-12-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "b3f756e69c0c1f257869cfa6ef239368a512c81b59c18a69851b2e5a73ec484d",
-    "dist/2023-12-22/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "61d020bea165d8abc361335e393c2c3bb1e59b6fdb0f6f65326392ec7dc3ea35",
-    "dist/2023-12-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "94e83a4ba2d141e9fc0d824a6f5e077796fd53b7b32578a1bf6e63cda1f9ee4d",
-    "dist/2023-12-22/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "9679bfb1664e6d14882e68940fe8960773f56f4867904a3259189f9eb96952ca",
-    "dist/2023-12-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "807b24b0568e83cc807e29ae6062a766f72ef48e12f9f257d78f6db4b9ee5621",
-    "dist/2023-12-22/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "d3898d851c5f728a9894e7755d0b6ff06133823b1773e5c80b29155f6e1152a6",
-    "dist/2023-12-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "9ecdd32e65c85130f8a1c82c8fd9d613a4c59b1e4fafd01771089a052d4a481c",
-    "dist/2023-12-22/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "a6b5ef2065cd5cef17e48791dae08090b755c00caca4efc1aa5eac9c2783e92e",
-    "dist/2023-12-22/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "df756fb3868a3ed347a92df37fc4aac696560d645696d5d86a15d84bde257546",
-    "dist/2023-12-22/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "777dac6ecbefe1e266c7bfd04644f428ae25318e80137a36d404009442ea208e",
-    "dist/2023-12-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "6802baa472bbf3f766346f24cf7b001cf87ea7f974bd1e1abdcc56b4c2b39bdd",
-    "dist/2023-12-22/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "5db8e7c4904c55a5d362669375bf72482e27042b7a156bd8b9d1c322b2bf521a",
-    "dist/2023-12-22/rust-std-beta-sparcv9-sun-solaris.tar.gz": "0ddd12279d34cc6190e0b1e163cee51d94be809fefa4adf801fea0f217a3519a",
-    "dist/2023-12-22/rust-std-beta-sparcv9-sun-solaris.tar.xz": "96ed998c6f254c9a5fe560474480db553cd7428cca65ba9a7732136bce191e48",
-    "dist/2023-12-22/rust-std-beta-thumbv6m-none-eabi.tar.gz": "aa36baeedb2b567f75a0fa550f2ebb507f135d4fe784343a576216237a87d643",
-    "dist/2023-12-22/rust-std-beta-thumbv6m-none-eabi.tar.xz": "0792a2de23b8c8e552565bcf691ca604760d5201ae247ec14122df11d3819f30",
-    "dist/2023-12-22/rust-std-beta-thumbv7em-none-eabi.tar.gz": "93a045ef6b38b1de7347880d299dcaf6f721af301fc811e47388b0b94c6290a6",
-    "dist/2023-12-22/rust-std-beta-thumbv7em-none-eabi.tar.xz": "c6f13b394ad21bd6058fae6845543d5f265e8124fd43ce16885800c4bd62a370",
-    "dist/2023-12-22/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "8ee5dc194cfd20626671d6b7924b68246d4cc820ca669d8fa9778086b043c3dc",
-    "dist/2023-12-22/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "f702b3ece0c74a4391e4ce954456babba8d170a1ffff438222a9bfd22df139a3",
-    "dist/2023-12-22/rust-std-beta-thumbv7m-none-eabi.tar.gz": "3cd3bc99d559a56ac8795c3602c59652877bac85e0a847c981c9ec2b1a86039b",
-    "dist/2023-12-22/rust-std-beta-thumbv7m-none-eabi.tar.xz": "0d8132f6922844c017fa0c0c3ec463e4a55e3fed7603fb2e8374ecf5c1405e52",
-    "dist/2023-12-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "ab1bc71bd1b00c0d38a3a0a3be1e5fc5a494219d2d37181da53b042b3b896c67",
-    "dist/2023-12-22/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "5cd28af392967e42e43f51233637ff690a524d840c50a328d5d52c594977b316",
-    "dist/2023-12-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "647b9db01306e225ee1867e194531028215a9fdb02b3f8713c07c39dd41d0c85",
-    "dist/2023-12-22/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "9a6ee652c9e15708f2aab76a20918f414875a8a52323a49d727b58aacc22d1f0",
-    "dist/2023-12-22/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "c16e452e889c9d56d417c871ac4f9290275df11563d458e1abc52e4ac3db0414",
-    "dist/2023-12-22/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "23a74836c303dc91e6ed9fd2078e130184ac19ac230946bd95e59c53666534bf",
-    "dist/2023-12-22/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "c8d01ed9cfe9938ed078e3f14ef9f4fa5367534ebe115f243fee8095ef3c174f",
-    "dist/2023-12-22/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "a24e99a9d45b19db342d5c5f903ad90a27be9c996278b76823121fd09d5a298c",
-    "dist/2023-12-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "e417661f5c42593e75b09b4a3531965e46f5dbd631809d6364e59d47a894b1c3",
-    "dist/2023-12-22/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "081ec9d8504af85ce93bc60ae5f3eaad8bd06864b084a97911e126564720b3f7",
-    "dist/2023-12-22/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "1df5182c5103454eb69f05b3e6c9aefe1374e43659f3e4cf68f0ac07052670eb",
-    "dist/2023-12-22/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "863278bd1a5281e6b04232e35df48a1dac7e909d3b51922cb328304cb6db9af2",
-    "dist/2023-12-22/rust-std-beta-wasm32-unknown-unknown.tar.gz": "6d80b9f8875f677a8e472c431d6df15babba2a9af62622da5a073ca9da467f69",
-    "dist/2023-12-22/rust-std-beta-wasm32-unknown-unknown.tar.xz": "cc9bf2bd9db87859e17ffd0b9a3ffb8c073e521fc035b75639a7e77fd04a210b",
-    "dist/2023-12-22/rust-std-beta-wasm32-wasi-preview1-threads.tar.gz": "7b2db2cb1fb7b35cecee218780fdc223464522bf4e5ac0e3c3342396bea77755",
-    "dist/2023-12-22/rust-std-beta-wasm32-wasi-preview1-threads.tar.xz": "ed893747e7165c97b2a2abfe4793493056cda613040eb5783ba0c4a57560f42c",
-    "dist/2023-12-22/rust-std-beta-wasm32-wasi.tar.gz": "cfd98053e598d830055a35702de43866b6c94b48a36c63c1683a302482bc4cc4",
-    "dist/2023-12-22/rust-std-beta-wasm32-wasi.tar.xz": "f57bc02b197d8f4c0d119f4ecaed6c405cc85bac7d00a55f2dc39e97ebc8411b",
-    "dist/2023-12-22/rust-std-beta-x86_64-apple-darwin.tar.gz": "70405814aefa163d60eabc777b882233797d075ef5a3052285a6aa4acf7c9c0a",
-    "dist/2023-12-22/rust-std-beta-x86_64-apple-darwin.tar.xz": "c26043ff5bb98223083aa58f659f3ef069f5cc97e5f3c1a62664197e3d8bae66",
-    "dist/2023-12-22/rust-std-beta-x86_64-apple-ios.tar.gz": "37a2b083652163adfd848872c7b42570ad6fb365ec679a1c89a8248c517021a4",
-    "dist/2023-12-22/rust-std-beta-x86_64-apple-ios.tar.xz": "cbba44d048a5c48dd4162dced5414eca2416047f2387708e46a2045553a45fa4",
-    "dist/2023-12-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "17e93708f7c0b4328d24db2ad2a82c3001c1bc03def829b7e182e5407fe74b82",
-    "dist/2023-12-22/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "761b39d8ab6b9061c0afd4fa2faaa88c7cda6322d615e57863b51a5a2826d70e",
-    "dist/2023-12-22/rust-std-beta-x86_64-linux-android.tar.gz": "f45d09e9a6c383c6cf9cff99d0046639d26636be78e194354e951fa99388e479",
-    "dist/2023-12-22/rust-std-beta-x86_64-linux-android.tar.xz": "fe323b71cfbb300f881d05879d03491aca507a644b261c16f148690dbb20a01e",
-    "dist/2023-12-22/rust-std-beta-x86_64-pc-solaris.tar.gz": "0dce2b6572bde41461086c6394121de7b97329f8192562684954542baef1ff05",
-    "dist/2023-12-22/rust-std-beta-x86_64-pc-solaris.tar.xz": "164fa2c995df0d6446c218e037025de1b225d92a51155b5b54328f67493e8202",
-    "dist/2023-12-22/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "848e55f4583bd589ae457d37b8d7367adafc24b87c35a08065114b3acdd731f9",
-    "dist/2023-12-22/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "c900770454c026b80f9b80bb745a84381f91492d552fcc7ba013e5fd46b2a63d",
-    "dist/2023-12-22/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "577f8db6e8654e9f3d97c83bbfa2eaa89fb0fe8c9362b976b9796297d189b6a8",
-    "dist/2023-12-22/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "5d2523bb1b31b4b43c527b8307ac8e00ad7e957fa652fe0628cb8e6796404d20",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "5a185ac2058969ed6aedbd864cf7037fe999eacfb9e11eb21f89696d6341741c",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "7f6e73e0cc5fae9b9e9142427decf8c4d48289033412d452a40c1a345f4311a8",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "c1974528eeea3346e070192f3729fbcc4fc9d6bbdb0c0b9ba73763758a695124",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "b4da6ab7e3bef63c2f381f7506ff0f65f302e0ed14d4f78016968b0cff3a5f5f",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-illumos.tar.gz": "3f50aa342f03ad5235112560fe0f3c64f5139d09291e3ab6859d8169ff43d631",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-illumos.tar.xz": "799eeb21df5ff213c8ec1f6250497665924b865b34d9c1a5f914eed48255278c",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "ac88a7247dec36da73d30cb58c067cd1bd6c5bc70e5820d031963fced0907c28",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "3de39c55f71a295ff38bce9843965309a40dbfe1c888f13dbde3935d26ebdfc0",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "eeae5e12254e54c87ed818e8449c2489717d1c3c25858c6e8a1a7502e57172e0",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "0d54e6882ffce573f70954d98e1f0c9f0758c5d6262e546ed95c055798d26bef",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "da056f4b1d8544382b90cae7061be549b2e06e3e880feb9d788200c022ab297c",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "f340687b51519830a1e566c84c0114581c817ac32e80f90b8baf0fbe960fdd5d",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "6ea1fedb7db6f51b79164ad39246dc2c86f743346feb760f4835c870be3931b2",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "7fe78fc5dfcb2d85b521dba2c9640233615fab04a8a1b8b27a2e0efabc5b5b60",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-none.tar.gz": "8eb08022fd4b78b50784ab9671a81b69c899ff2e73d9ae08b6ea44ed018b2c8a",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-none.tar.xz": "6ab096ba0bad97de603be50a05e16a33bffbaf4a97853d9f838721075b18aab8",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-redox.tar.gz": "84632635271947ff93b1afdd35779e7c307182d964e3b2aff60e57c0ab02a9eb",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-redox.tar.xz": "b21150ef965377a699410a0350395e0daf57e3ab8a3d90654482b17960dfd26b",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-uefi.tar.gz": "7a703ac3b26a1ec21a64f6517f03938e458db5d46977f02f9359febe7e3e4a79",
-    "dist/2023-12-22/rust-std-beta-x86_64-unknown-uefi.tar.xz": "83607ae59dddf457d655a2e60ad6d7b500a144fec4d41a7f684555204754e2d2",
-    "dist/2023-12-22/rustc-beta-aarch64-apple-darwin.tar.gz": "4988d34a6c048ee278f0d675e05260a0ab7f635c09c8ac6964ea97dcd244b9a7",
-    "dist/2023-12-22/rustc-beta-aarch64-apple-darwin.tar.xz": "a5a218eea6a3edf9b8af70046525fa6259ebf391d6e91f0630f6ae441a227a82",
-    "dist/2023-12-22/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "0980f8dfdc522146433cab04f2b83378b0c5bdb632cd02e280469ddff02e8bbf",
-    "dist/2023-12-22/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "25cf2c04a79313040860831dcce67a123ee362e09bb185a16af171163ec8b087",
-    "dist/2023-12-22/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "e21656abc9b9111baf5fdf9aebbf29b4ac8123c163dfb979b5f047c530020f29",
-    "dist/2023-12-22/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "3087de6766ffa175dbf7c53153b24cbc29db1fccc06170fd70bd3dc3a97bae62",
-    "dist/2023-12-22/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "e2464b82f2e1c4450d4f9f6fca8c5d2315e6227651d7485cd487d39fbe7f940c",
-    "dist/2023-12-22/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "9d4909db94be068ef943eba3709195a028e3928198a87f38e72a6fe013e592db",
-    "dist/2023-12-22/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "9217ecb54faf8c2964476c3c7a9ec6955b276c4c5b89e5ff13d76fe4863ba8ef",
-    "dist/2023-12-22/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "fad7556560de459c4cbb59071a35746ee520ca15b5972e926039d46847a47888",
-    "dist/2023-12-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "69d94023fd5d8a48873ecde6892ee1be354fb56a91c9bc16b32d7b8bf090ad07",
-    "dist/2023-12-22/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "14ab98c13452b8b7e5ba8853b957355487c61f0a89d385c2ec8d16d8fec382aa",
-    "dist/2023-12-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "85190846421ade8edb5da369977598641bfac215754bdbdceccb181adf49d2b4",
-    "dist/2023-12-22/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "5b0de94607e7e1192463dd1c8615cf035040cf1a51ccf4d08459f659e14aebb4",
-    "dist/2023-12-22/rustc-beta-i686-pc-windows-gnu.tar.gz": "dfb48dd8d18099b63eab2e0f6e01dd520e6d137725596af611d68092f7d2228b",
-    "dist/2023-12-22/rustc-beta-i686-pc-windows-gnu.tar.xz": "f9bdb3dac14ded817c6f406767ef140838cedd74b9b2b6daed6419cf096245da",
-    "dist/2023-12-22/rustc-beta-i686-pc-windows-msvc.tar.gz": "a01af2a20955790992eb248a290161184429d43c8ddd65d8fd18dbb6499edd6f",
-    "dist/2023-12-22/rustc-beta-i686-pc-windows-msvc.tar.xz": "334b999f3e7c6c8deed7807e398338393f32c641989bd61c631a79a3a7441d67",
-    "dist/2023-12-22/rustc-beta-i686-unknown-linux-gnu.tar.gz": "334126bcfc14e8ffa5df43c4265b844db5a2b72458f5b3328f6863ea59580b12",
-    "dist/2023-12-22/rustc-beta-i686-unknown-linux-gnu.tar.xz": "aefe562ff063ab5eea83fdb58577e6ffbbf9cdf111e5390ee29640e5169c2c7c",
-    "dist/2023-12-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "1a9eea2e8fa598c438de05d33d0af4f7b648fc50ff25013b3926c6125dc75542",
-    "dist/2023-12-22/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "1f0d707a8d96071b1154ff1ffca518a9573d7c1d95835bd35bc3660a8a4d6cb8",
-    "dist/2023-12-22/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "6cf83e99462198dfd6fd4b7d5dc4ccffbbfc433d5e3b082028420ad7e2da6144",
-    "dist/2023-12-22/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "295e22e887c9b2d686628fc927d6560e0f71f2330517242d36d1d98159d43a6d",
-    "dist/2023-12-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "3b970b0cf7243e766a773c9f30557d8d20da668467b85c5cc60fd2f7e927cb09",
-    "dist/2023-12-22/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "dd4470357d4351081c9c1526c6a4c66642b11c88f8ac194ae7f0414593b2e561",
-    "dist/2023-12-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "7684ac7d4a96678d599bed67a11338531f09b500769d94b2b70cf1b1854a0e33",
-    "dist/2023-12-22/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "b9f98f6003605d179d298ca1080448784601f9648817e5c84371e54eaafcf36f",
-    "dist/2023-12-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "376b86e4cb259c5c85286203c00405570a77346441037e175c631b2753f4f421",
-    "dist/2023-12-22/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "d4d1b511f2ce2dd2dbbcdde760879b0ce87ac1c191f73d9b264403c328d3c505",
-    "dist/2023-12-22/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "b46bd2d835f98a293f259d90659334bd289cfff34d4fac544be2add0b4072014",
-    "dist/2023-12-22/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "6c3e19a3b0dd8deef825f9c6ecba405df6b8a390f6366991c1947f09401f7192",
-    "dist/2023-12-22/rustc-beta-x86_64-apple-darwin.tar.gz": "5c735a5d0ae69383db88bbc0d7ea5a6f2300c82ce81d1a4b4f987157ac03dd6f",
-    "dist/2023-12-22/rustc-beta-x86_64-apple-darwin.tar.xz": "5f483a58253a0d6fa58503bd5bf58f8a79c32e49228bb4645a7931c61465d27e",
-    "dist/2023-12-22/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "ef3db1dbcb14174dc39670810c417b6395e092a92622d49d9bcf4074a02bd32c",
-    "dist/2023-12-22/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "d73c50be69cc0a817273c75ca86ba094509c9168bd445cfe81690bac48a613a7",
-    "dist/2023-12-22/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "4476c15df06fdfaf90a426a438cc10e5c0afb4e15ff4394d501cd8f8202f95a5",
-    "dist/2023-12-22/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "8066766e26df9171bb66e07001c1f3d279f84f48e90ac7cd80ef0439e6de29bb",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-freebsd.tar.gz": "7128054459be36bf501225ef22c105edf599ed4732829bd35c20d6831278c799",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-freebsd.tar.xz": "a4d6429df3ea63c4f58af3311f3cb986546932a73ae363a768ea6cb630a9b59c",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-illumos.tar.gz": "adbb9d176605339353b9c84f53da7301c262966a43e9c25fb5dc408591a5e30e",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-illumos.tar.xz": "69bacc4bdb3466862ab86a524516e88e1af3e6379a6bd5b38a5d872534d7584b",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "49b58d45a5eeed663619b6976ef5a97d1d69ee6d1426046f5cf352ce2730aa81",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "9896fc9d8a363a1684abc892f70f71047f43a27eca362911cc39474582a3df7f",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "f5e9ea5090e1a1f1478c1b6c9f4c2975955630717d00304105e7c2b4d30b5793",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "121f57a07ac943c6d48d4519d863e873501edb57d04d8e2842c847510dff73e1",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-netbsd.tar.gz": "0ba119cb9e004e008daf53d6f2687ac48b5cadcea81c69f8b7a0f967be0939ae",
-    "dist/2023-12-22/rustc-beta-x86_64-unknown-netbsd.tar.xz": "81b8265afce99ba1fd7db811611da0f7296b066c2db0f4e65bababaad3f04ea6",
-    "dist/2023-12-22/rustc-nightly-aarch64-apple-darwin.tar.gz": "101130c9df70b39a6eb8b63ce1c457d8060c961d4ab845f4edb7b02e1b68e5e2",
-    "dist/2023-12-22/rustc-nightly-aarch64-apple-darwin.tar.xz": "ac84e13cc222d4bfc6670b2bec5407c77792ebf82c51e812ceb3bc972a9cfe24",
-    "dist/2023-12-22/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "8ca4faf6ccf792534c95b8091786d8b2b79ba99bfcd2537e2cb7fd97a3fc46ba",
-    "dist/2023-12-22/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "97db2f021e7aacdac1c81ab72264eede6cb72cd83f1c317ae84a3ff39b05584e",
-    "dist/2023-12-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "c274e2470c8cc801495f7a656a10250024173d5927b7ffa2e9251e0b776da5f4",
-    "dist/2023-12-22/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "024917a1f37a2db0bc8519dbcdecde7321c5d460886b76817791ea484595c44e",
-    "dist/2023-12-22/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "bcd861c8f6c7f7355f7d6196c405061e90a2907adbca52400b8dcea7bc9b42f1",
-    "dist/2023-12-22/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "19c52eecdf2dd4fb0b6a5c240c440c6d47148e7264d7efaa77ac484a8429802b",
-    "dist/2023-12-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "38fe3274425db7e9142530be734b473fb5742ea10d05deec24168730d8e65d0f",
-    "dist/2023-12-22/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "1fe18e92829eb2b87264dee5631329804a7da8177cb15043fcac27c1913a0b89",
-    "dist/2023-12-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "41a723fbfbcc9c003b59fe17e0bef28d69ed89f165c42afcd00e3617a7da6915",
-    "dist/2023-12-22/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "7f834044d638e8e15d8900c38b8ec1fc6e4ef98efddf3ab7342b24e59525c6a0",
-    "dist/2023-12-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "814402e50600573b6fd79ba3a84fb8c441d71eb2f3eff0257565fd514830ab10",
-    "dist/2023-12-22/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "2f2650f7ad3d86dd63bd887f6e5e5e5051ffdeef672ee8dbc96c738acde79e21",
-    "dist/2023-12-22/rustc-nightly-i686-pc-windows-gnu.tar.gz": "6cded96f43ea2aeb2c15ae5e58521301110d6a2f8e8870ff2d6e5e1d8d5d13ff",
-    "dist/2023-12-22/rustc-nightly-i686-pc-windows-gnu.tar.xz": "2682f11a1375b1b93a9f7110f121340a4994f736c263d37037fb29a5b6df69a1",
-    "dist/2023-12-22/rustc-nightly-i686-pc-windows-msvc.tar.gz": "9322ff47c86859ba405d6584407b3ad514e6ee1b7a47525a0e20a918875defca",
-    "dist/2023-12-22/rustc-nightly-i686-pc-windows-msvc.tar.xz": "1dd7be7fd7e51ee9e8c053b2c7c222031aa436497e591ad87a5ee2f2289022f5",
-    "dist/2023-12-22/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "35e96a4ff0436ed31bb62e06b8898e3048cf11d3ae85f1097741f6b6d2ac0304",
-    "dist/2023-12-22/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "a8d4be1c79031e6ae2ebf594929cc4cbdd2e0655110ce2a9983e1adee1474b3a",
-    "dist/2023-12-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "7a2b50a5309770784a47662b5616026e735cb12ebd785c578c3a16965167ca3b",
-    "dist/2023-12-22/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "8cf64de71cd3566683e487832c3f4143f306d4fe9658fa1e16b794d3ee25552b",
-    "dist/2023-12-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "f1890a35bb23fdc85736e18a7230eb4ac68f1d1772a8b1defde1c6fc53b547db",
-    "dist/2023-12-22/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "5a1cbf44eec83fe1172cef13a38c2f23c2cc2753847ad9577b4cbbc0793ba96b",
-    "dist/2023-12-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "b5e7b7d42a233010142806953ba10820f45be90574c885d9218d41865310d606",
-    "dist/2023-12-22/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "073c15e2528c30fc51e7964649cd84fc54ce7d6e71f32c4bd5e25028cfe66f01",
-    "dist/2023-12-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "0a579f70e0e6752e5ee257fcc2c77a4986d608262089427f3ae38ad1ff1d8864",
-    "dist/2023-12-22/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "d9491f667829d36df5db42ad40e0ee6bd0f5d53d854d8648462c357fcc709ca1",
-    "dist/2023-12-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "01bc45a98dc4791b14498d58681a894e3646ea0588fbaf23465dad1034cf7dc4",
-    "dist/2023-12-22/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "4eca6ca78604697090e48c262aab864a14cdd15607272699cfb9f93b0fb3b9e7",
-    "dist/2023-12-22/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "c77f35e12eb4e664c3f59575401c20071e3489de8a80e47601321823d1c79b09",
-    "dist/2023-12-22/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "61f3c129cfabbc5e814ea0ebb183d6674dafa593f56c017262aa60d241041983",
-    "dist/2023-12-22/rustc-nightly-x86_64-apple-darwin.tar.gz": "2ef95843d229f3b5d5efe1d2cd1cf9a5d2a5500b9f8d00a6ba5eef55a8689643",
-    "dist/2023-12-22/rustc-nightly-x86_64-apple-darwin.tar.xz": "ee3ac1b167da164384d1e3ac8b6fbde9668b68705afa1a047a1049e90b5bf66d",
-    "dist/2023-12-22/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "a98e2f3976a5b64f802616c045861571c61eef332c7206e0bfb10fca580c6bf6",
-    "dist/2023-12-22/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "549caf445a9b4886c47bdf82628e365afe8cea59739a3b41308c828c4eb9e7e0",
-    "dist/2023-12-22/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "db9bb6ae1770056cd787162ab24e54bad0dc2c8bd2861c8c3ded642f9e963643",
-    "dist/2023-12-22/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "bc410fb240404e3c193e39667485919660d58b7a5774301f9d0cb21ff744eaa1",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "e113660740b61a1e20d72813e7ef076b7a894f5db3576abae812f501eebec409",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "a0bacdf5523cbc5b59f49fbf99eaa571609faa4aa8765a09f9f091ba3f4f5686",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-illumos.tar.gz": "29f8ee90239986050d96d1fbce42f0ec104653a44c49d050d5965ebbf8e94ff0",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-illumos.tar.xz": "c4c04dc8d91f53db3420114a6020c76771b6dddf43f322ec0575c69a6bba7be8",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "f40e5ba829e2e731e44fa0452433cca7ca0f41d717f45809c32804d172ee3e7f",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "5ca6206e9c4c7274f988026dae50774cf0b197b016d81adf15ca29816f9177fc",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "40c913469dbe202d27fc4f3f9f8072c415d2d788d62773de486f0a429d17ac21",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "bde66e4076b615d14e3e799604c8904d4506854e03cf5ac2be39a5839721f1a1",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "5538e8852c23f7070af754e1b19b7c685857f57cf33ed9ec9263a92bf57a14f2",
-    "dist/2023-12-22/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "2d6558de20de87ce02de647115fee7bcce5f017baf2dc4593a1c91ae53281813",
-    "dist/2023-12-22/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "3d5878aac23fb995cb29aeaf2579b30ce96d5f3571f53e21e20094d4cad69800",
-    "dist/2023-12-22/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "80866c0ab8848d31a250c0904222ef0dd19ef45fd1f1a48ff381c914ef6c1ab6",
-    "dist/2023-12-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "4082f5613caab9091d4134dee83f5cfbe401d59a2a1b2000f28c7094584f08dc",
-    "dist/2023-12-22/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "94230b1d3582e83967306da3f869970d190fae1c22ce61fd5708f8591165d9c7",
-    "dist/2023-12-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "7d59a37a6fbf86c16376f593a54adcbbdf214aa8d49561fd7337d27f437e49dd",
-    "dist/2023-12-22/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "6c6be9be98fe01756c077cd3f6ef23104e681476e0a4de006223273f3f9a1fd3",
-    "dist/2023-12-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "706b95856289e67c29999ffa4e3afce266c017da8fc66db95695571ae4560ecc",
-    "dist/2023-12-22/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "9f768f3c40aa3f9d130c4725eff036e1503b372161f136878f4877db44e3600d",
-    "dist/2023-12-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "6e276261f45d28a2110d3de8ae3de4888d041c831d63960bc242e0b0b7765dd5",
-    "dist/2023-12-22/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "e9b4bfb081445a4506f10249c7441f2d0424778f3ac0fbf5b5ac3b87ba9ef66d",
-    "dist/2023-12-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "f1aec801b69d4b67a58ae93741ffa018d0a49943e593592139abb6b217561366",
-    "dist/2023-12-22/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "f23b01ec072adf8c29943846ff90f2a1ced0619dcf9c3d517f4cfad64d726e02",
-    "dist/2023-12-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "b61d903932f63625e4163f9a0b7e83606bfdfda4706e68d9387af62f611a32bc",
-    "dist/2023-12-22/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "21bbc61820a28141db13095dc778524dd4ba1981d6c66caee45b0b72f7267016",
-    "dist/2023-12-22/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "bf8307795424917a3975b1cf4b0b490cf80a17154d66df2a8d869d1a3291ca5e",
-    "dist/2023-12-22/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "b651f28f2dabc67abaf2ee7e17cac5508f400bab82f8267ef9ae2ce2399f5c5f",
-    "dist/2023-12-22/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "deacde8dd4f34e24d981a585061922708af11d4638733eb49dbc1087ffd901ea",
-    "dist/2023-12-22/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "cefc12a2fa8b66dd66265d159b3ee16cfc87a8c183d7a158e4e610fd747cecb7",
-    "dist/2023-12-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "4996bcacbf363fd93440ff18eaeb09081d1e9e510ddcebc5f84c2a3292d5d0fe",
-    "dist/2023-12-22/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "dd6b37586054ac9ab7714f0712e1cd833df33820fc661fa3ffa52cbcaa31073b",
-    "dist/2023-12-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "2fcfbc0448df994daa9a625bfc75e69054105a6c120beefa84c3843ab36dc4d7",
-    "dist/2023-12-22/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "94282e425b30fff90c9429e1f0d2aa5cc69094a147c8dd4521b30fa98eade494",
-    "dist/2023-12-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "25445ecbc332fd305e81075c18c27efdf2027fdb2d263f921eb716cc3ea60609",
-    "dist/2023-12-22/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "9a55fa07a1a9c3b0c31b00d9b33b0ff727046b4f322e6297ffa290e7741de015",
-    "dist/2023-12-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "01b05f33dbfd00aa3ae500db2204f08e5908a4833c3a26f0473bed9605003bb8",
-    "dist/2023-12-22/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "946bad6ff6d59ee175d7defcd1567b2aaf5c197bbca8985b04b91eb58f3e6277",
-    "dist/2023-12-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "bc2df359ed8ac189459139a0bcd3556484588bb053a4c2a0e1f7c8fedf39849f",
-    "dist/2023-12-22/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "a870d941baff83185c43bade890a8c87bfb16e0549fbc74cacfec561740a72c7",
-    "dist/2023-12-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "3fdd608ac91db883b2829f38bfbbb332ac327ab070570384d182e47f875bbecb",
-    "dist/2023-12-22/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "0a503de10365cc8eea4405e2db265e95d0d6a52556c95e3ca8e06735551ca0c6",
-    "dist/2023-12-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "82e85800015ada8c40c613eef01a4120feb60a35e069ace15d018dcd6603554b",
-    "dist/2023-12-22/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "21de46c078d31ac953cb41271b020817ef9c3cc55cde7b6b280f0425d8fc7400",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "5886fcf2485728376b7fe7c6a2cf9331f4bb0cab204efe5458ab2ef816e48b5c",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "6c775b5604ce3b3680d9cb6c074c97708d6804d40d44ab4d2abcaa8fd8fbc509",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "51bc618c6c7fa1086032655b6cf7c54b30c12ddf28949840e7695c0e65ff9f30",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "911b8becd12efbb1a46edaf55a383ab8c193e077aa08d1bec8c38a0168557dc2",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "27b84d5cfb60f11b03e26c882f20aa1e58fbba568cd6fc32f0970ab91cc9ed44",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "21f62ffdfd1497e5bd32cb43a9fd3c39672c429ef878e35c2019e167444afecd",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "1338e6d90b781578326816eda5b698ab38efa733387e1df84bb56c3ba5c9fdb4",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "9ce18c0e954100fedef63baceeac4a01fa0b0f810dd5175e5fe61070151c8161",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "8493b82ddec3ea06c8a1b9bb8357c47164ca85856ed538c96678cbaba3361afe",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "cf00b45f38ed847039f7c031e7c1a0a62cf7f00fad5acc05d47edb7e28a0e546",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "96480091ef8533959ba49e01922569a202c8fa2de174be553fab8478cb5c455c",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "c237e0c157dc09ef2c47583f34253ee92db92ead9f77fd8701ddee998acc0aee",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "73b731dbb70e872550e584fc4d3c67b6cbaa2d9a9a97b2ce11bcf6ab3ea5c5fa",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "141fe48890292de4d39547787f4ff44f672d3a5de35ed775cb80d7c3684bec73",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "52b2bab5830100dc4d4fc53ffcae560d7801382dcb4af19d2554e2551312fd0c",
-    "dist/2023-12-22/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "2071421241ed9e5e00fd5f877863a3a145616a8585db472b35ea902affaee4ee"
+    "dist/2024-02-04/cargo-beta-aarch64-apple-darwin.tar.gz": "f39e4ae0a2e69b1cc1bca0910287974025fa70398e278083d5be71a6397f6e7d",
+    "dist/2024-02-04/cargo-beta-aarch64-apple-darwin.tar.xz": "52f51e11e352d96e6350c0860576dc088681a135ded0bc04e943ba95421b52a4",
+    "dist/2024-02-04/cargo-beta-aarch64-pc-windows-msvc.tar.gz": "60cd2c54379b2d0287072dfe7cff5b81bf51beb69ecb296d6f3036f2a2526f8b",
+    "dist/2024-02-04/cargo-beta-aarch64-pc-windows-msvc.tar.xz": "cdc5d36196fa99c6c3641000e66ff68be9f2cc95bf00cafa87ae8386400b8ee0",
+    "dist/2024-02-04/cargo-beta-aarch64-unknown-linux-gnu.tar.gz": "e78c45f00e9a88647e8829fc248739aff1f0ed0ab6ec60a3da5ce6d2c1f02cbf",
+    "dist/2024-02-04/cargo-beta-aarch64-unknown-linux-gnu.tar.xz": "541754f83b39db95b62c5a0d2f9650b53212e0d6c2989429323c79a27d96d8c7",
+    "dist/2024-02-04/cargo-beta-aarch64-unknown-linux-musl.tar.gz": "6ec7f1ee3284ae3e27da9667fe976d459262233bdf1a7692f8c72f467aeb5ff6",
+    "dist/2024-02-04/cargo-beta-aarch64-unknown-linux-musl.tar.xz": "89c46d7e3826e6ca21cd2b992492c08e7a1d261ef347cf29f018480956fcaf98",
+    "dist/2024-02-04/cargo-beta-arm-unknown-linux-gnueabi.tar.gz": "9af1091ed9deee05e3c1b590dccc88e3834f47c43193acc29d5539ec7922a7f3",
+    "dist/2024-02-04/cargo-beta-arm-unknown-linux-gnueabi.tar.xz": "14a55b1aa26cc7ced03857a4848c91eb25bc1735b1e314b453efb8856b96105e",
+    "dist/2024-02-04/cargo-beta-arm-unknown-linux-gnueabihf.tar.gz": "3104665d24262b8b7586777331e63ee1732fbf7656f05b7dd85a71534e7b47eb",
+    "dist/2024-02-04/cargo-beta-arm-unknown-linux-gnueabihf.tar.xz": "610486cfcb5022c6f99494b9f58f3494438c7d9af4e0a949d0c5d366d13acd74",
+    "dist/2024-02-04/cargo-beta-armv7-unknown-linux-gnueabihf.tar.gz": "bdeeb3b50477fb57f5d02796af0543deeff9d274e6c12dcef1a11f7517dd2ceb",
+    "dist/2024-02-04/cargo-beta-armv7-unknown-linux-gnueabihf.tar.xz": "95a5beba76cf3ceb27378f1f2f9ab92359ff5627603ce2f6a8f86bed6ecf61d8",
+    "dist/2024-02-04/cargo-beta-i686-pc-windows-gnu.tar.gz": "65d4fecddca8b303f062fa119af9a7eb145c4c91adf5d5ec045325f2f48c906a",
+    "dist/2024-02-04/cargo-beta-i686-pc-windows-gnu.tar.xz": "38e766e4d90270c8a5f82cd4d0a50c1c143987201194c9132b86bf7a1a969036",
+    "dist/2024-02-04/cargo-beta-i686-pc-windows-msvc.tar.gz": "ed2ade2a28c469f9b488a675054494f4f26b4c3bde90c17eea34454562262d08",
+    "dist/2024-02-04/cargo-beta-i686-pc-windows-msvc.tar.xz": "05c6dcfe9e14bc2ede72863fef1814feceb063044af7a31baba5961e29aaf1d5",
+    "dist/2024-02-04/cargo-beta-i686-unknown-linux-gnu.tar.gz": "5954537bd942311649da6daf95ff60afc7e9b03fd3fae0d1a97244338309786e",
+    "dist/2024-02-04/cargo-beta-i686-unknown-linux-gnu.tar.xz": "9148aed468ae49b94b14786eaf58f963e2c58e2a99a93afa481be0a9244b86d4",
+    "dist/2024-02-04/cargo-beta-loongarch64-unknown-linux-gnu.tar.gz": "213b7f752395db016555825664e3e4a3bd5da8943e8bd56ed5bd94380e92181a",
+    "dist/2024-02-04/cargo-beta-loongarch64-unknown-linux-gnu.tar.xz": "8d146499b36f2d08389ff7888d74daa9f18a7e43cc2283c5410dd5c386c9caec",
+    "dist/2024-02-04/cargo-beta-powerpc-unknown-linux-gnu.tar.gz": "12a828172bb26f88c1a11a6d68aed6f87c3dc47961f74c8eeb6451b38c204b90",
+    "dist/2024-02-04/cargo-beta-powerpc-unknown-linux-gnu.tar.xz": "3905b493ee8ed0bd4961739b91a0dc14340082a811ec5be6e44dd8194ffaa38d",
+    "dist/2024-02-04/cargo-beta-powerpc64-unknown-linux-gnu.tar.gz": "63eb2e4303af8f77ebd8d22c08fd7d6f209abec1dd9f19f5afd2c4b281e765cf",
+    "dist/2024-02-04/cargo-beta-powerpc64-unknown-linux-gnu.tar.xz": "5be0627e2aeb33a7888c9a884e019d65d53a463e5b2dbb23a11ac5a89cc175c3",
+    "dist/2024-02-04/cargo-beta-powerpc64le-unknown-linux-gnu.tar.gz": "12bd938eab15063da78bda1b5f0918b567f55587c494c85fe8b11b36f305e397",
+    "dist/2024-02-04/cargo-beta-powerpc64le-unknown-linux-gnu.tar.xz": "0a6247ab66282beac406aa0c25affb51dc43a0b2a40fc71a1d98efc680a6f67b",
+    "dist/2024-02-04/cargo-beta-riscv64gc-unknown-linux-gnu.tar.gz": "6e9a6b49a58ef886bf668c9827c31d3f9beb2ee227b8c7a017071bff7e1efb6a",
+    "dist/2024-02-04/cargo-beta-riscv64gc-unknown-linux-gnu.tar.xz": "f56cab3cbbf6dc2e605124b8edd6c9a7d7592d001e9b2f4ea04af890b6fe6335",
+    "dist/2024-02-04/cargo-beta-s390x-unknown-linux-gnu.tar.gz": "be35d6d6923da0a5c8599760a72b584cf9e131bf16effa184d79786e9613f8a6",
+    "dist/2024-02-04/cargo-beta-s390x-unknown-linux-gnu.tar.xz": "81cd24ac13498570894a98a69ffc552ad282dfe4a076018841881f65ed387e09",
+    "dist/2024-02-04/cargo-beta-x86_64-apple-darwin.tar.gz": "e828aeffa6c832ff7a1e71ae12d275f75df9c3087aa08959dc0b93d0f37f9f76",
+    "dist/2024-02-04/cargo-beta-x86_64-apple-darwin.tar.xz": "546c56de1500061d5a133e05662d2659e3e96619f20757750ae8865498b71eb6",
+    "dist/2024-02-04/cargo-beta-x86_64-pc-windows-gnu.tar.gz": "c10b9f15a31a05ba6f865d1a853ca3f9b178a3c886ab73b9577f8db0b870c592",
+    "dist/2024-02-04/cargo-beta-x86_64-pc-windows-gnu.tar.xz": "65c5941965768e31abcba7c57e660cd6fcf909157b6aca1bf2ea0983e5a844da",
+    "dist/2024-02-04/cargo-beta-x86_64-pc-windows-msvc.tar.gz": "14bf2ac915ba94f172bd2a569bb669101d877fbce5262071b5ebb8f8d81752a9",
+    "dist/2024-02-04/cargo-beta-x86_64-pc-windows-msvc.tar.xz": "b2ce5dce49edc9a872ec63251b00ce4bc7c232984fee8b8ee534d8bc04f2084d",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-freebsd.tar.gz": "d408172c12e290bf27828a2e806670c750428182d0caa5f1aa88b9a4d3fe1bc9",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-freebsd.tar.xz": "46a7ce49382615f896276eb1966b7815353d19927a9e54feac902777fc7de10e",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-illumos.tar.gz": "a28eccf6cc23b580980fba900943c93a71594ed0a8120c239ce882e02c1f4a6e",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-illumos.tar.xz": "950a9a326bf80c65b0cb0073c5b712368a7358b993b8850cf4ae2bfc6644671c",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-linux-gnu.tar.gz": "0676c47123c0292b2e4f18592801383bf73ade1069cf6d160f27a39d86641b4c",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-linux-gnu.tar.xz": "a3dda924031f949cd7b5ada8e67b506efa94fbd4201e00d9c1e1e589223a039f",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-linux-musl.tar.gz": "b00be1a9ea0d0ca1c81181d2e1263594c8654036d050e8417772bb10021a0018",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "bc464a4758ba8d585b2a6d7ba1f0f76c5bc8e21ffb699b4311cd54c702ab2295",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-netbsd.tar.gz": "4c165157f0fe6c96b3e54a73f795792cfc69aa979c71093eec918ddbce9a6c08",
+    "dist/2024-02-04/cargo-beta-x86_64-unknown-netbsd.tar.xz": "05cd0538b71c90f3e665b2feef453a0c4f4f6b1b68e4c8fe2339bd3d9c071af0",
+    "dist/2024-02-04/clippy-beta-aarch64-apple-darwin.tar.gz": "93cf112cfedead61356eb102bc55c811a23f67e13cf3933665de95f306c5a3ef",
+    "dist/2024-02-04/clippy-beta-aarch64-apple-darwin.tar.xz": "5389da6bb96c8928f18d018a25cd5d104d1c4ff9478ecf7c289434de3253d2cc",
+    "dist/2024-02-04/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "5403e94f79d7295bf565b061b6fa9e5d500068005a7012c47dd1f0422cadcc99",
+    "dist/2024-02-04/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "a285d22b4555524d94107292c45300129774448f2c1112e1744564e480ba07f1",
+    "dist/2024-02-04/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "4a6a2bc13f589b4de7a42d71517286740fc5670ad8247263338ebf13f021f5f1",
+    "dist/2024-02-04/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "6a007ff2a433dcd4a07efa6d55ae829cbbf4518dd5a5e52570bf70bee1876a22",
+    "dist/2024-02-04/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "b4ff74cdef7ddbaa97ce031fce580ef235dc890c08a65f334b7f9bd61fa7fae5",
+    "dist/2024-02-04/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "80bb641d57cd9077121640aa989a2a1b2c7ad802219b623d7b98527181061056",
+    "dist/2024-02-04/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "9f5a8c09e02bbfde36522f6b98ac19c6758f04a6fbb76cfafda357fabba20819",
+    "dist/2024-02-04/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "03aadb465c7761f000cb1515c98998afeb7557d1b20443c6b444949620290fc8",
+    "dist/2024-02-04/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "694c756a8df76057982652a6dd31406e52f46f1bb9af29e9e1221ee90b966713",
+    "dist/2024-02-04/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "224cdd5c675e68b5d0094a1b0d9cc08411b168dba5c3a8b6be15223ecce542e6",
+    "dist/2024-02-04/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "95c385adf93104d0ee31c59c10cdac2c7dbe073c40eec9a213d528109659e5e3",
+    "dist/2024-02-04/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "f649540bf91a48a9c8b58ed161b9665747a04054839bd21225d5d01d6abb6809",
+    "dist/2024-02-04/clippy-beta-i686-pc-windows-gnu.tar.gz": "b7597b2bf5e1a3b6041cc3e7773ef9385b3d1e0323411ee81eedad07ddec64a2",
+    "dist/2024-02-04/clippy-beta-i686-pc-windows-gnu.tar.xz": "a21cacbc47c6e9eb16e356e7724b1b71214a2b5fc513a50e8f4ce79060ddcd4d",
+    "dist/2024-02-04/clippy-beta-i686-pc-windows-msvc.tar.gz": "d71c3d482b328a01168f1cb8136f2ab76f5d55468984fad27039ea65f462fbfb",
+    "dist/2024-02-04/clippy-beta-i686-pc-windows-msvc.tar.xz": "e1f4ca9fa2dadc238126a995891da9bdb75dce196daf3f95a697653004fc2d4b",
+    "dist/2024-02-04/clippy-beta-i686-unknown-linux-gnu.tar.gz": "c2763fd5984be3105f649f5587cdb5af6ffd53fc3032ffce751730051a901e36",
+    "dist/2024-02-04/clippy-beta-i686-unknown-linux-gnu.tar.xz": "92a53f012b6770bf505082e27ccc182b20c0ae4954788c8ba51c140ec8981c8b",
+    "dist/2024-02-04/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "c39b59c5e347bbd169cd1c08c087db4f7ddf243416c9d0a144da620ffd99283e",
+    "dist/2024-02-04/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "1a973d60048b8a8541ab217cb00d5aa74fcb799b1f4f491666b07d4960aa8fa4",
+    "dist/2024-02-04/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "e40718072e3dde6e01bb9881a024a362057a8c22601d58273cbfa757999311e8",
+    "dist/2024-02-04/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "b47d5c9c7eb3351e7afc3648069e0e5d3eaf9f61b1ba2074f91f1b4a114cf6c0",
+    "dist/2024-02-04/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "ab30688d5eab3f7fdddf665ae00e23a168259da3bd9ef583e56c80800e20256c",
+    "dist/2024-02-04/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "4c08b61a36d8901e8c8fc397f7919b63264f9709b0b513683582da4378e4586c",
+    "dist/2024-02-04/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "88af713a59ad27e04a315a9887e0af3afaa118ef103b235a6874e7665e270f55",
+    "dist/2024-02-04/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "e6aac345a1a8c12168af05697379e885e896f1ecb51846a5183aff5f1efc321b",
+    "dist/2024-02-04/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "b57db645be80fe0ae5a8d3a496f4d00ff7af3bb0ff1032538a051da3b012cab7",
+    "dist/2024-02-04/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "be6d3d5cece8442b016be55ee46f4278797a7842d023af9d03edac6e528b6e8f",
+    "dist/2024-02-04/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "5f58a7aec4c2b9311cba0c11c88879e60fa9bdf541324f08b203ad739d4dc8a7",
+    "dist/2024-02-04/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "3b7e417060b91bd08e28d88f531947461c18a2aeeb3ceb7774171be7e55758c3",
+    "dist/2024-02-04/clippy-beta-x86_64-apple-darwin.tar.gz": "1806b225fd6b163ca5ff2fafe34b9fa085724f3c46133757b6a19fae3e253c69",
+    "dist/2024-02-04/clippy-beta-x86_64-apple-darwin.tar.xz": "bed30af2131873d94784ff69fedb51c80e0c0ffc5474c6ebb06d00292082d2b8",
+    "dist/2024-02-04/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "7a7c7e2b67105712265e776086c9dcb8fc84c1ad64c6cd3175b8235ea85f1287",
+    "dist/2024-02-04/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "9aa2a44e40c3221df88738db9fb9729989ce618c8a73e109f04ed758da044ef0",
+    "dist/2024-02-04/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "32f2acc1fb292a7f8af43e7eaf0e5cc57f21ce51ddb209ee5d9c4db50bedfa17",
+    "dist/2024-02-04/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "6e521228076657cdd451d924c3d0d48ae703f6a3ac1b6c64fc2b56553c924f11",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-freebsd.tar.gz": "cdf2ea498ea64ce119a861c4b4ed198f1971ff4562f239e1ae982a6bd50a8169",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-freebsd.tar.xz": "8716ccf9eb52a71fadfc177abd5dc75b1d9b1f14f7c523d12aefe5407d5380ee",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-illumos.tar.gz": "b845e1e8e0912abc1c165e757b28a569117ac7363282e691cad7dfbf2fbbebe9",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-illumos.tar.xz": "8a5577421bbcb6bf4ff052bfa0db9e22d65eeed578be3fb14946bddcf78aaf8d",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "730dced7639da52fe031ea9142012cd1c6f4a195312d99ce08f8b948ac317f78",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "4de9e4acf49f34cf7e99bee718d15081ea7e5b3cce56b1d180e125832126934e",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "b5ce09b95d2a77ba605d2083573c1d4832fe42c8ff6b5bd8507f1ccddf87a10a",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "fcf7c128a344f7b55481b82223b971fd5565db4023d443b315349a5ac5f5937d",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-netbsd.tar.gz": "8abaefeaf4d884e3214f657d8896bb440d93b3cd5f4e355fb8ae728d84713f40",
+    "dist/2024-02-04/clippy-beta-x86_64-unknown-netbsd.tar.xz": "a4b5e4b73c7a613f34ed592af4a73e50c4fe6f0f841f9749cab57530dea6033d",
+    "dist/2024-02-04/rust-std-beta-aarch64-apple-darwin.tar.gz": "54c24b06cf7b1cce6d74d0cf2ef38c0df0296e9b417116ef6bb340cf9a864f20",
+    "dist/2024-02-04/rust-std-beta-aarch64-apple-darwin.tar.xz": "17034b0eae96813fcfd0d8883fb7f4805b713404e15169e8c3de32801e4ca3bc",
+    "dist/2024-02-04/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "477879218f052b6f20b40d34b72a9fdb900a64fcd4a1392faa187eac44576456",
+    "dist/2024-02-04/rust-std-beta-aarch64-apple-ios-sim.tar.xz": "5fae8e638f4c6b61683db07c0de485a1cb677e4384c593f32c089d77ea5dfbd9",
+    "dist/2024-02-04/rust-std-beta-aarch64-apple-ios.tar.gz": "4cc45742a06693a713d72820c6ee830ed8bd4f6f5ddd3be1e32bca4f5f88fd4d",
+    "dist/2024-02-04/rust-std-beta-aarch64-apple-ios.tar.xz": "7d9adce8808f0f5f7b9c65091791107afd63f26de02fe156821a6125486f2255",
+    "dist/2024-02-04/rust-std-beta-aarch64-linux-android.tar.gz": "893a0befa7f506cf3a07712d7a731ce551209c97708cd7f0ab12fa6ff3f1da39",
+    "dist/2024-02-04/rust-std-beta-aarch64-linux-android.tar.xz": "b647047d64f2fded2e393f226a7d131c96e84f2cb0ea6ed8259f25648b56bc6f",
+    "dist/2024-02-04/rust-std-beta-aarch64-pc-windows-msvc.tar.gz": "74917077da50bff4ceaad96a8acd1e90f9ccef32aea2b2f5f48406ebafff4c35",
+    "dist/2024-02-04/rust-std-beta-aarch64-pc-windows-msvc.tar.xz": "08210e2b802cda619854608e361a08388b51b9fce1551c13e5068ddc22d0773c",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-fuchsia.tar.gz": "a51887dde95a5102eba99a754016900dd679e2cc6f65b7173a3d31c8d0f0148a",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-fuchsia.tar.xz": "57f7120e830dcbe8c95be39f00342f2fbbd8ccdb20f431e8bc940eccc4002864",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-linux-gnu.tar.gz": "6a79090eae406437761523e43e5a72b0ed040deb97db82da62718ee502573770",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-linux-gnu.tar.xz": "00f3df2addefb8968d668200a890593481587536d0628e4d8def08b77e79caaa",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-linux-musl.tar.gz": "42f0afcf90ffe70388c53d7642b035700af71b99e8382c5e95a94c6aec166e99",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-linux-musl.tar.xz": "337984596f0d3cfc5776830cf7cb36ec8d564041761666fe340ecb0a62332348",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-none-softfloat.tar.gz": "913e2255837674cd672c4959d567ccd786242acdbe78fa76119ceb8ede9b9846",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-none-softfloat.tar.xz": "660f879a8a3e19686cb944766b0e70b19d0a9fd344047ceaf5e8959bc019f36c",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-none.tar.gz": "4a210eefe84dbfe4e75fbc3a5475e58d86983e1f5c195e7c8b9f096e46ebfaeb",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-none.tar.xz": "ad03045b5fe2b25806b4b44f5920e75008234954318cdc9cac8159782f6fc314",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-uefi.tar.gz": "0c2988780468ff39ffe65cae5443bbdbb441aad18bf88312c14df76fefc748fd",
+    "dist/2024-02-04/rust-std-beta-aarch64-unknown-uefi.tar.xz": "0e4efbb711bd74cb280535ca424be4519f8e273b482eff4b5c4cfb7f0c142a74",
+    "dist/2024-02-04/rust-std-beta-arm-linux-androideabi.tar.gz": "6e6a0140c52670d962db55be6aa607618fbd4094828f27129cc94540ac94d893",
+    "dist/2024-02-04/rust-std-beta-arm-linux-androideabi.tar.xz": "fae70ac3c0be0a83c98eeac49e651c392c5962e10b4876120959d95209cff4ac",
+    "dist/2024-02-04/rust-std-beta-arm-unknown-linux-gnueabi.tar.gz": "48f73e51726a7685cee917fbf42464c13b77e3c4c36730477ce8a5213d0c8068",
+    "dist/2024-02-04/rust-std-beta-arm-unknown-linux-gnueabi.tar.xz": "03c4fdb9ab6737d48e9d1573188badf126acdfb96c4dd88c36d45fd7d61845c6",
+    "dist/2024-02-04/rust-std-beta-arm-unknown-linux-gnueabihf.tar.gz": "d17985406a6d241ae2e1f5c5571795ab712cc47fc2434fe78d69d3e581a768c8",
+    "dist/2024-02-04/rust-std-beta-arm-unknown-linux-gnueabihf.tar.xz": "ef29cc16781ad2422b78708634684f9310cf7783c2c88fef6cc378c1b21f86d1",
+    "dist/2024-02-04/rust-std-beta-arm-unknown-linux-musleabi.tar.gz": "df8bf07f5270c91bcdda1568fc870c128594a558d5fd26ebd8f4e9e1c7c026c8",
+    "dist/2024-02-04/rust-std-beta-arm-unknown-linux-musleabi.tar.xz": "114b42345f30ff26ac42044825209f7d1ae4b8b9a59c535ad199a78e8e2be1b8",
+    "dist/2024-02-04/rust-std-beta-arm-unknown-linux-musleabihf.tar.gz": "5b05057ef84727d0d62a575b1a4d8f87ea7b06cf242d294912bf97b52137a0ca",
+    "dist/2024-02-04/rust-std-beta-arm-unknown-linux-musleabihf.tar.xz": "a87b55c984fef378be2f50db63c0a66f715949e4365d467211b5c13839320cc3",
+    "dist/2024-02-04/rust-std-beta-armebv7r-none-eabi.tar.gz": "e8ac0f9c5f699c88a8da799b08111bee35719426ce6c0e2f53d0db14fb9b96d7",
+    "dist/2024-02-04/rust-std-beta-armebv7r-none-eabi.tar.xz": "7875d407748e983536bc0d3a385313a124de94390b780557d48fce9564a3754e",
+    "dist/2024-02-04/rust-std-beta-armebv7r-none-eabihf.tar.gz": "70415c0c7c4e9e53b12b1cbb0101398addb6b4aec59235011c2d73c059d0336e",
+    "dist/2024-02-04/rust-std-beta-armebv7r-none-eabihf.tar.xz": "2c9f18fc935938d5b9f9cb7915dab5aa6ca96032abf5a9e3313a63136c4cb11f",
+    "dist/2024-02-04/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.gz": "b00b34a021c2d80574bbb764b08e291ffd8db0f346b8c3486789c86f008b5d98",
+    "dist/2024-02-04/rust-std-beta-armv5te-unknown-linux-gnueabi.tar.xz": "b47a6f55b44add99ca66d06fa910259c809c5f4f01feb809e2a6b8513626e3fb",
+    "dist/2024-02-04/rust-std-beta-armv5te-unknown-linux-musleabi.tar.gz": "caa8182c95035b62ba22e23d3989ba2733b90f599276a7c1f79b911e19d97850",
+    "dist/2024-02-04/rust-std-beta-armv5te-unknown-linux-musleabi.tar.xz": "1dd6c111f945d727eb28c9005efaa367ee2de8b15c771d27cbcb9709202f85b2",
+    "dist/2024-02-04/rust-std-beta-armv7-linux-androideabi.tar.gz": "b4176be56ab844c0f3d652d5023b927b672173f96319f685a85e57742b713102",
+    "dist/2024-02-04/rust-std-beta-armv7-linux-androideabi.tar.xz": "3d3d96f5cec355401e3eee94e5a9b68e070f441090f691f1de15a13d6194154e",
+    "dist/2024-02-04/rust-std-beta-armv7-unknown-linux-gnueabi.tar.gz": "ee5fcd9e0a661d08a1cb752cbfdce62b01faa4c4bbc607d09bb0d39a2c598899",
+    "dist/2024-02-04/rust-std-beta-armv7-unknown-linux-gnueabi.tar.xz": "a2e7ab719dee92b6c2132a902045c0bb2688851243fc530eed6b1fbe1a053333",
+    "dist/2024-02-04/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.gz": "59ca2bacdca9b46e6e0b1803813d4021b685f676e53393e18b4497853a452d85",
+    "dist/2024-02-04/rust-std-beta-armv7-unknown-linux-gnueabihf.tar.xz": "f1b5b8843f804aef664a96896235384b1389de7084ba30be234c770dc9ab0517",
+    "dist/2024-02-04/rust-std-beta-armv7-unknown-linux-musleabi.tar.gz": "3825bb169e5d7abc0981f6a5179b143e2a695e395d0baa7cf181e8b752988ac7",
+    "dist/2024-02-04/rust-std-beta-armv7-unknown-linux-musleabi.tar.xz": "9aca61705d683d384e1d7e2392bdece52791d77edde6f45e2772bae766765434",
+    "dist/2024-02-04/rust-std-beta-armv7-unknown-linux-musleabihf.tar.gz": "46162ba65beed4d4ff70695870d02a39dba5ea4e1a71887140077e12847a3206",
+    "dist/2024-02-04/rust-std-beta-armv7-unknown-linux-musleabihf.tar.xz": "70841fa160053edb31d440eb47c54c58f4635bf4a95eac5624861b9d1e5dbbfe",
+    "dist/2024-02-04/rust-std-beta-armv7a-none-eabi.tar.gz": "ebc2f71d8486401144a193768cee0fdda3d43ec4ba7cb57434d3ec0ca9ee64dd",
+    "dist/2024-02-04/rust-std-beta-armv7a-none-eabi.tar.xz": "c8d54ac916b6c0651e8289deeee3dec76a06db7086957bca8c6039f4d10aef2a",
+    "dist/2024-02-04/rust-std-beta-armv7r-none-eabi.tar.gz": "b25ff694d355fafb41aaa7021c09c359b0af43a0217e1ee9d897f8f2e6ece91b",
+    "dist/2024-02-04/rust-std-beta-armv7r-none-eabi.tar.xz": "c22f40104c14a127d8df29f87fdb63db7aa919e11507c0bb8907dccd2d254f17",
+    "dist/2024-02-04/rust-std-beta-armv7r-none-eabihf.tar.gz": "3f73a17c6685760c30baed31cb746389b4b228704786a3a386ab432e933daae4",
+    "dist/2024-02-04/rust-std-beta-armv7r-none-eabihf.tar.xz": "fd8470f854538c8314d15d35b9a5159cf9b431ad7ccb79ea0542ba39d6e8a8dd",
+    "dist/2024-02-04/rust-std-beta-i586-pc-windows-msvc.tar.gz": "1377b2c1bc7a7066d7ae96316bc0a0339489cb71ef7f9f055731465df97ba8a0",
+    "dist/2024-02-04/rust-std-beta-i586-pc-windows-msvc.tar.xz": "77b22f2e94a3e1cefd057f051e568a6c8f4b17845272924dfbc193d8a290d96d",
+    "dist/2024-02-04/rust-std-beta-i586-unknown-linux-gnu.tar.gz": "222337a479e3d680d95c5189026890bdb3cae7eca78000f231e6747b9b403f22",
+    "dist/2024-02-04/rust-std-beta-i586-unknown-linux-gnu.tar.xz": "91447a0543f07bb36c71822ac4e8148e2e5982d1dd98fce7ba4171d7f418ff16",
+    "dist/2024-02-04/rust-std-beta-i586-unknown-linux-musl.tar.gz": "e2aa15ebd2a903f754fc9a46584b444b3fbbb9e42f2647ebe615f68711a0a27c",
+    "dist/2024-02-04/rust-std-beta-i586-unknown-linux-musl.tar.xz": "65f6975a8c06967f734bbd15589b14c5eb23951f10a79097f262083975654dd4",
+    "dist/2024-02-04/rust-std-beta-i686-linux-android.tar.gz": "073d7697a80e99cda4625f0bf1205744af9cab1a10456e44050fa8e6987007ab",
+    "dist/2024-02-04/rust-std-beta-i686-linux-android.tar.xz": "f142ffc490821bfc4bec5d69fb82c94aece9e379168f86b494b13289a597f23e",
+    "dist/2024-02-04/rust-std-beta-i686-pc-windows-gnu.tar.gz": "aaad81222f76855ffe5d2f6c5eadfe95562e9dfdf72a92531dd85b38568420f5",
+    "dist/2024-02-04/rust-std-beta-i686-pc-windows-gnu.tar.xz": "69923e0455f7b8f2cd28ef812118e359ce64789059d45e91ca5f8e382f1de1b8",
+    "dist/2024-02-04/rust-std-beta-i686-pc-windows-msvc.tar.gz": "1d66564ac675d5ca8c97ea7feb2b8e2fe606a560d27a137d996ce9814338cbba",
+    "dist/2024-02-04/rust-std-beta-i686-pc-windows-msvc.tar.xz": "8badfa48e9a654a48095026903e17392f7b4cae3501362579d345c541ddeb6bb",
+    "dist/2024-02-04/rust-std-beta-i686-unknown-freebsd.tar.gz": "3d45f7e407668cae7fae8cd8dc4e8ff8ca5f5a01baa4eb9401b81255d1e8947b",
+    "dist/2024-02-04/rust-std-beta-i686-unknown-freebsd.tar.xz": "c1788c7bbf8f4ee61c2d4623ed4efa8a8d15acc2963f3c146b48ed7d6f6010b7",
+    "dist/2024-02-04/rust-std-beta-i686-unknown-linux-gnu.tar.gz": "2e4434cad302be51543916055c8ba76b8c0c072476f6c491754b1a750aac8800",
+    "dist/2024-02-04/rust-std-beta-i686-unknown-linux-gnu.tar.xz": "5ac0bb47b9b6349a34ac1526f16714cdd580bd3aafcc3811001c69d8be21d0c4",
+    "dist/2024-02-04/rust-std-beta-i686-unknown-linux-musl.tar.gz": "21b1323043707f685bedd699a169e8acb189ca7431c1a3dc0ec7f56b27c2fec2",
+    "dist/2024-02-04/rust-std-beta-i686-unknown-linux-musl.tar.xz": "8fe2e260084c960bd29bede4be32371a34b1f801447628bbc32e7dae2d603784",
+    "dist/2024-02-04/rust-std-beta-i686-unknown-uefi.tar.gz": "4fc958f2c26ed27bd4537a31d2eee9a5b02bb5b0433402151e84756f470aebdc",
+    "dist/2024-02-04/rust-std-beta-i686-unknown-uefi.tar.xz": "a2c8235767448796d80f5408694d8ebbd6fa3b67d7c4fa03b7074836b4966114",
+    "dist/2024-02-04/rust-std-beta-loongarch64-unknown-linux-gnu.tar.gz": "a8689d5d7454dfe00acb84535813b47065cc09e17cc8006d5fc02da5f02f1cb0",
+    "dist/2024-02-04/rust-std-beta-loongarch64-unknown-linux-gnu.tar.xz": "d0eb4684222b53cac2eb84242a4e145f3f31ca855c296836b75340a0d432391e",
+    "dist/2024-02-04/rust-std-beta-loongarch64-unknown-none-softfloat.tar.gz": "6ee4ad6d9022bc69120709064dd93ff70cd3beb14ea28e82f3d4fed24ab07426",
+    "dist/2024-02-04/rust-std-beta-loongarch64-unknown-none-softfloat.tar.xz": "57ad740ec9ebf9b5bd3f082d89d63ff388523cb4d38e2cdf0b601bc7f07c6820",
+    "dist/2024-02-04/rust-std-beta-loongarch64-unknown-none.tar.gz": "a7400a7bbb873aac5c92339c8242966d1fa9553054f922193a2a8023b98a97ef",
+    "dist/2024-02-04/rust-std-beta-loongarch64-unknown-none.tar.xz": "7cd77b7c8a8b7c7c53d2ed454515766da3e02c7d6c63d880de9bc1c313f396a8",
+    "dist/2024-02-04/rust-std-beta-nvptx64-nvidia-cuda.tar.gz": "3b65431258133a690c976db006ad7b545cc980ff0352dcd03304741f5e82881e",
+    "dist/2024-02-04/rust-std-beta-nvptx64-nvidia-cuda.tar.xz": "87eaf905c3c189e9fca5a3f1dea6a0b53b7c4a84aa22c1ecf8b782c54c360a80",
+    "dist/2024-02-04/rust-std-beta-powerpc-unknown-linux-gnu.tar.gz": "97c12900755f780e32facd9ee3641394a3a7e32fe6e6a1cadd342ee367c95b6d",
+    "dist/2024-02-04/rust-std-beta-powerpc-unknown-linux-gnu.tar.xz": "a7c482e83c0ce07164921cc8ae48d02db9b795a5ea2e82c2948f598f68519289",
+    "dist/2024-02-04/rust-std-beta-powerpc64-unknown-linux-gnu.tar.gz": "9c1018fcdf362d891b6b1a63c36d5123917b2478bf010a0b32691c44480abcc7",
+    "dist/2024-02-04/rust-std-beta-powerpc64-unknown-linux-gnu.tar.xz": "fb93344ade418630bf610f9555babb0356ebbd369db73ea3edd88e96a48171f0",
+    "dist/2024-02-04/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.gz": "4c24f19b83a528af2ad0935d775106415708a03212092ba86bb271db38bd604e",
+    "dist/2024-02-04/rust-std-beta-powerpc64le-unknown-linux-gnu.tar.xz": "804bc2c1c51570cdc102c80c1514b773d0a05a8f2fdeff9f789b525b042a5071",
+    "dist/2024-02-04/rust-std-beta-riscv32i-unknown-none-elf.tar.gz": "8ef9ed0ff32193e46617bf2aab368bbc4b268175acae604e26db8a1a92c15983",
+    "dist/2024-02-04/rust-std-beta-riscv32i-unknown-none-elf.tar.xz": "3b0450f332e258d1bbeee5c78628349cb1a6fad9d7058e0f2137709c46d90713",
+    "dist/2024-02-04/rust-std-beta-riscv32imac-unknown-none-elf.tar.gz": "47cba66e90e6310139a511083eeac727a6c55e66533157a662cd613730df7123",
+    "dist/2024-02-04/rust-std-beta-riscv32imac-unknown-none-elf.tar.xz": "ce19df99deffaf9002272d8c8b8c51f6d1dda93fc2babe8d786494add2607b27",
+    "dist/2024-02-04/rust-std-beta-riscv32imafc-unknown-none-elf.tar.gz": "fb8842df07fe5d0c782c9a4b260de7cf71835f7c4ca18f5241c9dc245c75bc7e",
+    "dist/2024-02-04/rust-std-beta-riscv32imafc-unknown-none-elf.tar.xz": "5b14d80923b4561c3147d5a6a45ad73f0c187f8ff38ce51c7f54a95f17d0e3f0",
+    "dist/2024-02-04/rust-std-beta-riscv32imc-unknown-none-elf.tar.gz": "19f2c43070c2cd477a07d9ab2e0a9fe8e3d41aaff75e09b5bcb89e6dbf8d0d12",
+    "dist/2024-02-04/rust-std-beta-riscv32imc-unknown-none-elf.tar.xz": "f5d413c8763e72aea96ca97a71927fd81fcd6341a8d7cacd070898b255f6d8ea",
+    "dist/2024-02-04/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.gz": "227a42a01e2bfe5089afb478f3c78385ee989fe70199110ae8e5fb8f7d9c899a",
+    "dist/2024-02-04/rust-std-beta-riscv64gc-unknown-linux-gnu.tar.xz": "9a09c50ae0773469186754b6d14638a0d2d170f3cbac9dc36f4911a248480ea3",
+    "dist/2024-02-04/rust-std-beta-riscv64gc-unknown-none-elf.tar.gz": "70b168b86fb960124e9b4ed510848f5420647dcb82d36cce887aacbb7bf2783e",
+    "dist/2024-02-04/rust-std-beta-riscv64gc-unknown-none-elf.tar.xz": "db3a0c4e36a182926360317694053b9ee7e24d6f77f3c15eb9ff79482b3d129a",
+    "dist/2024-02-04/rust-std-beta-riscv64imac-unknown-none-elf.tar.gz": "127cb67bac139a8621b87a475be07dda3fc92616f15068145ebebd7087230815",
+    "dist/2024-02-04/rust-std-beta-riscv64imac-unknown-none-elf.tar.xz": "07e2ca92ade33338a800f3b9c0b8aad2ddc1c699247a3144bd70b3f2d93e84ec",
+    "dist/2024-02-04/rust-std-beta-s390x-unknown-linux-gnu.tar.gz": "6fc83881b97579aeb2c2873f18a5e63ac06a4b94889e0054a8515e2f23b8b1c7",
+    "dist/2024-02-04/rust-std-beta-s390x-unknown-linux-gnu.tar.xz": "b85f994c59b82db877fb42e2e06ac193de136e8b362284d211c66607a7272328",
+    "dist/2024-02-04/rust-std-beta-sparc64-unknown-linux-gnu.tar.gz": "d3188ab7fc2cba5474cb6c1cb0edeffe20ab90beb05cb42e83c4eeaff3c66d9f",
+    "dist/2024-02-04/rust-std-beta-sparc64-unknown-linux-gnu.tar.xz": "3e40bcf0c16e96fa81d814d81631e99069026d8b27b10c905ed22218d5842cbe",
+    "dist/2024-02-04/rust-std-beta-sparcv9-sun-solaris.tar.gz": "cde8e5c30725da66f9c6d6c67283e2d55cb22c1b65c4a0ac8157e3b7c79ae567",
+    "dist/2024-02-04/rust-std-beta-sparcv9-sun-solaris.tar.xz": "4832c0e385467bb0c5276971d5ecf4bf0e77247e54f90480be635a6a4a43ddb6",
+    "dist/2024-02-04/rust-std-beta-thumbv6m-none-eabi.tar.gz": "5ee43f29701f44060770a8be635708ace9143eb77926f6a6c946a3e02c56bf92",
+    "dist/2024-02-04/rust-std-beta-thumbv6m-none-eabi.tar.xz": "0af4c3a0270c53648b88a915466b592ab6a29aa959a014748fa95b9f511140e8",
+    "dist/2024-02-04/rust-std-beta-thumbv7em-none-eabi.tar.gz": "e57337af619b9e2de45d5268944d9ba3ea7ef19d8413a3e13a72c9ce08fe252b",
+    "dist/2024-02-04/rust-std-beta-thumbv7em-none-eabi.tar.xz": "26bbe4aa8ea10b4dbdd21da2f62118d42adbb852bd01bedab9cff47d79ac3887",
+    "dist/2024-02-04/rust-std-beta-thumbv7em-none-eabihf.tar.gz": "ac22acf98402d2091d60e4d6e934ef474d0ca40882121d595f7a809fa575264a",
+    "dist/2024-02-04/rust-std-beta-thumbv7em-none-eabihf.tar.xz": "3f0623d888b00d6ef243888322f9ef1781927c304e1ebd93b0d68457e0a551db",
+    "dist/2024-02-04/rust-std-beta-thumbv7m-none-eabi.tar.gz": "c23866c57b3781b12fa372d8a1a98626be669dfc86eb568aeafc9bbefe5c2fd5",
+    "dist/2024-02-04/rust-std-beta-thumbv7m-none-eabi.tar.xz": "64d2e9a717e0d6dc1bcdb3ba76937ced9d941ed1aa367fd2ebc9d6056b527a26",
+    "dist/2024-02-04/rust-std-beta-thumbv7neon-linux-androideabi.tar.gz": "864689308f8f72faad3b1812dbb67de254f4f0acbbc28302665b29f8e6aec9c8",
+    "dist/2024-02-04/rust-std-beta-thumbv7neon-linux-androideabi.tar.xz": "737ca7c2c4f8a1ec87ab0819676926a7d13ee4c074359530e02fdaa11a51cace",
+    "dist/2024-02-04/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.gz": "68f0aee311b2fa12686249a4ace1f1f1fe254e4ee9aafbe6e7f429c98fd024c9",
+    "dist/2024-02-04/rust-std-beta-thumbv7neon-unknown-linux-gnueabihf.tar.xz": "cfe3bdbf666576340a7a6ba22422b88389356c21bccce60f31540a1a18095e74",
+    "dist/2024-02-04/rust-std-beta-thumbv8m.base-none-eabi.tar.gz": "bb0a27b78f4c006c5e9d04f7446433e13908837d947c8c73ede878219a189a52",
+    "dist/2024-02-04/rust-std-beta-thumbv8m.base-none-eabi.tar.xz": "271d1471e2ec7901582911bd341896e07d38ac7a762ee3000964cf8cc9f3d73e",
+    "dist/2024-02-04/rust-std-beta-thumbv8m.main-none-eabi.tar.gz": "e875ae5276bcf3bf112815ddcb8320d9b3e67f7d65ffda9bf194f54c49b55758",
+    "dist/2024-02-04/rust-std-beta-thumbv8m.main-none-eabi.tar.xz": "4f38da22bce7fdfd9cf0b0f24cce08b298af54dd2c20d8a6a10b888b66a5f120",
+    "dist/2024-02-04/rust-std-beta-thumbv8m.main-none-eabihf.tar.gz": "28ec4144e3ac2fd74fb5f59844b29623b6286173893d5b487157c7103d0e59b9",
+    "dist/2024-02-04/rust-std-beta-thumbv8m.main-none-eabihf.tar.xz": "c870d0ab781cffbf6bf7d0d0484b0a484eb4c4102d36f32d823b9c20c2886078",
+    "dist/2024-02-04/rust-std-beta-wasm32-unknown-emscripten.tar.gz": "23f8c320114c329109f081a868e5ec464d766883fe947538b26c31757b6305b9",
+    "dist/2024-02-04/rust-std-beta-wasm32-unknown-emscripten.tar.xz": "41c3cf36b6dab93202e792c4da186f5aef0ef5499d425a33ebafd1b4a7c5ff3f",
+    "dist/2024-02-04/rust-std-beta-wasm32-unknown-unknown.tar.gz": "09670117cb42829fcd871ed702652744d0599f715db8f1dd82ed462f01de87c0",
+    "dist/2024-02-04/rust-std-beta-wasm32-unknown-unknown.tar.xz": "5c04dc908e258dfce00306b6b6bdc5b5ee48031a6b5d602e7326e670f594fbd2",
+    "dist/2024-02-04/rust-std-beta-wasm32-wasi-preview1-threads.tar.gz": "09b5f40f1a449bb7cb6ef868bb3998f3ae4bd4f85ca594cca8b934166931a549",
+    "dist/2024-02-04/rust-std-beta-wasm32-wasi-preview1-threads.tar.xz": "b4de2d6ca31aafaa24871d15f4e0297064da72db884609223462232571df6ec2",
+    "dist/2024-02-04/rust-std-beta-wasm32-wasi.tar.gz": "194999685f52e9c489bd7e46cc1ab24fa2e37559a987d4fd90453b30b7e8b152",
+    "dist/2024-02-04/rust-std-beta-wasm32-wasi.tar.xz": "6f251f32b9959e7a602d6d9ddb89647970c79f129911084756550697c9e93893",
+    "dist/2024-02-04/rust-std-beta-x86_64-apple-darwin.tar.gz": "bc4f9b694c886df968db188f4687281d701f6fc4e19a1b59abaea247097dcd9d",
+    "dist/2024-02-04/rust-std-beta-x86_64-apple-darwin.tar.xz": "18530dddf369372f1f3543f8f7f34200c278cffbb2de148ec4016b07b96ae683",
+    "dist/2024-02-04/rust-std-beta-x86_64-apple-ios.tar.gz": "ac0ed15c9d62aaf8ae298def444cd5cd06a1701564fab564d4a4c767c294c1a1",
+    "dist/2024-02-04/rust-std-beta-x86_64-apple-ios.tar.xz": "57171af9b001f9b0ebd66c7643cb0a93e752320f188b6948b261abf27179360d",
+    "dist/2024-02-04/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.gz": "29efc21fac21062e5a0af8f2431be998cd949b12e1f73b569967e9aee68bcefa",
+    "dist/2024-02-04/rust-std-beta-x86_64-fortanix-unknown-sgx.tar.xz": "d1d290ac8ddf7ec133fe1de3e5307855a86dd5780a434091198294d18194869b",
+    "dist/2024-02-04/rust-std-beta-x86_64-linux-android.tar.gz": "1f3a99d4d9f9283e62d9922145b63bb6ca58744eca51d3ba28277b6ae2581fdf",
+    "dist/2024-02-04/rust-std-beta-x86_64-linux-android.tar.xz": "34f8d2ef07c40b34d8893f93f42d9f06bde8d56c146ec1b6518a497fd68e6ca0",
+    "dist/2024-02-04/rust-std-beta-x86_64-pc-solaris.tar.gz": "e15b87f78925ee15b3c71c6f3cdc0cff12dd06369be53402d7115300c07e316d",
+    "dist/2024-02-04/rust-std-beta-x86_64-pc-solaris.tar.xz": "4f5a353057ec31568f3403c01d30d1d3aa22721be942c61928634c5e10332ce0",
+    "dist/2024-02-04/rust-std-beta-x86_64-pc-windows-gnu.tar.gz": "898e9bacfd9fc7f34a7543066304f4f5dd3596ef37d4a3b3bac5524ffd6ef236",
+    "dist/2024-02-04/rust-std-beta-x86_64-pc-windows-gnu.tar.xz": "3a4cf02b56049bb998aea963651c0c26e8084bb4232c2efa8be14740836c4da1",
+    "dist/2024-02-04/rust-std-beta-x86_64-pc-windows-msvc.tar.gz": "3d2d2896d535374396e3cd5b71b4135baf5a5ae2aaecc591981127dcb7717555",
+    "dist/2024-02-04/rust-std-beta-x86_64-pc-windows-msvc.tar.xz": "2b3a4329cd34ae5d61f0ce8712e5e73cfa9e11a6b861f7e796a2055533f8e1a1",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-freebsd.tar.gz": "a89890d16282ba9c030e32c5904117be8317c69fce09611bf8ebff440d13a1fb",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-freebsd.tar.xz": "a02a5962c65cbe60667a45d5ad5ec28f1dc86d18344c619fba00f9afd96519e1",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-fuchsia.tar.gz": "1dc8c719ac47a37c47993b75e1b1280579504bb01bf3feb39b30a10b947b75ff",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-fuchsia.tar.xz": "106c9d4fd1072dfbacb67674a2b0753c9742fb87e83ff32cf3ad3ce1f8d94874",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-illumos.tar.gz": "a004aab7ce4f922afa7248af5fa17fd1966a9e79b472ae4ea9496e7915bbf0f3",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-illumos.tar.xz": "0f3df2ea274c6bf201617c5b385b0e7752077e6497a3dd49f45f2431e3f2af38",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-gnu.tar.gz": "b929350cb8aef37ac3a32f06c144cbd75884f60b26ec9316c1f675a472f1c522",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-gnu.tar.xz": "20fffbd0d4e5bb19a428c2c808aa47f6d7a285291df204fe73a45f7d3720c3a4",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-gnux32.tar.gz": "383746f4d90d7dbca5297928bf5705d50f974ac3c97fe4dadd6ec33b5aa65059",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-gnux32.tar.xz": "60372cc7f84c6727272360ae1fdc316376ec12f632365a8deb9420f953cece2f",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-musl.tar.gz": "2fb0649206c57187b216464d6db86cbb4385e061098348181d654976570f74c4",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-linux-musl.tar.xz": "6a22fa944f66afdc4af68d25f37b88f80dec10211e808965e0f9a41f7a5e18b6",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-netbsd.tar.gz": "3700739a966b4e9e12088518d22ff535065f666c6f8c74fc8384fb183f4e8fe5",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-netbsd.tar.xz": "b6561834aa28caad3b68248863834e8320ee43916488336f575a6860efb1a509",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-none.tar.gz": "7a56f666a6b42b666afc12555f3b82c0877c2c3beedba53037d8a66ea0ab2c8e",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-none.tar.xz": "3f8a61eb7a7015b639769d9cee9b78653b0efe4da1333b315a67982e88ed2f54",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-redox.tar.gz": "4b3aebbaced9a09de3d2b1d745d53feec2b927e0ae15ee822cc57b003f4cdb6b",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-redox.tar.xz": "69d286adaba6f18daf052156cf88e994bee40b3e8a9c467d51b3f7264e8c5882",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-uefi.tar.gz": "0dc258a276435d1a689d1067913573a4454d5b0e54e90304338f07b0cb6b7c68",
+    "dist/2024-02-04/rust-std-beta-x86_64-unknown-uefi.tar.xz": "ca131284758bfd1defac4e95b68dba9bdb496b2a1ed4312b05ce996308d870b1",
+    "dist/2024-02-04/rustc-beta-aarch64-apple-darwin.tar.gz": "f874ba6539750fc510fa67749f6a341c80497a0ea7ace5b8366849fb3a304973",
+    "dist/2024-02-04/rustc-beta-aarch64-apple-darwin.tar.xz": "8a1a9359e59c7057a39eeaaa6bbb180b61e00993d534b63b52ac447b31345886",
+    "dist/2024-02-04/rustc-beta-aarch64-pc-windows-msvc.tar.gz": "449e0a684783ba2ad04e4aa18761da9ee4144333426335b0503526d7d0c23f3e",
+    "dist/2024-02-04/rustc-beta-aarch64-pc-windows-msvc.tar.xz": "4075cbd97eceae6ba41a2862a6149f72c33ddd351c6cdf8e401de19b485ae3e2",
+    "dist/2024-02-04/rustc-beta-aarch64-unknown-linux-gnu.tar.gz": "99a1c8fcc434905b80086d276dbb162105d7803f8594a44b518245877320e387",
+    "dist/2024-02-04/rustc-beta-aarch64-unknown-linux-gnu.tar.xz": "32ab0d6814abbb16724ea6d7d422fea587fa8d4fb7e49d04c418e9f58c380464",
+    "dist/2024-02-04/rustc-beta-aarch64-unknown-linux-musl.tar.gz": "04dec9fdfa8429ed3b53aac9445a54a4a486d1c4439d91e3c5214c62207163c8",
+    "dist/2024-02-04/rustc-beta-aarch64-unknown-linux-musl.tar.xz": "797f8ed5112414d258de8b28f0d1d85661fa35ae0699ad89a868d7f16123e5e0",
+    "dist/2024-02-04/rustc-beta-arm-unknown-linux-gnueabi.tar.gz": "31c3ad00fd019cdda335630da3791633f28b79a84d847404e877efa1d963b700",
+    "dist/2024-02-04/rustc-beta-arm-unknown-linux-gnueabi.tar.xz": "265de8a5d1317fd686497ddcbd47adc96270b9318333296edbe57247907cea87",
+    "dist/2024-02-04/rustc-beta-arm-unknown-linux-gnueabihf.tar.gz": "080f20064ce64e26b35d15c0bcefd20edc37f0f4627eec997fefb99932635687",
+    "dist/2024-02-04/rustc-beta-arm-unknown-linux-gnueabihf.tar.xz": "aa144f7121a29087a6b6e057a646fa091ec7af5b48b2701c7bb514c698d510e4",
+    "dist/2024-02-04/rustc-beta-armv7-unknown-linux-gnueabihf.tar.gz": "bf1f0a9764e04d9d07702ba7563c93ec17ae527332d72b4e21d8de9bd176c4c5",
+    "dist/2024-02-04/rustc-beta-armv7-unknown-linux-gnueabihf.tar.xz": "17ed4d2cac212fcfbe1c75c482f195100ee2fabcdd85cedf78b5ea8f1355148b",
+    "dist/2024-02-04/rustc-beta-i686-pc-windows-gnu.tar.gz": "fa0e1ad64cf3b59682df001192c91c26edf1d41fda8f0fb3a6c535fa1597098f",
+    "dist/2024-02-04/rustc-beta-i686-pc-windows-gnu.tar.xz": "3f5eb74282649ed398d8a60bda4098ea8ec10b81a00cc48c65976f68d064ba6a",
+    "dist/2024-02-04/rustc-beta-i686-pc-windows-msvc.tar.gz": "188f1c8c1b38ece4b50db74422ab7d4b8dc40d5ee2f9a10ad2a797ea748f4ce0",
+    "dist/2024-02-04/rustc-beta-i686-pc-windows-msvc.tar.xz": "b9768ef55563ba4008b5886e6b20b7dfb81668452f264cf4cf9809e6fa3e1d84",
+    "dist/2024-02-04/rustc-beta-i686-unknown-linux-gnu.tar.gz": "c369728545e027cdaf9b92243f98979e66684d79159192ee7a22a62603905942",
+    "dist/2024-02-04/rustc-beta-i686-unknown-linux-gnu.tar.xz": "ec946c31d336a69912f6f0effa0986532dbdd915a1b268c419e5ba68365671fe",
+    "dist/2024-02-04/rustc-beta-loongarch64-unknown-linux-gnu.tar.gz": "f49cac3db11d02f6b197354b25e2181ae7afd13837df3bccca8cda135373ae6d",
+    "dist/2024-02-04/rustc-beta-loongarch64-unknown-linux-gnu.tar.xz": "b4ffc655994a64dd5644a30363e0518a2958337f187da7e4a9285658c899ab6b",
+    "dist/2024-02-04/rustc-beta-powerpc-unknown-linux-gnu.tar.gz": "b29c64744cc8154e1eb89ec525fbc92187b666d1f7d013523d0f7e6c089b5be9",
+    "dist/2024-02-04/rustc-beta-powerpc-unknown-linux-gnu.tar.xz": "5534dba963a2ae299f16b85c1fb76bfd62e94e4c9da16a97aaec26572b61f217",
+    "dist/2024-02-04/rustc-beta-powerpc64-unknown-linux-gnu.tar.gz": "a432e73044ffa25fb6c104a82156048519f79faa6e1845e5e0d5ef448d1d682d",
+    "dist/2024-02-04/rustc-beta-powerpc64-unknown-linux-gnu.tar.xz": "aa1688326584956677dd76c0e3620e34a3287c077b882b5b159e0d756cbf189b",
+    "dist/2024-02-04/rustc-beta-powerpc64le-unknown-linux-gnu.tar.gz": "8534f8087cbbf9f4f44f43cc8c276dba304aa0b5f9ea437cfa162d667aef1774",
+    "dist/2024-02-04/rustc-beta-powerpc64le-unknown-linux-gnu.tar.xz": "12bcba399fbff493b114bb4726a6b3fe32936a1f42134b1496b6ce44baea52dc",
+    "dist/2024-02-04/rustc-beta-riscv64gc-unknown-linux-gnu.tar.gz": "5ca25bc3c268c3df4de1740fd62f5dfb62482833be38180aa34bf220b9ec3021",
+    "dist/2024-02-04/rustc-beta-riscv64gc-unknown-linux-gnu.tar.xz": "e7187288ac175404c2a3e78776324e70c2a0d3b6fb673366eac881a48f11ab74",
+    "dist/2024-02-04/rustc-beta-s390x-unknown-linux-gnu.tar.gz": "31735567bd85a94325af81e5029c652c8b1b2e5824c4f65fa48f864aca65393e",
+    "dist/2024-02-04/rustc-beta-s390x-unknown-linux-gnu.tar.xz": "916afb19bb784d80093a372fa6316c72d2fa1aee3aa038554a3335ae3f62f773",
+    "dist/2024-02-04/rustc-beta-x86_64-apple-darwin.tar.gz": "d1445ab2c427e1e504521047c5e1e8d43b43dc4bb9dcf859e3d8b0110a6de257",
+    "dist/2024-02-04/rustc-beta-x86_64-apple-darwin.tar.xz": "cafb899caeec207a7e2842f03210b85d50d09f152468ab9ec1e53fa8c7511da1",
+    "dist/2024-02-04/rustc-beta-x86_64-pc-windows-gnu.tar.gz": "eab3692edecd9957cbd0e2f8fe148ee81600ddde9d07e7693859bd2943784b49",
+    "dist/2024-02-04/rustc-beta-x86_64-pc-windows-gnu.tar.xz": "4b711b2375c16990d9f22ca32baedf8b0d57073d914ea392028944a019a7e4cb",
+    "dist/2024-02-04/rustc-beta-x86_64-pc-windows-msvc.tar.gz": "80de1f677bbf1d1c51fcabe130b81dd97cc49fcacc96bc9dbda94da1acf4d504",
+    "dist/2024-02-04/rustc-beta-x86_64-pc-windows-msvc.tar.xz": "912e3ab500ed82ecca7688bbb7c5c40555cbb4d5ea9ec059a9287f69ca7241ab",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-freebsd.tar.gz": "632ba8e019403eddde89653cd4bf1864fd0b274603399371871cd1ded296d1d9",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-freebsd.tar.xz": "b5de56f1f686befd7d225c4fc0636132119a28e6ed22e56300347e8c8fd4388b",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-illumos.tar.gz": "f906f3492094d609d8d5fb5a563a8f2201dc21c65228c7d214a57ea795e8bca5",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-illumos.tar.xz": "4f29c6a41a993794dfdca0502c33ef77a3a888281c3b9e368f1befdfecc643e2",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-linux-gnu.tar.gz": "ce323665ebe9bc3d96e7016af21e18788e42e94c647ff1c08cdeb6ad9acc3b1c",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-linux-gnu.tar.xz": "6db29020afc7fb486f305e3508ee978c2ce44ce9b844ec6fe0102a16c798dc13",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-linux-musl.tar.gz": "b5b5dd243653e8f1073542774c918152eeb73020859dcc3229045b1980d50bae",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-linux-musl.tar.xz": "f8127a732817b1d5c091f7a508c3d5367b33e57ea6be023161be1bcc35b3b62d",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-netbsd.tar.gz": "73b19bc4dc2f44a04cae327ddc4740915bffb0a2182ff94438c614dce3b5ddf2",
+    "dist/2024-02-04/rustc-beta-x86_64-unknown-netbsd.tar.xz": "d72e53f0a99a897d5f36999957fee251d67030fbf711b1b8d554011ad0a7e559",
+    "dist/2024-02-04/rustc-nightly-aarch64-apple-darwin.tar.gz": "f81993a7d1c0677779a6a44ec1f475abb03e8c79ec493cb22ff194b0d6edfc2b",
+    "dist/2024-02-04/rustc-nightly-aarch64-apple-darwin.tar.xz": "a6247fae04e79529097f2ff5b9c8110ce4f015ba5f9503fbcd0c15c8ba84eb9e",
+    "dist/2024-02-04/rustc-nightly-aarch64-pc-windows-msvc.tar.gz": "012a0b1eff9a277c8b7dc01204346922f64099450269716dafe8c7d257bdc043",
+    "dist/2024-02-04/rustc-nightly-aarch64-pc-windows-msvc.tar.xz": "d16d3c5da39586678fa34932f597294277d1949ff57b99e67ce5b4dcfda9ffc6",
+    "dist/2024-02-04/rustc-nightly-aarch64-unknown-linux-gnu.tar.gz": "defca5334cffc68e2b79917455ac7e8e210870794f23189ac0a8fdab7cfd7364",
+    "dist/2024-02-04/rustc-nightly-aarch64-unknown-linux-gnu.tar.xz": "2c0af5b6a06fc2e539ad0774b95f021dfbd75730d900d13567ea8ee757f9ecb1",
+    "dist/2024-02-04/rustc-nightly-aarch64-unknown-linux-musl.tar.gz": "93bebac9baaf10f90b535a46f8a33abe55b2d468d7ec27ae53ac6ff31afe2833",
+    "dist/2024-02-04/rustc-nightly-aarch64-unknown-linux-musl.tar.xz": "937f84bf311714bccc88ef1e982e3261e04e5fc5419de098fbc65df15df3975c",
+    "dist/2024-02-04/rustc-nightly-arm-unknown-linux-gnueabi.tar.gz": "87d8a6dc5ad4103eea1cf5ee76858b4e78188302fbb6e0ac846f284b388f8e7a",
+    "dist/2024-02-04/rustc-nightly-arm-unknown-linux-gnueabi.tar.xz": "74878a2b70a1476588a5638b953711bd62c25027a9555d10e6fd4e5218a7d817",
+    "dist/2024-02-04/rustc-nightly-arm-unknown-linux-gnueabihf.tar.gz": "1fb50fa12f3c412e30df241ac6215a19bb600a04a1fb3332434f9c73bc7d2b74",
+    "dist/2024-02-04/rustc-nightly-arm-unknown-linux-gnueabihf.tar.xz": "85807b419b6f45493c60f3ab3f5d00fe7ffaca6366e6a0ec57227a30ffae2f22",
+    "dist/2024-02-04/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "63d233d9ac741f842c21762032ec4f0139a9b46cc8a4785bfc1b9ad6b586a128",
+    "dist/2024-02-04/rustc-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "199b00d4bb829f9688cbc9e8fa065d80ef4d20c1723c39f4b1a61ebfc544bc88",
+    "dist/2024-02-04/rustc-nightly-i686-pc-windows-gnu.tar.gz": "e66c39fbd427b6cfd027095110c954035e5a3d117b848c7cc072ca93f41bcbcb",
+    "dist/2024-02-04/rustc-nightly-i686-pc-windows-gnu.tar.xz": "9974067580a9d77f4722914c0d60dcb2e451cdb9c059514982bbf4721bd62ce5",
+    "dist/2024-02-04/rustc-nightly-i686-pc-windows-msvc.tar.gz": "e8189dd6c054dc1cba690a9805593d173de64009166b4542c30cd902cb82537a",
+    "dist/2024-02-04/rustc-nightly-i686-pc-windows-msvc.tar.xz": "5b9bc862dbf5bf00accf769fd70b9915c4a0faad7fc8ca648789aeefbb7f5ba6",
+    "dist/2024-02-04/rustc-nightly-i686-unknown-linux-gnu.tar.gz": "b0eebf6d08c9f730458f444afd15d405465adbf2dffe93bf9a042f28d11851e4",
+    "dist/2024-02-04/rustc-nightly-i686-unknown-linux-gnu.tar.xz": "248c1ecddaddee7dbdf3eabcb4a1b645005103b0ee0659d1bc71b5a59c1c9e4b",
+    "dist/2024-02-04/rustc-nightly-loongarch64-unknown-linux-gnu.tar.gz": "ea139b005b21e1baed7f79944af6cb2d8f24ac8c7bb009474e3a578250c6a65a",
+    "dist/2024-02-04/rustc-nightly-loongarch64-unknown-linux-gnu.tar.xz": "a3601a3bdc6bb998fe8a6a9ade212179addbbb684c0c47c46cb1c0632ab9fe41",
+    "dist/2024-02-04/rustc-nightly-powerpc-unknown-linux-gnu.tar.gz": "d64bffffff505541789ab0395187506c916f5b239ef3d0875dbb0f0c79c575e8",
+    "dist/2024-02-04/rustc-nightly-powerpc-unknown-linux-gnu.tar.xz": "5e1c528da9fa9818e5f581342346fa30b99d073dbce2241b4ebecfb7cf9674a7",
+    "dist/2024-02-04/rustc-nightly-powerpc64-unknown-linux-gnu.tar.gz": "0603be408a0bc368f669eb193c115bca687d7d6d1026fca6de5d317acb3597da",
+    "dist/2024-02-04/rustc-nightly-powerpc64-unknown-linux-gnu.tar.xz": "f61303e16f16c61f89e8dda24a5706808ef79f5fce7da8ee36b7aa3ec70f66f1",
+    "dist/2024-02-04/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "288e7b6b31aff284f06b14f1eb4ea0b2547aa019e8865d05710a64fe9993ddb2",
+    "dist/2024-02-04/rustc-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "885ef5324a55e78557b290bdf10501e27763daec209ad56f2e1840435a6e944b",
+    "dist/2024-02-04/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "3ccf5a674d290e1ede918516002d0b626828299edb7fe87dfc128cc9afa9770c",
+    "dist/2024-02-04/rustc-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "374a74c1b950f4be741f69d7f2670ac0d037a2a657361b94cd1c32892481edec",
+    "dist/2024-02-04/rustc-nightly-s390x-unknown-linux-gnu.tar.gz": "f21d304ea482d889319f285b5246f44461acdf6dabe288962065441bea82186b",
+    "dist/2024-02-04/rustc-nightly-s390x-unknown-linux-gnu.tar.xz": "d617d2b45de255f4588c2a9dc9686be554113b2683b8d8b149d1ce128da2dcc3",
+    "dist/2024-02-04/rustc-nightly-x86_64-apple-darwin.tar.gz": "26c662009b90638796c48a72de57e64e994491754112c5d6af0a65d24f4ef149",
+    "dist/2024-02-04/rustc-nightly-x86_64-apple-darwin.tar.xz": "811acb173348408b59b1ad63e0d2f8cbeccb91a86f13b432a6b70e8d6ebae937",
+    "dist/2024-02-04/rustc-nightly-x86_64-pc-windows-gnu.tar.gz": "3cd84e215365e8eba1aec1c6ed630e8899b1dcb36d04d52f1fbb713150eb60cd",
+    "dist/2024-02-04/rustc-nightly-x86_64-pc-windows-gnu.tar.xz": "454f0b75e6dd0bd893413dc7e2f36170d3af041e1e2b7d4792cc61f7cd7f27e2",
+    "dist/2024-02-04/rustc-nightly-x86_64-pc-windows-msvc.tar.gz": "512a0922ee16c4d5264b7ea398788651d04910dcdb3edd87bd8fc3914855c29c",
+    "dist/2024-02-04/rustc-nightly-x86_64-pc-windows-msvc.tar.xz": "e5a43c30c0016728aaff405ef3e28eefd8b60eb878fc31a5038aa056ae8cfb1f",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-freebsd.tar.gz": "0330724ffe7c0d4b3ed38514c303b1cbed3deb0e074e8d36f7de96c469c0c51d",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-freebsd.tar.xz": "5159bb4b9e32f64ed4712ab52dcc373e4838cec0f8e5bc16b281481a828dc84e",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-illumos.tar.gz": "d8bdb12e09d76f4b4ebe9f089a6bc11f501e994ef23aefe7574b5c5a583fd2fc",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-illumos.tar.xz": "301584763ea946532eca1e5be8ff7b7587ac9066c8f047f90598158e1ae6f5cf",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-linux-gnu.tar.gz": "3f4d36a06c74d62bb097e4b94b4ab1caf3d8d63650e0e4ef038748dab13c4413",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-linux-gnu.tar.xz": "33446798bf2f60451e31376286da2ad62372ef5ec048453900f6e6b3c4f0f0ee",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-linux-musl.tar.gz": "9a1fc786d418a927a63ceae0999e641767de5cc8821fc57dbe0546f495d21600",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-linux-musl.tar.xz": "0a36838259d73d577126cdee909b6446d62730d0d13655442312fca9cd13ce84",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-netbsd.tar.gz": "30e91ca5a0389898d9eea8a063b52dc4dd5e7f8cafba1024fbbf1d80ab28c590",
+    "dist/2024-02-04/rustc-nightly-x86_64-unknown-netbsd.tar.xz": "49238b11b1626dcfc8bebf02912935922585bfdce777c8eb7bf5abfabe664af0",
+    "dist/2024-02-04/rustfmt-nightly-aarch64-apple-darwin.tar.gz": "4e7d77d6a66ff3bf1de608913429e78a87ff80d8260e078d7e866a09b6ed74cc",
+    "dist/2024-02-04/rustfmt-nightly-aarch64-apple-darwin.tar.xz": "ebb64953e7919ff371b1625e48cd7c9063fc7fc72f085603831ed7a1eef371d3",
+    "dist/2024-02-04/rustfmt-nightly-aarch64-pc-windows-msvc.tar.gz": "44bb652d0268e03bc333ccc90f96107e249ee3d96a688aac1f3a27161c62a176",
+    "dist/2024-02-04/rustfmt-nightly-aarch64-pc-windows-msvc.tar.xz": "e272d2633828e00ebf0a1708b807fa958cac2673b162637c4983a40f191574e7",
+    "dist/2024-02-04/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz": "aa9b56b48fda4844f56bd7a0073c91b5aa79215f61444346e9849036ba003252",
+    "dist/2024-02-04/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz": "b23367c99e79d2db72b16d9d77addd3790ddf0889987beb24c917e4e54bcf511",
+    "dist/2024-02-04/rustfmt-nightly-aarch64-unknown-linux-musl.tar.gz": "c001dba171255113d25c2e2743ca2b4cb36aa0a628da333911b92474ae8e6603",
+    "dist/2024-02-04/rustfmt-nightly-aarch64-unknown-linux-musl.tar.xz": "14a2b8a352b1fc0c6c993c5a51cf4d23ed50b6b14b092f78917808861dc4ac49",
+    "dist/2024-02-04/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.gz": "ec2e8f55671b1d9643d338530263feb47f99d81ff7c862ac46ad32b8459b6435",
+    "dist/2024-02-04/rustfmt-nightly-arm-unknown-linux-gnueabi.tar.xz": "10b957fc066da91fa81eeeca66e2f7c97c7e7fc9d496471fd22b086a9e2bb62e",
+    "dist/2024-02-04/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.gz": "1dd859841cea9ac9d09a1521c57ddbe042bdc693c7df60ff34c876a8faca3745",
+    "dist/2024-02-04/rustfmt-nightly-arm-unknown-linux-gnueabihf.tar.xz": "b11ca576f29df7c81496c4b379435853a0bfee8ff838d2c57e1e3cded6f889eb",
+    "dist/2024-02-04/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.gz": "e0c53737686587010f4fd299430a0d48e47ad0f3d12e29a5d6810dceabd09b09",
+    "dist/2024-02-04/rustfmt-nightly-armv7-unknown-linux-gnueabihf.tar.xz": "f70dc356985081a43f19c2cc6e599f2967d9c0a60b2d9be0a3939a04a88b768a",
+    "dist/2024-02-04/rustfmt-nightly-i686-pc-windows-gnu.tar.gz": "159c4a6ebbce05142bf6e844c4e6cfc9a90eb298f581db7521ea5fb1fd303731",
+    "dist/2024-02-04/rustfmt-nightly-i686-pc-windows-gnu.tar.xz": "8cb69a4ff1207c0b7944dd71e1af666e12be5c8ec0d0ec244b2e4d9b99535f29",
+    "dist/2024-02-04/rustfmt-nightly-i686-pc-windows-msvc.tar.gz": "0eb4218c6d271c194282ca11af2436e2ed2e51ee3b62725a04a995afb3bc6ff9",
+    "dist/2024-02-04/rustfmt-nightly-i686-pc-windows-msvc.tar.xz": "2f9e4d03968cf07b950d188135d231d1183d92520c76a4ded3973acb374bdefc",
+    "dist/2024-02-04/rustfmt-nightly-i686-unknown-linux-gnu.tar.gz": "b6648b637564ffe5cf79da7c7eb73df377a2d0e0e0c66a05806af4fc87f61afa",
+    "dist/2024-02-04/rustfmt-nightly-i686-unknown-linux-gnu.tar.xz": "09e2aae1c73f874ce4dbdb84d532264cc21d99444e0b7b1e9239a002fe0c2466",
+    "dist/2024-02-04/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.gz": "87bfeb0da3af4ad9f341482325b81d13691e749b73627eabe7c73ac5bcd126e3",
+    "dist/2024-02-04/rustfmt-nightly-loongarch64-unknown-linux-gnu.tar.xz": "2bf074d90957c17e3d8962dd8ab68d0a76f4deaf86f1104cce56d2748fc21b3a",
+    "dist/2024-02-04/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.gz": "7fe5ee7ce30a1fbe5c5c0f20ef311f5840eebc9466e7c4bb2082a12bad2d987c",
+    "dist/2024-02-04/rustfmt-nightly-powerpc-unknown-linux-gnu.tar.xz": "43c3d64ed01e56c1961dbcde4d9c2c14a799d141d6c00ac72500ac84aafaf696",
+    "dist/2024-02-04/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.gz": "d6a54980ef61acb4f2422f0f621a6168055df95720fd864b58748884606e8a6b",
+    "dist/2024-02-04/rustfmt-nightly-powerpc64-unknown-linux-gnu.tar.xz": "d0d9fa1a65ef6dcf0d1fa1496d1682ca627cb978a8bf4a68ab3f27060daa37ed",
+    "dist/2024-02-04/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.gz": "fcd0539279be6ee5f2ed11f1ae0879596a29804d2415398a016b26aa1683f08a",
+    "dist/2024-02-04/rustfmt-nightly-powerpc64le-unknown-linux-gnu.tar.xz": "cfceea6563230c64b4e77110e98dc41208c6d50b3d4bce3133abd7f66db5ce29",
+    "dist/2024-02-04/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.gz": "6559653ef0a9b2d52baa94f6fd14433769b3001401daac03536ad0d1528418c1",
+    "dist/2024-02-04/rustfmt-nightly-riscv64gc-unknown-linux-gnu.tar.xz": "ac1c4f99a801e853c175735338a5485de2ad21ff633da75ced8b11ccd86ecd68",
+    "dist/2024-02-04/rustfmt-nightly-s390x-unknown-linux-gnu.tar.gz": "33835f14d65e2c21c1b69a45c70c89939a37b4d5b07660ef2acbba033c7bc8a1",
+    "dist/2024-02-04/rustfmt-nightly-s390x-unknown-linux-gnu.tar.xz": "46b8eb78bc1842b66e14e1995359cd85349ad2fd30a5b5c3a369de346dad8fa1",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-apple-darwin.tar.gz": "d7f0bb3f2e4d6cd6c68817cd99ef7cdd95ca274e86866edb9b76bfad071ccf37",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-apple-darwin.tar.xz": "7d86a0aeba42a5571b01ca7008c38854e17c067c53794c34d18ebc1cad536ae8",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-pc-windows-gnu.tar.gz": "5b788121f69bc0e16dabb014d7efaef4855d20016d2d710e6bf0e35dfc16d5b0",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-pc-windows-gnu.tar.xz": "b4b4ad7ecd280001aff71cf264f465e47effe52260c95fb23c884ab5fe4d51a8",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-pc-windows-msvc.tar.gz": "6075688bb91902af0c114fe9619a0102f57641bf88b8902eb950f9d324bf5a25",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-pc-windows-msvc.tar.xz": "908068a7088b20c1dc52eaefb9aa4314233536c40520b491e55a555283b243ce",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz": "5a9af3515b1b142127a9686b4f41d4c8050a496e0387a2a2703fe092bffaeb68",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz": "6796dbdeadd39bc66686bbdf9966fc488684543f806c25315c3a682c4c989c58",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-illumos.tar.gz": "4f763f33318529e1d400d2058b8ff8de6d29e37de0744a8e0ae17ae677465c81",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-illumos.tar.xz": "18aa04c9e8d00593f11b5e593a64875197e3db7de752215882d247a39c71ef0d",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz": "5be7c353d1e1f8445936f1572b5d99ca190a914c71341bb855048c5003c0cda2",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz": "1342bf737bba2e9787203da78d859f40739af4c57e9ec5bc0e07966e91388813",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-linux-musl.tar.gz": "0776b76ae5338f186f631a1f0e6f755d03612892399d96f3c2d9c59ba9f094c3",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-linux-musl.tar.xz": "36d491cc2eb35250536d3b053d180835c8041d9f6ed96f243c04e9644d040c96",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-netbsd.tar.gz": "185e2dee21941bc4c3e8edcf5f12d334b2c339f3f388f182a8ae519928e907e4",
+    "dist/2024-02-04/rustfmt-nightly-x86_64-unknown-netbsd.tar.xz": "d770b13ad43852d6e91bea1747b6e82b1cddc716307f8df4dd95941df76a1355"
   }
 }
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 1ef8cf7de3c..808fb0c07ea 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -83,6 +83,7 @@ static TARGETS: &[&str] = &[
     "armebv7r-none-eabihf",
     "armv7r-none-eabi",
     "armv7r-none-eabihf",
+    "armv8r-none-eabihf",
     "armv7s-apple-ios",
     "bpfeb-unknown-none",
     "bpfel-unknown-none",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject cdf84b69d0416c57ac9dc3459af80dfb4883d27
+Subproject ccc84ccec4b7340eb916aefda1cb3e2fe17d8e7
diff --git a/src/tools/clippy/.github/driver.sh b/src/tools/clippy/.github/driver.sh
index c05c6ecc115..40a2aad0f53 100644..100755
--- a/src/tools/clippy/.github/driver.sh
+++ b/src/tools/clippy/.github/driver.sh
@@ -11,9 +11,16 @@ if [[ ${OS} == "Windows" ]]; then
 else
 	desired_sysroot=/tmp
 fi
+# Set --sysroot in command line
 sysroot=$(./target/debug/clippy-driver --sysroot $desired_sysroot --print sysroot)
 test "$sysroot" = $desired_sysroot
 
+# Set --sysroot in arg_file.txt and pass @arg_file.txt to command line
+echo "--sysroot=$desired_sysroot" > arg_file.txt
+sysroot=$(./target/debug/clippy-driver @arg_file.txt --print sysroot)
+test "$sysroot" = $desired_sysroot
+
+# Setting SYSROOT in command line
 sysroot=$(SYSROOT=$desired_sysroot ./target/debug/clippy-driver --print sysroot)
 test "$sysroot" = $desired_sysroot
 
@@ -24,6 +31,14 @@ test "$sysroot" = $desired_sysroot
     SYSROOT=/tmp RUSTFLAGS="--sysroot=$(rustc --print sysroot)" ../target/debug/cargo-clippy clippy --verbose
 )
 
+# Check that the --sysroot argument is only passed once via arg_file.txt (SYSROOT is ignored)
+(  
+    echo "fn main() {}" > target/driver_test.rs
+    echo "--sysroot="$(./target/debug/clippy-driver --print sysroot)"" > arg_file.txt
+    echo "--verbose" >> arg_file.txt
+    SYSROOT=/tmp ./target/debug/clippy-driver @arg_file.txt ./target/driver_test.rs
+)
+
 # Make sure this isn't set - clippy-driver should cope without it
 unset CARGO_MANIFEST_DIR
 
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 5fa45ceeb39..9b853567219 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,11 +6,65 @@ document.
 
 ## Unreleased / Beta / In Rust Nightly
 
-[09ac14c9...master](https://github.com/rust-lang/rust-clippy/compare/09ac14c9...master)
+[a859e5cc...master](https://github.com/rust-lang/rust-clippy/compare/a859e5cc...master)
+
+## Rust 1.76
+
+Current stable, released 2024-02-08
+
+[View all 85 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-11-02T20%3A23%3A40Z..2023-12-16T13%3A11%3A08Z+base%3Amaster)
+
+### New Lints
+
+- [`infinite_loop`]
+  [#11829](https://github.com/rust-lang/rust-clippy/pull/11829)
+- [`ineffective_open_options`]
+  [#11902](https://github.com/rust-lang/rust-clippy/pull/11902)
+- [`uninhabited_references`]
+  [#11878](https://github.com/rust-lang/rust-clippy/pull/11878)
+- [`repeat_vec_with_capacity`]
+  [#11597](https://github.com/rust-lang/rust-clippy/pull/11597)
+- [`test_attr_in_doctest`]
+  [#11872](https://github.com/rust-lang/rust-clippy/pull/11872)
+- [`option_map_or_err_ok`]
+  [#11864](https://github.com/rust-lang/rust-clippy/pull/11864)
+- [`join_absolute_paths`]
+  [#11453](https://github.com/rust-lang/rust-clippy/pull/11453)
+- [`impl_hash_borrow_with_str_and_bytes`]
+  [#11781](https://github.com/rust-lang/rust-clippy/pull/11781)
+- [`iter_over_hash_type`]
+  [#11791](https://github.com/rust-lang/rust-clippy/pull/11791)
+
+### Moves and Deprecations
+
+- Renamed `blocks_in_if_conditions` to [`blocks_in_conditions`]
+  [#11853](https://github.com/rust-lang/rust-clippy/pull/11853)
+- Moved [`implied_bounds_in_impls`] to `complexity` (Now warn-by-default)
+  [#11867](https://github.com/rust-lang/rust-clippy/pull/11867)
+- Moved [`if_same_then_else`] to `style` (Now warn-by-default)
+  [#11809](https://github.com/rust-lang/rust-clippy/pull/11809)
+
+### Enhancements
+
+- [`missing_safety_doc`], [`unnecessary_safety_doc`], [`missing_panics_doc`], [`missing_errors_doc`]:
+  Added the [`check-private-items`] configuration to enable lints on private items
+  [#11842](https://github.com/rust-lang/rust-clippy/pull/11842)
+
+### ICE Fixes
+
+- [`impl_trait_in_params`]: No longer crashes when a function has generics but no function parameters
+  [#11804](https://github.com/rust-lang/rust-clippy/pull/11804)
+- [`unused_enumerate_index`]: No longer crashes on empty tuples
+  [#11756](https://github.com/rust-lang/rust-clippy/pull/11756)
+
+### Others
+
+- Clippy now respects the `CARGO` environment value
+  [#11944](https://github.com/rust-lang/rust-clippy/pull/11944)
 
 ## Rust 1.75
 
-Current stable, released 2023-12-28
+Released 2023-12-28
 
 [View all 69 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-09-25T11%3A47%3A47Z..2023-11-02T16%3A41%3A59Z+base%3Amaster)
 
@@ -5198,6 +5252,7 @@ Released 2018-09-13
 [`implied_bounds_in_impls`]: https://rust-lang.github.io/rust-clippy/master/index.html#implied_bounds_in_impls
 [`impossible_comparisons`]: https://rust-lang.github.io/rust-clippy/master/index.html#impossible_comparisons
 [`imprecise_flops`]: https://rust-lang.github.io/rust-clippy/master/index.html#imprecise_flops
+[`incompatible_msrv`]: https://rust-lang.github.io/rust-clippy/master/index.html#incompatible_msrv
 [`inconsistent_digit_grouping`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_digit_grouping
 [`inconsistent_struct_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#inconsistent_struct_constructor
 [`incorrect_clone_impl_on_copy_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#incorrect_clone_impl_on_copy_type
@@ -5276,6 +5331,7 @@ Released 2018-09-13
 [`let_with_type_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_with_type_underscore
 [`lines_filter_map_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#lines_filter_map_ok
 [`linkedlist`]: https://rust-lang.github.io/rust-clippy/master/index.html#linkedlist
+[`lint_groups_priority`]: https://rust-lang.github.io/rust-clippy/master/index.html#lint_groups_priority
 [`little_endian_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#little_endian_bytes
 [`logic_bug`]: https://rust-lang.github.io/rust-clippy/master/index.html#logic_bug
 [`lossy_float_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#lossy_float_literal
@@ -5284,6 +5340,7 @@ Released 2018-09-13
 [`manual_assert`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_assert
 [`manual_async_fn`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_async_fn
 [`manual_bits`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits
+[`manual_c_str_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals
 [`manual_clamp`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp
 [`manual_filter`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter
 [`manual_filter_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_filter_map
@@ -5523,6 +5580,7 @@ Released 2018-09-13
 [`redundant_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_slicing
 [`redundant_static_lifetimes`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
 [`redundant_type_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_type_annotations
+[`ref_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_as_ptr
 [`ref_binding_to_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_binding_to_reference
 [`ref_in_deref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_in_deref
 [`ref_option_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_option_ref
@@ -5622,6 +5680,7 @@ Released 2018-09-13
 [`to_digit_is_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some
 [`to_string_in_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_display
 [`to_string_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_in_format_args
+[`to_string_trait_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#to_string_trait_impl
 [`todo`]: https://rust-lang.github.io/rust-clippy/master/index.html#todo
 [`too_many_arguments`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_arguments
 [`too_many_lines`]: https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines
@@ -5677,6 +5736,7 @@ Released 2018-09-13
 [`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
 [`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation
 [`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings
+[`unnecessary_result_map_or_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_result_map_or_else
 [`unnecessary_safety_comment`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_comment
 [`unnecessary_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_safety_doc
 [`unnecessary_self_imports`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_self_imports
@@ -5819,4 +5879,6 @@ Released 2018-09-13
 [`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
+[`allow-comparison-to-zero`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-comparison-to-zero
+[`allowed-wildcard-imports`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-wildcard-imports
 <!-- end autogenerated links to configuration documentation -->
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index eda20531e40..321424880d1 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy"
-version = "0.1.77"
+version = "0.1.78"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 7f7aff92bf1..f2357e2b5de 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -151,6 +151,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold)
 * [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one)
 * [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map)
+* [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals)
 
 
 ## `cognitive-complexity-threshold`
@@ -828,3 +829,35 @@ exported visibility, or whether they are marked as "pub".
 * [`pub_underscore_fields`](https://rust-lang.github.io/rust-clippy/master/index.html#pub_underscore_fields)
 
 
+## `allow-comparison-to-zero`
+Don't lint when comparing the result of a modulo operation to zero.
+
+**Default Value:** `true`
+
+---
+**Affected lints:**
+* [`modulo_arithmetic`](https://rust-lang.github.io/rust-clippy/master/index.html#modulo_arithmetic)
+
+
+## `allowed-wildcard-imports`
+List of path segments allowed to have wildcard imports.
+
+#### Example
+
+```toml
+allowed-wildcard-imports = [ "utils", "common" ]
+```
+
+#### Noteworthy
+
+1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.
+2. Paths with any segment that containing the word 'prelude'
+are already allowed by default.
+
+**Default Value:** `[]`
+
+---
+**Affected lints:**
+* [`wildcard_imports`](https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports)
+
+
diff --git a/src/tools/clippy/clippy_config/Cargo.toml b/src/tools/clippy/clippy_config/Cargo.toml
index 74b8e5eaa1c..2edc5ed592c 100644
--- a/src/tools/clippy/clippy_config/Cargo.toml
+++ b/src/tools/clippy/clippy_config/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_config"
-version = "0.1.77"
+version = "0.1.78"
 edition = "2021"
 
 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 4e9ddbf8259..9741b94d504 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -260,7 +260,7 @@ define_Conf! {
     ///
     /// Suppress lints whenever the suggested change would cause breakage for other crates.
     (avoid_breaking_exported_api: bool = true),
-    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP.
+    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS.
     ///
     /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
     #[default_text = ""]
@@ -567,6 +567,26 @@ define_Conf! {
     /// 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::PubliclyExported),
+    /// Lint: MODULO_ARITHMETIC.
+    ///
+    /// Don't lint when comparing the result of a modulo operation to zero.
+    (allow_comparison_to_zero: bool = true),
+    /// Lint: WILDCARD_IMPORTS.
+    ///
+    /// List of path segments allowed to have wildcard imports.
+    ///
+    /// #### Example
+    ///
+    /// ```toml
+    /// allowed-wildcard-imports = [ "utils", "common" ]
+    /// ```
+    ///
+    /// #### Noteworthy
+    ///
+    /// 1. This configuration has no effects if used with `warn_on_all_wildcard_imports = true`.
+    /// 2. Paths with any segment that containing the word 'prelude'
+    /// are already allowed by default.
+    (allowed_wildcard_imports: FxHashSet<String> = FxHashSet::default()),
 }
 
 /// Search for the configuration file.
diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs
index 533e375a310..5449feed090 100644
--- a/src/tools/clippy/clippy_config/src/lib.rs
+++ b/src/tools/clippy/clippy_config/src/lib.rs
@@ -4,7 +4,9 @@
 #![allow(
     clippy::must_use_candidate,
     clippy::missing_panics_doc,
-    rustc::untranslatable_diagnostic_trivial
+    rustc::diagnostic_outside_of_impl,
+    rustc::untranslatable_diagnostic,
+    rustc::untranslatable_diagnostic_trivial,
 )]
 
 extern crate rustc_ast;
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs
index 72d5b9aff28..f4389db627d 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_config/src/msrvs.rs
@@ -3,6 +3,7 @@ use rustc_semver::RustcVersion;
 use rustc_session::Session;
 use rustc_span::{sym, Symbol};
 use serde::Deserialize;
+use std::fmt;
 
 macro_rules! msrv_aliases {
     ($($major:literal,$minor:literal,$patch:literal {
@@ -16,6 +17,8 @@ macro_rules! msrv_aliases {
 
 // names may refer to stabilized feature flags or library items
 msrv_aliases! {
+    1,77,0 { C_STR_LITERALS }
+    1,76,0 { PTR_FROM_REF }
     1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }
     1,70,0 { OPTION_RESULT_IS_VARIANT_AND, BINARY_HEAP_RETAIN }
     1,68,0 { PATH_MAIN_SEPARATOR_STR }
@@ -58,6 +61,16 @@ pub struct Msrv {
     stack: Vec<RustcVersion>,
 }
 
+impl fmt::Display for Msrv {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        if let Some(msrv) = self.current() {
+            write!(f, "{msrv}")
+        } else {
+            f.write_str("1.0.0")
+        }
+    }
+}
+
 impl<'de> Deserialize<'de> for Msrv {
     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
     where
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index 416e9a680dd..6e6e315bb65 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_lints"
-version = "0.1.77"
+version = "0.1.78"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
diff --git a/src/tools/clippy/clippy_lints/src/absolute_paths.rs b/src/tools/clippy/clippy_lints/src/absolute_paths.rs
index 3822b83b4bc..8ba661afeeb 100644
--- a/src/tools/clippy/clippy_lints/src/absolute_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/absolute_paths.rs
@@ -62,7 +62,7 @@ impl LateLintPass<'_> for AbsolutePaths {
         } = self;
 
         if !path.span.from_expansion()
-            && let Some(node) = cx.tcx.opt_hir_node(hir_id)
+            && let node = cx.tcx.hir_node(hir_id)
             && !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(_, _)))
             && let [first, rest @ ..] = path.segments
             // Handle `::std`
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index e11f83f2260..2d1c250ace9 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -499,6 +499,7 @@ struct NotSimplificationVisitor<'a, 'tcx> {
 impl<'a, 'tcx> Visitor<'tcx> for NotSimplificationVisitor<'a, 'tcx> {
     fn visit_expr(&mut self, expr: &'tcx Expr<'_>) {
         if let ExprKind::Unary(UnOp::Not, inner) = &expr.kind
+            && !expr.span.from_expansion()
             && !inner.span.from_expansion()
             && let Some(suggestion) = simplify_not(self.cx, inner)
             && self.cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow
diff --git a/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs b/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs
new file mode 100644
index 00000000000..a39b972b56a
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs
@@ -0,0 +1,168 @@
+use super::LINT_GROUPS_PRIORITY;
+use clippy_utils::diagnostics::span_lint_and_then;
+use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Applicability;
+use rustc_lint::{unerased_lint_store, LateContext};
+use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
+use serde::{Deserialize, Serialize};
+use std::collections::BTreeMap;
+use std::ops::Range;
+use std::path::Path;
+use toml::Spanned;
+
+#[derive(Deserialize, Serialize, Debug)]
+struct LintConfigTable {
+    level: String,
+    priority: Option<i64>,
+}
+
+#[derive(Deserialize, Debug)]
+#[serde(untagged)]
+enum LintConfig {
+    Level(String),
+    Table(LintConfigTable),
+}
+
+impl LintConfig {
+    fn level(&self) -> &str {
+        match self {
+            LintConfig::Level(level) => level,
+            LintConfig::Table(table) => &table.level,
+        }
+    }
+
+    fn priority(&self) -> i64 {
+        match self {
+            LintConfig::Level(_) => 0,
+            LintConfig::Table(table) => table.priority.unwrap_or(0),
+        }
+    }
+
+    fn is_implicit(&self) -> bool {
+        if let LintConfig::Table(table) = self {
+            table.priority.is_none()
+        } else {
+            true
+        }
+    }
+}
+
+type LintTable = BTreeMap<Spanned<String>, Spanned<LintConfig>>;
+
+#[derive(Deserialize, Debug)]
+struct Lints {
+    #[serde(default)]
+    rust: LintTable,
+    #[serde(default)]
+    clippy: LintTable,
+}
+
+#[derive(Deserialize, Debug)]
+struct CargoToml {
+    lints: Lints,
+}
+
+#[derive(Default, Debug)]
+struct LintsAndGroups {
+    lints: Vec<Spanned<String>>,
+    groups: Vec<(Spanned<String>, Spanned<LintConfig>)>,
+}
+
+fn toml_span(range: Range<usize>, file: &SourceFile) -> Span {
+    Span::new(
+        file.start_pos + BytePos::from_usize(range.start),
+        file.start_pos + BytePos::from_usize(range.end),
+        SyntaxContext::root(),
+        None,
+    )
+}
+
+fn check_table(cx: &LateContext<'_>, table: LintTable, groups: &FxHashSet<&str>, file: &SourceFile) {
+    let mut by_priority = BTreeMap::<_, LintsAndGroups>::new();
+    for (name, config) in table {
+        let lints_and_groups = by_priority.entry(config.as_ref().priority()).or_default();
+        if groups.contains(name.get_ref().as_str()) {
+            lints_and_groups.groups.push((name, config));
+        } else {
+            lints_and_groups.lints.push(name);
+        }
+    }
+    let low_priority = by_priority
+        .iter()
+        .find(|(_, lints_and_groups)| !lints_and_groups.lints.is_empty())
+        .map_or(-1, |(&lowest_lint_priority, _)| lowest_lint_priority - 1);
+
+    for (priority, LintsAndGroups { lints, groups }) in by_priority {
+        let Some(last_lint_alphabetically) = lints.last() else {
+            continue;
+        };
+
+        for (group, config) in groups {
+            span_lint_and_then(
+                cx,
+                LINT_GROUPS_PRIORITY,
+                toml_span(group.span(), file),
+                &format!(
+                    "lint group `{}` has the same priority ({priority}) as a lint",
+                    group.as_ref()
+                ),
+                |diag| {
+                    let config_span = toml_span(config.span(), file);
+                    if config.as_ref().is_implicit() {
+                        diag.span_label(config_span, "has an implicit priority of 0");
+                    }
+                    // add the label to next lint after this group that has the same priority
+                    let lint = lints
+                        .iter()
+                        .filter(|lint| lint.span().start > group.span().start)
+                        .min_by_key(|lint| lint.span().start)
+                        .unwrap_or(last_lint_alphabetically);
+                    diag.span_label(toml_span(lint.span(), file), "has the same priority as this lint");
+                    diag.note("the order of the lints in the table is ignored by Cargo");
+                    let mut suggestion = String::new();
+                    Serialize::serialize(
+                        &LintConfigTable {
+                            level: config.as_ref().level().into(),
+                            priority: Some(low_priority),
+                        },
+                        toml::ser::ValueSerializer::new(&mut suggestion),
+                    )
+                    .unwrap();
+                    diag.span_suggestion_verbose(
+                        config_span,
+                        format!(
+                            "to have lints override the group set `{}` to a lower priority",
+                            group.as_ref()
+                        ),
+                        suggestion,
+                        Applicability::MaybeIncorrect,
+                    );
+                },
+            );
+        }
+    }
+}
+
+pub fn check(cx: &LateContext<'_>) {
+    if let Ok(file) = cx.tcx.sess.source_map().load_file(Path::new("Cargo.toml"))
+        && let Some(src) = file.src.as_deref()
+        && let Ok(cargo_toml) = toml::from_str::<CargoToml>(src)
+    {
+        let mut rustc_groups = FxHashSet::default();
+        let mut clippy_groups = FxHashSet::default();
+        for (group, ..) in unerased_lint_store(cx.tcx.sess).get_lint_groups() {
+            match group.split_once("::") {
+                None => {
+                    rustc_groups.insert(group);
+                },
+                Some(("clippy", group)) => {
+                    clippy_groups.insert(group);
+                },
+                _ => {},
+            }
+        }
+
+        check_table(cx, cargo_toml.lints.rust, &rustc_groups, &file);
+        check_table(cx, cargo_toml.lints.clippy, &clippy_groups, &file);
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/cargo/mod.rs b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
index d8107f61f37..95d5449781b 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
@@ -1,5 +1,6 @@
 mod common_metadata;
 mod feature_name;
+mod lint_groups_priority;
 mod multiple_crate_versions;
 mod wildcard_dependencies;
 
@@ -165,6 +166,43 @@ declare_clippy_lint! {
     "wildcard dependencies being used"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for lint groups with the same priority as lints in the `Cargo.toml`
+    /// [`[lints]` table](https://doc.rust-lang.org/cargo/reference/manifest.html#the-lints-section).
+    ///
+    /// This lint will be removed once [cargo#12918](https://github.com/rust-lang/cargo/issues/12918)
+    /// is resolved.
+    ///
+    /// ### Why is this bad?
+    /// The order of lints in the `[lints]` is ignored, to have a lint override a group the
+    /// `priority` field needs to be used, otherwise the sort order is undefined.
+    ///
+    /// ### Known problems
+    /// Does not check lints inherited using `lints.workspace = true`
+    ///
+    /// ### Example
+    /// ```toml
+    /// # Passed as `--allow=clippy::similar_names --warn=clippy::pedantic`
+    /// # which results in `similar_names` being `warn`
+    /// [lints.clippy]
+    /// pedantic = "warn"
+    /// similar_names = "allow"
+    /// ```
+    /// Use instead:
+    /// ```toml
+    /// # Passed as `--warn=clippy::pedantic --allow=clippy::similar_names`
+    /// # which results in `similar_names` being `allow`
+    /// [lints.clippy]
+    /// pedantic = { level = "warn", priority = -1 }
+    /// similar_names = "allow"
+    /// ```
+    #[clippy::version = "1.76.0"]
+    pub LINT_GROUPS_PRIORITY,
+    correctness,
+    "a lint group in `Cargo.toml` at the same priority as a lint"
+}
+
 pub struct Cargo {
     pub allowed_duplicate_crates: FxHashSet<String>,
     pub ignore_publish: bool,
@@ -175,7 +213,8 @@ impl_lint_pass!(Cargo => [
     REDUNDANT_FEATURE_NAMES,
     NEGATIVE_FEATURE_NAMES,
     MULTIPLE_CRATE_VERSIONS,
-    WILDCARD_DEPENDENCIES
+    WILDCARD_DEPENDENCIES,
+    LINT_GROUPS_PRIORITY,
 ]);
 
 impl LateLintPass<'_> for Cargo {
@@ -188,6 +227,8 @@ impl LateLintPass<'_> for Cargo {
         ];
         static WITH_DEPS_LINTS: &[&Lint] = &[MULTIPLE_CRATE_VERSIONS];
 
+        lint_groups_priority::check(cx);
+
         if !NO_DEPS_LINTS
             .iter()
             .all(|&lint| is_lint_allowed(cx, lint, CRATE_HIR_ID))
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
index 91bad8256ec..0f29743856a 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
@@ -68,9 +68,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv
 
 fn is_child_of_cast(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     let map = cx.tcx.hir();
-    if let Some(parent_id) = map.opt_parent_id(expr.hir_id)
-        && let Some(parent) = cx.tcx.opt_hir_node(parent_id)
-    {
+    if let Some(parent_id) = map.opt_parent_id(expr.hir_id) {
+        let parent = cx.tcx.hir_node(parent_id);
         let expr = match parent {
             Node::Block(block) => {
                 if let Some(parent_expr) = block.expr {
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index e05b8f66d86..14f2f4a7f59 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -18,6 +18,7 @@ mod fn_to_numeric_cast_any;
 mod fn_to_numeric_cast_with_truncation;
 mod ptr_as_ptr;
 mod ptr_cast_constness;
+mod ref_as_ptr;
 mod unnecessary_cast;
 mod utils;
 mod zero_ptr;
@@ -689,6 +690,30 @@ declare_clippy_lint! {
     "using `0 as *{const, mut} T`"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for casts of references to pointer using `as`
+    /// and suggests `std::ptr::from_ref` and `std::ptr::from_mut` instead.
+    ///
+    /// ### Why is this bad?
+    /// Using `as` casts may result in silently changing mutability or type.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// let a_ref = &1;
+    /// let a_ptr = a_ref as *const _;
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// let a_ref = &1;
+    /// let a_ptr = std::ptr::from_ref(a_ref);
+    /// ```
+    #[clippy::version = "1.77.0"]
+    pub REF_AS_PTR,
+    pedantic,
+    "using `as` to cast a reference to pointer"
+}
+
 pub struct Casts {
     msrv: Msrv,
 }
@@ -724,6 +749,7 @@ impl_lint_pass!(Casts => [
     AS_PTR_CAST_MUT,
     CAST_NAN_TO_INT,
     ZERO_PTR,
+    REF_AS_PTR,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -771,7 +797,9 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
 
             as_underscore::check(cx, expr, cast_to_hir);
 
-            if self.msrv.meets(msrvs::BORROW_AS_PTR) {
+            if self.msrv.meets(msrvs::PTR_FROM_REF) {
+                ref_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
+            } else if self.msrv.meets(msrvs::BORROW_AS_PTR) {
                 borrow_as_ptr::check(cx, expr, cast_expr, cast_to_hir);
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs
new file mode 100644
index 00000000000..d600d2aec1b
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/casts/ref_as_ptr.rs
@@ -0,0 +1,55 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_no_std_crate;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::sugg::Sugg;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, Mutability, Ty, TyKind};
+use rustc_lint::LateContext;
+use rustc_middle::ty::{self, TypeAndMut};
+
+use super::REF_AS_PTR;
+
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to_hir_ty: &Ty<'_>) {
+    let (cast_from, cast_to) = (
+        cx.typeck_results().expr_ty(cast_expr),
+        cx.typeck_results().expr_ty(expr),
+    );
+
+    if matches!(cast_from.kind(), ty::Ref(..))
+        && let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, .. }) = cast_to.kind()
+    {
+        let core_or_std = if is_no_std_crate(cx) { "core" } else { "std" };
+        let fn_name = match to_mutbl {
+            Mutability::Not => "from_ref",
+            Mutability::Mut => "from_mut",
+        };
+
+        let mut app = Applicability::MachineApplicable;
+        let turbofish = match &cast_to_hir_ty.kind {
+            TyKind::Infer => String::new(),
+            TyKind::Ptr(mut_ty) => {
+                if matches!(mut_ty.ty.kind, TyKind::Infer) {
+                    String::new()
+                } else {
+                    format!(
+                        "::<{}>",
+                        snippet_with_applicability(cx, mut_ty.ty.span, "/* type */", &mut app)
+                    )
+                }
+            },
+            _ => return,
+        };
+
+        let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app);
+
+        span_lint_and_sugg(
+            cx,
+            REF_AS_PTR,
+            expr.span,
+            "reference as raw pointer",
+            "try",
+            format!("{core_or_std}::ptr::{fn_name}{turbofish}({cast_expr_sugg})"),
+            app,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index bb86b6f3075..81d0def4322 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -144,8 +144,7 @@ pub(super) fn check<'tcx>(
 
     if cast_from.kind() == cast_to.kind() && !in_external_macro(cx.sess(), expr.span) {
         if let Some(id) = path_to_local(cast_expr)
-            && let Some(span) = cx.tcx.hir().opt_span(id)
-            && !span.eq_ctxt(cast_expr.span)
+            && !cx.tcx.hir().span(id).eq_ctxt(cast_expr.span)
         {
             // Binding context is different than the identifiers context.
             // Weird macro wizardry could be involved here.
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 639edd8da30..0a5baabd973 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -71,6 +71,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::borrow_deref_ref::BORROW_DEREF_REF_INFO,
     crate::box_default::BOX_DEFAULT_INFO,
     crate::cargo::CARGO_COMMON_METADATA_INFO,
+    crate::cargo::LINT_GROUPS_PRIORITY_INFO,
     crate::cargo::MULTIPLE_CRATE_VERSIONS_INFO,
     crate::cargo::NEGATIVE_FEATURE_NAMES_INFO,
     crate::cargo::REDUNDANT_FEATURE_NAMES_INFO,
@@ -96,6 +97,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO,
     crate::casts::PTR_AS_PTR_INFO,
     crate::casts::PTR_CAST_CONSTNESS_INFO,
+    crate::casts::REF_AS_PTR_INFO,
     crate::casts::UNNECESSARY_CAST_INFO,
     crate::casts::ZERO_PTR_INFO,
     crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
@@ -212,6 +214,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::implicit_saturating_add::IMPLICIT_SATURATING_ADD_INFO,
     crate::implicit_saturating_sub::IMPLICIT_SATURATING_SUB_INFO,
     crate::implied_bounds_in_impls::IMPLIED_BOUNDS_IN_IMPLS_INFO,
+    crate::incompatible_msrv::INCOMPATIBLE_MSRV_INFO,
     crate::inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR_INFO,
     crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO,
     crate::indexing_slicing::INDEXING_SLICING_INFO,
@@ -384,6 +387,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::methods::ITER_SKIP_ZERO_INFO,
     crate::methods::ITER_WITH_DRAIN_INFO,
     crate::methods::JOIN_ABSOLUTE_PATHS_INFO,
+    crate::methods::MANUAL_C_STR_LITERALS_INFO,
     crate::methods::MANUAL_FILTER_MAP_INFO,
     crate::methods::MANUAL_FIND_MAP_INFO,
     crate::methods::MANUAL_IS_VARIANT_AND_INFO,
@@ -452,6 +456,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::methods::UNNECESSARY_JOIN_INFO,
     crate::methods::UNNECESSARY_LAZY_EVALUATIONS_INFO,
     crate::methods::UNNECESSARY_LITERAL_UNWRAP_INFO,
+    crate::methods::UNNECESSARY_RESULT_MAP_OR_ELSE_INFO,
     crate::methods::UNNECESSARY_SORT_BY_INFO,
     crate::methods::UNNECESSARY_TO_OWNED_INFO,
     crate::methods::UNWRAP_OR_DEFAULT_INFO,
@@ -656,6 +661,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::tests_outside_test_module::TESTS_OUTSIDE_TEST_MODULE_INFO,
     crate::thread_local_initializer_can_be_made_const::THREAD_LOCAL_INITIALIZER_CAN_BE_MADE_CONST_INFO,
     crate::to_digit_is_some::TO_DIGIT_IS_SOME_INFO,
+    crate::to_string_trait_impl::TO_STRING_TRAIT_IMPL_INFO,
     crate::trailing_empty_array::TRAILING_EMPTY_ARRAY_INFO,
     crate::trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS_INFO,
     crate::trait_bounds::TYPE_REPETITION_IN_BOUNDS_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index 6b0423200d7..b0f46f5c646 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -195,7 +195,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
             && let Some(def_id) = trait_ref.trait_def_id()
             && cx.tcx.is_diagnostic_item(sym::Default, def_id)
             && let impl_item_hir = child.id.hir_id()
-            && let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir)
+            && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
             && let ImplItemKind::Fn(_, b) = &impl_item.kind
             && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b)
             && let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index ba452775015..2b4ce6ddfaa 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -226,7 +226,7 @@ declare_clippy_lint! {
     ///     unimplemented!();
     /// }
     /// ```
-    #[clippy::version = "1.40.0"]
+    #[clippy::version = "1.76.0"]
     pub TEST_ATTR_IN_DOCTEST,
     suspicious,
     "presence of `#[test]` in code examples"
diff --git a/src/tools/clippy/clippy_lints/src/empty_drop.rs b/src/tools/clippy/clippy_lints/src/empty_drop.rs
index 1d2b907b948..74db250b3ae 100644
--- a/src/tools/clippy/clippy_lints/src/empty_drop.rs
+++ b/src/tools/clippy/clippy_lints/src/empty_drop.rs
@@ -42,7 +42,7 @@ impl LateLintPass<'_> for EmptyDrop {
         }) = item.kind
             && trait_ref.trait_def_id() == cx.tcx.lang_items().drop_trait()
             && let impl_item_hir = child.id.hir_id()
-            && let Some(Node::ImplItem(impl_item)) = cx.tcx.opt_hir_node(impl_item_hir)
+            && let Node::ImplItem(impl_item) = cx.tcx.hir_node(impl_item_hir)
             && let ImplItemKind::Fn(_, b) = &impl_item.kind
             && let Body { value: func_expr, .. } = cx.tcx.hir().body(*b)
             && let func_expr = peel_blocks(func_expr)
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index b7776263060..218d7c6c01a 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -123,11 +123,11 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
 
 // TODO: Replace with Map::is_argument(..) when it's fixed
 fn is_argument(tcx: TyCtxt<'_>, id: HirId) -> bool {
-    match tcx.opt_hir_node(id) {
-        Some(Node::Pat(Pat {
+    match tcx.hir_node(id) {
+        Node::Pat(Pat {
             kind: PatKind::Binding(..),
             ..
-        })) => (),
+        }) => (),
         _ => return false,
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index 450cee4007c..40be71a0e5d 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -3,15 +3,14 @@ use clippy_utils::higher::VecArgs;
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::type_diagnostic_name;
 use clippy_utils::usage::{local_used_after_expr, local_used_in};
-use clippy_utils::{higher, is_adjusted, path_to_local, path_to_local_id};
+use clippy_utils::{get_path_from_caller_to_method_type, higher, is_adjusted, path_to_local, path_to_local_id};
 use rustc_errors::Applicability;
-use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingAnnotation, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, TyKind, Unsafety};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{
-    self, Binder, ClosureArgs, ClosureKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, GenericArgsRef,
-    ImplPolarity, List, Region, RegionKind, Ty, TypeVisitableExt, TypeckResults,
+    self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, ImplPolarity, List, Region, RegionKind,
+    Ty, TypeVisitableExt, TypeckResults,
 };
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
@@ -21,8 +20,8 @@ use rustc_trait_selection::traits::error_reporting::InferCtxtExt as _;
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for closures which just call another function where
-    /// the function can be called directly. `unsafe` functions or calls where types
-    /// get adjusted are ignored.
+    /// the function can be called directly. `unsafe` functions, calls where types
+    /// get adjusted or where the callee is marked `#[track_caller]` are ignored.
     ///
     /// ### Why is this bad?
     /// Needlessly creating a closure adds code for no benefit
@@ -136,7 +135,14 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
                     .map_or(callee_ty, |a| a.target.peel_refs());
 
                 let sig = match callee_ty_adjusted.kind() {
-                    ty::FnDef(def, _) => cx.tcx.fn_sig(def).skip_binder().skip_binder(),
+                    ty::FnDef(def, _) => {
+                        // Rewriting `x(|| f())` to `x(f)` where f is marked `#[track_caller]` moves the `Location`
+                        if cx.tcx.has_attr(*def, sym::track_caller) {
+                            return;
+                        }
+
+                        cx.tcx.fn_sig(def).skip_binder().skip_binder()
+                    },
                     ty::FnPtr(sig) => sig.skip_binder(),
                     ty::Closure(_, subs) => cx
                         .tcx
@@ -186,6 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
             },
             ExprKind::MethodCall(path, self_, args, _) if check_inputs(typeck, body.params, Some(self_), args) => {
                 if let Some(method_def_id) = typeck.type_dependent_def_id(body.value.hir_id)
+                    && !cx.tcx.has_attr(method_def_id, sym::track_caller)
                     && check_sig(cx, closure, cx.tcx.fn_sig(method_def_id).skip_binder().skip_binder())
                 {
                     span_lint_and_then(
@@ -195,11 +202,12 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
                         "redundant closure",
                         |diag| {
                             let args = typeck.node_args(body.value.hir_id);
-                            let name = get_ufcs_type_name(cx, method_def_id, args);
+                            let caller = self_.hir_id.owner.def_id;
+                            let type_name = get_path_from_caller_to_method_type(cx.tcx, caller, method_def_id, args);
                             diag.span_suggestion(
                                 expr.span,
                                 "replace the closure with the method itself",
-                                format!("{}::{}", name, path.ident.name),
+                                format!("{}::{}", type_name, path.ident.name),
                                 Applicability::MachineApplicable,
                             );
                         },
@@ -301,27 +309,3 @@ fn has_late_bound_to_non_late_bound_regions(from_sig: FnSig<'_>, to_sig: FnSig<'
         .zip(to_sig.inputs_and_output)
         .any(|(from_ty, to_ty)| check_ty(from_ty, to_ty))
 }
-
-fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, args: GenericArgsRef<'tcx>) -> String {
-    let assoc_item = cx.tcx.associated_item(method_def_id);
-    let def_id = assoc_item.container_id(cx.tcx);
-    match assoc_item.container {
-        ty::TraitContainer => cx.tcx.def_path_str(def_id),
-        ty::ImplContainer => {
-            let ty = cx.tcx.type_of(def_id).instantiate_identity();
-            match ty.kind() {
-                ty::Adt(adt, _) => cx.tcx.def_path_str(adt.did()),
-                ty::Array(..)
-                | ty::Dynamic(..)
-                | ty::Never
-                | ty::RawPtr(_)
-                | ty::Ref(..)
-                | ty::Slice(_)
-                | ty::Tuple(_) => {
-                    format!("<{}>", EarlyBinder::bind(ty).instantiate(cx.tcx, args))
-                },
-                _ => ty.to_string(),
-            }
-        },
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index e8c1e5db35e..de048fef5f2 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -111,7 +111,7 @@ fn look_in_block<'tcx, 'hir>(cx: &LateContext<'tcx>, kind: &'tcx ExprKind<'hir>)
         // Find id of the local that expr_end_of_block resolves to
         && let ExprKind::Path(QPath::Resolved(None, expr_path)) = expr_end_of_block.kind
         && let Res::Local(expr_res) = expr_path.res
-        && let Some(Node::Pat(res_pat)) = cx.tcx.opt_hir_node(expr_res)
+        && let Node::Pat(res_pat) = cx.tcx.hir_node(expr_res)
 
         // Find id of the local we found in the block
         && let PatKind::Binding(BindingAnnotation::NONE, local_hir_id, _ident, None) = local.pat.kind
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
new file mode 100644
index 00000000000..f2f0e7d4266
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -0,0 +1,133 @@
+use clippy_config::msrvs::Msrv;
+use clippy_utils::diagnostics::span_lint;
+use rustc_attr::{StabilityLevel, StableSince};
+use rustc_data_structures::fx::FxHashMap;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::TyCtxt;
+use rustc_semver::RustcVersion;
+use rustc_session::impl_lint_pass;
+use rustc_span::def_id::DefId;
+use rustc_span::Span;
+
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// This lint checks that no function newer than the defined MSRV (minimum
+    /// supported rust version) is used in the crate.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// It would prevent the crate to be actually used with the specified MSRV.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// // MSRV of 1.3.0
+    /// use std::thread::sleep;
+    /// use std::time::Duration;
+    ///
+    /// // Sleep was defined in `1.4.0`.
+    /// sleep(Duration::new(1, 0));
+    /// ```
+    ///
+    /// To fix this problem, either increase your MSRV or use another item
+    /// available in your current MSRV.
+    #[clippy::version = "1.77.0"]
+    pub INCOMPATIBLE_MSRV,
+    suspicious,
+    "ensures that all items used in the crate are available for the current MSRV"
+}
+
+pub struct IncompatibleMsrv {
+    msrv: Msrv,
+    is_above_msrv: FxHashMap<DefId, RustcVersion>,
+}
+
+impl_lint_pass!(IncompatibleMsrv => [INCOMPATIBLE_MSRV]);
+
+impl IncompatibleMsrv {
+    pub fn new(msrv: Msrv) -> Self {
+        Self {
+            msrv,
+            is_above_msrv: FxHashMap::default(),
+        }
+    }
+
+    #[allow(clippy::cast_lossless)]
+    fn get_def_id_version(&mut self, tcx: TyCtxt<'_>, def_id: DefId) -> RustcVersion {
+        if let Some(version) = self.is_above_msrv.get(&def_id) {
+            return *version;
+        }
+        let version = if let Some(version) = tcx
+            .lookup_stability(def_id)
+            .and_then(|stability| match stability.level {
+                StabilityLevel::Stable {
+                    since: StableSince::Version(version),
+                    ..
+                } => Some(RustcVersion::new(
+                    version.major as _,
+                    version.minor as _,
+                    version.patch as _,
+                )),
+                _ => None,
+            }) {
+            version
+        } else if let Some(parent_def_id) = tcx.opt_parent(def_id) {
+            self.get_def_id_version(tcx, parent_def_id)
+        } else {
+            RustcVersion::new(1, 0, 0)
+        };
+        self.is_above_msrv.insert(def_id, version);
+        version
+    }
+
+    fn emit_lint_if_under_msrv(&mut self, cx: &LateContext<'_>, def_id: DefId, span: Span) {
+        if def_id.is_local() {
+            // We don't check local items since their MSRV is supposed to always be valid.
+            return;
+        }
+        let version = self.get_def_id_version(cx.tcx, def_id);
+        if self.msrv.meets(version) {
+            return;
+        }
+        self.emit_lint_for(cx, span, version);
+    }
+
+    fn emit_lint_for(&self, cx: &LateContext<'_>, span: Span, version: RustcVersion) {
+        span_lint(
+            cx,
+            INCOMPATIBLE_MSRV,
+            span,
+            &format!(
+                "current MSRV (Minimum Supported Rust Version) is `{}` but this item is stable since `{version}`",
+                self.msrv
+            ),
+        );
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for IncompatibleMsrv {
+    extract_msrv_attr!(LateContext);
+
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if self.msrv.current().is_none() {
+            // If there is no MSRV, then no need to check anything...
+            return;
+        }
+        match expr.kind {
+            ExprKind::MethodCall(_, _, _, span) => {
+                if let Some(method_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
+                    self.emit_lint_if_under_msrv(cx, method_did, span);
+                }
+            },
+            ExprKind::Call(call, [_]) => {
+                if let ExprKind::Path(qpath) = call.kind
+                    && let Some(path_def_id) = cx.qpath_res(&qpath, call.hir_id).opt_def_id()
+                {
+                    self.emit_lint_if_under_msrv(cx, path_def_id, call.span);
+                }
+            },
+            _ => {},
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
index 5417c13d079..252be30c4e2 100644
--- a/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
+++ b/src/tools/clippy/clippy_lints/src/index_refutable_slice.rs
@@ -248,7 +248,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
 
                 // Checking for slice indexing
                 && let parent_id = map.parent_id(expr.hir_id)
-                && let Some(hir::Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id)
+                && let hir::Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id)
                 && let hir::ExprKind::Index(_, index_expr, _) = parent_expr.kind
                 && let Some(Constant::Int(index_value)) = constant(cx, cx.typeck_results(), index_expr)
                 && let Ok(index_value) = index_value.try_into()
@@ -256,7 +256,7 @@ impl<'a, 'tcx> Visitor<'tcx> for SliceIndexLintingVisitor<'a, 'tcx> {
 
                 // Make sure that this slice index is read only
                 && let maybe_addrof_id = map.parent_id(parent_id)
-                && let Some(hir::Node::Expr(maybe_addrof_expr)) = cx.tcx.opt_hir_node(maybe_addrof_id)
+                && let hir::Node::Expr(maybe_addrof_expr) = cx.tcx.hir_node(maybe_addrof_id)
                 && let hir::ExprKind::AddrOf(_kind, hir::Mutability::Not, _inner_expr) = maybe_addrof_expr.kind
             {
                 use_info.index_use.push((index_value, map.span(parent_expr.hir_id)));
diff --git a/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs b/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs
index 8110c1970d9..6c6eff9ba48 100644
--- a/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs
@@ -34,7 +34,7 @@ declare_clippy_lint! {
     ///         let value = &my_map[key];
     ///     }
     /// ```
-    #[clippy::version = "1.75.0"]
+    #[clippy::version = "1.76.0"]
     pub ITER_OVER_HASH_TYPE,
     restriction,
     "iterating over unordered hash-based types (`HashMap` and `HashSet`)"
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index c1ab020117c..27d85cde532 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -147,9 +147,9 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
             && let Some(output) =
                 parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder())
         {
-            let (name, kind) = match cx.tcx.opt_hir_node(ty_hir_id) {
-                Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"),
-                Some(Node::Item(x)) => match x.kind {
+            let (name, kind) = match cx.tcx.hir_node(ty_hir_id) {
+                Node::ForeignItem(x) => (x.ident.name, "extern type"),
+                Node::Item(x) => match x.kind {
                     ItemKind::Struct(..) => (x.ident.name, "struct"),
                     ItemKind::Enum(..) => (x.ident.name, "enum"),
                     ItemKind::Union(..) => (x.ident.name, "union"),
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index feb4d188f39..14bd82f9c97 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -10,7 +10,12 @@
 #![feature(stmt_expr_attributes)]
 #![recursion_limit = "512"]
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
-#![allow(clippy::missing_docs_in_private_items, clippy::must_use_candidate)]
+#![allow(
+    clippy::missing_docs_in_private_items,
+    clippy::must_use_candidate,
+    rustc::diagnostic_outside_of_impl,
+    rustc::untranslatable_diagnostic,
+)]
 #![warn(trivial_casts, trivial_numeric_casts)]
 // warn on lints, that are included in `rust-lang/rust`s bootstrap
 #![warn(rust_2018_idioms, unused_lifetimes)]
@@ -26,6 +31,7 @@ extern crate rustc_abi;
 extern crate rustc_arena;
 extern crate rustc_ast;
 extern crate rustc_ast_pretty;
+extern crate rustc_attr;
 extern crate rustc_data_structures;
 extern crate rustc_driver;
 extern crate rustc_errors;
@@ -153,6 +159,7 @@ mod implicit_return;
 mod implicit_saturating_add;
 mod implicit_saturating_sub;
 mod implied_bounds_in_impls;
+mod incompatible_msrv;
 mod inconsistent_struct_constructor;
 mod index_refutable_slice;
 mod indexing_slicing;
@@ -325,6 +332,7 @@ mod temporary_assignment;
 mod tests_outside_test_module;
 mod thread_local_initializer_can_be_made_const;
 mod to_digit_is_some;
+mod to_string_trait_impl;
 mod trailing_empty_array;
 mod trait_bounds;
 mod transmute;
@@ -521,6 +529,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         ref allowed_dotfiles,
         ref allowed_idents_below_min_chars,
         ref allowed_scripts,
+        ref allowed_wildcard_imports,
         ref arithmetic_side_effects_allowed_binary,
         ref arithmetic_side_effects_allowed_unary,
         ref arithmetic_side_effects_allowed,
@@ -575,6 +584,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         check_private_items,
         pub_underscore_fields_behavior,
         ref allowed_duplicate_crates,
+        allow_comparison_to_zero,
 
         blacklisted_names: _,
         cyclomatic_complexity_threshold: _,
@@ -872,7 +882,12 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         ))
     });
     store.register_early_pass(|| Box::new(option_env_unwrap::OptionEnvUnwrap));
-    store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
+    store.register_late_pass(move |_| {
+        Box::new(wildcard_imports::WildcardImports::new(
+            warn_on_all_wildcard_imports,
+            allowed_wildcard_imports.clone(),
+        ))
+    });
     store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
     store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
     store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default());
@@ -968,7 +983,12 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(|_| Box::new(default_instead_of_iter_empty::DefaultIterEmpty));
     store.register_late_pass(move |_| Box::new(manual_rem_euclid::ManualRemEuclid::new(msrv())));
     store.register_late_pass(move |_| Box::new(manual_retain::ManualRetain::new(msrv())));
-    store.register_late_pass(move |_| Box::new(operators::Operators::new(verbose_bit_mask_threshold)));
+    store.register_late_pass(move |_| {
+        Box::new(operators::Operators::new(
+            verbose_bit_mask_threshold,
+            allow_comparison_to_zero,
+        ))
+    });
     store.register_late_pass(|_| Box::<std_instead_of_core::StdReexports>::default());
     store.register_late_pass(move |_| Box::new(instant_subtraction::InstantSubtraction::new(msrv())));
     store.register_late_pass(|_| Box::new(partialeq_to_none::PartialeqToNone));
@@ -1094,6 +1114,8 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| {
         Box::new(thread_local_initializer_can_be_made_const::ThreadLocalInitializerCanBeMadeConst::new(msrv()))
     });
+    store.register_late_pass(move |_| Box::new(incompatible_msrv::IncompatibleMsrv::new(msrv())));
+    store.register_late_pass(|_| Box::new(to_string_trait_impl::ToStringTraitImpl));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index ffef84d1fad..f5636945f20 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -176,7 +176,7 @@ fn check_fn_inner<'tcx>(
                             _ => None,
                         });
                         for bound in lifetimes {
-                            if !bound.is_static() && !bound.is_elided() {
+                            if bound.res != LifetimeName::Static && !bound.is_elided() {
                                 return;
                             }
                         }
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index 3c9bde86bb6..b5e39b33c6a 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -672,7 +672,7 @@ declare_clippy_lint! {
     ///     }
     /// }
     /// ```
-    #[clippy::version = "1.75.0"]
+    #[clippy::version = "1.76.0"]
     pub INFINITE_LOOP,
     restriction,
     "possibly unintended infinite loop"
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index 62bc663191f..245a903f998 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -201,12 +201,12 @@ fn never_loop_expr<'tcx>(
                 })
             })
         },
-        ExprKind::Block(b, l) => {
-            if l.is_some() {
+        ExprKind::Block(b, _) => {
+            if b.targeted_by_break {
                 local_labels.push((b.hir_id, false));
             }
             let ret = never_loop_block(cx, b, local_labels, main_loop_id);
-            let jumped_to = l.is_some() && local_labels.pop().unwrap().1;
+            let jumped_to = b.targeted_by_break && local_labels.pop().unwrap().1;
             match ret {
                 NeverLoopResult::Diverging if jumped_to => NeverLoopResult::Normal,
                 _ => ret,
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 920a887a6fd..5f015db2b33 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
@@ -63,7 +63,7 @@ pub(super) fn check<'tcx>(
                             && let PatKind::Binding(bind_ann, ..) = pat.kind
                             && !matches!(bind_ann, BindingAnnotation(_, Mutability::Mut))
                             && let parent_node = cx.tcx.hir().parent_id(hir_id)
-                            && let Some(Node::Local(parent_let_expr)) = cx.tcx.opt_hir_node(parent_node)
+                            && let Node::Local(parent_let_expr) = cx.tcx.hir_node(parent_node)
                             && let Some(init) = parent_let_expr.init
                         {
                             match init.kind {
diff --git a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
index 71a83a68db9..e1768c6d976 100644
--- a/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_rem_euclid.rs
@@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
             // Also ensures the const is nonzero since zero can't be a divisor
             && const1 == const2 && const2 == const3
             && let Some(hir_id) = path_to_local(expr3)
-            && let Some(Node::Pat(_)) = cx.tcx.opt_hir_node(hir_id)
+            && let Node::Pat(_) = cx.tcx.hir_node(hir_id)
         {
             // Apply only to params or locals with annotated types
             match cx.tcx.hir().find_parent(hir_id) {
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index 1fe247dacb9..6f15fca089e 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -11,6 +11,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_semver::RustcVersion;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::sym;
+use rustc_span::Span;
 
 const ACCEPTABLE_METHODS: [&[&str]; 5] = [
     &paths::BINARYHEAP_ITER,
@@ -28,6 +29,7 @@ const ACCEPTABLE_TYPES: [(rustc_span::Symbol, Option<RustcVersion>); 7] = [
     (sym::Vec, None),
     (sym::VecDeque, None),
 ];
+const MAP_TYPES: [rustc_span::Symbol; 2] = [sym::BTreeMap, sym::HashMap];
 
 declare_clippy_lint! {
     /// ### What it does
@@ -44,6 +46,7 @@ declare_clippy_lint! {
     /// ```no_run
     /// let mut vec = vec![0, 1, 2];
     /// vec.retain(|x| x % 2 == 0);
+    /// vec.retain(|x| x % 2 == 0);
     /// ```
     #[clippy::version = "1.64.0"]
     pub MANUAL_RETAIN,
@@ -74,9 +77,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain {
             && let Some(collect_def_id) = cx.typeck_results().type_dependent_def_id(collect_expr.hir_id)
             && cx.tcx.is_diagnostic_item(sym::iterator_collect_fn, collect_def_id)
         {
-            check_into_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
-            check_iter(cx, parent_expr, left_expr, target_expr, &self.msrv);
-            check_to_owned(cx, parent_expr, left_expr, target_expr, &self.msrv);
+            check_into_iter(cx, left_expr, target_expr, parent_expr.span, &self.msrv);
+            check_iter(cx, left_expr, target_expr, parent_expr.span, &self.msrv);
+            check_to_owned(cx, left_expr, target_expr, parent_expr.span, &self.msrv);
         }
     }
 
@@ -85,9 +88,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualRetain {
 
 fn check_into_iter(
     cx: &LateContext<'_>,
-    parent_expr: &hir::Expr<'_>,
     left_expr: &hir::Expr<'_>,
     target_expr: &hir::Expr<'_>,
+    parent_expr_span: Span,
     msrv: &Msrv,
 ) {
     if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind
@@ -98,16 +101,39 @@ fn check_into_iter(
         && Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn()
         && match_acceptable_type(cx, left_expr, msrv)
         && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)
+        && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = target_expr.kind
+        && let hir::ExprKind::Closure(closure) = closure_expr.kind
+        && let filter_body = cx.tcx.hir().body(closure.body)
+        && let [filter_params] = filter_body.params
     {
-        suggest(cx, parent_expr, left_expr, target_expr);
+        if match_map_type(cx, left_expr) {
+            if let hir::PatKind::Tuple([key_pat, value_pat], _) = filter_params.pat.kind {
+                if let Some(sugg) = make_sugg(cx, key_pat, value_pat, left_expr, filter_body) {
+                    make_span_lint_and_sugg(cx, parent_expr_span, sugg);
+                }
+            }
+            // Cannot lint other cases because `retain` requires two parameters
+        } else {
+            // Can always move because `retain` and `filter` have the same bound on the predicate
+            // for other types
+            make_span_lint_and_sugg(
+                cx,
+                parent_expr_span,
+                format!(
+                    "{}.retain({})",
+                    snippet(cx, left_expr.span, ".."),
+                    snippet(cx, closure_expr.span, "..")
+                ),
+            );
+        }
     }
 }
 
 fn check_iter(
     cx: &LateContext<'_>,
-    parent_expr: &hir::Expr<'_>,
     left_expr: &hir::Expr<'_>,
     target_expr: &hir::Expr<'_>,
+    parent_expr_span: Span,
     msrv: &Msrv,
 ) {
     if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
@@ -122,16 +148,50 @@ fn check_iter(
         && match_acceptable_def_path(cx, iter_expr_def_id)
         && match_acceptable_type(cx, left_expr, msrv)
         && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)
+        && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind
+        && let hir::ExprKind::Closure(closure) = closure_expr.kind
+        && let filter_body = cx.tcx.hir().body(closure.body)
+        && let [filter_params] = filter_body.params
     {
-        suggest(cx, parent_expr, left_expr, filter_expr);
+        match filter_params.pat.kind {
+            // hir::PatKind::Binding(_, _, _, None) => {
+            //     // Be conservative now. Do nothing here.
+            //     // TODO: Ideally, we can rewrite the lambda by stripping one level of reference
+            // },
+            hir::PatKind::Tuple([_, _], _) => {
+                // the `&&` reference for the `filter` method will be auto derefed to `ref`
+                // so, we can directly use the lambda
+                // https://doc.rust-lang.org/reference/patterns.html#binding-modes
+                make_span_lint_and_sugg(
+                    cx,
+                    parent_expr_span,
+                    format!(
+                        "{}.retain({})",
+                        snippet(cx, left_expr.span, ".."),
+                        snippet(cx, closure_expr.span, "..")
+                    ),
+                );
+            },
+            hir::PatKind::Ref(pat, _) => make_span_lint_and_sugg(
+                cx,
+                parent_expr_span,
+                format!(
+                    "{}.retain(|{}| {})",
+                    snippet(cx, left_expr.span, ".."),
+                    snippet(cx, pat.span, ".."),
+                    snippet(cx, filter_body.value.span, "..")
+                ),
+            ),
+            _ => {},
+        }
     }
 }
 
 fn check_to_owned(
     cx: &LateContext<'_>,
-    parent_expr: &hir::Expr<'_>,
     left_expr: &hir::Expr<'_>,
     target_expr: &hir::Expr<'_>,
+    parent_expr_span: Span,
     msrv: &Msrv,
 ) {
     if msrv.meets(msrvs::STRING_RETAIN)
@@ -147,43 +207,25 @@ fn check_to_owned(
         && let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
         && is_type_lang_item(cx, ty, hir::LangItem::String)
         && SpanlessEq::new(cx).eq_expr(left_expr, str_expr)
-    {
-        suggest(cx, parent_expr, left_expr, filter_expr);
-    }
-}
-
-fn suggest(cx: &LateContext<'_>, parent_expr: &hir::Expr<'_>, left_expr: &hir::Expr<'_>, filter_expr: &hir::Expr<'_>) {
-    if let hir::ExprKind::MethodCall(_, _, [closure], _) = filter_expr.kind
-        && let hir::ExprKind::Closure(&hir::Closure { body, .. }) = closure.kind
-        && let filter_body = cx.tcx.hir().body(body)
+        && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind
+        && let hir::ExprKind::Closure(closure) = closure_expr.kind
+        && let filter_body = cx.tcx.hir().body(closure.body)
         && let [filter_params] = filter_body.params
-        && let Some(sugg) = match filter_params.pat.kind {
-            hir::PatKind::Binding(_, _, filter_param_ident, None) => Some(format!(
-                "{}.retain(|{filter_param_ident}| {})",
-                snippet(cx, left_expr.span, ".."),
-                snippet(cx, filter_body.value.span, "..")
-            )),
-            hir::PatKind::Tuple([key_pat, value_pat], _) => make_sugg(cx, key_pat, value_pat, left_expr, filter_body),
-            hir::PatKind::Ref(pat, _) => match pat.kind {
-                hir::PatKind::Binding(_, _, filter_param_ident, None) => Some(format!(
-                    "{}.retain(|{filter_param_ident}| {})",
+    {
+        if let hir::PatKind::Ref(pat, _) = filter_params.pat.kind {
+            make_span_lint_and_sugg(
+                cx,
+                parent_expr_span,
+                format!(
+                    "{}.retain(|{}| {})",
                     snippet(cx, left_expr.span, ".."),
+                    snippet(cx, pat.span, ".."),
                     snippet(cx, filter_body.value.span, "..")
-                )),
-                _ => None,
-            },
-            _ => None,
+                ),
+            );
         }
-    {
-        span_lint_and_sugg(
-            cx,
-            MANUAL_RETAIN,
-            parent_expr.span,
-            "this expression can be written more simply using `.retain()`",
-            "consider calling `.retain()` instead",
-            sugg,
-            Applicability::MachineApplicable,
-        );
+        // Be conservative now. Do nothing for the `Binding` case.
+        // TODO: Ideally, we can rewrite the lambda by stripping one level of reference
     }
 }
 
@@ -229,3 +271,20 @@ fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv
             && acceptable_msrv.map_or(true, |acceptable_msrv| msrv.meets(acceptable_msrv))
     })
 }
+
+fn match_map_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
+    let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
+    MAP_TYPES.iter().any(|ty| is_type_diagnostic_item(cx, expr_ty, *ty))
+}
+
+fn make_span_lint_and_sugg(cx: &LateContext<'_>, span: Span, sugg: String) {
+    span_lint_and_sugg(
+        cx,
+        MANUAL_RETAIN,
+        span,
+        "this expression can be written more simply using `.retain()`",
+        "consider calling `.retain()` instead",
+        sugg,
+        Applicability::MachineApplicable,
+    );
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
index 9251130a305..7339362193e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_next.rs
@@ -44,7 +44,7 @@ pub(super) fn check<'tcx>(
             // add note if not multi-line
             span_lint_and_then(cx, FILTER_NEXT, expr.span, msg, |diag| {
                 let (applicability, pat) = if let Some(id) = path_to_local(recv)
-                    && let Some(hir::Node::Pat(pat)) = cx.tcx.opt_hir_node(id)
+                    && let hir::Node::Pat(pat) = cx.tcx.hir_node(id)
                     && let hir::PatKind::Binding(BindingAnnotation(_, Mutability::Not), _, ident, _) = pat.kind
                 {
                     (Applicability::Unspecified, Some((pat.span, ident)))
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs
new file mode 100644
index 00000000000..cb9fb373c10
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_c_str_literals.rs
@@ -0,0 +1,197 @@
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::get_parent_expr;
+use clippy_utils::source::snippet;
+use rustc_ast::{LitKind, StrStyle};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind, Node, QPath, TyKind};
+use rustc_lint::LateContext;
+use rustc_span::{sym, Span, Symbol};
+
+use super::MANUAL_C_STR_LITERALS;
+
+/// Checks:
+/// - `b"...".as_ptr()`
+/// - `b"...".as_ptr().cast()`
+/// - `"...".as_ptr()`
+/// - `"...".as_ptr().cast()`
+///
+/// Iff the parent call of `.cast()` isn't `CStr::from_ptr`, to avoid linting twice.
+pub(super) fn check_as_ptr<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &'tcx Expr<'tcx>,
+    receiver: &'tcx Expr<'tcx>,
+    msrv: &Msrv,
+) {
+    if let ExprKind::Lit(lit) = receiver.kind
+        && let LitKind::ByteStr(_, StrStyle::Cooked) | LitKind::Str(_, StrStyle::Cooked) = lit.node
+        && let casts_removed = peel_ptr_cast_ancestors(cx, expr)
+        && !get_parent_expr(cx, casts_removed).is_some_and(
+            |parent| matches!(parent.kind, ExprKind::Call(func, _) if is_c_str_function(cx, func).is_some()),
+        )
+        && let Some(sugg) = rewrite_as_cstr(cx, lit.span)
+        && msrv.meets(msrvs::C_STR_LITERALS)
+    {
+        span_lint_and_sugg(
+            cx,
+            MANUAL_C_STR_LITERALS,
+            receiver.span,
+            "manually constructing a nul-terminated string",
+            r#"use a `c""` literal"#,
+            sugg,
+            // an additional cast may be needed, since the type of `CStr::as_ptr` and
+            // `"".as_ptr()` can differ and is platform dependent
+            Applicability::HasPlaceholders,
+        );
+    }
+}
+
+/// Checks if the callee is a "relevant" `CStr` function considered by this lint.
+/// Returns the function name.
+fn is_c_str_function(cx: &LateContext<'_>, func: &Expr<'_>) -> Option<Symbol> {
+    if let ExprKind::Path(QPath::TypeRelative(cstr, fn_name)) = &func.kind
+        && let TyKind::Path(QPath::Resolved(_, ty_path)) = &cstr.kind
+        && cx.tcx.lang_items().c_str() == ty_path.res.opt_def_id()
+    {
+        Some(fn_name.ident.name)
+    } else {
+        None
+    }
+}
+
+/// Checks calls to the `CStr` constructor functions:
+/// - `CStr::from_bytes_with_nul(..)`
+/// - `CStr::from_bytes_with_nul_unchecked(..)`
+/// - `CStr::from_ptr(..)`
+pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, func: &Expr<'_>, args: &[Expr<'_>], msrv: &Msrv) {
+    if let Some(fn_name) = is_c_str_function(cx, func)
+        && let [arg] = args
+        && msrv.meets(msrvs::C_STR_LITERALS)
+    {
+        match fn_name.as_str() {
+            name @ ("from_bytes_with_nul" | "from_bytes_with_nul_unchecked")
+                if !arg.span.from_expansion()
+                    && let ExprKind::Lit(lit) = arg.kind
+                    && let LitKind::ByteStr(_, StrStyle::Cooked) | LitKind::Str(_, StrStyle::Cooked) = lit.node =>
+            {
+                check_from_bytes(cx, expr, arg, name);
+            },
+            "from_ptr" => check_from_ptr(cx, expr, arg),
+            _ => {},
+        }
+    }
+}
+
+/// Checks `CStr::from_ptr(b"foo\0".as_ptr().cast())`
+fn check_from_ptr(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>) {
+    if let ExprKind::MethodCall(method, lit, ..) = peel_ptr_cast(arg).kind
+        && method.ident.name == sym::as_ptr
+        && !lit.span.from_expansion()
+        && let ExprKind::Lit(lit) = lit.kind
+        && let LitKind::ByteStr(_, StrStyle::Cooked) = lit.node
+        && let Some(sugg) = rewrite_as_cstr(cx, lit.span)
+    {
+        span_lint_and_sugg(
+            cx,
+            MANUAL_C_STR_LITERALS,
+            expr.span,
+            "calling `CStr::from_ptr` with a byte string literal",
+            r#"use a `c""` literal"#,
+            sugg,
+            Applicability::MachineApplicable,
+        );
+    }
+}
+/// Checks `CStr::from_bytes_with_nul(b"foo\0")`
+fn check_from_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, method: &str) {
+    let (span, applicability) = if let Some(parent) = get_parent_expr(cx, expr)
+        && let ExprKind::MethodCall(method, ..) = parent.kind
+        && [sym::unwrap, sym::expect].contains(&method.ident.name)
+    {
+        (parent.span, Applicability::MachineApplicable)
+    } else if method == "from_bytes_with_nul_unchecked" {
+        // `*_unchecked` returns `&CStr` directly, nothing needs to be changed
+        (expr.span, Applicability::MachineApplicable)
+    } else {
+        // User needs to remove error handling, can't be machine applicable
+        (expr.span, Applicability::HasPlaceholders)
+    };
+
+    let Some(sugg) = rewrite_as_cstr(cx, arg.span) else {
+        return;
+    };
+
+    span_lint_and_sugg(
+        cx,
+        MANUAL_C_STR_LITERALS,
+        span,
+        "calling `CStr::new` with a byte string literal",
+        r#"use a `c""` literal"#,
+        sugg,
+        applicability,
+    );
+}
+
+/// Rewrites a byte string literal to a c-str literal.
+/// `b"foo\0"` -> `c"foo"`
+///
+/// Returns `None` if it doesn't end in a NUL byte.
+fn rewrite_as_cstr(cx: &LateContext<'_>, span: Span) -> Option<String> {
+    let mut sugg = String::from("c") + snippet(cx, span.source_callsite(), "..").trim_start_matches('b');
+
+    // NUL byte should always be right before the closing quote.
+    if let Some(quote_pos) = sugg.rfind('"') {
+        // Possible values right before the quote:
+        // - literal NUL value
+        if sugg.as_bytes()[quote_pos - 1] == b'\0' {
+            sugg.remove(quote_pos - 1);
+        }
+        // - \x00
+        else if sugg[..quote_pos].ends_with("\\x00") {
+            sugg.replace_range(quote_pos - 4..quote_pos, "");
+        }
+        // - \0
+        else if sugg[..quote_pos].ends_with("\\0") {
+            sugg.replace_range(quote_pos - 2..quote_pos, "");
+        }
+        // No known suffix, so assume it's not a C-string.
+        else {
+            return None;
+        }
+    }
+
+    Some(sugg)
+}
+
+fn get_cast_target<'tcx>(e: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx>> {
+    match &e.kind {
+        ExprKind::MethodCall(method, receiver, [], _) if method.ident.as_str() == "cast" => Some(receiver),
+        ExprKind::Cast(expr, _) => Some(expr),
+        _ => None,
+    }
+}
+
+/// `x.cast()` -> `x`
+/// `x as *const _` -> `x`
+/// `x` -> `x` (returns the same expression for non-cast exprs)
+fn peel_ptr_cast<'tcx>(e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
+    get_cast_target(e).map_or(e, peel_ptr_cast)
+}
+
+/// Same as `peel_ptr_cast`, but the other way around, by walking up the ancestor cast expressions:
+///
+/// `foo(x.cast() as *const _)`
+///      ^ given this `x` expression, returns the `foo(...)` expression
+fn peel_ptr_cast_ancestors<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
+    let mut prev = e;
+    for (_, node) in cx.tcx.hir().parent_iter(e.hir_id) {
+        if let Node::Expr(e) = node
+            && get_cast_target(e).is_some()
+        {
+            prev = e;
+        } else {
+            break;
+        }
+    }
+    prev
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs
index 52ea584a2c8..3226fa9cd3f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_unwrap_or.rs
@@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
     unwrap_arg: &'tcx hir::Expr<'_>,
     msrv: &Msrv,
 ) -> bool {
-    // lint if the caller of `map()` is an `Option`
+    // lint if the caller of `map()` is an `Option` or a `Result`.
     let is_option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Option);
     let is_result = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result);
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 03bcf108914..e8a7a321bf4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -51,6 +51,7 @@ mod iter_skip_zero;
 mod iter_with_drain;
 mod iterator_step_by_zero;
 mod join_absolute_paths;
+mod manual_c_str_literals;
 mod manual_is_variant_and;
 mod manual_next_back;
 mod manual_ok_or;
@@ -113,6 +114,7 @@ mod unnecessary_iter_cloned;
 mod unnecessary_join;
 mod unnecessary_lazy_eval;
 mod unnecessary_literal_unwrap;
+mod unnecessary_result_map_or_else;
 mod unnecessary_sort_by;
 mod unnecessary_to_owned;
 mod unwrap_expect_used;
@@ -3951,6 +3953,64 @@ declare_clippy_lint! {
     "cloning an `Option` via `as_ref().cloned()`"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for usage of `.map_or_else()` "map closure" for `Result` type.
+    ///
+    /// ### Why is this bad?
+    /// This can be written more concisely by using `unwrap_or_else()`.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// # fn handle_error(_: ()) -> u32 { 0 }
+    /// let x: Result<u32, ()> = Ok(0);
+    /// let y = x.map_or_else(|err| handle_error(err), |n| n);
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// # fn handle_error(_: ()) -> u32 { 0 }
+    /// let x: Result<u32, ()> = Ok(0);
+    /// let y = x.unwrap_or_else(|err| handle_error(err));
+    /// ```
+    #[clippy::version = "1.77.0"]
+    pub UNNECESSARY_RESULT_MAP_OR_ELSE,
+    suspicious,
+    "making no use of the \"map closure\" when calling `.map_or_else(|err| handle_error(err), |n| n)`"
+}
+
+declare_clippy_lint! {
+    /// Checks for the manual creation of C strings (a string with a `NUL` byte at the end), either
+    /// through one of the `CStr` constructor functions, or more plainly by calling `.as_ptr()`
+    /// on a (byte) string literal with a hardcoded `\0` byte at the end.
+    ///
+    /// ### Why is this bad?
+    /// This can be written more concisely using `c"str"` literals and is also less error-prone,
+    /// because the compiler checks for interior `NUL` bytes and the terminating `NUL` byte is inserted automatically.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// # use std::ffi::CStr;
+    /// # mod libc { pub unsafe fn puts(_: *const i8) {} }
+    /// fn needs_cstr(_: &CStr) {}
+    ///
+    /// needs_cstr(CStr::from_bytes_with_nul(b"Hello\0").unwrap());
+    /// unsafe { libc::puts("World\0".as_ptr().cast()) }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// # use std::ffi::CStr;
+    /// # mod libc { pub unsafe fn puts(_: *const i8) {} }
+    /// fn needs_cstr(_: &CStr) {}
+    ///
+    /// needs_cstr(c"Hello");
+    /// unsafe { libc::puts(c"World".as_ptr()) }
+    /// ```
+    #[clippy::version = "1.76.0"]
+    pub MANUAL_C_STR_LITERALS,
+    pedantic,
+    r#"creating a `CStr` through functions when `c""` literals can be used"#
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Msrv,
@@ -4109,6 +4169,8 @@ impl_lint_pass!(Methods => [
     MANUAL_IS_VARIANT_AND,
     STR_SPLIT_AT_NEWLINE,
     OPTION_AS_REF_CLONED,
+    UNNECESSARY_RESULT_MAP_OR_ELSE,
+    MANUAL_C_STR_LITERALS,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -4136,6 +4198,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
             hir::ExprKind::Call(func, args) => {
                 from_iter_instead_of_collect::check(cx, expr, args, func);
                 unnecessary_fallible_conversions::check_function(cx, expr, func);
+                manual_c_str_literals::check(cx, expr, func, args, &self.msrv);
             },
             hir::ExprKind::MethodCall(method_call, receiver, args, _) => {
                 let method_span = method_call.ident.span;
@@ -4354,6 +4417,7 @@ impl Methods {
                     }
                 },
                 ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
+                ("as_ptr", []) => manual_c_str_literals::check_as_ptr(cx, expr, recv, &self.msrv),
                 ("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
                 ("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
                 ("cloned", []) => {
@@ -4592,6 +4656,7 @@ impl Methods {
                 },
                 ("map_or_else", [def, map]) => {
                     result_map_or_else_none::check(cx, expr, recv, def, map);
+                    unnecessary_result_map_or_else::check(cx, expr, recv, def, map);
                 },
                 ("next", []) => {
                     if let Some((name2, recv2, args2, _, _)) = method_call(recv) {
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
index 624597ffca9..ab36f854fcb 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
@@ -135,7 +135,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrapVisitor<'a, 'tcx> {
 
     fn visit_path(&mut self, path: &Path<'tcx>, _: HirId) {
         if let Res::Local(local_id) = path.res
-            && let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id)
+            && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
             && let PatKind::Binding(_, local_id, ..) = pat.kind
         {
             self.identifiers.insert(local_id);
@@ -166,7 +166,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReferenceVisitor<'a, 'tcx> {
                 && let ExprKind::Path(ref path) = expr.kind
                 && let QPath::Resolved(_, path) = path
                 && let Res::Local(local_id) = path.res
-                && let Some(Node::Pat(pat)) = self.cx.tcx.opt_hir_node(local_id)
+                && let Node::Pat(pat) = self.cx.tcx.hir_node(local_id)
                 && let PatKind::Binding(_, local_id, ..) = pat.kind
                 && self.identifiers.contains(&local_id)
             {
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
index f3577ef6082..2046692bbd0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_fold.rs
@@ -99,7 +99,6 @@ fn check_fold_with_op(
             cx,
             UNNECESSARY_FOLD,
             fold_span.with_hi(expr.span.hi()),
-            // TODO #2371 don't suggest e.g., .any(|x| f(x)) if we can suggest .any(f)
             "this `.fold` can be written more succinctly using another method",
             "try",
             sugg,
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs
new file mode 100644
index 00000000000..7b0cf48ac43
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_result_map_or_else.rs
@@ -0,0 +1,95 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::peel_blocks;
+use clippy_utils::source::snippet;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_hir::{Closure, Expr, ExprKind, HirId, QPath, Stmt, StmtKind};
+use rustc_lint::LateContext;
+use rustc_span::symbol::sym;
+
+use super::UNNECESSARY_RESULT_MAP_OR_ELSE;
+
+fn emit_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, def_arg: &Expr<'_>) {
+    let msg = "unused \"map closure\" when calling `Result::map_or_else` value";
+    let self_snippet = snippet(cx, recv.span, "..");
+    let err_snippet = snippet(cx, def_arg.span, "..");
+    span_lint_and_sugg(
+        cx,
+        UNNECESSARY_RESULT_MAP_OR_ELSE,
+        expr.span,
+        msg,
+        "consider using `unwrap_or_else`",
+        format!("{self_snippet}.unwrap_or_else({err_snippet})"),
+        Applicability::MachineApplicable,
+    );
+}
+
+fn get_last_chain_binding_hir_id(mut hir_id: HirId, statements: &[Stmt<'_>]) -> Option<HirId> {
+    for stmt in statements {
+        if let StmtKind::Local(local) = stmt.kind
+            && let Some(init) = local.init
+            && let ExprKind::Path(QPath::Resolved(_, path)) = init.kind
+            && let hir::def::Res::Local(local_hir_id) = path.res
+            && local_hir_id == hir_id
+        {
+            hir_id = local.pat.hir_id;
+        } else {
+            return None;
+        }
+    }
+    Some(hir_id)
+}
+
+fn handle_qpath(
+    cx: &LateContext<'_>,
+    expr: &Expr<'_>,
+    recv: &Expr<'_>,
+    def_arg: &Expr<'_>,
+    expected_hir_id: HirId,
+    qpath: QPath<'_>,
+) {
+    if let QPath::Resolved(_, path) = qpath
+        && let hir::def::Res::Local(hir_id) = path.res
+        && expected_hir_id == hir_id
+    {
+        emit_lint(cx, expr, recv, def_arg);
+    }
+}
+
+/// lint use of `_.map_or_else(|err| err, |n| n)` for `Result`s.
+pub(super) fn check<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &'tcx Expr<'_>,
+    recv: &'tcx Expr<'_>,
+    def_arg: &'tcx Expr<'_>,
+    map_arg: &'tcx Expr<'_>,
+) {
+    // lint if the caller of `map_or_else()` is a `Result`
+    if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result)
+        && let ExprKind::Closure(&Closure { body, .. }) = map_arg.kind
+        && let body = cx.tcx.hir().body(body)
+        && let Some(first_param) = body.params.first()
+    {
+        let body_expr = peel_blocks(body.value);
+
+        match body_expr.kind {
+            ExprKind::Path(qpath) => {
+                handle_qpath(cx, expr, recv, def_arg, first_param.pat.hir_id, qpath);
+            },
+            // If this is a block (that wasn't peeled off), then it means there are statements.
+            ExprKind::Block(block, _) => {
+                if let Some(block_expr) = block.expr
+                    // First we ensure that this is a "binding chain" (each statement is a binding
+                    // of the previous one) and that it is a binding of the closure argument.
+                    && let Some(last_chain_binding_id) =
+                        get_last_chain_binding_hir_id(first_param.pat.hir_id, block.stmts)
+                    && let ExprKind::Path(qpath) = block_expr.kind
+                {
+                    handle_qpath(cx, expr, recv, def_arg, last_chain_binding_id, qpath);
+                }
+            },
+            _ => {},
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
index 41168230752..70cc43e266c 100644
--- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
@@ -91,10 +91,10 @@ impl Visitor<'_> for IdentVisitor<'_, '_> {
         let node = if hir_id.local_id == ItemLocalId::from_u32(0) {
             // In this case, we can just use `find`, `Owner`'s `node` field is private anyway so we can't
             // reimplement it even if we wanted to
-            cx.tcx.opt_hir_node(hir_id)
+            Some(cx.tcx.hir_node(hir_id))
         } else {
             let owner = cx.tcx.hir_owner_nodes(hir_id.owner);
-            owner.nodes.get(hir_id.local_id).copied().flatten().map(|p| p.node)
+            owner.nodes.get(hir_id.local_id).copied().map(|p| p.node)
         };
         let Some(node) = node else {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index 195ce17629a..b593e48ae2e 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -213,11 +213,8 @@ fn check_for_unsequenced_reads(vis: &mut ReadVisitor<'_, '_>) {
         if parent_id == cur_id {
             break;
         }
-        let Some(parent_node) = vis.cx.tcx.opt_hir_node(parent_id) else {
-            break;
-        };
 
-        let stop_early = match parent_node {
+        let stop_early = match vis.cx.tcx.hir_node(parent_id) {
             Node::Expr(expr) => check_expr(vis, expr),
             Node::Stmt(stmt) => check_stmt(vis, stmt),
             Node::Item(_) => {
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 0d234f7f9b5..580160efeb7 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -357,7 +357,7 @@ fn reduce_expression<'a>(cx: &LateContext<'_>, expr: &'a Expr<'a>) -> Option<Vec
             }
         },
         ExprKind::Block(block, _) => {
-            if block.stmts.is_empty() {
+            if block.stmts.is_empty() && !block.targeted_by_break {
                 block.expr.as_ref().and_then(|e| {
                     match block.rules {
                         BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) => None,
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index f8365deebd4..10ab380ba1b 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -453,7 +453,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                 if parent_id == cur_expr.hir_id {
                     break;
                 }
-                if let Some(Node::Expr(parent_expr)) = cx.tcx.opt_hir_node(parent_id) {
+                if let Node::Expr(parent_expr) = cx.tcx.hir_node(parent_id) {
                     match &parent_expr.kind {
                         ExprKind::AddrOf(..) => {
                             // `&e` => `e` must be referenced.
diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
index d621051ef16..ae14016f482 100644
--- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs
@@ -252,7 +252,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion {
                 {
                     (
                         trait_item_id,
-                        FnKind::ImplTraitFn(cx.tcx.erase_regions(trait_ref.args) as *const _ as usize),
+                        FnKind::ImplTraitFn(std::ptr::from_ref(cx.tcx.erase_regions(trait_ref.args)) as usize),
                         usize::from(sig.decl.implicit_self.has_implicit_self()),
                     )
                 } else {
@@ -390,7 +390,6 @@ fn has_matching_args(kind: FnKind, args: GenericArgsRef<'_>) -> bool {
             GenericArgKind::Type(ty) => matches!(*ty.kind(), ty::Param(ty) if ty.index as usize == idx),
             GenericArgKind::Const(c) => matches!(c.kind(), ConstKind::Param(c) if c.index as usize == idx),
         }),
-        #[allow(trivial_casts)]
-        FnKind::ImplTraitFn(expected_args) => args as *const _ as usize == expected_args,
+        FnKind::ImplTraitFn(expected_args) => std::ptr::from_ref(args) as usize == expected_args,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs
index 4c09c4eea58..e002429e3a4 100644
--- a/src/tools/clippy/clippy_lints/src/operators/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs
@@ -771,6 +771,7 @@ declare_clippy_lint! {
 pub struct Operators {
     arithmetic_context: numeric_arithmetic::Context,
     verbose_bit_mask_threshold: u64,
+    modulo_arithmetic_allow_comparison_to_zero: bool,
 }
 impl_lint_pass!(Operators => [
     ABSURD_EXTREME_COMPARISONS,
@@ -801,10 +802,11 @@ impl_lint_pass!(Operators => [
     SELF_ASSIGNMENT,
 ]);
 impl Operators {
-    pub fn new(verbose_bit_mask_threshold: u64) -> Self {
+    pub fn new(verbose_bit_mask_threshold: u64, modulo_arithmetic_allow_comparison_to_zero: bool) -> Self {
         Self {
             arithmetic_context: numeric_arithmetic::Context::default(),
             verbose_bit_mask_threshold,
+            modulo_arithmetic_allow_comparison_to_zero,
         }
     }
 }
@@ -835,12 +837,19 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
                 cmp_owned::check(cx, op.node, lhs, rhs);
                 float_cmp::check(cx, e, op.node, lhs, rhs);
                 modulo_one::check(cx, e, op.node, rhs);
-                modulo_arithmetic::check(cx, e, op.node, lhs, rhs);
+                modulo_arithmetic::check(
+                    cx,
+                    e,
+                    op.node,
+                    lhs,
+                    rhs,
+                    self.modulo_arithmetic_allow_comparison_to_zero,
+                );
             },
             ExprKind::AssignOp(op, lhs, rhs) => {
                 self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);
                 misrefactored_assign_op::check(cx, e, op.node, lhs, rhs);
-                modulo_arithmetic::check(cx, e, op.node, lhs, rhs);
+                modulo_arithmetic::check(cx, e, op.node, lhs, rhs, false);
             },
             ExprKind::Assign(lhs, rhs, _) => {
                 assign_op_pattern::check(cx, e, lhs, rhs);
diff --git a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
index cb3916484c1..40d4a842bef 100644
--- a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
@@ -1,7 +1,7 @@
 use clippy_utils::consts::{constant, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::sext;
-use rustc_hir::{BinOpKind, Expr};
+use rustc_hir::{BinOpKind, Expr, ExprKind, Node};
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, Ty};
 use std::fmt::Display;
@@ -14,8 +14,13 @@ pub(super) fn check<'tcx>(
     op: BinOpKind,
     lhs: &'tcx Expr<'_>,
     rhs: &'tcx Expr<'_>,
+    allow_comparison_to_zero: bool,
 ) {
     if op == BinOpKind::Rem {
+        if allow_comparison_to_zero && used_in_comparison_with_zero(cx, e) {
+            return;
+        }
+
         let lhs_operand = analyze_operand(lhs, cx, e);
         let rhs_operand = analyze_operand(rhs, cx, e);
         if let Some(lhs_operand) = lhs_operand
@@ -28,6 +33,26 @@ pub(super) fn check<'tcx>(
     };
 }
 
+fn used_in_comparison_with_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    let Some(Node::Expr(parent_expr)) = cx.tcx.hir().find_parent(expr.hir_id) else {
+        return false;
+    };
+    let ExprKind::Binary(op, lhs, rhs) = parent_expr.kind else {
+        return false;
+    };
+
+    if op.node == BinOpKind::Eq || op.node == BinOpKind::Ne {
+        if let Some(Constant::Int(0)) = constant(cx, cx.typeck_results(), rhs) {
+            return true;
+        }
+        if let Some(Constant::Int(0)) = constant(cx, cx.typeck_results(), lhs) {
+            return true;
+        }
+    }
+
+    false
+}
+
 struct OperandInfo {
     string_representation: Option<String>,
     is_negative: bool,
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index 334e6770ae4..915da18aafe 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -2,6 +2,7 @@ use crate::rustc_lint::LintContext;
 use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
 use clippy_utils::get_parent_expr;
 use clippy_utils::sugg::Sugg;
+use hir::Param;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
@@ -13,6 +14,7 @@ use rustc_middle::hir::nested_filter;
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
 use rustc_session::declare_lint_pass;
+use rustc_span::ExpnKind;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -89,7 +91,12 @@ fn find_innermost_closure<'tcx>(
     cx: &LateContext<'tcx>,
     mut expr: &'tcx hir::Expr<'tcx>,
     mut steps: usize,
-) -> Option<(&'tcx hir::Expr<'tcx>, &'tcx hir::FnDecl<'tcx>, ty::Asyncness)> {
+) -> Option<(
+    &'tcx hir::Expr<'tcx>,
+    &'tcx hir::FnDecl<'tcx>,
+    ty::Asyncness,
+    &'tcx [Param<'tcx>],
+)> {
     let mut data = None;
 
     while let hir::ExprKind::Closure(closure) = expr.kind
@@ -110,6 +117,7 @@ fn find_innermost_closure<'tcx>(
             } else {
                 ty::Asyncness::No
             },
+            body.params,
         ));
         steps -= 1;
     }
@@ -152,7 +160,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
             // without this check, we'd end up linting twice.
             && !matches!(recv.kind, hir::ExprKind::Call(..))
             && let (full_expr, call_depth) = get_parent_call_exprs(cx, expr)
-            && let Some((body, fn_decl, coroutine_kind)) = find_innermost_closure(cx, recv, call_depth)
+            && let Some((body, fn_decl, coroutine_kind, params)) = find_innermost_closure(cx, recv, call_depth)
+            // outside macros we lint properly. Inside macros, we lint only ||() style closures.
+            && (!matches!(expr.span.ctxt().outer_expn_data().kind, ExpnKind::Macro(_, _)) || params.is_empty())
         {
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index 2c511ee0bc0..700a5dd4a85 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -4,8 +4,10 @@ use clippy_utils::ty::needs_ordered_drop;
 use rustc_ast::Mutability;
 use rustc_hir::def::Res;
 use rustc_hir::{BindingAnnotation, ByRef, ExprKind, HirId, Local, Node, Pat, PatKind, QPath};
+use rustc_hir_typeck::expr_use_visitor::PlaceBase;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::UpvarCapture;
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::Ident;
 use rustc_span::DesugaringKind;
@@ -69,6 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
             // the local is user-controlled
             && !in_external_macro(cx.sess(), local.span)
             && !is_from_proc_macro(cx, expr)
+            && !is_by_value_closure_capture(cx, local.hir_id, binding_id)
         {
             span_lint_and_help(
                 cx,
@@ -82,6 +85,29 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
     }
 }
 
+/// Checks if the enclosing body is a closure and if the given local is captured by value.
+///
+/// In those cases, the redefinition may be necessary to force a move:
+/// ```
+/// fn assert_static<T: 'static>(_: T) {}
+///
+/// let v = String::new();
+/// let closure = || {
+///   let v = v; // <- removing this redefinition makes `closure` no longer `'static`
+///   dbg!(&v);
+/// };
+/// assert_static(closure);
+/// ```
+fn is_by_value_closure_capture(cx: &LateContext<'_>, redefinition: HirId, root_variable: HirId) -> bool {
+    let closure_def_id = cx.tcx.hir().enclosing_body_owner(redefinition);
+
+    cx.tcx.is_closure_or_coroutine(closure_def_id.to_def_id())
+        && cx.tcx.closure_captures(closure_def_id).iter().any(|c| {
+            matches!(c.info.capture_kind, UpvarCapture::ByValue)
+                && matches!(c.place.base, PlaceBase::Upvar(upvar) if upvar.var_path.hir_id == root_variable)
+        })
+}
+
 /// Find the annotation of a binding introduced by a pattern, or `None` if it's not introduced.
 fn find_binding(pat: &Pat<'_>, name: Ident) -> Option<BindingAnnotation> {
     let mut ret = None;
diff --git a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
index 07fcb69afbc..c8352c05265 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
@@ -188,7 +188,6 @@ impl LateLintPass<'_> for RedundantTypeAnnotations {
                     match init_lit.node {
                         // In these cases the annotation is redundant
                         LitKind::Str(..)
-                        | LitKind::ByteStr(..)
                         | LitKind::Byte(..)
                         | LitKind::Char(..)
                         | LitKind::Bool(..)
@@ -202,6 +201,16 @@ impl LateLintPass<'_> for RedundantTypeAnnotations {
                             }
                         },
                         LitKind::Err => (),
+                        LitKind::ByteStr(..) => {
+                            // We only lint if the type annotation is an array type (e.g. &[u8; 4]).
+                            // If instead it is a slice (e.g. &[u8]) it may not be redundant, so we
+                            // don't lint.
+                            if let hir::TyKind::Ref(_, mut_ty) = ty.kind
+                                && matches!(mut_ty.ty.kind, hir::TyKind::Array(..))
+                            {
+                                span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation");
+                            }
+                        },
                     }
                 },
                 _ => (),
diff --git a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
index 5a4933a3fce..fcb79f6d694 100644
--- a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
+++ b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
@@ -42,7 +42,7 @@ declare_clippy_lint! {
     /// //                                      ^^^ this closure executes 123 times
     /// //                                          and the vecs will have the expected capacity
     /// ```
-    #[clippy::version = "1.74.0"]
+    #[clippy::version = "1.76.0"]
     pub REPEAT_VEC_WITH_CAPACITY,
     suspicious,
     "repeating a `Vec::with_capacity` expression which does not retain capacity"
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index e0175046587..2af466d3f51 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -2,10 +2,14 @@ use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then, span_lin
 use clippy_utils::source::{snippet_opt, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
 use clippy_utils::visitors::{for_each_expr_with_closures, Descend};
-use clippy_utils::{fn_def_id, is_from_proc_macro, is_inside_let_else, path_to_local_id, span_find_starting_semi};
+use clippy_utils::{
+    fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, path_to_local_id,
+    span_find_starting_semi,
+};
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
+use rustc_hir::LangItem::ResultErr;
 use rustc_hir::{
     Block, Body, Expr, ExprKind, FnDecl, HirId, ItemKind, LangItem, MatchSource, Node, OwnerNode, PatKind, QPath, Stmt,
     StmtKind,
@@ -18,6 +22,7 @@ use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{BytePos, Pos, Span};
 use std::borrow::Cow;
+use std::fmt::Display;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -146,14 +151,14 @@ impl<'tcx> RetReplacement<'tcx> {
     }
 }
 
-impl<'tcx> ToString for RetReplacement<'tcx> {
-    fn to_string(&self) -> String {
+impl<'tcx> Display for RetReplacement<'tcx> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
-            Self::Empty => String::new(),
-            Self::Block => "{}".to_string(),
-            Self::Unit => "()".to_string(),
-            Self::IfSequence(inner, _) => format!("({inner})"),
-            Self::Expr(inner, _) => inner.to_string(),
+            Self::Empty => write!(f, ""),
+            Self::Block => write!(f, "{{}}"),
+            Self::Unit => write!(f, "()"),
+            Self::IfSequence(inner, _) => write!(f, "({inner})"),
+            Self::Expr(inner, _) => write!(f, "{inner}"),
         }
     }
 }
@@ -181,7 +186,15 @@ impl<'tcx> LateLintPass<'tcx> for Return {
         if !in_external_macro(cx.sess(), stmt.span)
             && let StmtKind::Semi(expr) = stmt.kind
             && let ExprKind::Ret(Some(ret)) = expr.kind
-            && let ExprKind::Match(.., MatchSource::TryDesugar(_)) = ret.kind
+            // return Err(...)? desugars to a match
+            // over a Err(...).branch()
+            // which breaks down to a branch call, with the callee being
+            // the constructor of the Err variant
+            && let ExprKind::Match(maybe_cons, _, MatchSource::TryDesugar(_)) = ret.kind
+            && let ExprKind::Call(_, [maybe_result_err]) = maybe_cons.kind
+            && let ExprKind::Call(maybe_constr, _) = maybe_result_err.kind
+            && is_res_lang_ctor(cx, path_res(cx, maybe_constr), ResultErr)
+
             // Ensure this is not the final stmt, otherwise removing it would cause a compile error
             && let OwnerNode::Item(item) = cx.tcx.hir_owner_node(cx.tcx.hir().get_parent_item(expr.hir_id))
             && let ItemKind::Fn(_, _, body) = item.kind
diff --git a/src/tools/clippy/clippy_lints/src/same_name_method.rs b/src/tools/clippy/clippy_lints/src/same_name_method.rs
index 7a351dab2d4..07806b182f2 100644
--- a/src/tools/clippy/clippy_lints/src/same_name_method.rs
+++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs
@@ -76,8 +76,8 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
                 match of_trait {
                     Some(trait_ref) => {
                         let mut methods_in_trait: BTreeSet<Symbol> =
-                            if let Some(Node::TraitRef(TraitRef { path, .. })) =
-                                cx.tcx.opt_hir_node(trait_ref.hir_ref_id)
+                            if let Node::TraitRef(TraitRef { path, .. }) =
+                                cx.tcx.hir_node(trait_ref.hir_ref_id)
                                 && let Res::Def(DefKind::Trait, did) = path.res
                             {
                                 // FIXME: if
diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
index 98f3235af10..fc5a45dd56d 100644
--- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
+++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
@@ -73,7 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
         if let Some(self_def) = self_ty.ty_adt_def()
             && let Some(self_local_did) = self_def.did().as_local()
             && let self_id = cx.tcx.local_def_id_to_hir_id(self_local_did)
-            && let Some(Node::Item(x)) = cx.tcx.opt_hir_node(self_id)
+            && let Node::Item(x) = cx.tcx.hir_node(self_id)
             && let type_name = x.ident.name.as_str().to_lowercase()
             && (impl_item.ident.name.as_str() == type_name
                 || impl_item.ident.name.as_str().replace('_', "") == type_name)
diff --git a/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs
new file mode 100644
index 00000000000..e1cea99085f
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/to_string_trait_impl.rs
@@ -0,0 +1,67 @@
+use clippy_utils::diagnostics::span_lint_and_help;
+use rustc_hir::{Impl, Item, ItemKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::declare_lint_pass;
+use rustc_span::sym;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for direct implementations of `ToString`.
+    /// ### Why is this bad?
+    /// This trait is automatically implemented for any type which implements the `Display` trait.
+    /// As such, `ToString` shouldn’t be implemented directly: `Display` should be implemented instead,
+    /// and you get the `ToString` implementation for free.
+    /// ### Example
+    /// ```no_run
+    /// struct Point {
+    ///   x: usize,
+    ///   y: usize,
+    /// }
+    ///
+    /// impl ToString for Point {
+    ///   fn to_string(&self) -> String {
+    ///     format!("({}, {})", self.x, self.y)
+    ///   }
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// struct Point {
+    ///   x: usize,
+    ///   y: usize,
+    /// }
+    ///
+    /// impl std::fmt::Display for Point {
+    ///   fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+    ///     write!(f, "({}, {})", self.x, self.y)
+    ///   }
+    /// }
+    /// ```
+    #[clippy::version = "1.77.0"]
+    pub TO_STRING_TRAIT_IMPL,
+    style,
+    "check for direct implementations of `ToString`"
+}
+
+declare_lint_pass!(ToStringTraitImpl => [TO_STRING_TRAIT_IMPL]);
+
+impl<'tcx> LateLintPass<'tcx> for ToStringTraitImpl {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'tcx>) {
+        if let ItemKind::Impl(Impl {
+            of_trait: Some(trait_ref),
+            ..
+        }) = it.kind
+            && let Some(trait_did) = trait_ref.trait_def_id()
+            && cx.tcx.is_diagnostic_item(sym::ToString, trait_did)
+        {
+            span_lint_and_help(
+                cx,
+                TO_STRING_TRAIT_IMPL,
+                it.span,
+                "direct implementation of `ToString`",
+                None,
+                "prefer implementing `Display` instead",
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
index 209035804e4..224ec475c51 100644
--- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
@@ -69,14 +69,6 @@ fn span_error(cx: &LateContext<'_>, method_span: Span, expr: &Expr<'_>) {
     );
 }
 
-fn get_ty_def_id(ty: Ty<'_>) -> Option<DefId> {
-    match ty.peel_refs().kind() {
-        ty::Adt(adt, _) => Some(adt.did()),
-        ty::Foreign(def_id) => Some(*def_id),
-        _ => None,
-    }
-}
-
 fn get_hir_ty_def_id<'tcx>(tcx: TyCtxt<'tcx>, hir_ty: rustc_hir::Ty<'tcx>) -> Option<DefId> {
     let TyKind::Path(qpath) = hir_ty.kind else { return None };
     match qpath {
@@ -131,21 +123,49 @@ fn get_impl_trait_def_id(cx: &LateContext<'_>, method_def_id: LocalDefId) -> Opt
     }
 }
 
-#[allow(clippy::unnecessary_def_path)]
+/// When we have `x == y` where `x = &T` and `y = &T`, then that resolves to
+/// `<&T as PartialEq<&T>>::eq`, which is not the same as `<T as PartialEq<T>>::eq`,
+/// however we still would want to treat it the same, because we know that it's a blanket impl
+/// that simply delegates to the `PartialEq` impl with one reference removed.
+///
+/// Still, we can't just do `lty.peel_refs() == rty.peel_refs()` because when we have `x = &T` and
+/// `y = &&T`, this is not necessarily the same as `<T as PartialEq<T>>::eq`
+///
+/// So to avoid these FNs and FPs, we keep removing a layer of references from *both* sides
+/// until both sides match the expected LHS and RHS type (or they don't).
+fn matches_ty<'tcx>(
+    mut left: Ty<'tcx>,
+    mut right: Ty<'tcx>,
+    expected_left: Ty<'tcx>,
+    expected_right: Ty<'tcx>,
+) -> bool {
+    while let (&ty::Ref(_, lty, _), &ty::Ref(_, rty, _)) = (left.kind(), right.kind()) {
+        if lty == expected_left && rty == expected_right {
+            return true;
+        }
+        left = lty;
+        right = rty;
+    }
+    false
+}
+
 fn check_partial_eq(cx: &LateContext<'_>, method_span: Span, method_def_id: LocalDefId, name: Ident, expr: &Expr<'_>) {
-    let args = cx
-        .tcx
-        .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(method_def_id).skip_binder())
-        .inputs();
+    let Some(sig) = cx
+        .typeck_results()
+        .liberated_fn_sigs()
+        .get(cx.tcx.local_def_id_to_hir_id(method_def_id))
+    else {
+        return;
+    };
+
     // That has two arguments.
-    if let [self_arg, other_arg] = args
-        && let Some(self_arg) = get_ty_def_id(*self_arg)
-        && let Some(other_arg) = get_ty_def_id(*other_arg)
+    if let [self_arg, other_arg] = sig.inputs()
+        && let &ty::Ref(_, self_arg, _) = self_arg.kind()
+        && let &ty::Ref(_, other_arg, _) = other_arg.kind()
         // The two arguments are of the same type.
-        && self_arg == other_arg
         && let Some(trait_def_id) = get_impl_trait_def_id(cx, method_def_id)
         // The trait is `PartialEq`.
-        && Some(trait_def_id) == get_trait_def_id(cx, &["core", "cmp", "PartialEq"])
+        && cx.tcx.is_diagnostic_item(sym::PartialEq, trait_def_id)
     {
         let to_check_op = if name.name == sym::eq {
             BinOpKind::Eq
@@ -154,31 +174,19 @@ fn check_partial_eq(cx: &LateContext<'_>, method_span: Span, method_def_id: Loca
         };
         let is_bad = match expr.kind {
             ExprKind::Binary(op, left, right) if op.node == to_check_op => {
-                // Then we check if the left-hand element is of the same type as `self`.
-                if let Some(left_ty) = cx.typeck_results().expr_ty_opt(left)
-                    && let Some(left_id) = get_ty_def_id(left_ty)
-                    && self_arg == left_id
-                    && let Some(right_ty) = cx.typeck_results().expr_ty_opt(right)
-                    && let Some(right_id) = get_ty_def_id(right_ty)
-                    && other_arg == right_id
-                {
-                    true
-                } else {
-                    false
-                }
+                // Then we check if the LHS matches self_arg and RHS matches other_arg
+                let left_ty = cx.typeck_results().expr_ty_adjusted(left);
+                let right_ty = cx.typeck_results().expr_ty_adjusted(right);
+                matches_ty(left_ty, right_ty, self_arg, other_arg)
             },
-            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;
-                }
+            ExprKind::MethodCall(segment, receiver, [arg], _) if segment.ident.name == name.name => {
+                let receiver_ty = cx.typeck_results().expr_ty_adjusted(receiver);
+                let arg_ty = cx.typeck_results().expr_ty_adjusted(arg);
+
                 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
+                    && matches_ty(receiver_ty, arg_ty, self_arg, other_arg)
                 {
                     true
                 } else {
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 adc66e15ff5..6b3ea7700b7 100644
--- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::{is_res_lang_ctor, is_trait_method, match_trait_method, paths};
+use clippy_utils::macros::{is_panic, root_macro_call_first_node};
+use clippy_utils::{is_res_lang_ctor, is_trait_method, match_trait_method, paths, peel_blocks};
 use hir::{ExprKind, PatKind};
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
@@ -82,37 +83,72 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
         }
 
         if let Some(exp) = block.expr
-            && matches!(exp.kind, hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, _))
+            && matches!(
+                exp.kind,
+                hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, hir::MatchSource::Normal)
+            )
         {
             check_expr(cx, exp);
         }
     }
 }
 
+fn non_consuming_err_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool {
+    // if there is a guard, we consider the result to be consumed
+    if arm.guard.is_some() {
+        return false;
+    }
+    if is_unreachable_or_panic(cx, arm.body) {
+        // if the body is unreachable or there is a panic,
+        // we consider the result to be consumed
+        return false;
+    }
+
+    if let PatKind::TupleStruct(ref path, [inner_pat], _) = arm.pat.kind {
+        return is_res_lang_ctor(cx, cx.qpath_res(path, inner_pat.hir_id), hir::LangItem::ResultErr);
+    }
+
+    false
+}
+
+fn non_consuming_ok_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool {
+    // if there is a guard, we consider the result to be consumed
+    if arm.guard.is_some() {
+        return false;
+    }
+    if is_unreachable_or_panic(cx, arm.body) {
+        // if the body is unreachable or there is a panic,
+        // we consider the result to be consumed
+        return false;
+    }
+
+    if is_ok_wild_or_dotdot_pattern(cx, arm.pat) {
+        return true;
+    }
+    false
+}
+
 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)
+                && is_ok_wild_or_dotdot_pattern(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
-                    }
-                })
-                .collect();
-            if !found_arms.is_empty() {
-                emit_lint(cx, expr.span, op, found_arms.as_slice());
+        // we will capture only the case where the match is Ok( ) or Err( )
+        // prefer to match the minimum possible, and expand later if needed
+        // to avoid false positives on something as used as this
+        hir::ExprKind::Match(expr, [arm1, arm2], hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => {
+            if non_consuming_ok_arm(cx, arm1) && non_consuming_err_arm(cx, arm2) {
+                emit_lint(cx, expr.span, op, &[arm1.pat.span]);
+            }
+            if non_consuming_ok_arm(cx, arm2) && non_consuming_err_arm(cx, arm1) {
+                emit_lint(cx, expr.span, op, &[arm2.pat.span]);
             }
         },
+        hir::ExprKind::Match(_, _, hir::MatchSource::Normal) => {},
         _ if let Some(op) = should_lint(cx, expr) => {
             emit_lint(cx, expr.span, op, &[]);
         },
@@ -130,25 +166,40 @@ fn should_lint<'a>(cx: &LateContext<'a>, mut inner: &'a hir::Expr<'a>) -> Option
     check_io_mode(cx, inner)
 }
 
-fn pattern_is_ignored_ok(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> bool {
+fn is_ok_wild_or_dotdot_pattern<'a>(cx: &LateContext<'a>, pat: &hir::Pat<'a>) -> 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
+    if let PatKind::TupleStruct(ref path, inner_pat, _) = 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,
-        };
+        if matches!(inner_pat, []) {
+            return true;
+        }
+
+        if let [cons_pat] = inner_pat
+            && matches!(cons_pat.kind, PatKind::Wild)
+        {
+            return true;
+        }
+        return false;
     }
     false
 }
 
+// this is partially taken from panic_unimplemented
+fn is_unreachable_or_panic(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
+    let expr = peel_blocks(expr);
+    let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
+        return false;
+    };
+    if is_panic(cx, macro_call.def_id) {
+        return !cx.tcx.hir().is_inside_const_context(expr.hir_id);
+    }
+    matches!(cx.tcx.item_name(macro_call.def_id).as_str(), "unreachable")
+}
+
 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!(
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 288df0fd663..29c67341a46 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -490,9 +490,9 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
                             format!("ClosureKind::Coroutine(CoroutineKind::Coroutine(Movability::{movability:?})")
                         },
                     },
-                    ClosureKind::CoroutineClosure(desugaring) => format!(
-                        "ClosureKind::CoroutineClosure(CoroutineDesugaring::{desugaring:?})"
-                    ),
+                    ClosureKind::CoroutineClosure(desugaring) => {
+                        format!("ClosureKind::CoroutineClosure(CoroutineDesugaring::{desugaring:?})")
+                    },
                 };
 
                 let ret_ty = match fn_decl.output {
diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
index b82bd1d7e7c..5410e8ac117 100644
--- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
@@ -1,6 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::is_test_module_or_function;
 use clippy_utils::source::{snippet, snippet_with_applicability};
+use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Item, ItemKind, PathSegment, UseKind};
@@ -100,13 +101,15 @@ declare_clippy_lint! {
 pub struct WildcardImports {
     warn_on_all: bool,
     test_modules_deep: u32,
+    allowed_segments: FxHashSet<String>,
 }
 
 impl WildcardImports {
-    pub fn new(warn_on_all: bool) -> Self {
+    pub fn new(warn_on_all: bool, allowed_wildcard_imports: FxHashSet<String>) -> Self {
         Self {
             warn_on_all,
             test_modules_deep: 0,
+            allowed_segments: allowed_wildcard_imports,
         }
     }
 }
@@ -190,6 +193,7 @@ impl WildcardImports {
         item.span.from_expansion()
             || is_prelude_import(segments)
             || (is_super_only_import(segments) && self.test_modules_deep > 0)
+            || is_allowed_via_config(segments, &self.allowed_segments)
     }
 }
 
@@ -198,10 +202,18 @@ impl WildcardImports {
 fn is_prelude_import(segments: &[PathSegment<'_>]) -> bool {
     segments
         .iter()
-        .any(|ps| ps.ident.name.as_str().contains(sym::prelude.as_str()))
+        .any(|ps| ps.ident.as_str().contains(sym::prelude.as_str()))
 }
 
 // Allow "super::*" imports in tests.
 fn is_super_only_import(segments: &[PathSegment<'_>]) -> bool {
     segments.len() == 1 && segments[0].ident.name == kw::Super
 }
+
+// Allow skipping imports containing user configured segments,
+// i.e. "...::utils::...::*" if user put `allowed-wildcard-imports = ["utils"]` in `Clippy.toml`
+fn is_allowed_via_config(segments: &[PathSegment<'_>], allowed_segments: &FxHashSet<String>) -> bool {
+    // segment matching need to be exact instead of using 'contains', in case user unintentionaly put
+    // a single character in the config thus skipping most of the warnings.
+    segments.iter().any(|seg| allowed_segments.contains(seg.ident.as_str()))
+}
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index b8869eedf52..c7454fa3328 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_utils"
-version = "0.1.77"
+version = "0.1.78"
 edition = "2021"
 publish = false
 
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 4e499ff4cc6..6a33e11be46 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -1,5 +1,6 @@
 #![feature(array_chunks)]
 #![feature(box_patterns)]
+#![feature(control_flow_enum)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
 #![feature(lint_reasons)]
@@ -8,7 +9,13 @@
 #![feature(assert_matches)]
 #![recursion_limit = "512"]
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
-#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc, clippy::must_use_candidate)]
+#![allow(
+    clippy::missing_errors_doc,
+    clippy::missing_panics_doc,
+    clippy::must_use_candidate,
+    rustc::diagnostic_outside_of_impl,
+    rustc::untranslatable_diagnostic,
+)]
 // warn on the same lints as `clippy_lints`
 #![warn(trivial_casts, trivial_numeric_casts)]
 // warn on lints, that are included in `rust-lang/rust`s bootstrap
@@ -75,6 +82,7 @@ use core::mem;
 use core::ops::ControlFlow;
 use std::collections::hash_map::Entry;
 use std::hash::BuildHasherDefault;
+use std::iter::{once, repeat};
 use std::sync::{Mutex, MutexGuard, OnceLock};
 
 use itertools::Itertools;
@@ -84,6 +92,7 @@ use rustc_data_structures::packed::Pu128;
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LocalModDefId, LOCAL_CRATE};
+use rustc_hir::definitions::{DefPath, DefPathData};
 use rustc_hir::hir_id::{HirIdMap, HirIdSet};
 use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
 use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
@@ -102,8 +111,8 @@ use rustc_middle::ty::binding::BindingMode;
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{
-    self as rustc_ty, Binder, BorrowKind, ClosureKind, FloatTy, IntTy, ParamEnv, ParamEnvAnd, Ty, TyCtxt, TypeAndMut,
-    TypeVisitableExt, UintTy, UpvarCapture,
+    self as rustc_ty, Binder, BorrowKind, ClosureKind, EarlyBinder, FloatTy, GenericArgsRef, IntTy, ParamEnv,
+    ParamEnvAnd, Ty, TyCtxt, TypeAndMut, TypeVisitableExt, UintTy, UpvarCapture,
 };
 use rustc_span::hygiene::{ExpnKind, MacroKind};
 use rustc_span::source_map::SourceMap;
@@ -114,10 +123,7 @@ use visitors::Visitable;
 
 use crate::consts::{constant, mir_to_const, Constant};
 use crate::higher::Range;
-use crate::ty::{
-    adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type,
-    ty_is_fn_once_param,
-};
+use crate::ty::{adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type};
 use crate::visitors::for_each_expr;
 
 use rustc_middle::hir::nested_filter;
@@ -177,10 +183,10 @@ pub fn expr_or_init<'a, 'b, 'tcx: 'b>(cx: &LateContext<'tcx>, mut expr: &'a Expr
 /// canonical binding `HirId`.
 pub fn find_binding_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
     let hir = cx.tcx.hir();
-    if let Some(Node::Pat(pat)) = cx.tcx.opt_hir_node(hir_id)
+    if let Node::Pat(pat) = cx.tcx.hir_node(hir_id)
         && matches!(pat.kind, PatKind::Binding(BindingAnnotation::NONE, ..))
         && let parent = hir.parent_id(hir_id)
-        && let Some(Node::Local(local)) = cx.tcx.opt_hir_node(parent)
+        && let Node::Local(local) = cx.tcx.hir_node(parent)
     {
         return local.init;
     }
@@ -1327,7 +1333,7 @@ pub fn get_enclosing_block<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Optio
     let map = &cx.tcx.hir();
     let enclosing_node = map
         .get_enclosing_scope(hir_id)
-        .and_then(|enclosing_id| cx.tcx.opt_hir_node(enclosing_id));
+        .map(|enclosing_id| cx.tcx.hir_node(enclosing_id));
     enclosing_node.and_then(|node| match node {
         Node::Block(block) => Some(block),
         Node::Item(&Item {
@@ -1353,46 +1359,12 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>(
     for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) {
         match node {
             Node::Expr(e) => match e.kind {
-                ExprKind::Closure { .. } => {
+                ExprKind::Closure { .. }
                     if let rustc_ty::Closure(_, subs) = cx.typeck_results().expr_ty(e).kind()
-                        && subs.as_closure().kind() == ClosureKind::FnOnce
-                    {
-                        continue;
-                    }
-                    let is_once = walk_to_expr_usage(cx, e, |node, id| {
-                        let Node::Expr(e) = node else {
-                            return None;
-                        };
-                        match e.kind {
-                            ExprKind::Call(f, _) if f.hir_id == id => Some(()),
-                            ExprKind::Call(f, args) => {
-                                let i = args.iter().position(|arg| arg.hir_id == id)?;
-                                let sig = expr_sig(cx, f)?;
-                                let predicates = sig
-                                    .predicates_id()
-                                    .map_or(cx.param_env, |id| cx.tcx.param_env(id))
-                                    .caller_bounds();
-                                sig.input(i).and_then(|ty| {
-                                    ty_is_fn_once_param(cx.tcx, ty.skip_binder(), predicates).then_some(())
-                                })
-                            },
-                            ExprKind::MethodCall(_, receiver, args, _) => {
-                                let i = std::iter::once(receiver)
-                                    .chain(args.iter())
-                                    .position(|arg| arg.hir_id == id)?;
-                                let id = cx.typeck_results().type_dependent_def_id(e.hir_id)?;
-                                let ty = cx.tcx.fn_sig(id).instantiate_identity().skip_binder().inputs()[i];
-                                ty_is_fn_once_param(cx.tcx, ty, cx.tcx.param_env(id).caller_bounds()).then_some(())
-                            },
-                            _ => None,
-                        }
-                    })
-                    .is_some();
-                    if !is_once {
-                        return Some(e);
-                    }
-                },
-                ExprKind::Loop(..) => return Some(e),
+                        && subs.as_closure().kind() == ClosureKind::FnOnce => {},
+
+                // Note: A closure's kind is determined by how it's used, not it's captures.
+                ExprKind::Closure { .. } | ExprKind::Loop(..) => return Some(e),
                 _ => (),
             },
             Node::Stmt(_) | Node::Block(_) | Node::Local(_) | Node::Arm(_) => (),
@@ -2590,26 +2562,30 @@ pub fn is_test_module_or_function(tcx: TyCtxt<'_>, item: &Item<'_>) -> bool {
             && item.ident.name.as_str().split('_').any(|a| a == "test" || a == "tests")
 }
 
-/// Walks the HIR tree from the given expression, up to the node where the value produced by the
-/// expression is consumed. Calls the function for every node encountered this way until it returns
-/// `Some`.
+/// Walks up the HIR tree from the given expression in an attempt to find where the value is
+/// consumed.
+///
+/// Termination has three conditions:
+/// - The given function returns `Break`. This function will return the value.
+/// - The consuming node is found. This function will return `Continue(use_node, child_id)`.
+/// - No further parent nodes are found. This will trigger a debug assert or return `None`.
 ///
-/// This allows walking through `if`, `match`, `break`, block expressions to find where the value
-/// produced by the expression is consumed.
+/// This allows walking through `if`, `match`, `break`, and block expressions to find where the
+/// value produced by the expression is consumed.
 pub fn walk_to_expr_usage<'tcx, T>(
     cx: &LateContext<'tcx>,
     e: &Expr<'tcx>,
-    mut f: impl FnMut(Node<'tcx>, HirId) -> Option<T>,
-) -> Option<T> {
+    mut f: impl FnMut(HirId, Node<'tcx>, HirId) -> ControlFlow<T>,
+) -> Option<ControlFlow<T, (Node<'tcx>, HirId)>> {
     let map = cx.tcx.hir();
     let mut iter = map.parent_iter(e.hir_id);
     let mut child_id = e.hir_id;
 
     while let Some((parent_id, parent)) = iter.next() {
-        if let Some(x) = f(parent, child_id) {
-            return Some(x);
+        if let ControlFlow::Break(x) = f(parent_id, parent, child_id) {
+            return Some(ControlFlow::Break(x));
         }
-        let parent = match parent {
+        let parent_expr = match parent {
             Node::Expr(e) => e,
             Node::Block(Block { expr: Some(body), .. }) | Node::Arm(Arm { body, .. }) if body.hir_id == child_id => {
                 child_id = parent_id;
@@ -2619,18 +2595,19 @@ pub fn walk_to_expr_usage<'tcx, T>(
                 child_id = parent_id;
                 continue;
             },
-            _ => return None,
+            _ => return Some(ControlFlow::Continue((parent, child_id))),
         };
-        match parent.kind {
+        match parent_expr.kind {
             ExprKind::If(child, ..) | ExprKind::Match(child, ..) if child.hir_id != child_id => child_id = parent_id,
             ExprKind::Break(Destination { target_id: Ok(id), .. }, _) => {
                 child_id = id;
                 iter = map.parent_iter(id);
             },
-            ExprKind::Block(..) => child_id = parent_id,
-            _ => return None,
+            ExprKind::Block(..) | ExprKind::DropTemps(_) => child_id = parent_id,
+            _ => return Some(ControlFlow::Continue((parent, child_id))),
         }
     }
+    debug_assert!(false, "no parent node found for `{child_id:?}`");
     None
 }
 
@@ -2674,6 +2651,8 @@ pub enum ExprUseNode<'tcx> {
     Callee,
     /// Access of a field.
     FieldAccess(Ident),
+    Expr,
+    Other,
 }
 impl<'tcx> ExprUseNode<'tcx> {
     /// Checks if the value is returned from the function.
@@ -2696,10 +2675,10 @@ impl<'tcx> ExprUseNode<'tcx> {
             )),
             Self::Return(id) => {
                 let hir_id = cx.tcx.local_def_id_to_hir_id(id.def_id);
-                if let Some(Node::Expr(Expr {
+                if let Node::Expr(Expr {
                     kind: ExprKind::Closure(c),
                     ..
-                })) = cx.tcx.opt_hir_node(hir_id)
+                }) = cx.tcx.hir_node(hir_id)
                 {
                     match c.fn_decl.output {
                         FnRetTy::DefaultReturn(_) => None,
@@ -2750,144 +2729,104 @@ impl<'tcx> ExprUseNode<'tcx> {
                 let sig = cx.tcx.fn_sig(id).skip_binder();
                 Some(DefinedTy::Mir(cx.tcx.param_env(id).and(sig.input(i))))
             },
-            Self::Local(_) | Self::FieldAccess(..) | Self::Callee => None,
+            Self::Local(_) | Self::FieldAccess(..) | Self::Callee | Self::Expr | Self::Other => None,
         }
     }
 }
 
 /// Gets the context an expression's value is used in.
-#[expect(clippy::too_many_lines)]
 pub fn expr_use_ctxt<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> Option<ExprUseCtxt<'tcx>> {
     let mut adjustments = [].as_slice();
     let mut is_ty_unified = false;
     let mut moved_before_use = false;
     let ctxt = e.span.ctxt();
-    walk_to_expr_usage(cx, e, &mut |parent, child_id| {
-        // LocalTableInContext returns the wrong lifetime, so go use `expr_adjustments` instead.
+    walk_to_expr_usage(cx, e, &mut |parent_id, parent, child_id| {
         if adjustments.is_empty()
             && let Node::Expr(e) = cx.tcx.hir_node(child_id)
         {
             adjustments = cx.typeck_results().expr_adjustments(e);
         }
-        match parent {
-            Node::Local(l) if l.span.ctxt() == ctxt => Some(ExprUseCtxt {
-                node: ExprUseNode::Local(l),
-                adjustments,
-                is_ty_unified,
-                moved_before_use,
-            }),
+        if cx.tcx.hir().span(parent_id).ctxt() != ctxt {
+            return ControlFlow::Break(());
+        }
+        if let Node::Expr(e) = parent {
+            match e.kind {
+                ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id != child_id => {
+                    is_ty_unified = true;
+                    moved_before_use = true;
+                },
+                ExprKind::Block(_, Some(_)) | ExprKind::Break(..) => {
+                    is_ty_unified = true;
+                    moved_before_use = true;
+                },
+                ExprKind::Block(..) => moved_before_use = true,
+                _ => {},
+            }
+        }
+        ControlFlow::Continue(())
+    })?
+    .continue_value()
+    .map(|(use_node, child_id)| {
+        let node = match use_node {
+            Node::Local(l) => ExprUseNode::Local(l),
+            Node::ExprField(field) => ExprUseNode::Field(field),
+
             Node::Item(&Item {
                 kind: ItemKind::Static(..) | ItemKind::Const(..),
                 owner_id,
-                span,
                 ..
             })
             | Node::TraitItem(&TraitItem {
                 kind: TraitItemKind::Const(..),
                 owner_id,
-                span,
                 ..
             })
             | Node::ImplItem(&ImplItem {
                 kind: ImplItemKind::Const(..),
                 owner_id,
-                span,
                 ..
-            }) if span.ctxt() == ctxt => Some(ExprUseCtxt {
-                node: ExprUseNode::ConstStatic(owner_id),
-                adjustments,
-                is_ty_unified,
-                moved_before_use,
-            }),
+            }) => ExprUseNode::ConstStatic(owner_id),
 
             Node::Item(&Item {
                 kind: ItemKind::Fn(..),
                 owner_id,
-                span,
                 ..
             })
             | Node::TraitItem(&TraitItem {
                 kind: TraitItemKind::Fn(..),
                 owner_id,
-                span,
                 ..
             })
             | Node::ImplItem(&ImplItem {
                 kind: ImplItemKind::Fn(..),
                 owner_id,
-                span,
                 ..
-            }) if span.ctxt() == ctxt => Some(ExprUseCtxt {
-                node: ExprUseNode::Return(owner_id),
-                adjustments,
-                is_ty_unified,
-                moved_before_use,
-            }),
-
-            Node::ExprField(field) if field.span.ctxt() == ctxt => Some(ExprUseCtxt {
-                node: ExprUseNode::Field(field),
-                adjustments,
-                is_ty_unified,
-                moved_before_use,
-            }),
+            }) => ExprUseNode::Return(owner_id),
 
-            Node::Expr(parent) if parent.span.ctxt() == ctxt => match parent.kind {
-                ExprKind::Ret(_) => Some(ExprUseCtxt {
-                    node: ExprUseNode::Return(OwnerId {
-                        def_id: cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
-                    }),
-                    adjustments,
-                    is_ty_unified,
-                    moved_before_use,
-                }),
-                ExprKind::Closure(closure) => Some(ExprUseCtxt {
-                    node: ExprUseNode::Return(OwnerId { def_id: closure.def_id }),
-                    adjustments,
-                    is_ty_unified,
-                    moved_before_use,
-                }),
-                ExprKind::Call(func, args) => Some(ExprUseCtxt {
-                    node: match args.iter().position(|arg| arg.hir_id == child_id) {
-                        Some(i) => ExprUseNode::FnArg(func, i),
-                        None => ExprUseNode::Callee,
-                    },
-                    adjustments,
-                    is_ty_unified,
-                    moved_before_use,
-                }),
-                ExprKind::MethodCall(name, _, args, _) => Some(ExprUseCtxt {
-                    node: ExprUseNode::MethodArg(
-                        parent.hir_id,
-                        name.args,
-                        args.iter().position(|arg| arg.hir_id == child_id).map_or(0, |i| i + 1),
-                    ),
-                    adjustments,
-                    is_ty_unified,
-                    moved_before_use,
-                }),
-                ExprKind::Field(child, name) if child.hir_id == e.hir_id => Some(ExprUseCtxt {
-                    node: ExprUseNode::FieldAccess(name),
-                    adjustments,
-                    is_ty_unified,
-                    moved_before_use,
+            Node::Expr(use_expr) => match use_expr.kind {
+                ExprKind::Ret(_) => ExprUseNode::Return(OwnerId {
+                    def_id: cx.tcx.hir().body_owner_def_id(cx.enclosing_body.unwrap()),
                 }),
-                ExprKind::If(e, _, _) | ExprKind::Match(e, _, _) if e.hir_id != child_id => {
-                    is_ty_unified = true;
-                    moved_before_use = true;
-                    None
-                },
-                ExprKind::Block(_, Some(_)) | ExprKind::Break(..) => {
-                    is_ty_unified = true;
-                    moved_before_use = true;
-                    None
+                ExprKind::Closure(closure) => ExprUseNode::Return(OwnerId { def_id: closure.def_id }),
+                ExprKind::Call(func, args) => match args.iter().position(|arg| arg.hir_id == child_id) {
+                    Some(i) => ExprUseNode::FnArg(func, i),
+                    None => ExprUseNode::Callee,
                 },
-                ExprKind::Block(..) => {
-                    moved_before_use = true;
-                    None
-                },
-                _ => None,
+                ExprKind::MethodCall(name, _, args, _) => ExprUseNode::MethodArg(
+                    use_expr.hir_id,
+                    name.args,
+                    args.iter().position(|arg| arg.hir_id == child_id).map_or(0, |i| i + 1),
+                ),
+                ExprKind::Field(child, name) if child.hir_id == e.hir_id => ExprUseNode::FieldAccess(name),
+                _ => ExprUseNode::Expr,
             },
-            _ => None,
+            _ => ExprUseNode::Other,
+        };
+        ExprUseCtxt {
+            node,
+            adjustments,
+            is_ty_unified,
+            moved_before_use,
         }
     })
 }
@@ -3264,3 +3203,131 @@ pub fn is_never_expr<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> Option<
             })
     }
 }
+
+/// Produces a path from a local caller to the type of the called method. Suitable for user
+/// output/suggestions.
+///
+/// Returned path can be either absolute (for methods defined non-locally), or relative (for local
+/// methods).
+pub fn get_path_from_caller_to_method_type<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    from: LocalDefId,
+    method: DefId,
+    args: GenericArgsRef<'tcx>,
+) -> String {
+    let assoc_item = tcx.associated_item(method);
+    let def_id = assoc_item.container_id(tcx);
+    match assoc_item.container {
+        rustc_ty::TraitContainer => get_path_to_callee(tcx, from, def_id),
+        rustc_ty::ImplContainer => {
+            let ty = tcx.type_of(def_id).instantiate_identity();
+            get_path_to_ty(tcx, from, ty, args)
+        },
+    }
+}
+
+fn get_path_to_ty<'tcx>(tcx: TyCtxt<'tcx>, from: LocalDefId, ty: Ty<'tcx>, args: GenericArgsRef<'tcx>) -> String {
+    match ty.kind() {
+        rustc_ty::Adt(adt, _) => get_path_to_callee(tcx, from, adt.did()),
+        // TODO these types need to be recursively resolved as well
+        rustc_ty::Array(..)
+        | rustc_ty::Dynamic(..)
+        | rustc_ty::Never
+        | rustc_ty::RawPtr(_)
+        | rustc_ty::Ref(..)
+        | rustc_ty::Slice(_)
+        | rustc_ty::Tuple(_) => format!("<{}>", EarlyBinder::bind(ty).instantiate(tcx, args)),
+        _ => ty.to_string(),
+    }
+}
+
+/// Produce a path from some local caller to the callee. Suitable for user output/suggestions.
+fn get_path_to_callee(tcx: TyCtxt<'_>, from: LocalDefId, callee: DefId) -> String {
+    // only search for a relative path if the call is fully local
+    if callee.is_local() {
+        let callee_path = tcx.def_path(callee);
+        let caller_path = tcx.def_path(from.to_def_id());
+        maybe_get_relative_path(&caller_path, &callee_path, 2)
+    } else {
+        tcx.def_path_str(callee)
+    }
+}
+
+/// Tries to produce a relative path from `from` to `to`; if such a path would contain more than
+/// `max_super` `super` items, produces an absolute path instead. Both `from` and `to` should be in
+/// the local crate.
+///
+/// Suitable for user output/suggestions.
+///
+/// This ignores use items, and assumes that the target path is visible from the source
+/// path (which _should_ be a reasonable assumption since we in order to be able to use an object of
+/// certain type T, T is required to be visible).
+///
+/// TODO make use of `use` items. Maybe we should have something more sophisticated like
+/// rust-analyzer does? <https://docs.rs/ra_ap_hir_def/0.0.169/src/ra_ap_hir_def/find_path.rs.html#19-27>
+fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> String {
+    use itertools::EitherOrBoth::{Both, Left, Right};
+
+    // 1. skip the segments common for both paths (regardless of their type)
+    let unique_parts = to
+        .data
+        .iter()
+        .zip_longest(from.data.iter())
+        .skip_while(|el| matches!(el, Both(l, r) if l == r))
+        .map(|el| match el {
+            Both(l, r) => Both(l.data, r.data),
+            Left(l) => Left(l.data),
+            Right(r) => Right(r.data),
+        });
+
+    // 2. for the remaning segments, construct relative path using only mod names and `super`
+    let mut go_up_by = 0;
+    let mut path = Vec::new();
+    for el in unique_parts {
+        match el {
+            Both(l, r) => {
+                // consider:
+                // a::b::sym:: ::    refers to
+                // c::d::e  ::f::sym
+                // result should be super::super::c::d::e::f
+                //
+                // alternatively:
+                // a::b::c  ::d::sym refers to
+                // e::f::sym:: ::
+                // result should be super::super::super::super::e::f
+                if let DefPathData::TypeNs(s) = l {
+                    path.push(s.to_string());
+                }
+                if let DefPathData::TypeNs(_) = r {
+                    go_up_by += 1;
+                }
+            },
+            // consider:
+            // a::b::sym:: ::    refers to
+            // c::d::e  ::f::sym
+            // when looking at `f`
+            Left(DefPathData::TypeNs(sym)) => path.push(sym.to_string()),
+            // consider:
+            // a::b::c  ::d::sym refers to
+            // e::f::sym:: ::
+            // when looking at `d`
+            Right(DefPathData::TypeNs(_)) => go_up_by += 1,
+            _ => {},
+        }
+    }
+
+    if go_up_by > max_super {
+        // `super` chain would be too long, just use the absolute path instead
+        once(String::from("crate"))
+            .chain(to.data.iter().filter_map(|el| {
+                if let DefPathData::TypeNs(sym) = el.data {
+                    Some(sym.to_string())
+                } else {
+                    None
+                }
+            }))
+            .join("::")
+    } else {
+        repeat(String::from("super")).take(go_up_by).chain(path).join("::")
+    }
+}
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 81f4fcc2133..8d5bcd665ad 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -174,7 +174,7 @@ fn check_rvalue<'tcx>(
                 ))
             }
         },
-        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_), _) | Rvalue::ShallowInitBox(_, _) => {
+        Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) | NullOp::DebugAssertions, _) | Rvalue::ShallowInitBox(_, _) => {
             Ok(())
         },
         Rvalue::UnaryOp(_, operand) => {
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 11bb16ff6c5..6762c883005 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -1000,35 +1000,6 @@ pub fn adt_and_variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option<
     }
 }
 
-/// Checks if the type is a type parameter implementing `FnOnce`, but not `FnMut`.
-pub fn ty_is_fn_once_param<'tcx>(tcx: TyCtxt<'_>, ty: Ty<'tcx>, predicates: &'tcx [ty::Clause<'_>]) -> bool {
-    let ty::Param(ty) = *ty.kind() else {
-        return false;
-    };
-    let lang = tcx.lang_items();
-    let (Some(fn_once_id), Some(fn_mut_id), Some(fn_id)) = (lang.fn_once_trait(), lang.fn_mut_trait(), lang.fn_trait())
-    else {
-        return false;
-    };
-    predicates
-        .iter()
-        .try_fold(false, |found, p| {
-            if let ty::ClauseKind::Trait(p) = p.kind().skip_binder()
-                && let ty::Param(self_ty) = p.trait_ref.self_ty().kind()
-                && ty.index == self_ty.index
-            {
-                // This should use `super_traits_of`, but that's a private function.
-                if p.trait_ref.def_id == fn_once_id {
-                    return Some(true);
-                } else if p.trait_ref.def_id == fn_mut_id || p.trait_ref.def_id == fn_id {
-                    return None;
-                }
-            }
-            Some(found)
-        })
-        .unwrap_or(false)
-}
-
 /// Comes up with an "at least" guesstimate for the type's size, not taking into
 /// account the layout of type parameters.
 pub fn approx_ty_size<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> u64 {
diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml
index 5aaafb41721..0f90cef5cdd 100644
--- a/src/tools/clippy/declare_clippy_lint/Cargo.toml
+++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "declare_clippy_lint"
-version = "0.1.77"
+version = "0.1.78"
 edition = "2021"
 publish = false
 
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index d2d56e59ee3..fcf5c456270 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-01-25"
+channel = "nightly-2024-02-08"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index b944a299256..bdf1cf0a224 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -1,3 +1,5 @@
+#![allow(rustc::diagnostic_outside_of_impl)]
+#![allow(rustc::untranslatable_diagnostic)]
 #![feature(rustc_private)]
 #![feature(let_chains)]
 #![feature(lazy_cell)]
@@ -22,9 +24,11 @@ use rustc_session::EarlyDiagCtxt;
 use rustc_span::symbol::Symbol;
 
 use std::env;
+use std::fs::read_to_string;
 use std::ops::Deref;
 use std::path::Path;
 use std::process::exit;
+use std::string::ToString;
 
 use anstream::println;
 
@@ -188,12 +192,31 @@ pub fn main() {
 
     exit(rustc_driver::catch_with_exit_code(move || {
         let mut orig_args: Vec<String> = env::args().collect();
-        let has_sysroot_arg = arg_value(&orig_args, "--sysroot", |_| true).is_some();
+
+        let has_sysroot_arg = |args: &mut [String]| -> bool {
+            if arg_value(args, "--sysroot", |_| true).is_some() {
+                return true;
+            }
+            // https://doc.rust-lang.org/rustc/command-line-arguments.html#path-load-command-line-flags-from-a-path
+            // Beside checking for existence of `--sysroot` on the command line, we need to
+            // check for the arg files that are prefixed with @ as well to be consistent with rustc
+            for arg in args.iter() {
+                if let Some(arg_file_path) = arg.strip_prefix('@') {
+                    if let Ok(arg_file) = read_to_string(arg_file_path) {
+                        let split_arg_file: Vec<String> = arg_file.lines().map(ToString::to_string).collect();
+                        if arg_value(&split_arg_file, "--sysroot", |_| true).is_some() {
+                            return true;
+                        }
+                    }
+                }
+            }
+            false
+        };
 
         let sys_root_env = std::env::var("SYSROOT").ok();
         let pass_sysroot_env_if_given = |args: &mut Vec<String>, sys_root_env| {
             if let Some(sys_root) = sys_root_env {
-                if !has_sysroot_arg {
+                if !has_sysroot_arg(args) {
                     args.extend(vec!["--sysroot".into(), sys_root]);
                 }
             };
diff --git a/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr
new file mode 100644
index 00000000000..103e60d8484
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.stderr
@@ -0,0 +1,45 @@
+error: lint group `rust_2018_idioms` has the same priority (0) as a lint
+ --> Cargo.toml:7:1
+  |
+7 | rust_2018_idioms = "warn"
+  | ^^^^^^^^^^^^^^^^   ------ has an implicit priority of 0
+8 | bare_trait_objects = "allow"
+  | ------------------ has the same priority as this lint
+  |
+  = note: the order of the lints in the table is ignored by Cargo
+  = note: `#[deny(clippy::lint_groups_priority)]` on by default
+help: to have lints override the group set `rust_2018_idioms` to a lower priority
+  |
+7 | rust_2018_idioms = { level = "warn", priority = -1 }
+  |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: lint group `unused` has the same priority (0) as a lint
+  --> Cargo.toml:10:1
+   |
+10 | unused = { level = "deny" }
+   | ^^^^^^   ------------------ has an implicit priority of 0
+11 | unused_braces = { level = "allow", priority = 1 }
+12 | unused_attributes = { level = "allow" }
+   | ----------------- has the same priority as this lint
+   |
+   = note: the order of the lints in the table is ignored by Cargo
+help: to have lints override the group set `unused` to a lower priority
+   |
+10 | unused = { level = "deny", priority = -1 }
+   |          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: lint group `pedantic` has the same priority (-1) as a lint
+  --> Cargo.toml:19:1
+   |
+19 | pedantic = { level = "warn", priority = -1 }
+   | ^^^^^^^^
+20 | similar_names = { level = "allow", priority = -1 }
+   | ------------- has the same priority as this lint
+   |
+   = note: the order of the lints in the table is ignored by Cargo
+help: to have lints override the group set `pedantic` to a lower priority
+   |
+19 | pedantic = { level = "warn", priority = -2 }
+   |            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: could not compile `fail` (lib) due to 3 previous errors
diff --git a/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.toml b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.toml
new file mode 100644
index 00000000000..4ce41f78171
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "fail"
+version = "0.1.0"
+publish = false
+
+[lints.rust]
+rust_2018_idioms = "warn"
+bare_trait_objects = "allow"
+
+unused = { level = "deny" }
+unused_braces = { level = "allow", priority = 1 }
+unused_attributes = { level = "allow" }
+
+# `warnings` is not a group so the order it is passed does not matter
+warnings = "deny"
+deprecated  = "allow"
+
+[lints.clippy]
+pedantic = { level = "warn", priority = -1 }
+similar_names = { level = "allow", priority = -1 }
diff --git a/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/src/lib.rs b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/src/lib.rs
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/fail/src/lib.rs
@@ -0,0 +1 @@
+
diff --git a/src/tools/clippy/tests/ui-cargo/lint_groups_priority/pass/Cargo.toml b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/pass/Cargo.toml
new file mode 100644
index 00000000000..e9fcf803d93
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/pass/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "pass"
+version = "0.1.0"
+publish = false
+
+[lints.clippy]
+pedantic = { level = "warn", priority = -1 }
+style = { level = "warn", priority = 1 }
+similar_names = "allow"
+dbg_macro = { level = "warn", priority = 2 }
diff --git a/src/tools/clippy/tests/ui-cargo/lint_groups_priority/pass/src/lib.rs b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/pass/src/lib.rs
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/src/tools/clippy/tests/ui-cargo/lint_groups_priority/pass/src/lib.rs
@@ -0,0 +1 @@
+
diff --git a/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.fixed b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.fixed
index 6c58e07d846..497f783087a 100644
--- a/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.fixed
+++ b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.fixed
@@ -1,4 +1,4 @@
-#![allow(clippy::redundant_clone, clippy::unnecessary_operation)]
+#![allow(clippy::redundant_clone, clippy::unnecessary_operation, clippy::incompatible_msrv)]
 #![warn(clippy::manual_non_exhaustive, clippy::borrow_as_ptr, clippy::manual_bits)]
 
 use std::mem::{size_of, size_of_val};
diff --git a/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.rs b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.rs
index e1dc3f4389c..6e7874108a3 100644
--- a/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.rs
+++ b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::redundant_clone, clippy::unnecessary_operation)]
+#![allow(clippy::redundant_clone, clippy::unnecessary_operation, clippy::incompatible_msrv)]
 #![warn(clippy::manual_non_exhaustive, clippy::borrow_as_ptr, clippy::manual_bits)]
 
 use std::mem::{size_of, size_of_val};
diff --git a/src/tools/clippy/tests/ui-toml/modulo_arithmetic/clippy.toml b/src/tools/clippy/tests/ui-toml/modulo_arithmetic/clippy.toml
new file mode 100644
index 00000000000..de80f4ae598
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/modulo_arithmetic/clippy.toml
@@ -0,0 +1 @@
+allow-comparison-to-zero = false
diff --git a/src/tools/clippy/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs b/src/tools/clippy/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs
new file mode 100644
index 00000000000..27d27564baf
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.rs
@@ -0,0 +1,10 @@
+#![warn(clippy::modulo_arithmetic)]
+
+fn main() {
+    let a = -1;
+    let b = 2;
+    let c = a % b == 0;
+    let c = a % b != 0;
+    let c = 0 == a % b;
+    let c = 0 != a % b;
+}
diff --git a/src/tools/clippy/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.stderr b/src/tools/clippy/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.stderr
new file mode 100644
index 00000000000..da644b05a11
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/modulo_arithmetic/modulo_arithmetic.stderr
@@ -0,0 +1,40 @@
+error: you are using modulo operator on types that might have different signs
+  --> $DIR/modulo_arithmetic.rs:6:13
+   |
+LL |     let c = a % b == 0;
+   |             ^^^^^
+   |
+   = note: double check for expected result especially when interoperating with different languages
+   = note: or consider using `rem_euclid` or similar function
+   = note: `-D clippy::modulo-arithmetic` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::modulo_arithmetic)]`
+
+error: you are using modulo operator on types that might have different signs
+  --> $DIR/modulo_arithmetic.rs:7:13
+   |
+LL |     let c = a % b != 0;
+   |             ^^^^^
+   |
+   = note: double check for expected result especially when interoperating with different languages
+   = note: or consider using `rem_euclid` or similar function
+
+error: you are using modulo operator on types that might have different signs
+  --> $DIR/modulo_arithmetic.rs:8:18
+   |
+LL |     let c = 0 == a % b;
+   |                  ^^^^^
+   |
+   = note: double check for expected result especially when interoperating with different languages
+   = note: or consider using `rem_euclid` or similar function
+
+error: you are using modulo operator on types that might have different signs
+  --> $DIR/modulo_arithmetic.rs:9:18
+   |
+LL |     let c = 0 != a % b;
+   |                  ^^^^^
+   |
+   = note: double check for expected result especially when interoperating with different languages
+   = note: or consider using `rem_euclid` or similar function
+
+error: aborting due to 4 previous errors
+
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 fc683e514ba..f097d2503e1 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
@@ -3,6 +3,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            absolute-paths-max-segments
            accept-comment-above-attributes
            accept-comment-above-statement
+           allow-comparison-to-zero
            allow-dbg-in-tests
            allow-expect-in-tests
            allow-mixed-uninlined-format-args
@@ -14,6 +15,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            allowed-duplicate-crates
            allowed-idents-below-min-chars
            allowed-scripts
+           allowed-wildcard-imports
            arithmetic-side-effects-allowed
            arithmetic-side-effects-allowed-binary
            arithmetic-side-effects-allowed-unary
@@ -80,6 +82,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            absolute-paths-max-segments
            accept-comment-above-attributes
            accept-comment-above-statement
+           allow-comparison-to-zero
            allow-dbg-in-tests
            allow-expect-in-tests
            allow-mixed-uninlined-format-args
@@ -91,6 +94,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            allowed-duplicate-crates
            allowed-idents-below-min-chars
            allowed-scripts
+           allowed-wildcard-imports
            arithmetic-side-effects-allowed
            arithmetic-side-effects-allowed-binary
            arithmetic-side-effects-allowed-unary
@@ -157,6 +161,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
            absolute-paths-max-segments
            accept-comment-above-attributes
            accept-comment-above-statement
+           allow-comparison-to-zero
            allow-dbg-in-tests
            allow-expect-in-tests
            allow-mixed-uninlined-format-args
@@ -168,6 +173,7 @@ error: error reading Clippy's configuration file: unknown field `allow_mixed_uni
            allowed-duplicate-crates
            allowed-idents-below-min-chars
            allowed-scripts
+           allowed-wildcard-imports
            arithmetic-side-effects-allowed
            arithmetic-side-effects-allowed-binary
            arithmetic-side-effects-allowed-unary
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml b/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml
index 875aaeef6c9..68815c1756a 100644
--- a/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml
@@ -1 +1,4 @@
 warn-on-all-wildcard-imports = true
+
+# This should be ignored since `warn-on-all-wildcard-imports` has higher precedence
+allowed-wildcard-imports = ["utils"]
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
index 1752f48856c..af72d6be0e0 100644
--- a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
@@ -3,9 +3,28 @@
 mod prelude {
     pub const FOO: u8 = 1;
 }
+
+mod utils {
+    pub const BAR: u8 = 1;
+    pub fn print() {}
+}
+
+mod my_crate {
+    pub mod utils {
+        pub fn my_util_fn() {}
+    }
+}
+
+use utils::{BAR, print};
+//~^ ERROR: usage of wildcard import
+use my_crate::utils::my_util_fn;
+//~^ ERROR: usage of wildcard import
 use prelude::FOO;
 //~^ ERROR: usage of wildcard import
 
 fn main() {
     let _ = FOO;
+    let _ = BAR;
+    print();
+    my_util_fn();
 }
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
index 331c2c59c22..91009dd8835 100644
--- a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
@@ -3,9 +3,28 @@
 mod prelude {
     pub const FOO: u8 = 1;
 }
+
+mod utils {
+    pub const BAR: u8 = 1;
+    pub fn print() {}
+}
+
+mod my_crate {
+    pub mod utils {
+        pub fn my_util_fn() {}
+    }
+}
+
+use utils::*;
+//~^ ERROR: usage of wildcard import
+use my_crate::utils::*;
+//~^ ERROR: usage of wildcard import
 use prelude::*;
 //~^ ERROR: usage of wildcard import
 
 fn main() {
     let _ = FOO;
+    let _ = BAR;
+    print();
+    my_util_fn();
 }
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
index f11fda6a0c6..a733d786d0e 100644
--- a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
@@ -1,11 +1,23 @@
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:6:5
+  --> $DIR/wildcard_imports.rs:18:5
    |
-LL | use prelude::*;
-   |     ^^^^^^^^^^ help: try: `prelude::FOO`
+LL | use utils::*;
+   |     ^^^^^^^^ help: try: `utils::{BAR, print}`
    |
    = note: `-D clippy::wildcard-imports` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
 
-error: aborting due to 1 previous error
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:20:5
+   |
+LL | use my_crate::utils::*;
+   |     ^^^^^^^^^^^^^^^^^^ help: try: `my_crate::utils::my_util_fn`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:22:5
+   |
+LL | use prelude::*;
+   |     ^^^^^^^^^^ help: try: `prelude::FOO`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/clippy.toml b/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/clippy.toml
new file mode 100644
index 00000000000..6b7882e64a8
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/clippy.toml
@@ -0,0 +1 @@
+allowed-wildcard-imports = ["utils"]
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.fixed b/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.fixed
new file mode 100644
index 00000000000..d539525c45e
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.fixed
@@ -0,0 +1,26 @@
+#![warn(clippy::wildcard_imports)]
+
+mod utils {
+    pub fn print() {}
+}
+
+mod utils_plus {
+    pub fn do_something() {}
+}
+
+mod my_crate {
+    pub mod utils {
+        pub fn my_util_fn() {}
+    }
+}
+
+use my_crate::utils::*;
+use utils::*;
+use utils_plus::do_something;
+//~^ ERROR: usage of wildcard import
+
+fn main() {
+    print();
+    my_util_fn();
+    do_something();
+}
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs b/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs
new file mode 100644
index 00000000000..9169d16a08b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.rs
@@ -0,0 +1,26 @@
+#![warn(clippy::wildcard_imports)]
+
+mod utils {
+    pub fn print() {}
+}
+
+mod utils_plus {
+    pub fn do_something() {}
+}
+
+mod my_crate {
+    pub mod utils {
+        pub fn my_util_fn() {}
+    }
+}
+
+use my_crate::utils::*;
+use utils::*;
+use utils_plus::*;
+//~^ ERROR: usage of wildcard import
+
+fn main() {
+    print();
+    my_util_fn();
+    do_something();
+}
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.stderr b/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.stderr
new file mode 100644
index 00000000000..12c2f9cbada
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports_whitelist/wildcard_imports.stderr
@@ -0,0 +1,11 @@
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:19:5
+   |
+LL | use utils_plus::*;
+   |     ^^^^^^^^^^^^^ help: try: `utils_plus::do_something`
+   |
+   = note: `-D clippy::wildcard-imports` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
index 6c0de96d65e..289a5ef38b8 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.fixed
@@ -5,6 +5,7 @@ fn a() -> i32 {
     0
 }
 
+#[clippy::msrv = "1.75"]
 fn main() {
     let val = 1;
     let _p = std::ptr::addr_of!(val);
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.rs b/src/tools/clippy/tests/ui/borrow_as_ptr.rs
index c37c5357c82..b5328cb22dc 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.rs
@@ -5,6 +5,7 @@ fn a() -> i32 {
     0
 }
 
+#[clippy::msrv = "1.75"]
 fn main() {
     let val = 1;
     let _p = &val as *const i32;
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr.stderr b/src/tools/clippy/tests/ui/borrow_as_ptr.stderr
index 43a7a6bf5b5..b9861805905 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr.stderr
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr.stderr
@@ -1,5 +1,5 @@
 error: borrow as raw pointer
-  --> $DIR/borrow_as_ptr.rs:10:14
+  --> $DIR/borrow_as_ptr.rs:11:14
    |
 LL |     let _p = &val as *const i32;
    |              ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of!(val)`
@@ -8,7 +8,7 @@ LL |     let _p = &val as *const i32;
    = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`
 
 error: borrow as raw pointer
-  --> $DIR/borrow_as_ptr.rs:17:18
+  --> $DIR/borrow_as_ptr.rs:18:18
    |
 LL |     let _p_mut = &mut val_mut as *mut i32;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::addr_of_mut!(val_mut)`
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed
index a361a36474d..f66554de300 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.fixed
@@ -2,6 +2,7 @@
 #![feature(lang_items, start, libc)]
 #![no_std]
 
+#[clippy::msrv = "1.75"]
 #[start]
 fn main(_argc: isize, _argv: *const *const u8) -> isize {
     let val = 1;
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs
index b3fe01442b7..1fc254aafa7 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.rs
@@ -2,6 +2,7 @@
 #![feature(lang_items, start, libc)]
 #![no_std]
 
+#[clippy::msrv = "1.75"]
 #[start]
 fn main(_argc: isize, _argv: *const *const u8) -> isize {
     let val = 1;
diff --git a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr
index 2f258bcf966..1ef0a948a32 100644
--- a/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr
+++ b/src/tools/clippy/tests/ui/borrow_as_ptr_no_std.stderr
@@ -1,5 +1,5 @@
 error: borrow as raw pointer
-  --> $DIR/borrow_as_ptr_no_std.rs:8:14
+  --> $DIR/borrow_as_ptr_no_std.rs:9:14
    |
 LL |     let _p = &val as *const i32;
    |              ^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of!(val)`
@@ -8,7 +8,7 @@ LL |     let _p = &val as *const i32;
    = help: to override `-D warnings` add `#[allow(clippy::borrow_as_ptr)]`
 
 error: borrow as raw pointer
-  --> $DIR/borrow_as_ptr_no_std.rs:11:18
+  --> $DIR/borrow_as_ptr_no_std.rs:12:18
    |
 LL |     let _p_mut = &mut val_mut as *mut i32;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::addr_of_mut!(val_mut)`
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index 32c7499bf73..da28ec2e653 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -346,6 +346,23 @@ fn angle_brackets_and_args() {
     dyn_opt.map(<dyn TestTrait>::method_on_dyn);
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/12199
+fn track_caller_fp() {
+    struct S;
+    impl S {
+        #[track_caller]
+        fn add_location(self) {}
+    }
+
+    #[track_caller]
+    fn add_location() {}
+
+    fn foo(_: fn()) {}
+    fn foo2(_: fn(S)) {}
+    foo(|| add_location());
+    foo2(|s| s.add_location());
+}
+
 fn _late_bound_to_early_bound_regions() {
     struct Foo<'a>(&'a u32);
     impl<'a> Foo<'a> {
@@ -400,3 +417,57 @@ fn _closure_with_types() {
     let _ = f2(|x: u32| f(x));
     let _ = f2(|x| -> u32 { f(x) });
 }
+
+/// https://github.com/rust-lang/rust-clippy/issues/10854
+/// This is to verify that redundant_closure_for_method_calls resolves suggested paths to relative.
+mod issue_10854 {
+    pub mod test_mod {
+        pub struct Test;
+
+        impl Test {
+            pub fn method(self) -> i32 {
+                0
+            }
+        }
+
+        pub fn calls_test(test: Option<Test>) -> Option<i32> {
+            test.map(Test::method)
+        }
+
+        pub fn calls_outer(test: Option<super::Outer>) -> Option<i32> {
+            test.map(super::Outer::method)
+        }
+    }
+
+    pub struct Outer;
+
+    impl Outer {
+        pub fn method(self) -> i32 {
+            0
+        }
+    }
+
+    pub fn calls_into_mod(test: Option<test_mod::Test>) -> Option<i32> {
+        test.map(test_mod::Test::method)
+    }
+
+    mod a {
+        pub mod b {
+            pub mod c {
+                pub fn extreme_nesting(test: Option<super::super::super::d::Test>) -> Option<i32> {
+                    test.map(crate::issue_10854::d::Test::method)
+                }
+            }
+        }
+    }
+
+    mod d {
+        pub struct Test;
+
+        impl Test {
+            pub fn method(self) -> i32 {
+                0
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index 25b7431ba8c..f924100f8f4 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -346,6 +346,23 @@ fn angle_brackets_and_args() {
     dyn_opt.map(|d| d.method_on_dyn());
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/12199
+fn track_caller_fp() {
+    struct S;
+    impl S {
+        #[track_caller]
+        fn add_location(self) {}
+    }
+
+    #[track_caller]
+    fn add_location() {}
+
+    fn foo(_: fn()) {}
+    fn foo2(_: fn(S)) {}
+    foo(|| add_location());
+    foo2(|s| s.add_location());
+}
+
 fn _late_bound_to_early_bound_regions() {
     struct Foo<'a>(&'a u32);
     impl<'a> Foo<'a> {
@@ -400,3 +417,57 @@ fn _closure_with_types() {
     let _ = f2(|x: u32| f(x));
     let _ = f2(|x| -> u32 { f(x) });
 }
+
+/// https://github.com/rust-lang/rust-clippy/issues/10854
+/// This is to verify that redundant_closure_for_method_calls resolves suggested paths to relative.
+mod issue_10854 {
+    pub mod test_mod {
+        pub struct Test;
+
+        impl Test {
+            pub fn method(self) -> i32 {
+                0
+            }
+        }
+
+        pub fn calls_test(test: Option<Test>) -> Option<i32> {
+            test.map(|t| t.method())
+        }
+
+        pub fn calls_outer(test: Option<super::Outer>) -> Option<i32> {
+            test.map(|t| t.method())
+        }
+    }
+
+    pub struct Outer;
+
+    impl Outer {
+        pub fn method(self) -> i32 {
+            0
+        }
+    }
+
+    pub fn calls_into_mod(test: Option<test_mod::Test>) -> Option<i32> {
+        test.map(|t| t.method())
+    }
+
+    mod a {
+        pub mod b {
+            pub mod c {
+                pub fn extreme_nesting(test: Option<super::super::super::d::Test>) -> Option<i32> {
+                    test.map(|t| t.method())
+                }
+            }
+        }
+    }
+
+    mod d {
+        pub struct Test;
+
+        impl Test {
+            pub fn method(self) -> i32 {
+                0
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index 951e4ac749c..945de466d83 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -161,10 +161,34 @@ LL |     dyn_opt.map(|d| d.method_on_dyn());
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
 
 error: redundant closure
-  --> $DIR/eta.rs:389:19
+  --> $DIR/eta.rs:406:19
    |
 LL |     let _ = f(&0, |x, y| f2(x, y));
    |                   ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`
 
-error: aborting due to 27 previous errors
+error: redundant closure
+  --> $DIR/eta.rs:434:22
+   |
+LL |             test.map(|t| t.method())
+   |                      ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `Test::method`
+
+error: redundant closure
+  --> $DIR/eta.rs:438:22
+   |
+LL |             test.map(|t| t.method())
+   |                      ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `super::Outer::method`
+
+error: redundant closure
+  --> $DIR/eta.rs:451:18
+   |
+LL |         test.map(|t| t.method())
+   |                  ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `test_mod::Test::method`
+
+error: redundant closure
+  --> $DIR/eta.rs:458:30
+   |
+LL |                     test.map(|t| t.method())
+   |                              ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `crate::issue_10854::d::Test::method`
+
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/format_args.fixed b/src/tools/clippy/tests/ui/format_args.fixed
index ddd5976c408..cab20b11e07 100644
--- a/src/tools/clippy/tests/ui/format_args.fixed
+++ b/src/tools/clippy/tests/ui/format_args.fixed
@@ -14,6 +14,7 @@ use std::panic::Location;
 
 struct Somewhere;
 
+#[allow(clippy::to_string_trait_impl)]
 impl ToString for Somewhere {
     fn to_string(&self) -> String {
         String::from("somewhere")
diff --git a/src/tools/clippy/tests/ui/format_args.rs b/src/tools/clippy/tests/ui/format_args.rs
index 18e1bc1af67..bc3645cb2c2 100644
--- a/src/tools/clippy/tests/ui/format_args.rs
+++ b/src/tools/clippy/tests/ui/format_args.rs
@@ -14,6 +14,7 @@ use std::panic::Location;
 
 struct Somewhere;
 
+#[allow(clippy::to_string_trait_impl)]
 impl ToString for Somewhere {
     fn to_string(&self) -> String {
         String::from("somewhere")
diff --git a/src/tools/clippy/tests/ui/format_args.stderr b/src/tools/clippy/tests/ui/format_args.stderr
index dcdfa668aff..2f1714296d6 100644
--- a/src/tools/clippy/tests/ui/format_args.stderr
+++ b/src/tools/clippy/tests/ui/format_args.stderr
@@ -1,5 +1,5 @@
 error: `to_string` applied to a type that implements `Display` in `format!` args
-  --> $DIR/format_args.rs:76:72
+  --> $DIR/format_args.rs:77:72
    |
 LL |     let _ = format!("error: something failed at {}", Location::caller().to_string());
    |                                                                        ^^^^^^^^^^^^ help: remove this
@@ -8,145 +8,145 @@ LL |     let _ = format!("error: something failed at {}", Location::caller().to_
    = help: to override `-D warnings` add `#[allow(clippy::to_string_in_format_args)]`
 
 error: `to_string` applied to a type that implements `Display` in `write!` args
-  --> $DIR/format_args.rs:80:27
+  --> $DIR/format_args.rs:81:27
    |
 LL |         Location::caller().to_string()
    |                           ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `writeln!` args
-  --> $DIR/format_args.rs:85:27
+  --> $DIR/format_args.rs:86:27
    |
 LL |         Location::caller().to_string()
    |                           ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `print!` args
-  --> $DIR/format_args.rs:87:63
+  --> $DIR/format_args.rs:88:63
    |
 LL |     print!("error: something failed at {}", Location::caller().to_string());
    |                                                               ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:88:65
+  --> $DIR/format_args.rs:89:65
    |
 LL |     println!("error: something failed at {}", Location::caller().to_string());
    |                                                                 ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `eprint!` args
-  --> $DIR/format_args.rs:89:64
+  --> $DIR/format_args.rs:90:64
    |
 LL |     eprint!("error: something failed at {}", Location::caller().to_string());
    |                                                                ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `eprintln!` args
-  --> $DIR/format_args.rs:90:66
+  --> $DIR/format_args.rs:91:66
    |
 LL |     eprintln!("error: something failed at {}", Location::caller().to_string());
    |                                                                  ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `format_args!` args
-  --> $DIR/format_args.rs:91:77
+  --> $DIR/format_args.rs:92:77
    |
 LL |     let _ = format_args!("error: something failed at {}", Location::caller().to_string());
    |                                                                             ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `assert!` args
-  --> $DIR/format_args.rs:92:70
+  --> $DIR/format_args.rs:93:70
    |
 LL |     assert!(true, "error: something failed at {}", Location::caller().to_string());
    |                                                                      ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `assert_eq!` args
-  --> $DIR/format_args.rs:93:73
+  --> $DIR/format_args.rs:94:73
    |
 LL |     assert_eq!(0, 0, "error: something failed at {}", Location::caller().to_string());
    |                                                                         ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `assert_ne!` args
-  --> $DIR/format_args.rs:94:73
+  --> $DIR/format_args.rs:95:73
    |
 LL |     assert_ne!(0, 0, "error: something failed at {}", Location::caller().to_string());
    |                                                                         ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `panic!` args
-  --> $DIR/format_args.rs:95:63
+  --> $DIR/format_args.rs:96:63
    |
 LL |     panic!("error: something failed at {}", Location::caller().to_string());
    |                                                               ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:96:20
+  --> $DIR/format_args.rs:97:20
    |
 LL |     println!("{}", X(1).to_string());
    |                    ^^^^^^^^^^^^^^^^ help: use this: `*X(1)`
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:97:20
+  --> $DIR/format_args.rs:98:20
    |
 LL |     println!("{}", Y(&X(1)).to_string());
    |                    ^^^^^^^^^^^^^^^^^^^^ help: use this: `***Y(&X(1))`
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:98:24
+  --> $DIR/format_args.rs:99:24
    |
 LL |     println!("{}", Z(1).to_string());
    |                        ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:99:20
+  --> $DIR/format_args.rs:100:20
    |
 LL |     println!("{}", x.to_string());
    |                    ^^^^^^^^^^^^^ help: use this: `**x`
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:100:20
+  --> $DIR/format_args.rs:101:20
    |
 LL |     println!("{}", x_ref.to_string());
    |                    ^^^^^^^^^^^^^^^^^ help: use this: `***x_ref`
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:102:39
+  --> $DIR/format_args.rs:103:39
    |
 LL |     println!("{foo}{bar}", foo = "foo".to_string(), bar = "bar");
    |                                       ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:103:52
+  --> $DIR/format_args.rs:104:52
    |
 LL |     println!("{foo}{bar}", foo = "foo", bar = "bar".to_string());
    |                                                    ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:104:39
+  --> $DIR/format_args.rs:105:39
    |
 LL |     println!("{foo}{bar}", bar = "bar".to_string(), foo = "foo");
    |                                       ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:105:52
+  --> $DIR/format_args.rs:106:52
    |
 LL |     println!("{foo}{bar}", bar = "bar", foo = "foo".to_string());
    |                                                    ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `print!` args
-  --> $DIR/format_args.rs:117:37
+  --> $DIR/format_args.rs:118:37
    |
 LL |     print!("{}", (Location::caller().to_string()));
    |                                     ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `print!` args
-  --> $DIR/format_args.rs:118:39
+  --> $DIR/format_args.rs:119:39
    |
 LL |     print!("{}", ((Location::caller()).to_string()));
    |                                       ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `format!` args
-  --> $DIR/format_args.rs:146:38
+  --> $DIR/format_args.rs:147:38
    |
 LL |         let x = format!("{} {}", a, b.to_string());
    |                                      ^^^^^^^^^^^^ help: remove this
 
 error: `to_string` applied to a type that implements `Display` in `println!` args
-  --> $DIR/format_args.rs:160:24
+  --> $DIR/format_args.rs:161:24
    |
 LL |         println!("{}", original[..10].to_string());
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use this: `&original[..10]`
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
index 707a0e76e4e..118f0b48895 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
@@ -1,6 +1,11 @@
 //@aux-build:proc_macro_derive.rs
 #![warn(clippy::ignored_unit_patterns)]
-#![allow(clippy::let_unit_value, clippy::redundant_pattern_matching, clippy::single_match)]
+#![allow(
+    clippy::let_unit_value,
+    clippy::redundant_pattern_matching,
+    clippy::single_match,
+    clippy::needless_borrow
+)]
 
 fn foo() -> Result<(), ()> {
     unimplemented!()
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
index 544f2b8f692..92feb9e6c28 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
@@ -1,6 +1,11 @@
 //@aux-build:proc_macro_derive.rs
 #![warn(clippy::ignored_unit_patterns)]
-#![allow(clippy::let_unit_value, clippy::redundant_pattern_matching, clippy::single_match)]
+#![allow(
+    clippy::let_unit_value,
+    clippy::redundant_pattern_matching,
+    clippy::single_match,
+    clippy::needless_borrow
+)]
 
 fn foo() -> Result<(), ()> {
     unimplemented!()
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
index 05c8f281e55..18ca7ebbcf2 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
@@ -1,5 +1,5 @@
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:11:12
+  --> $DIR/ignored_unit_patterns.rs:16:12
    |
 LL |         Ok(_) => {},
    |            ^ help: use `()` instead of `_`: `()`
@@ -8,49 +8,49 @@ LL |         Ok(_) => {},
    = help: to override `-D warnings` add `#[allow(clippy::ignored_unit_patterns)]`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:12:13
+  --> $DIR/ignored_unit_patterns.rs:17:13
    |
 LL |         Err(_) => {},
    |             ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:14:15
+  --> $DIR/ignored_unit_patterns.rs:19:15
    |
 LL |     if let Ok(_) = foo() {}
    |               ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:16:28
+  --> $DIR/ignored_unit_patterns.rs:21:28
    |
 LL |     let _ = foo().map_err(|_| todo!());
    |                            ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:22:16
+  --> $DIR/ignored_unit_patterns.rs:27:16
    |
 LL |             Ok(_) => {},
    |                ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:24:17
+  --> $DIR/ignored_unit_patterns.rs:29:17
    |
 LL |             Err(_) => {},
    |                 ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:36:9
+  --> $DIR/ignored_unit_patterns.rs:41:9
    |
 LL |     let _ = foo().unwrap();
    |         ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:45:13
+  --> $DIR/ignored_unit_patterns.rs:50:13
    |
 LL |         (1, _) => unimplemented!(),
    |             ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:52:13
+  --> $DIR/ignored_unit_patterns.rs:57:13
    |
 LL |     for (x, _) in v {
    |             ^ help: use `()` instead of `_`: `()`
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.rs b/src/tools/clippy/tests/ui/incompatible_msrv.rs
new file mode 100644
index 00000000000..a92017fb0f6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.rs
@@ -0,0 +1,23 @@
+#![warn(clippy::incompatible_msrv)]
+#![feature(custom_inner_attributes)]
+#![clippy::msrv = "1.3.0"]
+
+use std::collections::hash_map::Entry;
+use std::collections::HashMap;
+use std::thread::sleep;
+use std::time::Duration;
+
+fn foo() {
+    let mut map: HashMap<&str, u32> = HashMap::new();
+    assert_eq!(map.entry("poneyland").key(), &"poneyland");
+    //~^ ERROR: is `1.3.0` but this item is stable since `1.10.0`
+    if let Entry::Vacant(v) = map.entry("poneyland") {
+        v.into_key();
+        //~^ ERROR: is `1.3.0` but this item is stable since `1.12.0`
+    }
+    // Should warn for `sleep` but not for `Duration` (which was added in `1.3.0`).
+    sleep(Duration::new(1, 0));
+    //~^ ERROR: is `1.3.0` but this item is stable since `1.4.0`
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.stderr b/src/tools/clippy/tests/ui/incompatible_msrv.stderr
new file mode 100644
index 00000000000..bd5ecd6ed2f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.stderr
@@ -0,0 +1,23 @@
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.10.0`
+  --> $DIR/incompatible_msrv.rs:12:39
+   |
+LL |     assert_eq!(map.entry("poneyland").key(), &"poneyland");
+   |                                       ^^^^^
+   |
+   = note: `-D clippy::incompatible-msrv` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.12.0`
+  --> $DIR/incompatible_msrv.rs:15:11
+   |
+LL |         v.into_key();
+   |           ^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`
+  --> $DIR/incompatible_msrv.rs:19:5
+   |
+LL |     sleep(Duration::new(1, 0));
+   |     ^^^^^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_c_str_literals.fixed b/src/tools/clippy/tests/ui/manual_c_str_literals.fixed
new file mode 100644
index 00000000000..a24d7088c88
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_c_str_literals.fixed
@@ -0,0 +1,60 @@
+#![warn(clippy::manual_c_str_literals)]
+#![allow(clippy::no_effect)]
+
+use std::ffi::CStr;
+
+macro_rules! cstr {
+    ($s:literal) => {
+        CStr::from_bytes_with_nul(concat!($s, "\0").as_bytes()).unwrap()
+    };
+}
+
+macro_rules! macro_returns_c_str {
+    () => {
+        CStr::from_bytes_with_nul(b"foo\0").unwrap();
+    };
+}
+
+macro_rules! macro_returns_byte_string {
+    () => {
+        b"foo\0"
+    };
+}
+
+#[clippy::msrv = "1.76.0"]
+fn pre_stabilization() {
+    CStr::from_bytes_with_nul(b"foo\0");
+}
+
+#[clippy::msrv = "1.77.0"]
+fn post_stabilization() {
+    c"foo";
+}
+
+fn main() {
+    c"foo";
+    c"foo";
+    c"foo";
+    c"foo\\0sdsd";
+    CStr::from_bytes_with_nul(br"foo\\0sdsd\0").unwrap();
+    CStr::from_bytes_with_nul(br"foo\x00").unwrap();
+    CStr::from_bytes_with_nul(br##"foo#a\0"##).unwrap();
+
+    unsafe { c"foo" };
+    unsafe { c"foo" };
+    let _: *const _ = c"foo".as_ptr();
+    let _: *const _ = c"foo".as_ptr();
+    let _: *const _ = "foo".as_ptr(); // not a C-string
+    let _: *const _ = "".as_ptr();
+    let _: *const _ = c"foo".as_ptr().cast::<i8>();
+    let _ = "电脑".as_ptr();
+    let _ = "电脑\\".as_ptr();
+    let _ = c"电脑\\".as_ptr();
+    let _ = c"电脑".as_ptr();
+    let _ = c"电脑".as_ptr();
+
+    // Macro cases, don't lint:
+    cstr!("foo");
+    macro_returns_c_str!();
+    CStr::from_bytes_with_nul(macro_returns_byte_string!()).unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/manual_c_str_literals.rs b/src/tools/clippy/tests/ui/manual_c_str_literals.rs
new file mode 100644
index 00000000000..0a007786720
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_c_str_literals.rs
@@ -0,0 +1,60 @@
+#![warn(clippy::manual_c_str_literals)]
+#![allow(clippy::no_effect)]
+
+use std::ffi::CStr;
+
+macro_rules! cstr {
+    ($s:literal) => {
+        CStr::from_bytes_with_nul(concat!($s, "\0").as_bytes()).unwrap()
+    };
+}
+
+macro_rules! macro_returns_c_str {
+    () => {
+        CStr::from_bytes_with_nul(b"foo\0").unwrap();
+    };
+}
+
+macro_rules! macro_returns_byte_string {
+    () => {
+        b"foo\0"
+    };
+}
+
+#[clippy::msrv = "1.76.0"]
+fn pre_stabilization() {
+    CStr::from_bytes_with_nul(b"foo\0");
+}
+
+#[clippy::msrv = "1.77.0"]
+fn post_stabilization() {
+    CStr::from_bytes_with_nul(b"foo\0");
+}
+
+fn main() {
+    CStr::from_bytes_with_nul(b"foo\0");
+    CStr::from_bytes_with_nul(b"foo\x00");
+    CStr::from_bytes_with_nul(b"foo\0").unwrap();
+    CStr::from_bytes_with_nul(b"foo\\0sdsd\0").unwrap();
+    CStr::from_bytes_with_nul(br"foo\\0sdsd\0").unwrap();
+    CStr::from_bytes_with_nul(br"foo\x00").unwrap();
+    CStr::from_bytes_with_nul(br##"foo#a\0"##).unwrap();
+
+    unsafe { CStr::from_ptr(b"foo\0".as_ptr().cast()) };
+    unsafe { CStr::from_ptr(b"foo\0".as_ptr() as *const _) };
+    let _: *const _ = b"foo\0".as_ptr();
+    let _: *const _ = "foo\0".as_ptr();
+    let _: *const _ = "foo".as_ptr(); // not a C-string
+    let _: *const _ = "".as_ptr();
+    let _: *const _ = b"foo\0".as_ptr().cast::<i8>();
+    let _ = "电脑".as_ptr();
+    let _ = "电脑\\".as_ptr();
+    let _ = "电脑\\\0".as_ptr();
+    let _ = "电脑\0".as_ptr();
+    let _ = "电脑\x00".as_ptr();
+
+    // Macro cases, don't lint:
+    cstr!("foo");
+    macro_returns_c_str!();
+    CStr::from_bytes_with_nul(macro_returns_byte_string!()).unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/manual_c_str_literals.stderr b/src/tools/clippy/tests/ui/manual_c_str_literals.stderr
new file mode 100644
index 00000000000..8de4e16f010
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_c_str_literals.stderr
@@ -0,0 +1,83 @@
+error: calling `CStr::new` with a byte string literal
+  --> $DIR/manual_c_str_literals.rs:31:5
+   |
+LL |     CStr::from_bytes_with_nul(b"foo\0");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"`
+   |
+   = note: `-D clippy::manual-c-str-literals` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_c_str_literals)]`
+
+error: calling `CStr::new` with a byte string literal
+  --> $DIR/manual_c_str_literals.rs:35:5
+   |
+LL |     CStr::from_bytes_with_nul(b"foo\0");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"`
+
+error: calling `CStr::new` with a byte string literal
+  --> $DIR/manual_c_str_literals.rs:36:5
+   |
+LL |     CStr::from_bytes_with_nul(b"foo\x00");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"`
+
+error: calling `CStr::new` with a byte string literal
+  --> $DIR/manual_c_str_literals.rs:37:5
+   |
+LL |     CStr::from_bytes_with_nul(b"foo\0").unwrap();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"`
+
+error: calling `CStr::new` with a byte string literal
+  --> $DIR/manual_c_str_literals.rs:38:5
+   |
+LL |     CStr::from_bytes_with_nul(b"foo\\0sdsd\0").unwrap();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo\\0sdsd"`
+
+error: calling `CStr::from_ptr` with a byte string literal
+  --> $DIR/manual_c_str_literals.rs:43:14
+   |
+LL |     unsafe { CStr::from_ptr(b"foo\0".as_ptr().cast()) };
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"`
+
+error: calling `CStr::from_ptr` with a byte string literal
+  --> $DIR/manual_c_str_literals.rs:44:14
+   |
+LL |     unsafe { CStr::from_ptr(b"foo\0".as_ptr() as *const _) };
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use a `c""` literal: `c"foo"`
+
+error: manually constructing a nul-terminated string
+  --> $DIR/manual_c_str_literals.rs:45:23
+   |
+LL |     let _: *const _ = b"foo\0".as_ptr();
+   |                       ^^^^^^^^ help: use a `c""` literal: `c"foo"`
+
+error: manually constructing a nul-terminated string
+  --> $DIR/manual_c_str_literals.rs:46:23
+   |
+LL |     let _: *const _ = "foo\0".as_ptr();
+   |                       ^^^^^^^ help: use a `c""` literal: `c"foo"`
+
+error: manually constructing a nul-terminated string
+  --> $DIR/manual_c_str_literals.rs:49:23
+   |
+LL |     let _: *const _ = b"foo\0".as_ptr().cast::<i8>();
+   |                       ^^^^^^^^ help: use a `c""` literal: `c"foo"`
+
+error: manually constructing a nul-terminated string
+  --> $DIR/manual_c_str_literals.rs:52:13
+   |
+LL |     let _ = "电脑\\\0".as_ptr();
+   |             ^^^^^^^^^^ help: use a `c""` literal: `c"电脑\\"`
+
+error: manually constructing a nul-terminated string
+  --> $DIR/manual_c_str_literals.rs:53:13
+   |
+LL |     let _ = "电脑\0".as_ptr();
+   |             ^^^^^^^^ help: use a `c""` literal: `c"电脑"`
+
+error: manually constructing a nul-terminated string
+  --> $DIR/manual_c_str_literals.rs:54:13
+   |
+LL |     let _ = "电脑\x00".as_ptr();
+   |             ^^^^^^^^^^ help: use a `c""` literal: `c"电脑"`
+
+error: aborting due to 13 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_retain.fixed b/src/tools/clippy/tests/ui/manual_retain.fixed
index 4dea3e8bfe6..5540029bf6b 100644
--- a/src/tools/clippy/tests/ui/manual_retain.fixed
+++ b/src/tools/clippy/tests/ui/manual_retain.fixed
@@ -14,6 +14,9 @@ fn main() {
     _msrv_153();
     _msrv_126();
     _msrv_118();
+
+    issue_10393();
+    issue_12081();
 }
 
 fn binary_heap_retain() {
@@ -23,6 +26,11 @@ fn binary_heap_retain() {
     binary_heap.retain(|x| x % 2 == 0);
     binary_heap.retain(|x| x % 2 == 0);
 
+    // Do lint, because we use pattern matching
+    let mut tuples = BinaryHeap::from([(0, 1), (1, 2), (2, 3)]);
+    tuples.retain(|(ref x, ref y)| *x == 0);
+    tuples.retain(|(x, y)| *x == 0);
+
     // Do not lint, because type conversion is performed
     binary_heap = binary_heap
         .into_iter()
@@ -55,6 +63,9 @@ fn btree_map_retain() {
     btree_map.retain(|_, &mut v| v % 2 == 0);
     btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
 
+    // Do not lint, because the parameters are not matched in tuple pattern
+    btree_map = btree_map.into_iter().filter(|t| t.0 % 2 == 0).collect();
+
     // Do not lint.
     btree_map = btree_map
         .into_iter()
@@ -76,6 +87,11 @@ fn btree_set_retain() {
     btree_set.retain(|x| x % 2 == 0);
     btree_set.retain(|x| x % 2 == 0);
 
+    // Do lint, because we use pattern matching
+    let mut tuples = BTreeSet::from([(0, 1), (1, 2), (2, 3)]);
+    tuples.retain(|(ref x, ref y)| *x == 0);
+    tuples.retain(|(x, y)| *x == 0);
+
     // Do not lint, because type conversion is performed
     btree_set = btree_set
         .iter()
@@ -108,6 +124,9 @@ fn hash_map_retain() {
     hash_map.retain(|_, &mut v| v % 2 == 0);
     hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0));
 
+    // Do not lint, because the parameters are not matched in tuple pattern
+    hash_map = hash_map.into_iter().filter(|t| t.0 % 2 == 0).collect();
+
     // Do not lint.
     hash_map = hash_map
         .into_iter()
@@ -128,6 +147,11 @@ fn hash_set_retain() {
     hash_set.retain(|x| x % 2 == 0);
     hash_set.retain(|x| x % 2 == 0);
 
+    // Do lint, because we use pattern matching
+    let mut tuples = HashSet::from([(0, 1), (1, 2), (2, 3)]);
+    tuples.retain(|(ref x, ref y)| *x == 0);
+    tuples.retain(|(x, y)| *x == 0);
+
     // Do not lint, because type conversion is performed
     hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();
     hash_set = hash_set
@@ -171,6 +195,11 @@ fn vec_retain() {
     vec.retain(|x| x % 2 == 0);
     vec.retain(|x| x % 2 == 0);
 
+    // Do lint, because we use pattern matching
+    let mut tuples = vec![(0, 1), (1, 2), (2, 3)];
+    tuples.retain(|(ref x, ref y)| *x == 0);
+    tuples.retain(|(x, y)| *x == 0);
+
     // Do not lint, because type conversion is performed
     vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();
     vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();
@@ -246,3 +275,37 @@ fn _msrv_118() {
     let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
     hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
 }
+
+fn issue_10393() {
+    // Do lint
+    let mut vec = vec![(0, 1), (1, 2), (2, 3)];
+    vec.retain(|(x, y)| *x == 0);
+
+    // Do lint
+    let mut tuples = vec![(true, -2), (false, 3)];
+    tuples.retain(|(_, n)| *n > 0);
+}
+
+fn issue_11457() {
+    // Do not lint, as we need to modify the closure
+    let mut vals = vec![1, 2, 3, 4];
+    vals = vals.iter().filter(|v| **v != 1).cloned().collect();
+
+    // Do not lint, as we need to modify the closure
+    let mut s = String::from("foobar");
+    s = s.chars().filter(|c| *c != 'o').to_owned().collect();
+}
+
+fn issue_12081() {
+    let mut vec = vec![0, 1, 2];
+
+    // Do lint
+    vec.retain(|&x| x == 0);
+    vec.retain(|&x| x == 0);
+    vec.retain(|&x| x == 0);
+
+    // Do lint
+    vec.retain(|x| *x == 0);
+    vec.retain(|x| *x == 0);
+    vec.retain(|x| *x == 0);
+}
diff --git a/src/tools/clippy/tests/ui/manual_retain.rs b/src/tools/clippy/tests/ui/manual_retain.rs
index d839550f33a..cee641d9d65 100644
--- a/src/tools/clippy/tests/ui/manual_retain.rs
+++ b/src/tools/clippy/tests/ui/manual_retain.rs
@@ -14,6 +14,9 @@ fn main() {
     _msrv_153();
     _msrv_126();
     _msrv_118();
+
+    issue_10393();
+    issue_12081();
 }
 
 fn binary_heap_retain() {
@@ -23,6 +26,11 @@ fn binary_heap_retain() {
     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
 
+    // Do lint, because we use pattern matching
+    let mut tuples = BinaryHeap::from([(0, 1), (1, 2), (2, 3)]);
+    tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
+    tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
+
     // Do not lint, because type conversion is performed
     binary_heap = binary_heap
         .into_iter()
@@ -58,6 +66,9 @@ fn btree_map_retain() {
         .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))
         .collect();
 
+    // Do not lint, because the parameters are not matched in tuple pattern
+    btree_map = btree_map.into_iter().filter(|t| t.0 % 2 == 0).collect();
+
     // Do not lint.
     btree_map = btree_map
         .into_iter()
@@ -79,6 +90,11 @@ fn btree_set_retain() {
     btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
     btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
 
+    // Do lint, because we use pattern matching
+    let mut tuples = BTreeSet::from([(0, 1), (1, 2), (2, 3)]);
+    tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
+    tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
+
     // Do not lint, because type conversion is performed
     btree_set = btree_set
         .iter()
@@ -114,6 +130,9 @@ fn hash_map_retain() {
         .filter(|(k, v)| (k % 2 == 0) && (v % 2 == 0))
         .collect();
 
+    // Do not lint, because the parameters are not matched in tuple pattern
+    hash_map = hash_map.into_iter().filter(|t| t.0 % 2 == 0).collect();
+
     // Do not lint.
     hash_map = hash_map
         .into_iter()
@@ -134,6 +153,11 @@ fn hash_set_retain() {
     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
 
+    // Do lint, because we use pattern matching
+    let mut tuples = HashSet::from([(0, 1), (1, 2), (2, 3)]);
+    tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
+    tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
+
     // Do not lint, because type conversion is performed
     hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect::<HashSet<i8>>();
     hash_set = hash_set
@@ -177,6 +201,11 @@ fn vec_retain() {
     vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();
     vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
 
+    // Do lint, because we use pattern matching
+    let mut tuples = vec![(0, 1), (1, 2), (2, 3)];
+    tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
+    tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
+
     // Do not lint, because type conversion is performed
     vec = vec.into_iter().filter(|x| x % 2 == 0).collect::<Vec<i8>>();
     vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect::<Vec<i8>>();
@@ -252,3 +281,37 @@ fn _msrv_118() {
     let mut hash_map: HashMap<i8, i8> = (0..8).map(|x| (x, x * 10)).collect();
     hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
 }
+
+fn issue_10393() {
+    // Do lint
+    let mut vec = vec![(0, 1), (1, 2), (2, 3)];
+    vec = vec.into_iter().filter(|(x, y)| *x == 0).collect();
+
+    // Do lint
+    let mut tuples = vec![(true, -2), (false, 3)];
+    tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect();
+}
+
+fn issue_11457() {
+    // Do not lint, as we need to modify the closure
+    let mut vals = vec![1, 2, 3, 4];
+    vals = vals.iter().filter(|v| **v != 1).cloned().collect();
+
+    // Do not lint, as we need to modify the closure
+    let mut s = String::from("foobar");
+    s = s.chars().filter(|c| *c != 'o').to_owned().collect();
+}
+
+fn issue_12081() {
+    let mut vec = vec![0, 1, 2];
+
+    // Do lint
+    vec = vec.iter().filter(|&&x| x == 0).copied().collect();
+    vec = vec.iter().filter(|&&x| x == 0).cloned().collect();
+    vec = vec.into_iter().filter(|&x| x == 0).collect();
+
+    // Do lint
+    vec = vec.iter().filter(|&x| *x == 0).copied().collect();
+    vec = vec.iter().filter(|&x| *x == 0).cloned().collect();
+    vec = vec.into_iter().filter(|x| *x == 0).collect();
+}
diff --git a/src/tools/clippy/tests/ui/manual_retain.stderr b/src/tools/clippy/tests/ui/manual_retain.stderr
index 0c5b1383b6a..2c872f3b430 100644
--- a/src/tools/clippy/tests/ui/manual_retain.stderr
+++ b/src/tools/clippy/tests/ui/manual_retain.stderr
@@ -1,5 +1,5 @@
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:22:5
+  --> $DIR/manual_retain.rs:25:5
    |
 LL |     binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
@@ -8,31 +8,43 @@ LL |     binary_heap = binary_heap.into_iter().filter(|x| x % 2 == 0).collect();
    = help: to override `-D warnings` add `#[allow(clippy::manual_retain)]`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:23:5
+  --> $DIR/manual_retain.rs:26:5
    |
 LL |     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:24:5
+  --> $DIR/manual_retain.rs:27:5
    |
 LL |     binary_heap = binary_heap.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `binary_heap.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:54:5
+  --> $DIR/manual_retain.rs:31:5
+   |
+LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:32:5
+   |
+LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:62:5
    |
 LL |     btree_map = btree_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|k, _| k % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:55:5
+  --> $DIR/manual_retain.rs:63:5
    |
 LL |     btree_map = btree_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_map.retain(|_, &mut v| v % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:56:5
+  --> $DIR/manual_retain.rs:64:5
    |
 LL | /     btree_map = btree_map
 LL | |         .into_iter()
@@ -41,37 +53,49 @@ LL | |         .collect();
    | |__________________^ help: consider calling `.retain()` instead: `btree_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:78:5
+  --> $DIR/manual_retain.rs:89:5
    |
 LL |     btree_set = btree_set.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:79:5
+  --> $DIR/manual_retain.rs:90:5
    |
 LL |     btree_set = btree_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:80:5
+  --> $DIR/manual_retain.rs:91:5
    |
 LL |     btree_set = btree_set.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `btree_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:110:5
+  --> $DIR/manual_retain.rs:95:5
+   |
+LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:96:5
+   |
+LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:126:5
    |
 LL |     hash_map = hash_map.into_iter().filter(|(k, _)| k % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|k, _| k % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:111:5
+  --> $DIR/manual_retain.rs:127:5
    |
 LL |     hash_map = hash_map.into_iter().filter(|(_, v)| v % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_map.retain(|_, &mut v| v % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:112:5
+  --> $DIR/manual_retain.rs:128:5
    |
 LL | /     hash_map = hash_map
 LL | |         .into_iter()
@@ -80,64 +104,136 @@ LL | |         .collect();
    | |__________________^ help: consider calling `.retain()` instead: `hash_map.retain(|k, &mut v| (k % 2 == 0) && (v % 2 == 0))`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:133:5
+  --> $DIR/manual_retain.rs:152:5
    |
 LL |     hash_set = hash_set.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:134:5
+  --> $DIR/manual_retain.rs:153:5
    |
 LL |     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:135:5
+  --> $DIR/manual_retain.rs:154:5
    |
 LL |     hash_set = hash_set.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `hash_set.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:164:5
+  --> $DIR/manual_retain.rs:158:5
+   |
+LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:159:5
+   |
+LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:188:5
    |
 LL |     s = s.chars().filter(|&c| c != 'o').to_owned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `s.retain(|c| c != 'o')`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:176:5
+  --> $DIR/manual_retain.rs:200:5
    |
 LL |     vec = vec.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:177:5
+  --> $DIR/manual_retain.rs:201:5
    |
 LL |     vec = vec.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:178:5
+  --> $DIR/manual_retain.rs:202:5
    |
 LL |     vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:200:5
+  --> $DIR/manual_retain.rs:206:5
+   |
+LL |     tuples = tuples.iter().filter(|(ref x, ref y)| *x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(ref x, ref y)| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:207:5
+   |
+LL |     tuples = tuples.iter().filter(|(x, y)| *x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(x, y)| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:229:5
    |
 LL |     vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).copied().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:201:5
+  --> $DIR/manual_retain.rs:230:5
    |
 LL |     vec_deque = vec_deque.iter().filter(|&x| x % 2 == 0).cloned().collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
 
 error: this expression can be written more simply using `.retain()`
-  --> $DIR/manual_retain.rs:202:5
+  --> $DIR/manual_retain.rs:231:5
    |
 LL |     vec_deque = vec_deque.into_iter().filter(|x| x % 2 == 0).collect();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec_deque.retain(|x| x % 2 == 0)`
 
-error: aborting due to 22 previous errors
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:288:5
+   |
+LL |     vec = vec.into_iter().filter(|(x, y)| *x == 0).collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|(x, y)| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:292:5
+   |
+LL |     tuples = tuples.into_iter().filter(|(_, n)| *n > 0).collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `tuples.retain(|(_, n)| *n > 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:309:5
+   |
+LL |     vec = vec.iter().filter(|&&x| x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:310:5
+   |
+LL |     vec = vec.iter().filter(|&&x| x == 0).cloned().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:311:5
+   |
+LL |     vec = vec.into_iter().filter(|&x| x == 0).collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|&x| x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:314:5
+   |
+LL |     vec = vec.iter().filter(|&x| *x == 0).copied().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:315:5
+   |
+LL |     vec = vec.iter().filter(|&x| *x == 0).cloned().collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
+
+error: this expression can be written more simply using `.retain()`
+  --> $DIR/manual_retain.rs:316:5
+   |
+LL |     vec = vec.into_iter().filter(|x| *x == 0).collect();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.retain()` instead: `vec.retain(|x| *x == 0)`
+
+error: aborting due to 38 previous errors
 
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs
index 4dbed24026c..c427b8580e1 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral.rs
@@ -114,4 +114,12 @@ fn main() {
     a_usize % b_usize;
     let mut a_usize: usize = 1;
     a_usize %= 2;
+
+    // No lint when comparing to zero
+    let a = -1;
+    let mut b = 2;
+    let c = a % b == 0;
+    let c = 0 == a % b;
+    let c = a % b != 0;
+    let c = 0 != a % b;
 }
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index ff1e2dc8875..23e8bf8a468 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -131,6 +131,9 @@ fn main() {
             0
         }
     }
+
+    // issue #11786
+    let x: (&str,) = ("",);
 }
 
 #[allow(clippy::needless_borrowed_reference)]
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index 597021539ac..27771a8f15b 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -131,6 +131,9 @@ fn main() {
             0
         }
     }
+
+    // issue #11786
+    let x: (&str,) = (&"",);
 }
 
 #[allow(clippy::needless_borrowed_reference)]
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index 44552ee6abe..a21ed8382c1 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -121,41 +121,47 @@ error: this expression creates a reference which is immediately dereferenced by
 LL |     (&&5).foo();
    |     ^^^^^ help: change this to: `(&5)`
 
+error: this expression creates a reference which is immediately dereferenced by the compiler
+  --> $DIR/needless_borrow.rs:136:23
+   |
+LL |     let x: (&str,) = (&"",);
+   |                       ^^^ help: change this to: `""`
+
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:175:13
+  --> $DIR/needless_borrow.rs:178:13
    |
 LL |             (&self.f)()
    |             ^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:184:13
+  --> $DIR/needless_borrow.rs:187:13
    |
 LL |             (&mut self.f)()
    |             ^^^^^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:221:22
+  --> $DIR/needless_borrow.rs:224:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:228:22
+  --> $DIR/needless_borrow.rs:231:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:232:22
+  --> $DIR/needless_borrow.rs:235:22
    |
 LL |         let _ = &mut (&mut x.u).x;
    |                      ^^^^^^^^^^ help: change this to: `x.u`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:233:22
+  --> $DIR/needless_borrow.rs:236:22
    |
 LL |         let _ = &mut (&mut { x.u }).x;
    |                      ^^^^^^^^^^^^^^ help: change this to: `{ x.u }`
 
-error: aborting due to 26 previous errors
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed
index 0147c73a94b..9b7da852663 100644
--- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed
+++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.fixed
@@ -77,3 +77,53 @@ fn issue11616() -> Result<(), ()> {
     };
     Ok(())
 }
+
+fn issue11982() {
+    mod bar {
+        pub struct Error;
+        pub fn foo(_: bool) -> Result<(), Error> {
+            Ok(())
+        }
+    }
+
+    pub struct Error;
+
+    impl From<bar::Error> for Error {
+        fn from(_: bar::Error) -> Self {
+            Error
+        }
+    }
+
+    fn foo(ok: bool) -> Result<(), Error> {
+        if !ok {
+            return bar::foo(ok).map(|_| Ok::<(), Error>(()))?;
+        };
+        Ok(())
+    }
+}
+
+fn issue11982_no_conversion() {
+    mod bar {
+        pub struct Error;
+        pub fn foo(_: bool) -> Result<(), Error> {
+            Ok(())
+        }
+    }
+
+    fn foo(ok: bool) -> Result<(), bar::Error> {
+        if !ok {
+            return bar::foo(ok).map(|_| Ok::<(), bar::Error>(()))?;
+        };
+        Ok(())
+    }
+}
+
+fn general_return() {
+    fn foo(ok: bool) -> Result<(), ()> {
+        let bar = Result::Ok(Result::<(), ()>::Ok(()));
+        if !ok {
+            return bar?;
+        };
+        Ok(())
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs
index 66e1f438f8c..68e76d2b640 100644
--- a/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs
+++ b/src/tools/clippy/tests/ui/needless_return_with_question_mark.rs
@@ -77,3 +77,53 @@ fn issue11616() -> Result<(), ()> {
     };
     Ok(())
 }
+
+fn issue11982() {
+    mod bar {
+        pub struct Error;
+        pub fn foo(_: bool) -> Result<(), Error> {
+            Ok(())
+        }
+    }
+
+    pub struct Error;
+
+    impl From<bar::Error> for Error {
+        fn from(_: bar::Error) -> Self {
+            Error
+        }
+    }
+
+    fn foo(ok: bool) -> Result<(), Error> {
+        if !ok {
+            return bar::foo(ok).map(|_| Ok::<(), Error>(()))?;
+        };
+        Ok(())
+    }
+}
+
+fn issue11982_no_conversion() {
+    mod bar {
+        pub struct Error;
+        pub fn foo(_: bool) -> Result<(), Error> {
+            Ok(())
+        }
+    }
+
+    fn foo(ok: bool) -> Result<(), bar::Error> {
+        if !ok {
+            return bar::foo(ok).map(|_| Ok::<(), bar::Error>(()))?;
+        };
+        Ok(())
+    }
+}
+
+fn general_return() {
+    fn foo(ok: bool) -> Result<(), ()> {
+        let bar = Result::Ok(Result::<(), ()>::Ok(()));
+        if !ok {
+            return bar?;
+        };
+        Ok(())
+    }
+}
diff --git a/src/tools/clippy/tests/ui/never_loop.rs b/src/tools/clippy/tests/ui/never_loop.rs
index c67a6d4494e..92f173d9db4 100644
--- a/src/tools/clippy/tests/ui/never_loop.rs
+++ b/src/tools/clippy/tests/ui/never_loop.rs
@@ -1,4 +1,4 @@
-#![feature(inline_const)]
+#![feature(inline_const, try_blocks)]
 #![allow(
     clippy::eq_op,
     clippy::single_match,
@@ -400,6 +400,15 @@ pub fn test32() {
     }
 }
 
+pub fn issue12205() -> Option<()> {
+    loop {
+        let _: Option<_> = try {
+            None?;
+            return Some(());
+        };
+    }
+}
+
 fn main() {
     test1();
     test2();
diff --git a/src/tools/clippy/tests/ui/nonminimal_bool.rs b/src/tools/clippy/tests/ui/nonminimal_bool.rs
index 4d48ef14d31..f7c3df7066f 100644
--- a/src/tools/clippy/tests/ui/nonminimal_bool.rs
+++ b/src/tools/clippy/tests/ui/nonminimal_bool.rs
@@ -145,3 +145,14 @@ fn issue10836() {
     // Should not lint
     let _: bool = !!Foo(true);
 }
+
+fn issue11932() {
+    let x: i32 = unimplemented!();
+
+    #[allow(clippy::nonminimal_bool)]
+    let _ = x % 2 == 0 || {
+        // Should not lint
+        assert!(x > 0);
+        x % 3 == 0
+    };
+}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
index f272d8359a3..ce5c7f2600b 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.fixed
@@ -102,3 +102,12 @@ mod issue11707 {
 fn avoid_double_parens() {
     std::convert::identity(13_i32 + 36_i32).leading_zeros();
 }
+
+fn fp_11274() {
+    macro_rules! m {
+        ($closure:expr) => {
+            $closure(1)
+        };
+    }
+    m!(|x| println!("{x}"));
+}
diff --git a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
index f45db8c9cff..ac09390e6ea 100644
--- a/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_closure_call_fixable.rs
@@ -102,3 +102,12 @@ mod issue11707 {
 fn avoid_double_parens() {
     std::convert::identity((|| 13_i32 + 36_i32)()).leading_zeros();
 }
+
+fn fp_11274() {
+    macro_rules! m {
+        ($closure:expr) => {
+            $closure(1)
+        };
+    }
+    m!(|x| println!("{x}"));
+}
diff --git a/src/tools/clippy/tests/ui/redundant_locals.rs b/src/tools/clippy/tests/ui/redundant_locals.rs
index 182d067a5e9..f6909828aa9 100644
--- a/src/tools/clippy/tests/ui/redundant_locals.rs
+++ b/src/tools/clippy/tests/ui/redundant_locals.rs
@@ -1,6 +1,7 @@
 //@aux-build:proc_macros.rs
 #![allow(unused, clippy::no_effect, clippy::needless_pass_by_ref_mut)]
 #![warn(clippy::redundant_locals)]
+#![feature(async_closure, coroutines)]
 
 extern crate proc_macros;
 use proc_macros::{external, with_span};
@@ -163,3 +164,48 @@ fn drop_compose() {
     let b = ComposeDrop { d: WithDrop(1) };
     let a = a;
 }
+
+fn issue12225() {
+    fn assert_static<T: 'static>(_: T) {}
+
+    let v1 = String::new();
+    let v2 = String::new();
+    let v3 = String::new();
+    let v4 = String::new();
+    let v5 = String::new();
+    let v6 = String::new();
+
+    assert_static(|| {
+        let v1 = v1;
+        dbg!(&v1);
+    });
+    assert_static(async {
+        let v2 = v2;
+        dbg!(&v2);
+    });
+    assert_static(|| async {
+        let v3 = v3;
+        dbg!(&v3);
+    });
+    assert_static(async || {
+        let v4 = v4;
+        dbg!(&v4);
+    });
+    assert_static(static || {
+        let v5 = v5;
+        yield;
+    });
+    assert_static(|| {
+        let v6 = v6;
+        yield;
+    });
+
+    fn foo(a: &str, b: &str) {}
+
+    let do_not_move = String::new();
+    let things_to_move = vec!["a".to_string(), "b".to_string()];
+    let futures = things_to_move.into_iter().map(|move_me| async {
+        let move_me = move_me;
+        foo(&do_not_move, &move_me)
+    });
+}
diff --git a/src/tools/clippy/tests/ui/redundant_locals.stderr b/src/tools/clippy/tests/ui/redundant_locals.stderr
index 30ab4aa2ea9..610d587ddad 100644
--- a/src/tools/clippy/tests/ui/redundant_locals.stderr
+++ b/src/tools/clippy/tests/ui/redundant_locals.stderr
@@ -1,11 +1,11 @@
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:12:5
+  --> $DIR/redundant_locals.rs:13:5
    |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:11:9
+  --> $DIR/redundant_locals.rs:12:9
    |
 LL |     let x = 1;
    |         ^
@@ -13,157 +13,157 @@ LL |     let x = 1;
    = help: to override `-D warnings` add `#[allow(clippy::redundant_locals)]`
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:17:5
+  --> $DIR/redundant_locals.rs:18:5
    |
 LL |     let mut x = x;
    |     ^^^^^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:16:9
+  --> $DIR/redundant_locals.rs:17:9
    |
 LL |     let mut x = 1;
    |         ^^^^^
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:47:5
+  --> $DIR/redundant_locals.rs:48:5
    |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:46:14
+  --> $DIR/redundant_locals.rs:47:14
    |
 LL | fn parameter(x: i32) {
    |              ^
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:52:5
+  --> $DIR/redundant_locals.rs:53:5
    |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:51:9
+  --> $DIR/redundant_locals.rs:52:9
    |
 LL |     let x = 1;
    |         ^
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:53:5
+  --> $DIR/redundant_locals.rs:54:5
    |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:52:9
+  --> $DIR/redundant_locals.rs:53:9
    |
 LL |     let x = x;
    |         ^
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:54:5
+  --> $DIR/redundant_locals.rs:55:5
    |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:53:9
+  --> $DIR/redundant_locals.rs:54:9
    |
 LL |     let x = x;
    |         ^
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:55:5
+  --> $DIR/redundant_locals.rs:56:5
    |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:54:9
+  --> $DIR/redundant_locals.rs:55:9
    |
 LL |     let x = x;
    |         ^
 
 error: redundant redefinition of a binding `a`
-  --> $DIR/redundant_locals.rs:61:5
+  --> $DIR/redundant_locals.rs:62:5
    |
 LL |     let a = a;
    |     ^^^^^^^^^^
    |
 help: `a` is initially defined here
-  --> $DIR/redundant_locals.rs:59:9
+  --> $DIR/redundant_locals.rs:60:9
    |
 LL |     let a = 1;
    |         ^
 
 error: redundant redefinition of a binding `b`
-  --> $DIR/redundant_locals.rs:62:5
+  --> $DIR/redundant_locals.rs:63:5
    |
 LL |     let b = b;
    |     ^^^^^^^^^^
    |
 help: `b` is initially defined here
-  --> $DIR/redundant_locals.rs:60:9
+  --> $DIR/redundant_locals.rs:61:9
    |
 LL |     let b = 2;
    |         ^
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:68:9
+  --> $DIR/redundant_locals.rs:69:9
    |
 LL |         let x = x;
    |         ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:67:13
+  --> $DIR/redundant_locals.rs:68:13
    |
 LL |         let x = 1;
    |             ^
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:75:9
+  --> $DIR/redundant_locals.rs:76:9
    |
 LL |         let x = x;
    |         ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:74:13
+  --> $DIR/redundant_locals.rs:75:13
    |
 LL |         let x = 1;
    |             ^
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:78:9
+  --> $DIR/redundant_locals.rs:79:9
    |
 LL |         let x = x;
    |         ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:77:6
+  --> $DIR/redundant_locals.rs:78:6
    |
 LL |     |x: i32| {
    |      ^
 
 error: redundant redefinition of a binding `x`
-  --> $DIR/redundant_locals.rs:97:9
+  --> $DIR/redundant_locals.rs:98:9
    |
 LL |         let x = x;
    |         ^^^^^^^^^^
    |
 help: `x` is initially defined here
-  --> $DIR/redundant_locals.rs:94:9
+  --> $DIR/redundant_locals.rs:95:9
    |
 LL |     let x = 1;
    |         ^
 
 error: redundant redefinition of a binding `a`
-  --> $DIR/redundant_locals.rs:152:5
+  --> $DIR/redundant_locals.rs:153:5
    |
 LL |     let a = a;
    |     ^^^^^^^^^^
    |
 help: `a` is initially defined here
-  --> $DIR/redundant_locals.rs:150:9
+  --> $DIR/redundant_locals.rs:151:9
    |
 LL |     let a = WithoutDrop(1);
    |         ^
diff --git a/src/tools/clippy/tests/ui/redundant_type_annotations.rs b/src/tools/clippy/tests/ui/redundant_type_annotations.rs
index acf53fea2bb..dc9b073ffba 100644
--- a/src/tools/clippy/tests/ui/redundant_type_annotations.rs
+++ b/src/tools/clippy/tests/ui/redundant_type_annotations.rs
@@ -196,13 +196,18 @@ fn test_simple_types() {
     let _var: &str = "test";
     //~^ ERROR: redundant type annotation
 
-    let _var: &[u8] = b"test";
+    let _var: &[u8; 4] = b"test";
     //~^ ERROR: redundant type annotation
 
     let _var: bool = false;
     //~^ ERROR: redundant type annotation
 }
 
+fn issue12212() {
+    // This should not be linted
+    let _var: &[u8] = b"test";
+}
+
 fn issue11190() {}
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/redundant_type_annotations.stderr b/src/tools/clippy/tests/ui/redundant_type_annotations.stderr
index d1f26f1832e..48df465ad49 100644
--- a/src/tools/clippy/tests/ui/redundant_type_annotations.stderr
+++ b/src/tools/clippy/tests/ui/redundant_type_annotations.stderr
@@ -94,8 +94,8 @@ LL |     let _var: &str = "test";
 error: redundant type annotation
   --> $DIR/redundant_type_annotations.rs:199:5
    |
-LL |     let _var: &[u8] = b"test";
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let _var: &[u8; 4] = b"test";
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: redundant type annotation
   --> $DIR/redundant_type_annotations.rs:202:5
diff --git a/src/tools/clippy/tests/ui/ref_as_ptr.fixed b/src/tools/clippy/tests/ui/ref_as_ptr.fixed
new file mode 100644
index 00000000000..7a946393f25
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_as_ptr.fixed
@@ -0,0 +1,110 @@
+#![warn(clippy::ref_as_ptr)]
+#![allow(clippy::unnecessary_mut_passed)]
+
+fn main() {
+    let _ = std::ptr::from_ref(&1u8);
+    let _ = std::ptr::from_ref::<u32>(&2u32);
+    let _ = std::ptr::from_ref::<f64>(&3.0f64);
+
+    let _ = std::ptr::from_ref(&4) as *const f32;
+    let _ = std::ptr::from_ref::<f32>(&5.0f32) as *const u32;
+
+    let _ = std::ptr::from_ref(&mut 6u8);
+    let _ = std::ptr::from_ref::<u32>(&mut 7u32);
+    let _ = std::ptr::from_ref::<f64>(&mut 8.0f64);
+
+    let _ = std::ptr::from_ref(&mut 9) as *const f32;
+    let _ = std::ptr::from_ref::<f32>(&mut 10.0f32) as *const u32;
+
+    let _ = std::ptr::from_mut(&mut 11u8);
+    let _ = std::ptr::from_mut::<u32>(&mut 12u32);
+    let _ = std::ptr::from_mut::<f64>(&mut 13.0f64);
+
+    let _ = std::ptr::from_mut(&mut 14) as *const f32;
+    let _ = std::ptr::from_mut::<f32>(&mut 15.0f32) as *const u32;
+
+    let _ = std::ptr::from_ref(&1u8);
+    let _ = std::ptr::from_ref::<u32>(&2u32);
+    let _ = std::ptr::from_ref::<f64>(&3.0f64);
+
+    let _ = std::ptr::from_ref(&4) as *const f32;
+    let _ = std::ptr::from_ref::<f32>(&5.0f32) as *const u32;
+
+    let val = 1;
+    let _ = std::ptr::from_ref(&val);
+    let _ = std::ptr::from_ref::<i32>(&val);
+
+    let _ = std::ptr::from_ref(&val) as *const f32;
+    let _ = std::ptr::from_ref::<i32>(&val) as *const f64;
+
+    let mut val: u8 = 2;
+    let _ = std::ptr::from_mut::<u8>(&mut val);
+    let _ = std::ptr::from_mut(&mut val);
+
+    let _ = std::ptr::from_ref::<u8>(&mut val);
+    let _ = std::ptr::from_ref(&mut val);
+
+    let _ = std::ptr::from_ref::<u8>(&mut val) as *const f64;
+    let _: *const Option<u8> = std::ptr::from_ref(&mut val) as *const _;
+
+    let _ = std::ptr::from_ref::<[usize; 7]>(&std::array::from_fn(|i| i * i));
+    let _ = std::ptr::from_ref::<[usize; 8]>(&mut std::array::from_fn(|i| i * i));
+    let _ = std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i));
+}
+
+#[clippy::msrv = "1.75"]
+fn _msrv_1_75() {
+    let val = &42_i32;
+    let mut_val = &mut 42_i32;
+
+    // `std::ptr::from_{ref, mut}` was stabilized in 1.76. Do not lint this
+    let _ = val as *const i32;
+    let _ = mut_val as *mut i32;
+}
+
+#[clippy::msrv = "1.76"]
+fn _msrv_1_76() {
+    let val = &42_i32;
+    let mut_val = &mut 42_i32;
+
+    let _ = std::ptr::from_ref::<i32>(val);
+    let _ = std::ptr::from_mut::<i32>(mut_val);
+}
+
+fn foo(val: &[u8]) {
+    let _ = std::ptr::from_ref(val);
+    let _ = std::ptr::from_ref::<[u8]>(val);
+}
+
+fn bar(val: &mut str) {
+    let _ = std::ptr::from_mut(val);
+    let _ = std::ptr::from_mut::<str>(val);
+}
+
+struct X<'a>(&'a i32);
+
+impl<'a> X<'a> {
+    fn foo(&self) -> *const i64 {
+        std::ptr::from_ref(self.0) as *const _
+    }
+
+    fn bar(&mut self) -> *const i64 {
+        std::ptr::from_ref(self.0) as *const _
+    }
+}
+
+struct Y<'a>(&'a mut i32);
+
+impl<'a> Y<'a> {
+    fn foo(&self) -> *const i64 {
+        std::ptr::from_ref(self.0) as *const _
+    }
+
+    fn bar(&mut self) -> *const i64 {
+        std::ptr::from_ref(self.0) as *const _
+    }
+
+    fn baz(&mut self) -> *const i64 {
+        std::ptr::from_mut(self.0) as *mut _
+    }
+}
diff --git a/src/tools/clippy/tests/ui/ref_as_ptr.rs b/src/tools/clippy/tests/ui/ref_as_ptr.rs
new file mode 100644
index 00000000000..6f745505b46
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_as_ptr.rs
@@ -0,0 +1,110 @@
+#![warn(clippy::ref_as_ptr)]
+#![allow(clippy::unnecessary_mut_passed)]
+
+fn main() {
+    let _ = &1u8 as *const _;
+    let _ = &2u32 as *const u32;
+    let _ = &3.0f64 as *const f64;
+
+    let _ = &4 as *const _ as *const f32;
+    let _ = &5.0f32 as *const f32 as *const u32;
+
+    let _ = &mut 6u8 as *const _;
+    let _ = &mut 7u32 as *const u32;
+    let _ = &mut 8.0f64 as *const f64;
+
+    let _ = &mut 9 as *const _ as *const f32;
+    let _ = &mut 10.0f32 as *const f32 as *const u32;
+
+    let _ = &mut 11u8 as *mut _;
+    let _ = &mut 12u32 as *mut u32;
+    let _ = &mut 13.0f64 as *mut f64;
+
+    let _ = &mut 14 as *mut _ as *const f32;
+    let _ = &mut 15.0f32 as *mut f32 as *const u32;
+
+    let _ = &1u8 as *const _;
+    let _ = &2u32 as *const u32;
+    let _ = &3.0f64 as *const f64;
+
+    let _ = &4 as *const _ as *const f32;
+    let _ = &5.0f32 as *const f32 as *const u32;
+
+    let val = 1;
+    let _ = &val as *const _;
+    let _ = &val as *const i32;
+
+    let _ = &val as *const _ as *const f32;
+    let _ = &val as *const i32 as *const f64;
+
+    let mut val: u8 = 2;
+    let _ = &mut val as *mut u8;
+    let _ = &mut val as *mut _;
+
+    let _ = &mut val as *const u8;
+    let _ = &mut val as *const _;
+
+    let _ = &mut val as *const u8 as *const f64;
+    let _: *const Option<u8> = &mut val as *const _ as *const _;
+
+    let _ = &std::array::from_fn(|i| i * i) as *const [usize; 7];
+    let _ = &mut std::array::from_fn(|i| i * i) as *const [usize; 8];
+    let _ = &mut std::array::from_fn(|i| i * i) as *mut [usize; 9];
+}
+
+#[clippy::msrv = "1.75"]
+fn _msrv_1_75() {
+    let val = &42_i32;
+    let mut_val = &mut 42_i32;
+
+    // `std::ptr::from_{ref, mut}` was stabilized in 1.76. Do not lint this
+    let _ = val as *const i32;
+    let _ = mut_val as *mut i32;
+}
+
+#[clippy::msrv = "1.76"]
+fn _msrv_1_76() {
+    let val = &42_i32;
+    let mut_val = &mut 42_i32;
+
+    let _ = val as *const i32;
+    let _ = mut_val as *mut i32;
+}
+
+fn foo(val: &[u8]) {
+    let _ = val as *const _;
+    let _ = val as *const [u8];
+}
+
+fn bar(val: &mut str) {
+    let _ = val as *mut _;
+    let _ = val as *mut str;
+}
+
+struct X<'a>(&'a i32);
+
+impl<'a> X<'a> {
+    fn foo(&self) -> *const i64 {
+        self.0 as *const _ as *const _
+    }
+
+    fn bar(&mut self) -> *const i64 {
+        self.0 as *const _ as *const _
+    }
+}
+
+struct Y<'a>(&'a mut i32);
+
+impl<'a> Y<'a> {
+    fn foo(&self) -> *const i64 {
+        self.0 as *const _ as *const _
+    }
+
+    fn bar(&mut self) -> *const i64 {
+        self.0 as *const _ as *const _
+    }
+
+    fn baz(&mut self) -> *const i64 {
+        self.0 as *mut _ as *mut _
+    }
+}
diff --git a/src/tools/clippy/tests/ui/ref_as_ptr.stderr b/src/tools/clippy/tests/ui/ref_as_ptr.stderr
new file mode 100644
index 00000000000..371d42df528
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ref_as_ptr.stderr
@@ -0,0 +1,269 @@
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:5:13
+   |
+LL |     let _ = &1u8 as *const _;
+   |             ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&1u8)`
+   |
+   = note: `-D clippy::ref-as-ptr` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ref_as_ptr)]`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:6:13
+   |
+LL |     let _ = &2u32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u32>(&2u32)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:7:13
+   |
+LL |     let _ = &3.0f64 as *const f64;
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f64>(&3.0f64)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:9:13
+   |
+LL |     let _ = &4 as *const _ as *const f32;
+   |             ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&4)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:10:13
+   |
+LL |     let _ = &5.0f32 as *const f32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f32>(&5.0f32)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:12:13
+   |
+LL |     let _ = &mut 6u8 as *const _;
+   |             ^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut 6u8)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:13:13
+   |
+LL |     let _ = &mut 7u32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u32>(&mut 7u32)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:14:13
+   |
+LL |     let _ = &mut 8.0f64 as *const f64;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f64>(&mut 8.0f64)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:16:13
+   |
+LL |     let _ = &mut 9 as *const _ as *const f32;
+   |             ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut 9)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:17:13
+   |
+LL |     let _ = &mut 10.0f32 as *const f32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f32>(&mut 10.0f32)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:19:13
+   |
+LL |     let _ = &mut 11u8 as *mut _;
+   |             ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(&mut 11u8)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:20:13
+   |
+LL |     let _ = &mut 12u32 as *mut u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<u32>(&mut 12u32)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:21:13
+   |
+LL |     let _ = &mut 13.0f64 as *mut f64;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<f64>(&mut 13.0f64)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:23:13
+   |
+LL |     let _ = &mut 14 as *mut _ as *const f32;
+   |             ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(&mut 14)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:24:13
+   |
+LL |     let _ = &mut 15.0f32 as *mut f32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<f32>(&mut 15.0f32)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:26:13
+   |
+LL |     let _ = &1u8 as *const _;
+   |             ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&1u8)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:27:13
+   |
+LL |     let _ = &2u32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u32>(&2u32)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:28:13
+   |
+LL |     let _ = &3.0f64 as *const f64;
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f64>(&3.0f64)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:30:13
+   |
+LL |     let _ = &4 as *const _ as *const f32;
+   |             ^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&4)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:31:13
+   |
+LL |     let _ = &5.0f32 as *const f32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<f32>(&5.0f32)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:34:13
+   |
+LL |     let _ = &val as *const _;
+   |             ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:35:13
+   |
+LL |     let _ = &val as *const i32;
+   |             ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<i32>(&val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:37:13
+   |
+LL |     let _ = &val as *const _ as *const f32;
+   |             ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:38:13
+   |
+LL |     let _ = &val as *const i32 as *const f64;
+   |             ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<i32>(&val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:41:13
+   |
+LL |     let _ = &mut val as *mut u8;
+   |             ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<u8>(&mut val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:42:13
+   |
+LL |     let _ = &mut val as *mut _;
+   |             ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(&mut val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:44:13
+   |
+LL |     let _ = &mut val as *const u8;
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u8>(&mut val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:45:13
+   |
+LL |     let _ = &mut val as *const _;
+   |             ^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:47:13
+   |
+LL |     let _ = &mut val as *const u8 as *const f64;
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<u8>(&mut val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:48:32
+   |
+LL |     let _: *const Option<u8> = &mut val as *const _ as *const _;
+   |                                ^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(&mut val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:50:13
+   |
+LL |     let _ = &std::array::from_fn(|i| i * i) as *const [usize; 7];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[usize; 7]>(&std::array::from_fn(|i| i * i))`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:51:13
+   |
+LL |     let _ = &mut std::array::from_fn(|i| i * i) as *const [usize; 8];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[usize; 8]>(&mut std::array::from_fn(|i| i * i))`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:52:13
+   |
+LL |     let _ = &mut std::array::from_fn(|i| i * i) as *mut [usize; 9];
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<[usize; 9]>(&mut std::array::from_fn(|i| i * i))`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:70:13
+   |
+LL |     let _ = val as *const i32;
+   |             ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<i32>(val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:71:13
+   |
+LL |     let _ = mut_val as *mut i32;
+   |             ^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<i32>(mut_val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:75:13
+   |
+LL |     let _ = val as *const _;
+   |             ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:76:13
+   |
+LL |     let _ = val as *const [u8];
+   |             ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref::<[u8]>(val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:80:13
+   |
+LL |     let _ = val as *mut _;
+   |             ^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:81:13
+   |
+LL |     let _ = val as *mut str;
+   |             ^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut::<str>(val)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:88:9
+   |
+LL |         self.0 as *const _ as *const _
+   |         ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:92:9
+   |
+LL |         self.0 as *const _ as *const _
+   |         ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:100:9
+   |
+LL |         self.0 as *const _ as *const _
+   |         ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:104:9
+   |
+LL |         self.0 as *const _ as *const _
+   |         ^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_ref(self.0)`
+
+error: reference as raw pointer
+  --> $DIR/ref_as_ptr.rs:108:9
+   |
+LL |         self.0 as *mut _ as *mut _
+   |         ^^^^^^^^^^^^^^^^ help: try: `std::ptr::from_mut(self.0)`
+
+error: aborting due to 44 previous errors
+
diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed
index 8304e2afd8b..1e7d04ffb9d 100644
--- a/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed
+++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.fixed
@@ -1,5 +1,5 @@
 #![warn(clippy::strlen_on_c_strings)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::manual_c_str_literals)]
 #![feature(rustc_private)]
 extern crate libc;
 
diff --git a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs
index deba40a9ea5..c3ad03591d4 100644
--- a/src/tools/clippy/tests/ui/strlen_on_c_strings.rs
+++ b/src/tools/clippy/tests/ui/strlen_on_c_strings.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::strlen_on_c_strings)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::manual_c_str_literals)]
 #![feature(rustc_private)]
 extern crate libc;
 
diff --git a/src/tools/clippy/tests/ui/to_string_trait_impl.rs b/src/tools/clippy/tests/ui/to_string_trait_impl.rs
new file mode 100644
index 00000000000..b0731632d45
--- /dev/null
+++ b/src/tools/clippy/tests/ui/to_string_trait_impl.rs
@@ -0,0 +1,31 @@
+#![warn(clippy::to_string_trait_impl)]
+
+use std::fmt::{self, Display};
+
+struct Point {
+    x: usize,
+    y: usize,
+}
+
+impl ToString for Point {
+    fn to_string(&self) -> String {
+        format!("({}, {})", self.x, self.y)
+    }
+}
+
+struct Foo;
+
+impl Display for Foo {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "Foo")
+    }
+}
+
+struct Bar;
+
+impl Bar {
+    #[allow(clippy::inherent_to_string)]
+    fn to_string(&self) -> String {
+        String::from("Bar")
+    }
+}
diff --git a/src/tools/clippy/tests/ui/to_string_trait_impl.stderr b/src/tools/clippy/tests/ui/to_string_trait_impl.stderr
new file mode 100644
index 00000000000..55fa9f12c0e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/to_string_trait_impl.stderr
@@ -0,0 +1,16 @@
+error: direct implementation of `ToString`
+  --> $DIR/to_string_trait_impl.rs:10:1
+   |
+LL | / impl ToString for Point {
+LL | |     fn to_string(&self) -> String {
+LL | |         format!("({}, {})", self.x, self.y)
+LL | |     }
+LL | | }
+   | |_^
+   |
+   = help: prefer implementing `Display` instead
+   = note: `-D clippy::to-string-trait-impl` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::to_string_trait_impl)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/unconditional_recursion.rs b/src/tools/clippy/tests/ui/unconditional_recursion.rs
index 7b898a6e0e7..6ad3bde51cd 100644
--- a/src/tools/clippy/tests/ui/unconditional_recursion.rs
+++ b/src/tools/clippy/tests/ui/unconditional_recursion.rs
@@ -206,6 +206,7 @@ impl PartialEq for S8 {
 
 struct S9;
 
+#[allow(clippy::to_string_trait_impl)]
 impl std::string::ToString for S9 {
     fn to_string(&self) -> String {
         //~^ ERROR: function cannot return without recursing
@@ -215,6 +216,7 @@ impl std::string::ToString for S9 {
 
 struct S10;
 
+#[allow(clippy::to_string_trait_impl)]
 impl std::string::ToString for S10 {
     fn to_string(&self) -> String {
         //~^ ERROR: function cannot return without recursing
@@ -225,6 +227,7 @@ impl std::string::ToString for S10 {
 
 struct S11;
 
+#[allow(clippy::to_string_trait_impl)]
 impl std::string::ToString for S11 {
     fn to_string(&self) -> String {
         //~^ ERROR: function cannot return without recursing
@@ -288,4 +291,63 @@ impl PartialEq for S15<'_> {
     }
 }
 
+mod issue12154 {
+    struct MyBox<T>(T);
+
+    impl<T> std::ops::Deref for MyBox<T> {
+        type Target = T;
+        fn deref(&self) -> &T {
+            &self.0
+        }
+    }
+
+    impl<T: PartialEq> PartialEq for MyBox<T> {
+        fn eq(&self, other: &Self) -> bool {
+            (**self).eq(&**other)
+        }
+    }
+
+    // Not necessarily related to the issue but another FP from the http crate that was fixed with it:
+    // https://docs.rs/http/latest/src/http/header/name.rs.html#1424
+    // We used to simply peel refs from the LHS and RHS, so we couldn't differentiate
+    // between `PartialEq<T> for &T` and `PartialEq<&T> for T` impls.
+    #[derive(PartialEq)]
+    struct HeaderName;
+    impl<'a> PartialEq<&'a HeaderName> for HeaderName {
+        fn eq(&self, other: &&'a HeaderName) -> bool {
+            *self == **other
+        }
+    }
+
+    impl<'a> PartialEq<HeaderName> for &'a HeaderName {
+        fn eq(&self, other: &HeaderName) -> bool {
+            *other == *self
+        }
+    }
+
+    // Issue #12181 but also fixed by the same PR
+    struct Foo;
+
+    impl Foo {
+        fn as_str(&self) -> &str {
+            "Foo"
+        }
+    }
+
+    impl PartialEq for Foo {
+        fn eq(&self, other: &Self) -> bool {
+            self.as_str().eq(other.as_str())
+        }
+    }
+
+    impl<T> PartialEq<T> for Foo
+    where
+        for<'a> &'a str: PartialEq<T>,
+    {
+        fn eq(&self, other: &T) -> bool {
+            (&self.as_str()).eq(other)
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/unconditional_recursion.stderr b/src/tools/clippy/tests/ui/unconditional_recursion.stderr
index 094b80d4586..93a5eac91d8 100644
--- a/src/tools/clippy/tests/ui/unconditional_recursion.stderr
+++ b/src/tools/clippy/tests/ui/unconditional_recursion.stderr
@@ -23,7 +23,7 @@ LL |         self.eq(other)
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> $DIR/unconditional_recursion.rs:210:5
+  --> $DIR/unconditional_recursion.rs:211:5
    |
 LL |     fn to_string(&self) -> String {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -34,7 +34,7 @@ LL |         self.to_string()
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> $DIR/unconditional_recursion.rs:219:5
+  --> $DIR/unconditional_recursion.rs:221:5
    |
 LL |     fn to_string(&self) -> String {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -45,7 +45,7 @@ LL |         x.to_string()
    = help: a `loop` may express intention better if this is on purpose
 
 error: function cannot return without recursing
-  --> $DIR/unconditional_recursion.rs:229:5
+  --> $DIR/unconditional_recursion.rs:232:5
    |
 LL |     fn to_string(&self) -> String {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -326,7 +326,7 @@ LL |         mine == theirs
    |         ^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> $DIR/unconditional_recursion.rs:244:5
+  --> $DIR/unconditional_recursion.rs:247:5
    |
 LL | /     fn new() -> Self {
 LL | |
@@ -335,13 +335,13 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> $DIR/unconditional_recursion.rs:246:9
+  --> $DIR/unconditional_recursion.rs:249:9
    |
 LL |         Self::default()
    |         ^^^^^^^^^^^^^^^
 
 error: function cannot return without recursing
-  --> $DIR/unconditional_recursion.rs:283:5
+  --> $DIR/unconditional_recursion.rs:286:5
    |
 LL | /     fn eq(&self, other: &Self) -> bool {
 LL | |
@@ -352,7 +352,7 @@ LL | |     }
    | |_____^
    |
 note: recursive call site
-  --> $DIR/unconditional_recursion.rs:287:9
+  --> $DIR/unconditional_recursion.rs:290:9
    |
 LL |         mine.eq(theirs)
    |         ^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unnecessary_fold.fixed b/src/tools/clippy/tests/ui/unnecessary_fold.fixed
index c884d26eb61..c5bc11b55ab 100644
--- a/src/tools/clippy/tests/ui/unnecessary_fold.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_fold.fixed
@@ -1,9 +1,15 @@
 #![allow(dead_code)]
 
+fn is_any(acc: bool, x: usize) -> bool {
+    acc || x > 2
+}
+
 /// Calls which should trigger the `UNNECESSARY_FOLD` lint
 fn unnecessary_fold() {
     // Can be replaced by .any
     let _ = (0..3).any(|x| x > 2);
+    // Can be replaced by .any (checking suggestion)
+    let _ = (0..3).fold(false, is_any);
     // Can be replaced by .all
     let _ = (0..3).all(|x| x > 2);
     // Can be replaced by .sum
diff --git a/src/tools/clippy/tests/ui/unnecessary_fold.rs b/src/tools/clippy/tests/ui/unnecessary_fold.rs
index 2e6d6ba52eb..3a5136eeeae 100644
--- a/src/tools/clippy/tests/ui/unnecessary_fold.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_fold.rs
@@ -1,9 +1,15 @@
 #![allow(dead_code)]
 
+fn is_any(acc: bool, x: usize) -> bool {
+    acc || x > 2
+}
+
 /// Calls which should trigger the `UNNECESSARY_FOLD` lint
 fn unnecessary_fold() {
     // Can be replaced by .any
     let _ = (0..3).fold(false, |acc, x| acc || x > 2);
+    // Can be replaced by .any (checking suggestion)
+    let _ = (0..3).fold(false, |acc, x| is_any(acc, x));
     // Can be replaced by .all
     let _ = (0..3).fold(true, |acc, x| acc && x > 2);
     // Can be replaced by .sum
diff --git a/src/tools/clippy/tests/ui/unnecessary_fold.stderr b/src/tools/clippy/tests/ui/unnecessary_fold.stderr
index f0d03963842..123d4a3be75 100644
--- a/src/tools/clippy/tests/ui/unnecessary_fold.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_fold.stderr
@@ -1,5 +1,5 @@
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:6:20
+  --> $DIR/unnecessary_fold.rs:10:20
    |
 LL |     let _ = (0..3).fold(false, |acc, x| acc || x > 2);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`
@@ -7,89 +7,98 @@ LL |     let _ = (0..3).fold(false, |acc, x| acc || x > 2);
    = note: `-D clippy::unnecessary-fold` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_fold)]`
 
+error: redundant closure
+  --> $DIR/unnecessary_fold.rs:12:32
+   |
+LL |     let _ = (0..3).fold(false, |acc, x| is_any(acc, x));
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `is_any`
+   |
+   = note: `-D clippy::redundant-closure` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
+
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:8:20
+  --> $DIR/unnecessary_fold.rs:14:20
    |
 LL |     let _ = (0..3).fold(true, |acc, x| acc && x > 2);
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `all(|x| x > 2)`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:10:25
+  --> $DIR/unnecessary_fold.rs:16:25
    |
 LL |     let _: i32 = (0..3).fold(0, |acc, x| acc + x);
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:12:25
+  --> $DIR/unnecessary_fold.rs:18:25
    |
 LL |     let _: i32 = (0..3).fold(1, |acc, x| acc * x);
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:17:41
+  --> $DIR/unnecessary_fold.rs:23:41
    |
 LL |     let _: bool = (0..3).map(|x| 2 * x).fold(false, |acc, x| acc || x > 2);
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:47:10
+  --> $DIR/unnecessary_fold.rs:53:10
    |
 LL |         .fold(false, |acc, x| acc || x > 2);
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `any(|x| x > 2)`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:58:33
+  --> $DIR/unnecessary_fold.rs:64:33
    |
 LL |         assert_eq!(map.values().fold(0, |x, y| x + y), 0);
    |                                 ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:61:30
+  --> $DIR/unnecessary_fold.rs:67:30
    |
 LL |         let _ = map.values().fold(0, |x, y| x + y);
    |                              ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:62:30
+  --> $DIR/unnecessary_fold.rs:68:30
    |
 LL |         let _ = map.values().fold(1, |x, y| x * y);
    |                              ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:63:35
+  --> $DIR/unnecessary_fold.rs:69:35
    |
 LL |         let _: i32 = map.values().fold(0, |x, y| x + y);
    |                                   ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:64:35
+  --> $DIR/unnecessary_fold.rs:70:35
    |
 LL |         let _: i32 = map.values().fold(1, |x, y| x * y);
    |                                   ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:65:31
+  --> $DIR/unnecessary_fold.rs:71:31
    |
 LL |         anything(map.values().fold(0, |x, y| x + y));
    |                               ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum::<i32>()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:66:31
+  --> $DIR/unnecessary_fold.rs:72:31
    |
 LL |         anything(map.values().fold(1, |x, y| x * y));
    |                               ^^^^^^^^^^^^^^^^^^^^^ help: try: `product::<i32>()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:67:26
+  --> $DIR/unnecessary_fold.rs:73:26
    |
 LL |         num(map.values().fold(0, |x, y| x + y));
    |                          ^^^^^^^^^^^^^^^^^^^^^ help: try: `sum()`
 
 error: this `.fold` can be written more succinctly using another method
-  --> $DIR/unnecessary_fold.rs:68:26
+  --> $DIR/unnecessary_fold.rs:74:26
    |
 LL |         num(map.values().fold(1, |x, y| x * y));
    |                          ^^^^^^^^^^^^^^^^^^^^^ help: try: `product()`
 
-error: aborting due to 15 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.fixed b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
index 463412daec0..11761c6c90e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
@@ -106,4 +106,11 @@ fn main() {
 
     // Issue #11885
     Cout << 16;
+
+    // Issue #11575
+    // Bad formatting is required to trigger the bug
+    #[rustfmt::skip]
+    'label: {
+        break 'label
+    };
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.rs b/src/tools/clippy/tests/ui/unnecessary_operation.rs
index f0d28e28902..de0081289ac 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.rs
@@ -110,4 +110,11 @@ fn main() {
 
     // Issue #11885
     Cout << 16;
+
+    // Issue #11575
+    // Bad formatting is required to trigger the bug
+    #[rustfmt::skip]
+    'label: {
+        break 'label
+    };
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.fixed b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.fixed
new file mode 100644
index 00000000000..224e0b52d75
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.fixed
@@ -0,0 +1,61 @@
+#![warn(clippy::unnecessary_result_map_or_else)]
+#![allow(clippy::unnecessary_literal_unwrap, clippy::let_and_return, clippy::let_unit_value)]
+
+fn main() {
+    let x: Result<(), ()> = Ok(());
+    x.unwrap_or_else(|err| err); //~ ERROR: unused "map closure" when calling
+
+    // Type ascribtion.
+    let x: Result<(), ()> = Ok(());
+    x.unwrap_or_else(|err: ()| err); //~ ERROR: unused "map closure" when calling
+
+    // Auto-deref.
+    let y = String::new();
+    let x: Result<&String, &String> = Ok(&y);
+    let y: &str = x.unwrap_or_else(|err| err); //~ ERROR: unused "map closure" when calling
+
+    // Temporary variable.
+    let x: Result<(), ()> = Ok(());
+    x.unwrap_or_else(|err| err);
+
+    // Should not warn.
+    let x: Result<usize, usize> = Ok(0);
+    x.map_or_else(|err| err, |n| n + 1);
+
+    // Should not warn.
+    let y = ();
+    let x: Result<(), ()> = Ok(());
+    x.map_or_else(|err| err, |_| y);
+
+    // Should not warn.
+    let y = ();
+    let x: Result<(), ()> = Ok(());
+    x.map_or_else(
+        |err| err,
+        |_| {
+            let tmp = y;
+            tmp
+        },
+    );
+
+    // Should not warn.
+    let x: Result<usize, usize> = Ok(1);
+    x.map_or_else(
+        |err| err,
+        |n| {
+            let tmp = n + 1;
+            tmp
+        },
+    );
+
+    // Should not warn.
+    let y = 0;
+    let x: Result<usize, usize> = Ok(1);
+    x.map_or_else(
+        |err| err,
+        |n| {
+            let tmp = n;
+            y
+        },
+    );
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.rs b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.rs
new file mode 100644
index 00000000000..4fe950a4cfa
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.rs
@@ -0,0 +1,69 @@
+#![warn(clippy::unnecessary_result_map_or_else)]
+#![allow(clippy::unnecessary_literal_unwrap, clippy::let_and_return, clippy::let_unit_value)]
+
+fn main() {
+    let x: Result<(), ()> = Ok(());
+    x.map_or_else(|err| err, |n| n); //~ ERROR: unused "map closure" when calling
+
+    // Type ascribtion.
+    let x: Result<(), ()> = Ok(());
+    x.map_or_else(|err: ()| err, |n: ()| n); //~ ERROR: unused "map closure" when calling
+
+    // Auto-deref.
+    let y = String::new();
+    let x: Result<&String, &String> = Ok(&y);
+    let y: &str = x.map_or_else(|err| err, |n| n); //~ ERROR: unused "map closure" when calling
+
+    // Temporary variable.
+    let x: Result<(), ()> = Ok(());
+    x.map_or_else(
+        //~^ ERROR: unused "map closure" when calling
+        |err| err,
+        |n| {
+            let tmp = n;
+            let tmp2 = tmp;
+            tmp2
+        },
+    );
+
+    // Should not warn.
+    let x: Result<usize, usize> = Ok(0);
+    x.map_or_else(|err| err, |n| n + 1);
+
+    // Should not warn.
+    let y = ();
+    let x: Result<(), ()> = Ok(());
+    x.map_or_else(|err| err, |_| y);
+
+    // Should not warn.
+    let y = ();
+    let x: Result<(), ()> = Ok(());
+    x.map_or_else(
+        |err| err,
+        |_| {
+            let tmp = y;
+            tmp
+        },
+    );
+
+    // Should not warn.
+    let x: Result<usize, usize> = Ok(1);
+    x.map_or_else(
+        |err| err,
+        |n| {
+            let tmp = n + 1;
+            tmp
+        },
+    );
+
+    // Should not warn.
+    let y = 0;
+    let x: Result<usize, usize> = Ok(1);
+    x.map_or_else(
+        |err| err,
+        |n| {
+            let tmp = n;
+            y
+        },
+    );
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.stderr b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.stderr
new file mode 100644
index 00000000000..0f83be5d556
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_result_map_or_else.stderr
@@ -0,0 +1,35 @@
+error: unused "map closure" when calling `Result::map_or_else` value
+  --> $DIR/unnecessary_result_map_or_else.rs:6:5
+   |
+LL |     x.map_or_else(|err| err, |n| n);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)`
+   |
+   = note: `-D clippy::unnecessary-result-map-or-else` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_result_map_or_else)]`
+
+error: unused "map closure" when calling `Result::map_or_else` value
+  --> $DIR/unnecessary_result_map_or_else.rs:10:5
+   |
+LL |     x.map_or_else(|err: ()| err, |n: ()| n);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err: ()| err)`
+
+error: unused "map closure" when calling `Result::map_or_else` value
+  --> $DIR/unnecessary_result_map_or_else.rs:15:19
+   |
+LL |     let y: &str = x.map_or_else(|err| err, |n| n);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)`
+
+error: unused "map closure" when calling `Result::map_or_else` value
+  --> $DIR/unnecessary_result_map_or_else.rs:19:5
+   |
+LL | /     x.map_or_else(
+LL | |
+LL | |         |err| err,
+LL | |         |n| {
+...  |
+LL | |         },
+LL | |     );
+   | |_____^ help: consider using `unwrap_or_else`: `x.unwrap_or_else(|err| err)`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index 2dd1d746626..7f01c981a93 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -27,6 +27,7 @@ impl AsRef<str> for X {
     }
 }
 
+#[allow(clippy::to_string_trait_impl)]
 impl ToString for X {
     fn to_string(&self) -> String {
         self.0.to_string()
@@ -265,6 +266,7 @@ mod issue_8507 {
         }
     }
 
+    #[allow(clippy::to_string_trait_impl)]
     impl ToString for Y {
         fn to_string(&self) -> String {
             self.0.to_string()
@@ -338,6 +340,7 @@ mod issue_9317 {
 
     struct Bytes {}
 
+    #[allow(clippy::to_string_trait_impl)]
     impl ToString for Bytes {
         fn to_string(&self) -> String {
             "123".to_string()
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index 17fad33402b..a270ed1e1c2 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -27,6 +27,7 @@ impl AsRef<str> for X {
     }
 }
 
+#[allow(clippy::to_string_trait_impl)]
 impl ToString for X {
     fn to_string(&self) -> String {
         self.0.to_string()
@@ -265,6 +266,7 @@ mod issue_8507 {
         }
     }
 
+    #[allow(clippy::to_string_trait_impl)]
     impl ToString for Y {
         fn to_string(&self) -> String {
             self.0.to_string()
@@ -338,6 +340,7 @@ mod issue_9317 {
 
     struct Bytes {}
 
+    #[allow(clippy::to_string_trait_impl)]
     impl ToString for Bytes {
         fn to_string(&self) -> String {
             "123".to_string()
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
index ad6fa422b8c..95ff5f2ec2c 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
@@ -1,11 +1,11 @@
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:154:64
+  --> $DIR/unnecessary_to_owned.rs:155:64
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                                                                ^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/unnecessary_to_owned.rs:154:20
+  --> $DIR/unnecessary_to_owned.rs:155:20
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,55 +13,55 @@ LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned())
    = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:155:40
+  --> $DIR/unnecessary_to_owned.rs:156:40
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                                        ^^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/unnecessary_to_owned.rs:155:21
+  --> $DIR/unnecessary_to_owned.rs:156:21
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                     ^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:156:48
+  --> $DIR/unnecessary_to_owned.rs:157:48
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                                                ^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/unnecessary_to_owned.rs:156:19
+  --> $DIR/unnecessary_to_owned.rs:157:19
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:157:35
+  --> $DIR/unnecessary_to_owned.rs:158:35
    |
 LL |     require_str(&String::from("x").to_string());
    |                                   ^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/unnecessary_to_owned.rs:157:18
+  --> $DIR/unnecessary_to_owned.rs:158:18
    |
 LL |     require_str(&String::from("x").to_string());
    |                  ^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:158:39
+  --> $DIR/unnecessary_to_owned.rs:159:39
    |
 LL |     require_slice(&[String::from("x")].to_owned());
    |                                       ^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/unnecessary_to_owned.rs:158:20
+  --> $DIR/unnecessary_to_owned.rs:159:20
    |
 LL |     require_slice(&[String::from("x")].to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:63:36
+  --> $DIR/unnecessary_to_owned.rs:64:36
    |
 LL |     require_c_str(&Cow::from(c_str).into_owned());
    |                                    ^^^^^^^^^^^^^ help: remove this
@@ -70,415 +70,415 @@ LL |     require_c_str(&Cow::from(c_str).into_owned());
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:64:19
+  --> $DIR/unnecessary_to_owned.rs:65:19
    |
 LL |     require_c_str(&c_str.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_os_string`
-  --> $DIR/unnecessary_to_owned.rs:66:20
+  --> $DIR/unnecessary_to_owned.rs:67:20
    |
 LL |     require_os_str(&os_str.to_os_string());
    |                    ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:67:38
+  --> $DIR/unnecessary_to_owned.rs:68:38
    |
 LL |     require_os_str(&Cow::from(os_str).into_owned());
    |                                      ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:68:20
+  --> $DIR/unnecessary_to_owned.rs:69:20
    |
 LL |     require_os_str(&os_str.to_owned());
    |                    ^^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_path_buf`
-  --> $DIR/unnecessary_to_owned.rs:70:18
+  --> $DIR/unnecessary_to_owned.rs:71:18
    |
 LL |     require_path(&path.to_path_buf());
    |                  ^^^^^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:71:34
+  --> $DIR/unnecessary_to_owned.rs:72:34
    |
 LL |     require_path(&Cow::from(path).into_owned());
    |                                  ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:72:18
+  --> $DIR/unnecessary_to_owned.rs:73:18
    |
 LL |     require_path(&path.to_owned());
    |                  ^^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:74:17
+  --> $DIR/unnecessary_to_owned.rs:75:17
    |
 LL |     require_str(&s.to_string());
    |                 ^^^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:75:30
+  --> $DIR/unnecessary_to_owned.rs:76:30
    |
 LL |     require_str(&Cow::from(s).into_owned());
    |                              ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:76:17
+  --> $DIR/unnecessary_to_owned.rs:77:17
    |
 LL |     require_str(&s.to_owned());
    |                 ^^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:77:17
+  --> $DIR/unnecessary_to_owned.rs:78:17
    |
 LL |     require_str(&x_ref.to_string());
    |                 ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:79:19
+  --> $DIR/unnecessary_to_owned.rs:80:19
    |
 LL |     require_slice(&slice.to_vec());
    |                   ^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:80:36
+  --> $DIR/unnecessary_to_owned.rs:81:36
    |
 LL |     require_slice(&Cow::from(slice).into_owned());
    |                                    ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:81:19
+  --> $DIR/unnecessary_to_owned.rs:82:19
    |
 LL |     require_slice(&array.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:82:19
+  --> $DIR/unnecessary_to_owned.rs:83:19
    |
 LL |     require_slice(&array_ref.to_owned());
    |                   ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:83:19
+  --> $DIR/unnecessary_to_owned.rs:84:19
    |
 LL |     require_slice(&slice.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:86:42
+  --> $DIR/unnecessary_to_owned.rs:87:42
    |
 LL |     require_x(&Cow::<X>::Owned(x.clone()).into_owned());
    |                                          ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:89:25
+  --> $DIR/unnecessary_to_owned.rs:90:25
    |
 LL |     require_deref_c_str(c_str.to_owned());
    |                         ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:90:26
+  --> $DIR/unnecessary_to_owned.rs:91:26
    |
 LL |     require_deref_os_str(os_str.to_owned());
    |                          ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:91:24
+  --> $DIR/unnecessary_to_owned.rs:92:24
    |
 LL |     require_deref_path(path.to_owned());
    |                        ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:92:23
+  --> $DIR/unnecessary_to_owned.rs:93:23
    |
 LL |     require_deref_str(s.to_owned());
    |                       ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:93:25
+  --> $DIR/unnecessary_to_owned.rs:94:25
    |
 LL |     require_deref_slice(slice.to_owned());
    |                         ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:95:30
+  --> $DIR/unnecessary_to_owned.rs:96:30
    |
 LL |     require_impl_deref_c_str(c_str.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:96:31
+  --> $DIR/unnecessary_to_owned.rs:97:31
    |
 LL |     require_impl_deref_os_str(os_str.to_owned());
    |                               ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:97:29
+  --> $DIR/unnecessary_to_owned.rs:98:29
    |
 LL |     require_impl_deref_path(path.to_owned());
    |                             ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:98:28
+  --> $DIR/unnecessary_to_owned.rs:99:28
    |
 LL |     require_impl_deref_str(s.to_owned());
    |                            ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:99:30
+  --> $DIR/unnecessary_to_owned.rs:100:30
    |
 LL |     require_impl_deref_slice(slice.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:101:29
+  --> $DIR/unnecessary_to_owned.rs:102:29
    |
 LL |     require_deref_str_slice(s.to_owned(), slice.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:101:43
+  --> $DIR/unnecessary_to_owned.rs:102:43
    |
 LL |     require_deref_str_slice(s.to_owned(), slice.to_owned());
    |                                           ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:102:29
+  --> $DIR/unnecessary_to_owned.rs:103:29
    |
 LL |     require_deref_slice_str(slice.to_owned(), s.to_owned());
    |                             ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:102:47
+  --> $DIR/unnecessary_to_owned.rs:103:47
    |
 LL |     require_deref_slice_str(slice.to_owned(), s.to_owned());
    |                                               ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:104:26
+  --> $DIR/unnecessary_to_owned.rs:105:26
    |
 LL |     require_as_ref_c_str(c_str.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:105:27
+  --> $DIR/unnecessary_to_owned.rs:106:27
    |
 LL |     require_as_ref_os_str(os_str.to_owned());
    |                           ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:106:25
+  --> $DIR/unnecessary_to_owned.rs:107:25
    |
 LL |     require_as_ref_path(path.to_owned());
    |                         ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:107:24
+  --> $DIR/unnecessary_to_owned.rs:108:24
    |
 LL |     require_as_ref_str(s.to_owned());
    |                        ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:108:24
+  --> $DIR/unnecessary_to_owned.rs:109:24
    |
 LL |     require_as_ref_str(x.to_owned());
    |                        ^^^^^^^^^^^^ help: use: `&x`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:109:26
+  --> $DIR/unnecessary_to_owned.rs:110:26
    |
 LL |     require_as_ref_slice(array.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:110:26
+  --> $DIR/unnecessary_to_owned.rs:111:26
    |
 LL |     require_as_ref_slice(array_ref.to_owned());
    |                          ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:111:26
+  --> $DIR/unnecessary_to_owned.rs:112:26
    |
 LL |     require_as_ref_slice(slice.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:113:31
+  --> $DIR/unnecessary_to_owned.rs:114:31
    |
 LL |     require_impl_as_ref_c_str(c_str.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:114:32
+  --> $DIR/unnecessary_to_owned.rs:115:32
    |
 LL |     require_impl_as_ref_os_str(os_str.to_owned());
    |                                ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:115:30
+  --> $DIR/unnecessary_to_owned.rs:116:30
    |
 LL |     require_impl_as_ref_path(path.to_owned());
    |                              ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:116:29
+  --> $DIR/unnecessary_to_owned.rs:117:29
    |
 LL |     require_impl_as_ref_str(s.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:117:29
+  --> $DIR/unnecessary_to_owned.rs:118:29
    |
 LL |     require_impl_as_ref_str(x.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `&x`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:118:31
+  --> $DIR/unnecessary_to_owned.rs:119:31
    |
 LL |     require_impl_as_ref_slice(array.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:119:31
+  --> $DIR/unnecessary_to_owned.rs:120:31
    |
 LL |     require_impl_as_ref_slice(array_ref.to_owned());
    |                               ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:120:31
+  --> $DIR/unnecessary_to_owned.rs:121:31
    |
 LL |     require_impl_as_ref_slice(slice.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:122:30
+  --> $DIR/unnecessary_to_owned.rs:123:30
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array.to_owned());
    |                              ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:122:44
+  --> $DIR/unnecessary_to_owned.rs:123:44
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array.to_owned());
    |                                            ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:123:30
+  --> $DIR/unnecessary_to_owned.rs:124:30
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
    |                              ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:123:44
+  --> $DIR/unnecessary_to_owned.rs:124:44
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
    |                                            ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:124:30
+  --> $DIR/unnecessary_to_owned.rs:125:30
    |
 LL |     require_as_ref_str_slice(s.to_owned(), slice.to_owned());
    |                              ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:124:44
+  --> $DIR/unnecessary_to_owned.rs:125:44
    |
 LL |     require_as_ref_str_slice(s.to_owned(), slice.to_owned());
    |                                            ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:125:30
+  --> $DIR/unnecessary_to_owned.rs:126:30
    |
 LL |     require_as_ref_slice_str(array.to_owned(), s.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:125:48
+  --> $DIR/unnecessary_to_owned.rs:126:48
    |
 LL |     require_as_ref_slice_str(array.to_owned(), s.to_owned());
    |                                                ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:126:30
+  --> $DIR/unnecessary_to_owned.rs:127:30
    |
 LL |     require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
    |                              ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:126:52
+  --> $DIR/unnecessary_to_owned.rs:127:52
    |
 LL |     require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
    |                                                    ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:127:30
+  --> $DIR/unnecessary_to_owned.rs:128:30
    |
 LL |     require_as_ref_slice_str(slice.to_owned(), s.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:127:48
+  --> $DIR/unnecessary_to_owned.rs:128:48
    |
 LL |     require_as_ref_slice_str(slice.to_owned(), s.to_owned());
    |                                                ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:129:20
+  --> $DIR/unnecessary_to_owned.rs:130:20
    |
 LL |     let _ = x.join(&x_ref.to_string());
    |                    ^^^^^^^^^^^^^^^^^^ help: use: `x_ref`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:131:13
+  --> $DIR/unnecessary_to_owned.rs:132:13
    |
 LL |     let _ = slice.to_vec().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:132:13
+  --> $DIR/unnecessary_to_owned.rs:133:13
    |
 LL |     let _ = slice.to_owned().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:133:13
+  --> $DIR/unnecessary_to_owned.rs:134:13
    |
 LL |     let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:134:13
+  --> $DIR/unnecessary_to_owned.rs:135:13
    |
 LL |     let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:136:13
+  --> $DIR/unnecessary_to_owned.rs:137:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_vec());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:137:13
+  --> $DIR/unnecessary_to_owned.rs:138:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_owned());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:138:13
+  --> $DIR/unnecessary_to_owned.rs:139:13
    |
 LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:139:13
+  --> $DIR/unnecessary_to_owned.rs:140:13
    |
 LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:201:14
+  --> $DIR/unnecessary_to_owned.rs:202:14
    |
 LL |     for t in file_types.to_vec() {
    |              ^^^^^^^^^^^^^^^^^^^
@@ -494,31 +494,31 @@ LL +         let path = match get_file_path(t) {
    |
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:224:14
+  --> $DIR/unnecessary_to_owned.rs:225:14
    |
 LL |     let _ = &["x"][..].to_vec().into_iter();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:229:14
+  --> $DIR/unnecessary_to_owned.rs:230:14
    |
 LL |     let _ = &["x"][..].to_vec().into_iter();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:276:24
+  --> $DIR/unnecessary_to_owned.rs:278:24
    |
 LL |         Box::new(build(y.to_string()))
    |                        ^^^^^^^^^^^^^ help: use: `y`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:384:12
+  --> $DIR/unnecessary_to_owned.rs:387:12
    |
 LL |         id("abc".to_string())
    |            ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:527:37
+  --> $DIR/unnecessary_to_owned.rs:530:37
    |
 LL |         IntoFuture::into_future(foo([].to_vec(), &0));
    |                                     ^^^^^^^^^^^ help: use: `[]`
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.fixed
index f87c898f9b7..e0ba216f41b 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.fixed
@@ -8,6 +8,7 @@ impl AsRef<str> for Issue12068 {
     }
 }
 
+#[allow(clippy::to_string_trait_impl)]
 impl ToString for Issue12068 {
     fn to_string(&self) -> String {
         String::new()
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.rs
index db5719e5880..70efc6ebba5 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.rs
@@ -8,6 +8,7 @@ impl AsRef<str> for Issue12068 {
     }
 }
 
+#[allow(clippy::to_string_trait_impl)]
 impl ToString for Issue12068 {
     fn to_string(&self) -> String {
         String::new()
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.stderr
index 4cfaeed3384..9aea15b48bf 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned_on_split.stderr
@@ -1,5 +1,5 @@
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned_on_split.rs:18:13
+  --> $DIR/unnecessary_to_owned_on_split.rs:19:13
    |
 LL |     let _ = "a".to_string().split('a').next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `"a".split('a')`
@@ -8,49 +8,49 @@ LL |     let _ = "a".to_string().split('a').next().unwrap();
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_to_owned)]`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned_on_split.rs:20:13
+  --> $DIR/unnecessary_to_owned_on_split.rs:21:13
    |
 LL |     let _ = "a".to_string().split("a").next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `"a".split("a")`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned_on_split.rs:22:13
+  --> $DIR/unnecessary_to_owned_on_split.rs:23:13
    |
 LL |     let _ = "a".to_owned().split('a').next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `"a".split('a')`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned_on_split.rs:24:13
+  --> $DIR/unnecessary_to_owned_on_split.rs:25:13
    |
 LL |     let _ = "a".to_owned().split("a").next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `"a".split("a")`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned_on_split.rs:26:13
+  --> $DIR/unnecessary_to_owned_on_split.rs:27:13
    |
 LL |     let _ = Issue12068.to_string().split('a').next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `Issue12068.as_ref().split('a')`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned_on_split.rs:29:13
+  --> $DIR/unnecessary_to_owned_on_split.rs:30:13
    |
 LL |     let _ = [1].to_vec().split(|x| *x == 2).next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned_on_split.rs:31:13
+  --> $DIR/unnecessary_to_owned_on_split.rs:32:13
    |
 LL |     let _ = [1].to_vec().split(|x| *x == 2).next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned_on_split.rs:33:13
+  --> $DIR/unnecessary_to_owned_on_split.rs:34:13
    |
 LL |     let _ = [1].to_owned().split(|x| *x == 2).next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned_on_split.rs:35:13
+  --> $DIR/unnecessary_to_owned_on_split.rs:36:13
    |
 LL |     let _ = [1].to_owned().split(|x| *x == 2).next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[1].split(|x| *x == 2)`
diff --git a/src/tools/clippy/tests/ui/unused_io_amount.rs b/src/tools/clippy/tests/ui/unused_io_amount.rs
index 9974600dad5..7e5a10c911b 100644
--- a/src/tools/clippy/tests/ui/unused_io_amount.rs
+++ b/src/tools/clippy/tests/ui/unused_io_amount.rs
@@ -229,4 +229,47 @@ fn on_return_should_not_raise<T: io::Read + io::Write>(s: &mut T) -> io::Result<
     s.read(&mut buf)
 }
 
+pub fn unwrap_in_block(rdr: &mut dyn std::io::Read) -> std::io::Result<usize> {
+    let read = { rdr.read(&mut [0])? };
+    Ok(read)
+}
+
+pub fn consumed_example(rdr: &mut dyn std::io::Read) {
+    match rdr.read(&mut [0]) {
+        Ok(0) => println!("EOF"),
+        Ok(_) => println!("fully read"),
+        Err(_) => println!("fail"),
+    };
+    match rdr.read(&mut [0]) {
+        Ok(0) => println!("EOF"),
+        Ok(_) => println!("fully read"),
+        Err(_) => println!("fail"),
+    }
+}
+
+pub fn unreachable_or_panic(rdr: &mut dyn std::io::Read) {
+    {
+        match rdr.read(&mut [0]) {
+            Ok(_) => unreachable!(),
+            Err(_) => println!("expected"),
+        }
+    }
+
+    {
+        match rdr.read(&mut [0]) {
+            Ok(_) => panic!(),
+            Err(_) => println!("expected"),
+        }
+    }
+}
+
+pub fn wildcards(rdr: &mut dyn std::io::Read) {
+    {
+        match rdr.read(&mut [0]) {
+            Ok(1) => todo!(),
+            _ => todo!(),
+        }
+    }
+}
+
 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 4af56d264bf..1aab56966a8 100644
--- a/src/tools/clippy/tests/ui/unused_io_amount.stderr
+++ b/src/tools/clippy/tests/ui/unused_io_amount.stderr
@@ -180,7 +180,7 @@ 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
@@ -193,7 +193,7 @@ 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
@@ -206,7 +206,7 @@ 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
@@ -219,7 +219,7 @@ 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
diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.fixed b/src/tools/clippy/tests/ui/while_let_on_iterator.fixed
index d628d2227b7..59b5c858d04 100644
--- a/src/tools/clippy/tests/ui/while_let_on_iterator.fixed
+++ b/src/tools/clippy/tests/ui/while_let_on_iterator.fixed
@@ -406,7 +406,7 @@ fn issue_8113() {
 fn fn_once_closure() {
     let mut it = 0..10;
     (|| {
-        for x in it {
+        for x in it.by_ref() {
             if x % 2 == 0 {
                 break;
             }
@@ -441,7 +441,19 @@ fn fn_once_closure() {
                 break;
             }
         }
-    })
+    });
+
+    trait MySpecialFnMut: FnOnce() {}
+    impl<T: FnOnce()> MySpecialFnMut for T {}
+    fn f4(_: impl MySpecialFnMut) {}
+    let mut it = 0..10;
+    f4(|| {
+        for x in it {
+            if x % 2 == 0 {
+                break;
+            }
+        }
+    });
 }
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.rs b/src/tools/clippy/tests/ui/while_let_on_iterator.rs
index 525dbbaaab6..559513d5694 100644
--- a/src/tools/clippy/tests/ui/while_let_on_iterator.rs
+++ b/src/tools/clippy/tests/ui/while_let_on_iterator.rs
@@ -441,7 +441,19 @@ fn fn_once_closure() {
                 break;
             }
         }
-    })
+    });
+
+    trait MySpecialFnMut: FnOnce() {}
+    impl<T: FnOnce()> MySpecialFnMut for T {}
+    fn f4(_: impl MySpecialFnMut) {}
+    let mut it = 0..10;
+    f4(|| {
+        while let Some(x) = it.next() {
+            if x % 2 == 0 {
+                break;
+            }
+        }
+    });
 }
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/while_let_on_iterator.stderr b/src/tools/clippy/tests/ui/while_let_on_iterator.stderr
index cdc83b81667..7b9a9dc049a 100644
--- a/src/tools/clippy/tests/ui/while_let_on_iterator.stderr
+++ b/src/tools/clippy/tests/ui/while_let_on_iterator.stderr
@@ -131,7 +131,7 @@ error: this loop could be written as a `for` loop
   --> $DIR/while_let_on_iterator.rs:409:9
    |
 LL |         while let Some(x) = it.next() {
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`
 
 error: this loop could be written as a `for` loop
   --> $DIR/while_let_on_iterator.rs:419:9
@@ -152,10 +152,16 @@ LL |         while let Some(x) = it.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:449:5
+  --> $DIR/while_let_on_iterator.rs:451:9
+   |
+LL |         while let Some(x) = it.next() {
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it`
+
+error: this loop could be written as a `for` loop
+  --> $DIR/while_let_on_iterator.rs:461:5
    |
 LL |     while let Some(..) = it.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it`
 
-error: aborting due to 26 previous errors
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 8be4def15de..ed1c559e1f6 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2467,6 +2467,7 @@ impl<'test> TestCx<'test> {
                     "-Zvalidate-mir",
                     "-Zlint-mir",
                     "-Zdump-mir-exclude-pass-number",
+                    "--crate-type=rlib",
                 ]);
                 if let Some(pass) = &self.props.mir_unit_test {
                     rustc.args(&["-Zmir-opt-level=0", &format!("-Zmir-enable-passes=+{}", pass)]);
diff --git a/src/tools/coverage-dump/src/covfun.rs b/src/tools/coverage-dump/src/covfun.rs
index 3a5866dea3e..49e3a6ed583 100644
--- a/src/tools/coverage-dump/src/covfun.rs
+++ b/src/tools/coverage-dump/src/covfun.rs
@@ -219,7 +219,7 @@ impl CovTerm {
 enum MappingKind {
     Code(CovTerm),
     Gap(CovTerm),
-    Expansion(u32),
+    Expansion(#[allow(dead_code)] u32),
     Skip,
     // Using raw identifiers here makes the dump output a little bit nicer
     // (via the derived Debug), at the expense of making this tool's source
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index e8e10f64ad2..de7a4b79d26 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -2,7 +2,9 @@
 #![allow(
     clippy::manual_range_contains,
     clippy::useless_format,
-    clippy::field_reassign_with_default
+    clippy::field_reassign_with_default,
+    rustc::diagnostic_outside_of_impl,
+    rustc::untranslatable_diagnostic,
 )]
 
 extern crate rustc_data_structures;
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index 74ff6ed4e0a..46f96a715f1 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -383,7 +383,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             // will never cause UB on the pointer itself.
             let (_, _, kind) = this.get_alloc_info(*alloc_id);
             if matches!(kind, AllocKind::LiveData) {
-                let alloc_extra = this.get_alloc_extra(*alloc_id).unwrap();
+                let alloc_extra = this.get_alloc_extra(*alloc_id)?; // can still fail for `extern static`
                 let alloc_borrow_tracker = &alloc_extra.borrow_tracker.as_ref().unwrap();
                 alloc_borrow_tracker.release_protector(&this.machine, borrow_tracker, *tag)?;
             }
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 057b883a3bf..5a2bb84f3ef 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -10,7 +10,7 @@
 #![feature(nonzero_ops)]
 #![feature(let_chains)]
 #![feature(lint_reasons)]
-#![cfg_attr(not(bootstrap), feature(trait_upcasting))]
+#![feature(trait_upcasting)]
 // Configure clippy and other lints
 #![allow(
     clippy::collapsible_else_if,
@@ -33,8 +33,10 @@
     clippy::bool_to_int_with_if,
     clippy::box_default,
     clippy::needless_question_mark,
+    rustc::diagnostic_outside_of_impl,
     // We are not implementing queries here so it's fine
-    rustc::potential_query_instability
+    rustc::potential_query_instability,
+    rustc::untranslatable_diagnostic,
 )]
 #![warn(
     rust_2018_idioms,
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 946887637ff..40d041c8fdb 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -2,7 +2,7 @@
 //! `Machine` trait.
 
 use std::borrow::Cow;
-use std::cell::{Cell, RefCell};
+use std::cell::RefCell;
 use std::collections::hash_map::Entry;
 use std::fmt;
 use std::path::Path;
@@ -336,20 +336,11 @@ pub struct AllocExtra<'tcx> {
     /// if this allocation is leakable. The backtrace is not
     /// pruned yet; that should be done before printing it.
     pub backtrace: Option<Vec<FrameInfo<'tcx>>>,
-    /// An offset inside this allocation that was deemed aligned even for symbolic alignment checks.
-    /// Invariant: the promised alignment will never be less than the native alignment of this allocation.
-    pub symbolic_alignment: Cell<Option<(Size, Align)>>,
 }
 
 impl VisitProvenance for AllocExtra<'_> {
     fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
-        let AllocExtra {
-            borrow_tracker,
-            data_race,
-            weak_memory,
-            backtrace: _,
-            symbolic_alignment: _,
-        } = self;
+        let AllocExtra { borrow_tracker, data_race, weak_memory, backtrace: _ } = self;
 
         borrow_tracker.visit_provenance(visit);
         data_race.visit_provenance(visit);
@@ -572,6 +563,14 @@ pub struct MiriMachine<'mir, 'tcx> {
     /// that is fixed per stack frame; this lets us have sometimes different results for the
     /// same const while ensuring consistent results within a single call.
     const_cache: RefCell<FxHashMap<(mir::Const<'tcx>, usize), OpTy<'tcx, Provenance>>>,
+
+    /// For each allocation, an offset inside that allocation that was deemed aligned even for
+    /// symbolic alignment checks. This cannot be stored in `AllocExtra` since it needs to be
+    /// tracked for vtables and function allocations as well as regular allocations.
+    ///
+    /// Invariant: the promised alignment will never be less than the native alignment of the
+    /// allocation.
+    pub(crate) symbolic_alignment: RefCell<FxHashMap<AllocId, (Size, Align)>>,
 }
 
 impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
@@ -698,6 +697,7 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
             collect_leak_backtraces: config.collect_leak_backtraces,
             allocation_spans: RefCell::new(FxHashMap::default()),
             const_cache: RefCell::new(FxHashMap::default()),
+            symbolic_alignment: RefCell::new(FxHashMap::default()),
         }
     }
 
@@ -810,6 +810,7 @@ impl VisitProvenance for MiriMachine<'_, '_> {
             collect_leak_backtraces: _,
             allocation_spans: _,
             const_cache: _,
+            symbolic_alignment: _,
         } = self;
 
         threads.visit_provenance(visit);
@@ -893,9 +894,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
             return None;
         }
         // Let's see which alignment we have been promised for this allocation.
-        let alloc_info = ecx.get_alloc_extra(alloc_id).unwrap(); // cannot fail since the allocation is live
-        let (promised_offset, promised_align) =
-            alloc_info.symbolic_alignment.get().unwrap_or((Size::ZERO, alloc_align));
+        let (promised_offset, promised_align) = ecx
+            .machine
+            .symbolic_alignment
+            .borrow()
+            .get(&alloc_id)
+            .copied()
+            .unwrap_or((Size::ZERO, alloc_align));
         if promised_align < align {
             // Definitely not enough.
             Some(Misalignment { has: promised_align, required: align })
@@ -1132,7 +1137,6 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> {
                 data_race: race_alloc,
                 weak_memory: buffer_alloc,
                 backtrace,
-                symbolic_alignment: Cell::new(None),
             },
             |ptr| ecx.global_base_pointer(ptr),
         )?;
diff --git a/src/tools/miri/src/provenance_gc.rs b/src/tools/miri/src/provenance_gc.rs
index ab178f82d9f..347951ce372 100644
--- a/src/tools/miri/src/provenance_gc.rs
+++ b/src/tools/miri/src/provenance_gc.rs
@@ -196,6 +196,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> {
         let this = self.eval_context_mut();
         let allocs = LiveAllocs { ecx: this, collected: allocs };
         this.machine.allocation_spans.borrow_mut().retain(|id, _| allocs.is_live(*id));
+        this.machine.symbolic_alignment.borrow_mut().retain(|id, _| allocs.is_live(*id));
         this.machine.intptrcast.borrow_mut().remove_unreachable_allocs(&allocs);
         if let Some(borrow_tracker) = &this.machine.borrow_tracker {
             borrow_tracker.borrow_mut().remove_unreachable_allocs(&allocs);
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index a002f2aad05..25654248db4 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -585,17 +585,17 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 }
                 if let Ok((alloc_id, offset, ..)) = this.ptr_try_get_alloc_id(ptr) {
                     let (_size, alloc_align, _kind) = this.get_alloc_info(alloc_id);
-                    // Not `get_alloc_extra_mut`, need to handle read-only allocations!
-                    let alloc_extra = this.get_alloc_extra(alloc_id)?;
                     // If the newly promised alignment is bigger than the native alignment of this
                     // allocation, and bigger than the previously promised alignment, then set it.
                     if align > alloc_align
-                        && !alloc_extra
+                        && !this
+                            .machine
                             .symbolic_alignment
-                            .get()
-                            .is_some_and(|(_, old_align)| align <= old_align)
+                            .get_mut()
+                            .get(&alloc_id)
+                            .is_some_and(|&(_, old_align)| align <= old_align)
                     {
-                        alloc_extra.symbolic_alignment.set(Some((offset, align)));
+                        this.machine.symbolic_alignment.get_mut().insert(alloc_id, (offset, align));
                     }
                 }
             }
diff --git a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs
index 0e7c3dbcc04..13f913454dc 100644
--- a/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs
+++ b/src/tools/miri/tests/fail/dyn-call-trait-mismatch.rs
@@ -1,4 +1,5 @@
 trait T1 {
+    #[allow(dead_code)]
     fn method1(self: Box<Self>);
 }
 trait T2 {
diff --git a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs
index 648ac07c43e..982f33b0a31 100644
--- a/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs
+++ b/src/tools/miri/tests/fail/dyn-upcast-trait-mismatch.rs
@@ -2,30 +2,36 @@
 #![allow(incomplete_features)]
 
 trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
+    #[allow(dead_code)]
     fn a(&self) -> i32 {
         10
     }
 
+    #[allow(dead_code)]
     fn z(&self) -> i32 {
         11
     }
 
+    #[allow(dead_code)]
     fn y(&self) -> i32 {
         12
     }
 }
 
 trait Bar: Foo {
+    #[allow(dead_code)]
     fn b(&self) -> i32 {
         20
     }
 
+    #[allow(dead_code)]
     fn w(&self) -> i32 {
         21
     }
 }
 
 trait Baz: Bar {
+    #[allow(dead_code)]
     fn c(&self) -> i32 {
         30
     }
diff --git a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs
new file mode 100644
index 00000000000..44604074982
--- /dev/null
+++ b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.rs
@@ -0,0 +1,12 @@
+//@compile-flags: -Zmiri-symbolic-alignment-check
+
+extern "C" {
+    static _dispatch_queue_attr_concurrent: [u8; 0];
+}
+
+static DISPATCH_QUEUE_CONCURRENT: &'static [u8; 0] =
+    unsafe { &_dispatch_queue_attr_concurrent };
+
+fn main() {
+    let _val = *DISPATCH_QUEUE_CONCURRENT; //~ERROR: is not supported
+}
diff --git a/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr
new file mode 100644
index 00000000000..a4249d2e881
--- /dev/null
+++ b/src/tools/miri/tests/fail/issue-miri-3288-ice-symbolic-alignment-extern-static.stderr
@@ -0,0 +1,14 @@
+error: unsupported operation: `extern` static `_dispatch_queue_attr_concurrent` from crate `issue_miri_3288_ice_symbolic_alignment_extern_static` is not supported by Miri
+  --> $DIR/issue-miri-3288-ice-symbolic-alignment-extern-static.rs:LL:CC
+   |
+LL |     let _val = *DISPATCH_QUEUE_CONCURRENT;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ `extern` static `_dispatch_queue_attr_concurrent` from crate `issue_miri_3288_ice_symbolic_alignment_extern_static` is not supported by Miri
+   |
+   = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/issue-miri-3288-ice-symbolic-alignment-extern-static.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/miri/tests/pass/align_offset_symbolic.rs b/src/tools/miri/tests/pass/align_offset_symbolic.rs
index 4df364bac7a..e96f11b1efa 100644
--- a/src/tools/miri/tests/pass/align_offset_symbolic.rs
+++ b/src/tools/miri/tests/pass/align_offset_symbolic.rs
@@ -1,6 +1,8 @@
 //@compile-flags: -Zmiri-symbolic-alignment-check
 #![feature(strict_provenance)]
 
+use std::mem;
+
 fn test_align_to() {
     const N: usize = 4;
     let d = Box::new([0u32; N]);
@@ -68,7 +70,7 @@ fn test_u64_array() {
     #[repr(align(8))]
     struct AlignToU64<T>(T);
 
-    const BYTE_LEN: usize = std::mem::size_of::<[u64; 4]>();
+    const BYTE_LEN: usize = mem::size_of::<[u64; 4]>();
     type Data = AlignToU64<[u8; BYTE_LEN]>;
 
     fn example(data: &Data) {
@@ -101,10 +103,29 @@ fn huge_align() {
     let _ = std::ptr::invalid::<HugeSize>(SIZE).align_offset(SIZE);
 }
 
+// This shows that we cannot store the promised alignment info in `AllocExtra`,
+// since vtables do not have an `AllocExtra`.
+fn vtable() {
+    #[cfg(target_pointer_width = "64")]
+    type TWOPTR = u128;
+    #[cfg(target_pointer_width = "32")]
+    type TWOPTR = u64;
+
+    let ptr: &dyn Send = &0;
+    let parts: (*const (), *const u8) = unsafe { mem::transmute(ptr) };
+    let vtable = parts.1 ;
+    let offset = vtable.align_offset(mem::align_of::<TWOPTR>());
+    let _vtable_aligned = vtable.wrapping_add(offset) as *const [TWOPTR; 0];
+    // FIXME: we can't actually do the access since vtable pointers act like zero-sized allocations.
+    // Enable the next line once https://github.com/rust-lang/rust/issues/117945 is implemented.
+    //let _place = unsafe { &*vtable_aligned };
+}
+
 fn main() {
     test_align_to();
     test_from_utf8();
     test_u64_array();
     test_cstr();
     huge_align();
+    vtable();
 }
diff --git a/src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs b/src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs
index ccf96b99672..2491bda0917 100644
--- a/src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs
+++ b/src/tools/miri/tests/pass/cast-rfc0401-vtable-kinds.rs
@@ -9,6 +9,7 @@ trait Foo<T> {
     }
 }
 
+#[allow(dead_code)]
 trait Bar {
     fn bar(&self) {
         println!("Bar!");
diff --git a/src/tools/miri/tests/pass/dyn-upcast.rs b/src/tools/miri/tests/pass/dyn-upcast.rs
index 8432012a9ba..529b9c471d4 100644
--- a/src/tools/miri/tests/pass/dyn-upcast.rs
+++ b/src/tools/miri/tests/pass/dyn-upcast.rs
@@ -383,14 +383,17 @@ fn struct_() {
 
 fn replace_vptr() {
     trait A {
+        #[allow(dead_code)]
         fn foo_a(&self);
     }
 
     trait B {
+        #[allow(dead_code)]
         fn foo_b(&self);
     }
 
     trait C: A + B {
+        #[allow(dead_code)]
         fn foo_c(&self);
     }
 
diff --git a/src/tools/miri/tests/pass/weak_memory/weak.rs b/src/tools/miri/tests/pass/weak_memory/weak.rs
index 4c3be6b3559..e10ccc277f6 100644
--- a/src/tools/miri/tests/pass/weak_memory/weak.rs
+++ b/src/tools/miri/tests/pass/weak_memory/weak.rs
@@ -11,6 +11,7 @@ use std::sync::atomic::Ordering::*;
 use std::sync::atomic::{fence, AtomicUsize};
 use std::thread::spawn;
 
+#[allow(dead_code)]
 #[derive(Copy, Clone)]
 struct EvilSend<T>(pub T);
 
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 6dc3eac44d4..f0af401d3da 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -47,7 +47,7 @@ impl Emitter for SilentEmitter {
         None
     }
 
-    fn emit_diagnostic(&mut self, _db: &Diagnostic) {}
+    fn emit_diagnostic(&mut self, _db: Diagnostic) {}
 }
 
 fn silent_emitter() -> Box<DynEmitter> {
@@ -64,7 +64,7 @@ struct SilentOnIgnoredFilesEmitter {
 }
 
 impl SilentOnIgnoredFilesEmitter {
-    fn handle_non_ignoreable_error(&mut self, db: &Diagnostic) {
+    fn handle_non_ignoreable_error(&mut self, db: Diagnostic) {
         self.has_non_ignorable_parser_errors = true;
         self.can_reset.store(false, Ordering::Release);
         self.emitter.emit_diagnostic(db);
@@ -86,7 +86,7 @@ impl Emitter for SilentOnIgnoredFilesEmitter {
         None
     }
 
-    fn emit_diagnostic(&mut self, db: &Diagnostic) {
+    fn emit_diagnostic(&mut self, db: Diagnostic) {
         if db.level() == DiagnosticLevel::Fatal {
             return self.handle_non_ignoreable_error(db);
         }
@@ -365,7 +365,7 @@ mod tests {
                 None
             }
 
-            fn emit_diagnostic(&mut self, _db: &Diagnostic) {
+            fn emit_diagnostic(&mut self, _db: Diagnostic) {
                 self.num_emitted_errors.fetch_add(1, Ordering::Release);
             }
         }
@@ -424,7 +424,7 @@ mod tests {
             );
             let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
             let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, Some(span));
-            emitter.emit_diagnostic(&fatal_diagnostic);
+            emitter.emit_diagnostic(fatal_diagnostic);
             assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1);
             assert_eq!(can_reset_errors.load(Ordering::Acquire), false);
         }
@@ -449,7 +449,7 @@ mod tests {
             );
             let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
             let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
-            emitter.emit_diagnostic(&non_fatal_diagnostic);
+            emitter.emit_diagnostic(non_fatal_diagnostic);
             assert_eq!(num_emitted_errors.load(Ordering::Acquire), 0);
             assert_eq!(can_reset_errors.load(Ordering::Acquire), true);
         }
@@ -473,7 +473,7 @@ mod tests {
             );
             let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
             let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
-            emitter.emit_diagnostic(&non_fatal_diagnostic);
+            emitter.emit_diagnostic(non_fatal_diagnostic);
             assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1);
             assert_eq!(can_reset_errors.load(Ordering::Acquire), false);
         }
@@ -512,9 +512,9 @@ mod tests {
             let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span));
             let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span));
             let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None);
-            emitter.emit_diagnostic(&bar_diagnostic);
-            emitter.emit_diagnostic(&foo_diagnostic);
-            emitter.emit_diagnostic(&fatal_diagnostic);
+            emitter.emit_diagnostic(bar_diagnostic);
+            emitter.emit_diagnostic(foo_diagnostic);
+            emitter.emit_diagnostic(fatal_diagnostic);
             assert_eq!(num_emitted_errors.load(Ordering::Acquire), 2);
             assert_eq!(can_reset_errors.load(Ordering::Acquire), false);
         }
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 451276b5ac1..03f8a701627 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -13,7 +13,8 @@ use std::path::{Path, PathBuf};
 // desirable, because large numbers of files are unwieldy in general. See issue
 // #73494.
 const ENTRY_LIMIT: usize = 900;
-const ISSUES_ENTRY_LIMIT: usize = 1807;
+// FIXME: The following limits should be reduced eventually.
+const ISSUES_ENTRY_LIMIT: usize = 1794;
 const ROOT_ENTRY_LIMIT: usize = 870;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
diff --git a/tests/assembly/is_aligned.rs b/tests/assembly/is_aligned.rs
index d152d200adf..c4a7823ce1a 100644
--- a/tests/assembly/is_aligned.rs
+++ b/tests/assembly/is_aligned.rs
@@ -2,8 +2,8 @@
 // only-x86_64
 // ignore-sgx
 // revisions: opt-speed opt-size
-// [opt-speed] compile-flags: -Copt-level=1
-// [opt-size] compile-flags: -Copt-level=s
+// [opt-speed] compile-flags: -Copt-level=2 -Cdebug-assertions=no
+// [opt-size] compile-flags: -Copt-level=s -Cdebug-assertions=no
 #![crate_type="rlib"]
 
 #![feature(core_intrinsics)]
diff --git a/tests/assembly/targets/targets-elf.rs b/tests/assembly/targets/targets-elf.rs
index 41f5df0fba0..6105ea430dd 100644
--- a/tests/assembly/targets/targets-elf.rs
+++ b/tests/assembly/targets/targets-elf.rs
@@ -174,6 +174,9 @@
 // revisions: armv7r_none_eabihf
 // [armv7r_none_eabihf] compile-flags: --target armv7r-none-eabihf
 // [armv7r_none_eabihf] needs-llvm-components: arm
+// revisions: armv8r_none_eabihf
+// [armv8r_none_eabihf] compile-flags: --target armv8r-none-eabihf
+// [armv8r_none_eabihf] needs-llvm-components: arm
 // FIXME: disabled since it fails on CI saying the csky component is missing
 /*
     revisions: csky_unknown_linux_gnuabiv2
diff --git a/tests/codegen-units/item-collection/instantiation-through-vtable.rs b/tests/codegen-units/item-collection/instantiation-through-vtable.rs
index e78226d4083..41edab7f879 100644
--- a/tests/codegen-units/item-collection/instantiation-through-vtable.rs
+++ b/tests/codegen-units/item-collection/instantiation-through-vtable.rs
@@ -26,7 +26,9 @@ fn start(_: isize, _: *const *const u8) -> isize {
     //~ MONO_ITEM fn std::ptr::drop_in_place::<Struct<u32>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal]
     //~ MONO_ITEM fn <Struct<u32> as Trait>::foo
     //~ MONO_ITEM fn <Struct<u32> as Trait>::bar
-    let _ = &s1 as &Trait;
+    let r1 = &s1 as &Trait;
+    r1.foo();
+    r1.bar();
 
     let s1 = Struct { _a: 0u64 };
     //~ MONO_ITEM fn std::ptr::drop_in_place::<Struct<u64>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal]
diff --git a/tests/codegen-units/item-collection/trait-method-default-impl.rs b/tests/codegen-units/item-collection/trait-method-default-impl.rs
index d953582cce9..c8a4552b11a 100644
--- a/tests/codegen-units/item-collection/trait-method-default-impl.rs
+++ b/tests/codegen-units/item-collection/trait-method-default-impl.rs
@@ -57,5 +57,8 @@ fn start(_: isize, _: *const *const u8) -> isize {
     //~ MONO_ITEM fn <u32 as SomeGenericTrait<i16>>::bar::<()>
     0u32.bar(0i16, ());
 
+    0i8.foo();
+    0i32.foo();
+
     0
 }
diff --git a/tests/codegen-units/item-collection/unsizing.rs b/tests/codegen-units/item-collection/unsizing.rs
index 34f52ce4e61..f578b00f276 100644
--- a/tests/codegen-units/item-collection/unsizing.rs
+++ b/tests/codegen-units/item-collection/unsizing.rs
@@ -75,5 +75,7 @@ fn start(_: isize, _: *const *const u8) -> isize {
     //~ MONO_ITEM fn <u32 as Trait>::foo
     let _wrapper_sized = wrapper_sized as Wrapper<Trait>;
 
+    false.foo();
+
     0
 }
diff --git a/tests/codegen/async-closure-debug.rs b/tests/codegen/async-closure-debug.rs
new file mode 100644
index 00000000000..6718d2b6627
--- /dev/null
+++ b/tests/codegen/async-closure-debug.rs
@@ -0,0 +1,21 @@
+// Just make sure that async closures don't ICE.
+//
+// compile-flags: -C debuginfo=2 --edition=2018
+// ignore-msvc
+
+// CHECK-DAG:  [[GEN_FN:!.*]] = !DINamespace(name: "async_closure_test"
+// CHECK-DAG:  [[CLOSURE:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{closure_env#0}", scope: [[GEN_FN]]
+// CHECK-DAG:  [[UPVAR:!.*]] = !DIDerivedType(tag: DW_TAG_member, name: "upvar", scope: [[CLOSURE]]
+
+#![feature(async_closure)]
+
+fn async_closure_test(upvar: &str) -> impl async Fn() + '_ {
+    async move || {
+        let hello = String::from("hello");
+        println!("{hello}, {upvar}");
+    }
+}
+
+fn main() {
+    let _async_closure = async_closure_test("world");
+}
diff --git a/tests/codegen/cffi/ffi-returns-twice.rs b/tests/codegen/cffi/ffi-returns-twice.rs
deleted file mode 100644
index 0fbe03f0bb6..00000000000
--- a/tests/codegen/cffi/ffi-returns-twice.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// compile-flags: -C no-prepopulate-passes
-#![crate_type = "lib"]
-#![feature(ffi_returns_twice)]
-
-pub fn bar() { unsafe { foo() } }
-
-extern "C" {
-    // CHECK: declare{{( dso_local)?}} void @foo(){{.*}}[[ATTRS:#[0-9]+]]
-    // CHECK: attributes [[ATTRS]] = { {{.*}}returns_twice{{.*}} }
-    #[ffi_returns_twice] pub fn foo();
-}
diff --git a/tests/codegen/direct-access-external-data.rs b/tests/codegen/direct-access-external-data.rs
new file mode 100644
index 00000000000..ec4bfc33518
--- /dev/null
+++ b/tests/codegen/direct-access-external-data.rs
@@ -0,0 +1,21 @@
+// only-loongarch64-unknown-linux-gnu
+
+// revisions: DEFAULT DIRECT INDIRECT
+// [DEFAULT] compile-flags: -C relocation-model=static
+// [DIRECT] compile-flags: -C relocation-model=static -Z direct-access-external-data=yes
+// [INDIRECT] compile-flags: -C relocation-model=static -Z direct-access-external-data=no
+
+#![crate_type = "rlib"]
+
+// DEFAULT: @VAR = external {{.*}} global i32
+// DIRECT: @VAR = external dso_local {{.*}} global i32
+// INDIRECT: @VAR = external {{.*}} global i32
+
+extern "C" {
+    static VAR: i32;
+}
+
+#[no_mangle]
+pub fn get() -> i32 {
+    unsafe { VAR }
+}
diff --git a/tests/incremental/const-generics/issue-62536.rs b/tests/incremental/const-generics/issue-62536.rs
index 93c1dbf44e9..022376768f2 100644
--- a/tests/incremental/const-generics/issue-62536.rs
+++ b/tests/incremental/const-generics/issue-62536.rs
@@ -1,4 +1,7 @@
 // revisions:cfail1
+
+#![allow(unused_variables)]
+
 struct S<T, const N: usize>([T; N]);
 
 fn f<T, const N: usize>(x: T) -> S<T, {N}> { panic!() }
diff --git a/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-1.rs b/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-1.rs
index 8262a2a211b..5c8af47ccbe 100644
--- a/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-1.rs
+++ b/tests/incremental/const-generics/try_unify_abstract_const_regression_tests/issue-77708-1.rs
@@ -1,6 +1,6 @@
 // revisions: cfail
 #![feature(generic_const_exprs)]
-#![allow(incomplete_features, unused_braces)]
+#![allow(incomplete_features, unused_braces, unused_variables)]
 
 trait Delegates<T> {}
 
diff --git a/tests/incremental/struct_change_field_name.rs b/tests/incremental/struct_change_field_name.rs
index a7c79e9d751..bd952bcc1c8 100644
--- a/tests/incremental/struct_change_field_name.rs
+++ b/tests/incremental/struct_change_field_name.rs
@@ -6,6 +6,7 @@
 // [cfail2] compile-flags: -Z query-dep-graph -Z assert-incr-state=loaded
 
 #![feature(rustc_attrs)]
+#![allow(unused_variables)]
 
 #[cfg(rpass1)]
 pub struct X {
diff --git a/tests/mir-opt/async_closure_shims.rs b/tests/mir-opt/async_closure_shims.rs
index ef3bdaaa145..2c99a2dad37 100644
--- a/tests/mir-opt/async_closure_shims.rs
+++ b/tests/mir-opt/async_closure_shims.rs
@@ -33,7 +33,7 @@ async fn call_once(f: impl AsyncFnOnce(i32)) {
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}.coroutine_closure_by_mut.0.mir
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_mut.0.mir
 // EMIT_MIR async_closure_shims.main-{closure#0}-{closure#0}-{closure#0}.coroutine_by_move.0.mir
-fn main() {
+pub fn main() {
     block_on(async {
         let b = 2i32;
         let mut async_closure = async move |a: i32| {
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
index ffbd97bb545..94cfb4e63fc 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
@@ -24,29 +24,11 @@
                           debug ptr => _6;
                           scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                               debug ptr => _6;
-                              let mut _8: *const [bool; 0];
-                              let mut _9: *mut [bool; 0];
+                              let mut _8: bool;
+                              let _9: ();
+                              let mut _10: *mut ();
+                              let mut _11: *const [bool; 0];
                               scope 12 {
-                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
-                                      debug ptr => _9;
-                                      scope 14 (inlined std::ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
-                                          debug self => _9;
-                                          let mut _10: *mut u8;
-                                          scope 15 {
-                                              scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                  debug ptr => _10;
-                                                  scope 17 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                      debug self => _10;
-                                                      scope 18 {
-                                                          scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                              debug self => _10;
-                                                          }
-                                                      }
-                                                  }
-                                              }
-                                          }
-                                      }
-                                  }
                               }
                           }
                       }
@@ -66,6 +48,7 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
+          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
@@ -73,30 +56,41 @@
           _7 = const 1_usize;
           _6 = const {0x1 as *mut [bool; 0]};
           StorageDead(_7);
-          StorageLive(_8);
-          StorageLive(_9);
           StorageLive(_10);
-          _8 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-          _5 = NonNull::<[bool; 0]> { pointer: _8 };
-          StorageDead(_10);
-          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_8);
+          _8 = cfg!(debug_assertions);
+          switchInt(move _8) -> [0: bb3, otherwise: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2: {
+          _10 = const {0x1 as *mut [bool; 0]} as *mut () (PtrToPtr);
+          _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
           StorageDead(_8);
+          _11 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+          _5 = NonNull::<[bool; 0]> { pointer: _11 };
+          StorageDead(_11);
+          StorageDead(_10);
           StorageDead(_6);
           _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
           StorageDead(_5);
           _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
           StorageDead(_4);
           _2 = Box::<[bool]>(_3, const std::alloc::Global);
+          StorageDead(_9);
           StorageDead(_3);
           _1 = A { foo: move _2 };
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind unreachable];
       }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
   }
   
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
index 7b6dcf1972b..ee85287882b 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -24,29 +24,11 @@
                           debug ptr => _6;
                           scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                               debug ptr => _6;
-                              let mut _8: *const [bool; 0];
-                              let mut _9: *mut [bool; 0];
+                              let mut _8: bool;
+                              let _9: ();
+                              let mut _10: *mut ();
+                              let mut _11: *const [bool; 0];
                               scope 12 {
-                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
-                                      debug ptr => _9;
-                                      scope 14 (inlined std::ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
-                                          debug self => _9;
-                                          let mut _10: *mut u8;
-                                          scope 15 {
-                                              scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                  debug ptr => _10;
-                                                  scope 17 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                      debug self => _10;
-                                                      scope 18 {
-                                                          scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                              debug self => _10;
-                                                          }
-                                                      }
-                                                  }
-                                              }
-                                          }
-                                      }
-                                  }
                               }
                           }
                       }
@@ -66,6 +48,7 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
+          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
@@ -73,34 +56,45 @@
           _7 = const 1_usize;
           _6 = const {0x1 as *mut [bool; 0]};
           StorageDead(_7);
-          StorageLive(_8);
-          StorageLive(_9);
           StorageLive(_10);
-          _8 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-          _5 = NonNull::<[bool; 0]> { pointer: _8 };
-          StorageDead(_10);
-          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_8);
+          _8 = cfg!(debug_assertions);
+          switchInt(move _8) -> [0: bb4, otherwise: bb3];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
+  
+      bb3: {
+          _10 = const {0x1 as *mut [bool; 0]} as *mut () (PtrToPtr);
+          _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
           StorageDead(_8);
+          _11 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+          _5 = NonNull::<[bool; 0]> { pointer: _11 };
+          StorageDead(_11);
+          StorageDead(_10);
           StorageDead(_6);
           _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
           StorageDead(_5);
           _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
           StorageDead(_4);
           _2 = Box::<[bool]>(_3, const std::alloc::Global);
+          StorageDead(_9);
           StorageDead(_3);
           _1 = A { foo: move _2 };
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind: bb2];
       }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2 (cleanup): {
-          resume;
-      }
   }
   
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
index ffbd97bb545..94cfb4e63fc 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
@@ -24,29 +24,11 @@
                           debug ptr => _6;
                           scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                               debug ptr => _6;
-                              let mut _8: *const [bool; 0];
-                              let mut _9: *mut [bool; 0];
+                              let mut _8: bool;
+                              let _9: ();
+                              let mut _10: *mut ();
+                              let mut _11: *const [bool; 0];
                               scope 12 {
-                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
-                                      debug ptr => _9;
-                                      scope 14 (inlined std::ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
-                                          debug self => _9;
-                                          let mut _10: *mut u8;
-                                          scope 15 {
-                                              scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                  debug ptr => _10;
-                                                  scope 17 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                      debug self => _10;
-                                                      scope 18 {
-                                                          scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                              debug self => _10;
-                                                          }
-                                                      }
-                                                  }
-                                              }
-                                          }
-                                      }
-                                  }
                               }
                           }
                       }
@@ -66,6 +48,7 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
+          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
@@ -73,30 +56,41 @@
           _7 = const 1_usize;
           _6 = const {0x1 as *mut [bool; 0]};
           StorageDead(_7);
-          StorageLive(_8);
-          StorageLive(_9);
           StorageLive(_10);
-          _8 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-          _5 = NonNull::<[bool; 0]> { pointer: _8 };
-          StorageDead(_10);
-          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_8);
+          _8 = cfg!(debug_assertions);
+          switchInt(move _8) -> [0: bb3, otherwise: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2: {
+          _10 = const {0x1 as *mut [bool; 0]} as *mut () (PtrToPtr);
+          _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
           StorageDead(_8);
+          _11 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+          _5 = NonNull::<[bool; 0]> { pointer: _11 };
+          StorageDead(_11);
+          StorageDead(_10);
           StorageDead(_6);
           _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
           StorageDead(_5);
           _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
           StorageDead(_4);
           _2 = Box::<[bool]>(_3, const std::alloc::Global);
+          StorageDead(_9);
           StorageDead(_3);
           _1 = A { foo: move _2 };
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind unreachable];
       }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
   }
   
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
index 7b6dcf1972b..ee85287882b 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -24,29 +24,11 @@
                           debug ptr => _6;
                           scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                               debug ptr => _6;
-                              let mut _8: *const [bool; 0];
-                              let mut _9: *mut [bool; 0];
+                              let mut _8: bool;
+                              let _9: ();
+                              let mut _10: *mut ();
+                              let mut _11: *const [bool; 0];
                               scope 12 {
-                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
-                                      debug ptr => _9;
-                                      scope 14 (inlined std::ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
-                                          debug self => _9;
-                                          let mut _10: *mut u8;
-                                          scope 15 {
-                                              scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                  debug ptr => _10;
-                                                  scope 17 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                      debug self => _10;
-                                                      scope 18 {
-                                                          scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                              debug self => _10;
-                                                          }
-                                                      }
-                                                  }
-                                              }
-                                          }
-                                      }
-                                  }
                               }
                           }
                       }
@@ -66,6 +48,7 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
+          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
@@ -73,34 +56,45 @@
           _7 = const 1_usize;
           _6 = const {0x1 as *mut [bool; 0]};
           StorageDead(_7);
-          StorageLive(_8);
-          StorageLive(_9);
           StorageLive(_10);
-          _8 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-          _5 = NonNull::<[bool; 0]> { pointer: _8 };
-          StorageDead(_10);
-          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_8);
+          _8 = cfg!(debug_assertions);
+          switchInt(move _8) -> [0: bb4, otherwise: bb3];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
+  
+      bb3: {
+          _10 = const {0x1 as *mut [bool; 0]} as *mut () (PtrToPtr);
+          _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
           StorageDead(_8);
+          _11 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+          _5 = NonNull::<[bool; 0]> { pointer: _11 };
+          StorageDead(_11);
+          StorageDead(_10);
           StorageDead(_6);
           _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
           StorageDead(_5);
           _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
           StorageDead(_4);
           _2 = Box::<[bool]>(_3, const std::alloc::Global);
+          StorageDead(_9);
           StorageDead(_3);
           _1 = A { foo: move _2 };
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind: bb2];
       }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2 (cleanup): {
-          resume;
-      }
   }
   
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
index df68ce496fd..4df38d6e61b 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
@@ -24,29 +24,11 @@
                           debug ptr => _6;
                           scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                               debug ptr => _6;
-                              let mut _8: *const [bool; 0];
-                              let mut _9: *mut [bool; 0];
+                              let mut _8: bool;
+                              let _9: ();
+                              let mut _10: *mut ();
+                              let mut _11: *const [bool; 0];
                               scope 12 {
-                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
-                                      debug ptr => _9;
-                                      scope 14 (inlined std::ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
-                                          debug self => _9;
-                                          let mut _10: *mut u8;
-                                          scope 15 {
-                                              scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                  debug ptr => _10;
-                                                  scope 17 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                      debug self => _10;
-                                                      scope 18 {
-                                                          scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                              debug self => _10;
-                                                          }
-                                                      }
-                                                  }
-                                              }
-                                          }
-                                      }
-                                  }
                               }
                           }
                       }
@@ -66,6 +48,7 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
+          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
@@ -75,31 +58,43 @@
 +         _7 = const 1_usize;
 +         _6 = const {0x1 as *mut [bool; 0]};
           StorageDead(_7);
-          StorageLive(_8);
-          StorageLive(_9);
           StorageLive(_10);
--         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-+         _8 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-          _5 = NonNull::<[bool; 0]> { pointer: _8 };
-          StorageDead(_10);
-          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_8);
+          _8 = cfg!(debug_assertions);
+          switchInt(move _8) -> [0: bb3, otherwise: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2: {
+-         _10 = _6 as *mut () (PtrToPtr);
++         _10 = const {0x1 as *mut [bool; 0]} as *mut () (PtrToPtr);
+          _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
           StorageDead(_8);
+-         _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
++         _11 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+          _5 = NonNull::<[bool; 0]> { pointer: _11 };
+          StorageDead(_11);
+          StorageDead(_10);
           StorageDead(_6);
           _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
           StorageDead(_5);
           _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
           StorageDead(_4);
           _2 = Box::<[bool]>(_3, const std::alloc::Global);
+          StorageDead(_9);
           StorageDead(_3);
           _1 = A { foo: move _2 };
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind unreachable];
       }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
   }
   
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
index e16ea22091e..6aac30bcd17 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
@@ -24,29 +24,11 @@
                           debug ptr => _6;
                           scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                               debug ptr => _6;
-                              let mut _8: *const [bool; 0];
-                              let mut _9: *mut [bool; 0];
+                              let mut _8: bool;
+                              let _9: ();
+                              let mut _10: *mut ();
+                              let mut _11: *const [bool; 0];
                               scope 12 {
-                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
-                                      debug ptr => _9;
-                                      scope 14 (inlined std::ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
-                                          debug self => _9;
-                                          let mut _10: *mut u8;
-                                          scope 15 {
-                                              scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                  debug ptr => _10;
-                                                  scope 17 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                      debug self => _10;
-                                                      scope 18 {
-                                                          scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                              debug self => _10;
-                                                          }
-                                                      }
-                                                  }
-                                              }
-                                          }
-                                      }
-                                  }
                               }
                           }
                       }
@@ -66,6 +48,7 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
+          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
@@ -75,35 +58,47 @@
 +         _7 = const 1_usize;
 +         _6 = const {0x1 as *mut [bool; 0]};
           StorageDead(_7);
-          StorageLive(_8);
-          StorageLive(_9);
           StorageLive(_10);
--         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-+         _8 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-          _5 = NonNull::<[bool; 0]> { pointer: _8 };
-          StorageDead(_10);
-          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_8);
+          _8 = cfg!(debug_assertions);
+          switchInt(move _8) -> [0: bb4, otherwise: bb3];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
+  
+      bb3: {
+-         _10 = _6 as *mut () (PtrToPtr);
++         _10 = const {0x1 as *mut [bool; 0]} as *mut () (PtrToPtr);
+          _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
           StorageDead(_8);
+-         _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
++         _11 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+          _5 = NonNull::<[bool; 0]> { pointer: _11 };
+          StorageDead(_11);
+          StorageDead(_10);
           StorageDead(_6);
           _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
           StorageDead(_5);
           _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
           StorageDead(_4);
           _2 = Box::<[bool]>(_3, const std::alloc::Global);
+          StorageDead(_9);
           StorageDead(_3);
           _1 = A { foo: move _2 };
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind: bb2];
       }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2 (cleanup): {
-          resume;
-      }
   }
   
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
index df68ce496fd..4df38d6e61b 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
@@ -24,29 +24,11 @@
                           debug ptr => _6;
                           scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                               debug ptr => _6;
-                              let mut _8: *const [bool; 0];
-                              let mut _9: *mut [bool; 0];
+                              let mut _8: bool;
+                              let _9: ();
+                              let mut _10: *mut ();
+                              let mut _11: *const [bool; 0];
                               scope 12 {
-                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
-                                      debug ptr => _9;
-                                      scope 14 (inlined std::ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
-                                          debug self => _9;
-                                          let mut _10: *mut u8;
-                                          scope 15 {
-                                              scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                  debug ptr => _10;
-                                                  scope 17 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                      debug self => _10;
-                                                      scope 18 {
-                                                          scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                              debug self => _10;
-                                                          }
-                                                      }
-                                                  }
-                                              }
-                                          }
-                                      }
-                                  }
                               }
                           }
                       }
@@ -66,6 +48,7 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
+          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
@@ -75,31 +58,43 @@
 +         _7 = const 1_usize;
 +         _6 = const {0x1 as *mut [bool; 0]};
           StorageDead(_7);
-          StorageLive(_8);
-          StorageLive(_9);
           StorageLive(_10);
--         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-+         _8 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-          _5 = NonNull::<[bool; 0]> { pointer: _8 };
-          StorageDead(_10);
-          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_8);
+          _8 = cfg!(debug_assertions);
+          switchInt(move _8) -> [0: bb3, otherwise: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2: {
+-         _10 = _6 as *mut () (PtrToPtr);
++         _10 = const {0x1 as *mut [bool; 0]} as *mut () (PtrToPtr);
+          _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
           StorageDead(_8);
+-         _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
++         _11 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+          _5 = NonNull::<[bool; 0]> { pointer: _11 };
+          StorageDead(_11);
+          StorageDead(_10);
           StorageDead(_6);
           _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
           StorageDead(_5);
           _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
           StorageDead(_4);
           _2 = Box::<[bool]>(_3, const std::alloc::Global);
+          StorageDead(_9);
           StorageDead(_3);
           _1 = A { foo: move _2 };
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind unreachable];
       }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
   }
   
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
index e16ea22091e..6aac30bcd17 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
@@ -24,29 +24,11 @@
                           debug ptr => _6;
                           scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                               debug ptr => _6;
-                              let mut _8: *const [bool; 0];
-                              let mut _9: *mut [bool; 0];
+                              let mut _8: bool;
+                              let _9: ();
+                              let mut _10: *mut ();
+                              let mut _11: *const [bool; 0];
                               scope 12 {
-                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
-                                      debug ptr => _9;
-                                      scope 14 (inlined std::ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
-                                          debug self => _9;
-                                          let mut _10: *mut u8;
-                                          scope 15 {
-                                              scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                  debug ptr => _10;
-                                                  scope 17 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                      debug self => _10;
-                                                      scope 18 {
-                                                          scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                              debug self => _10;
-                                                          }
-                                                      }
-                                                  }
-                                              }
-                                          }
-                                      }
-                                  }
                               }
                           }
                       }
@@ -66,6 +48,7 @@
           StorageLive(_1);
           StorageLive(_2);
           StorageLive(_3);
+          StorageLive(_9);
           StorageLive(_4);
           StorageLive(_5);
           StorageLive(_6);
@@ -75,35 +58,47 @@
 +         _7 = const 1_usize;
 +         _6 = const {0x1 as *mut [bool; 0]};
           StorageDead(_7);
-          StorageLive(_8);
-          StorageLive(_9);
           StorageLive(_10);
--         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-+         _8 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
-          _5 = NonNull::<[bool; 0]> { pointer: _8 };
-          StorageDead(_10);
-          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_8);
+          _8 = cfg!(debug_assertions);
+          switchInt(move _8) -> [0: bb4, otherwise: bb3];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
+  
+      bb3: {
+-         _10 = _6 as *mut () (PtrToPtr);
++         _10 = const {0x1 as *mut [bool; 0]} as *mut () (PtrToPtr);
+          _9 = NonNull::<T>::new_unchecked::precondition_check(move _10) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
           StorageDead(_8);
+-         _11 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
++         _11 = const {0x1 as *mut [bool; 0]} as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+          _5 = NonNull::<[bool; 0]> { pointer: _11 };
+          StorageDead(_11);
+          StorageDead(_10);
           StorageDead(_6);
           _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
           StorageDead(_5);
           _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
           StorageDead(_4);
           _2 = Box::<[bool]>(_3, const std::alloc::Global);
+          StorageDead(_9);
           StorageDead(_3);
           _1 = A { foo: move _2 };
           StorageDead(_2);
           _0 = const ();
           drop(_1) -> [return: bb1, unwind: bb2];
       }
-  
-      bb1: {
-          StorageDead(_1);
-          return;
-      }
-  
-      bb2 (cleanup): {
-          resume;
-      }
   }
   
diff --git a/tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
index 7a374c5675a..8b427cff677 100644
--- a/tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff
@@ -51,13 +51,13 @@
 -     }
 - 
 -     bb3: {
-          StorageLive(_8);
-          _8 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
           StorageLive(_9);
           _9 = (((_3.1: std::option::Option<u32>) as Some).0: u32);
+          StorageLive(_8);
+          _8 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
           _0 = const 0_u32;
-          StorageDead(_9);
           StorageDead(_8);
+          StorageDead(_9);
 -         goto -> bb4;
 +         goto -> bb3;
       }
diff --git a/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff
index 21f58a14a2b..b91a469225c 100644
--- a/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff
@@ -58,13 +58,13 @@
 - 
 -     bb4: {
 +     bb2: {
-          StorageLive(_9);
-          _9 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
           StorageLive(_10);
           _10 = (((_3.1: std::option::Option<u32>) as Some).0: u32);
+          StorageLive(_9);
+          _9 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
           _0 = const 0_u32;
-          StorageDead(_10);
           StorageDead(_9);
+          StorageDead(_10);
 -         goto -> bb6;
 +         goto -> bb4;
       }
diff --git a/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
index e058c409cb5..cc16af721ca 100644
--- a/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch.opt3.EarlyOtherwiseBranch.diff
@@ -51,13 +51,13 @@
 -     }
 - 
 -     bb3: {
-          StorageLive(_8);
-          _8 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
           StorageLive(_9);
           _9 = (((_3.1: std::option::Option<bool>) as Some).0: bool);
+          StorageLive(_8);
+          _8 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
           _0 = const 0_u32;
-          StorageDead(_9);
           StorageDead(_8);
+          StorageDead(_9);
 -         goto -> bb4;
 +         goto -> bb3;
       }
diff --git a/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
index f98d68e6ffc..eb8926d27ee 100644
--- a/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff
@@ -69,16 +69,16 @@
   
 -     bb4: {
 +     bb3: {
-          StorageLive(_11);
-          _11 = (((_4.0: std::option::Option<u32>) as Some).0: u32);
-          StorageLive(_12);
-          _12 = (((_4.1: std::option::Option<u32>) as Some).0: u32);
           StorageLive(_13);
           _13 = (((_4.2: std::option::Option<u32>) as Some).0: u32);
+          StorageLive(_12);
+          _12 = (((_4.1: std::option::Option<u32>) as Some).0: u32);
+          StorageLive(_11);
+          _11 = (((_4.0: std::option::Option<u32>) as Some).0: u32);
           _0 = const 0_u32;
-          StorageDead(_13);
-          StorageDead(_12);
           StorageDead(_11);
+          StorageDead(_12);
+          StorageDead(_13);
 -         goto -> bb5;
 +         goto -> bb4;
       }
diff --git a/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
index 0c94794fa3f..79cf1c0e34a 100644
--- a/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff
@@ -116,12 +116,12 @@
       }
   
       bb6: {
-          StorageLive(_12);
-          _39 = deref_copy (_4.0: &ViewportPercentageLength);
-          _12 = (((*_39) as Vw).0: f32);
           StorageLive(_13);
-          _40 = deref_copy (_4.1: &ViewportPercentageLength);
-          _13 = (((*_40) as Vw).0: f32);
+          _39 = deref_copy (_4.1: &ViewportPercentageLength);
+          _13 = (((*_39) as Vw).0: f32);
+          StorageLive(_12);
+          _40 = deref_copy (_4.0: &ViewportPercentageLength);
+          _12 = (((*_40) as Vw).0: f32);
           StorageLive(_14);
           StorageLive(_15);
           _15 = _12;
@@ -132,18 +132,18 @@
           StorageDead(_15);
           _3 = ViewportPercentageLength::Vw(move _14);
           StorageDead(_14);
-          StorageDead(_13);
           StorageDead(_12);
+          StorageDead(_13);
           goto -> bb10;
       }
   
       bb7: {
-          StorageLive(_17);
-          _41 = deref_copy (_4.0: &ViewportPercentageLength);
-          _17 = (((*_41) as Vh).0: f32);
           StorageLive(_18);
-          _42 = deref_copy (_4.1: &ViewportPercentageLength);
-          _18 = (((*_42) as Vh).0: f32);
+          _41 = deref_copy (_4.1: &ViewportPercentageLength);
+          _18 = (((*_41) as Vh).0: f32);
+          StorageLive(_17);
+          _42 = deref_copy (_4.0: &ViewportPercentageLength);
+          _17 = (((*_42) as Vh).0: f32);
           StorageLive(_19);
           StorageLive(_20);
           _20 = _17;
@@ -154,18 +154,18 @@
           StorageDead(_20);
           _3 = ViewportPercentageLength::Vh(move _19);
           StorageDead(_19);
-          StorageDead(_18);
           StorageDead(_17);
+          StorageDead(_18);
           goto -> bb10;
       }
   
       bb8: {
-          StorageLive(_22);
-          _43 = deref_copy (_4.0: &ViewportPercentageLength);
-          _22 = (((*_43) as Vmin).0: f32);
           StorageLive(_23);
-          _44 = deref_copy (_4.1: &ViewportPercentageLength);
-          _23 = (((*_44) as Vmin).0: f32);
+          _43 = deref_copy (_4.1: &ViewportPercentageLength);
+          _23 = (((*_43) as Vmin).0: f32);
+          StorageLive(_22);
+          _44 = deref_copy (_4.0: &ViewportPercentageLength);
+          _22 = (((*_44) as Vmin).0: f32);
           StorageLive(_24);
           StorageLive(_25);
           _25 = _22;
@@ -176,18 +176,18 @@
           StorageDead(_25);
           _3 = ViewportPercentageLength::Vmin(move _24);
           StorageDead(_24);
-          StorageDead(_23);
           StorageDead(_22);
+          StorageDead(_23);
           goto -> bb10;
       }
   
       bb9: {
-          StorageLive(_27);
-          _45 = deref_copy (_4.0: &ViewportPercentageLength);
-          _27 = (((*_45) as Vmax).0: f32);
           StorageLive(_28);
-          _46 = deref_copy (_4.1: &ViewportPercentageLength);
-          _28 = (((*_46) as Vmax).0: f32);
+          _45 = deref_copy (_4.1: &ViewportPercentageLength);
+          _28 = (((*_45) as Vmax).0: f32);
+          StorageLive(_27);
+          _46 = deref_copy (_4.0: &ViewportPercentageLength);
+          _27 = (((*_46) as Vmax).0: f32);
           StorageLive(_29);
           StorageLive(_30);
           _30 = _27;
@@ -198,8 +198,8 @@
           StorageDead(_30);
           _3 = ViewportPercentageLength::Vmax(move _29);
           StorageDead(_29);
-          StorageDead(_28);
           StorageDead(_27);
+          StorageDead(_28);
           goto -> bb10;
       }
   
diff --git a/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff b/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff
index 09cdce71857..af0337d0a7e 100644
--- a/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff
+++ b/tests/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff
@@ -59,13 +59,13 @@
       }
   
       bb5: {
-          StorageLive(_9);
-          _9 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
           StorageLive(_10);
           _10 = (((_3.1: std::option::Option<u32>) as Some).0: u32);
+          StorageLive(_9);
+          _9 = (((_3.0: std::option::Option<u32>) as Some).0: u32);
           _0 = const 0_u32;
-          StorageDead(_10);
           StorageDead(_9);
+          StorageDead(_10);
           goto -> bb8;
       }
   
diff --git a/tests/mir-opt/fn_ptr_shim.rs b/tests/mir-opt/fn_ptr_shim.rs
index c82260baefe..2650cbf9704 100644
--- a/tests/mir-opt/fn_ptr_shim.rs
+++ b/tests/mir-opt/fn_ptr_shim.rs
@@ -5,7 +5,7 @@
 // (as only `FnDef` and `FnPtr` callees are allowed in MIR).
 
 // EMIT_MIR core.ops-function-Fn-call.AddMovesForPackedDrops.before.mir
-fn main() {
+pub fn main() {
     call(noop as fn());
 }
 
diff --git a/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff b/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff
new file mode 100644
index 00000000000..b12de636f58
--- /dev/null
+++ b/tests/mir-opt/gvn_copy_moves.fn0.GVN.diff
@@ -0,0 +1,27 @@
+- // MIR for `fn0` before GVN
++ // MIR for `fn0` after GVN
+  
+  fn fn0() -> () {
+      let mut _0: ();
+      let mut _1: usize;
+      let mut _2: [u128; 6];
+      let mut _3: ([u128; 6],);
+      let mut _4: ([u128; 6],);
+      let mut _5: ();
+  
+      bb0: {
+          _1 = const 1_usize;
+          _2 = [const 42_u128; 6];
+-         _2[_1] = const 1_u128;
++         _2[1 of 2] = const 1_u128;
+          _3 = (_2,);
+          _4 = _3;
+-         _5 = fn1(move (_3.0: [u128; 6]), _4) -> [return: bb1, unwind unreachable];
++         _5 = fn1((_3.0: [u128; 6]), _3) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn_copy_moves.rs b/tests/mir-opt/gvn_copy_moves.rs
new file mode 100644
index 00000000000..d216825e5e6
--- /dev/null
+++ b/tests/mir-opt/gvn_copy_moves.rs
@@ -0,0 +1,46 @@
+// unit-test: GVN
+
+#![feature(custom_mir, core_intrinsics)]
+extern crate core;
+use core::intrinsics::mir::*;
+
+#[custom_mir(dialect = "runtime", phase = "initial")]
+fn fn0() {
+    // CHECK-LABEL: fn fn0(
+    mir! {
+        let a: usize;
+        let b: [u128; 6];
+        let c: ([u128; 6],);
+        let d: ([u128; 6],);
+        let x: ();
+        {
+            // CHECK: bb0: {
+            // CHECK-NEXT: _1 = const 1_usize;
+            // CHECK-NEXT: _2 = [const 42_u128; 6];
+            // CHECK-NEXT: _2[1 of 2] = const 1_u128;
+            // CHECK-NEXT: _3 = (_2,);
+            // CHECK-NEXT: _4 = _3;
+            // CHECK-NEXT: _5 = fn1((_3.0: [u128; 6]), _3)
+            a = 1_usize;
+            b = [42; 6];
+            b[a] = 1;
+            c = (b,);
+            d = c;
+            Call(x = fn1(Move(c.0), d), ReturnTo(bb1), UnwindUnreachable())
+        }
+        bb1 = {
+            Return()
+        }
+    }
+}
+
+#[inline(never)]
+fn fn1(a: [u128; 6], mut b: ([u128; 6],)) {
+    b.0 = [0; 6];
+}
+
+fn main() {
+    fn0();
+}
+
+// EMIT_MIR gvn_copy_moves.fn0.GVN.diff
diff --git a/tests/mir-opt/inline/cycle.g.Inline.panic-abort.diff b/tests/mir-opt/inline/cycle.g.Inline.panic-abort.diff
index 8f2baf4a3b6..1be0a4f2d29 100644
--- a/tests/mir-opt/inline/cycle.g.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/cycle.g.Inline.panic-abort.diff
@@ -4,35 +4,16 @@
   fn g() -> () {
       let mut _0: ();
       let _1: ();
-+     let mut _2: fn() {main};
-+     scope 1 (inlined f::<fn() {main}>) {
-+         debug g => _2;
-+         let mut _3: &fn() {main};
-+         let _4: ();
-+     }
   
       bb0: {
           StorageLive(_1);
--         _1 = f::<fn() {main}>(main) -> [return: bb1, unwind unreachable];
-+         StorageLive(_2);
-+         _2 = main;
-+         StorageLive(_4);
-+         StorageLive(_3);
-+         _3 = &_2;
-+         _4 = <fn() {main} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind unreachable];
+          _1 = f::<fn() {main}>(main) -> [return: bb1, unwind unreachable];
       }
   
       bb1: {
-+         StorageDead(_4);
-+         StorageDead(_2);
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb2: {
-+         StorageDead(_3);
-+         drop(_2) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff b/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff
index 1fd1014ba1d..da516220d50 100644
--- a/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/cycle.g.Inline.panic-unwind.diff
@@ -4,43 +4,16 @@
   fn g() -> () {
       let mut _0: ();
       let _1: ();
-+     let mut _2: fn() {main};
-+     scope 1 (inlined f::<fn() {main}>) {
-+         debug g => _2;
-+         let mut _3: &fn() {main};
-+         let _4: ();
-+     }
   
       bb0: {
           StorageLive(_1);
--         _1 = f::<fn() {main}>(main) -> [return: bb1, unwind continue];
-+         StorageLive(_2);
-+         _2 = main;
-+         StorageLive(_4);
-+         StorageLive(_3);
-+         _3 = &_2;
-+         _4 = <fn() {main} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind: bb3];
+          _1 = f::<fn() {main}>(main) -> [return: bb1, unwind continue];
       }
   
       bb1: {
-+         StorageDead(_4);
-+         StorageDead(_2);
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb2: {
-+         StorageDead(_3);
-+         drop(_2) -> [return: bb1, unwind continue];
-+     }
-+ 
-+     bb3 (cleanup): {
-+         drop(_2) -> [return: bb4, unwind terminate(cleanup)];
-+     }
-+ 
-+     bb4 (cleanup): {
-+         resume;
       }
   }
   
diff --git a/tests/mir-opt/inline/cycle.rs b/tests/mir-opt/inline/cycle.rs
index 350724235ba..c251226673d 100644
--- a/tests/mir-opt/inline/cycle.rs
+++ b/tests/mir-opt/inline/cycle.rs
@@ -13,9 +13,7 @@ fn f(g: impl Fn()) {
 #[inline(always)]
 fn g() {
     // CHECK-LABEL: fn g(
-    // CHECK-NOT: inlined
-    // CHECK: (inlined f::<fn() {main}>)
-    // CHECK-NOT: inlined
+    // CHECK-NOT: (inlined f::<fn() {main}>)
     f(main);
 }
 
diff --git a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff
index d437dbf5763..142b9c56598 100644
--- a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff
@@ -7,6 +7,10 @@
 +     scope 1 (inlined <C as Call>::call) {
 +         scope 2 (inlined <B<A> as Call>::call) {
 +             scope 3 (inlined <A as Call>::call) {
++                 scope 4 (inlined <B<C> as Call>::call) {
++                     scope 5 (inlined <C as Call>::call) {
++                     }
++                 }
 +             }
 +         }
 +     }
@@ -14,7 +18,7 @@
       bb0: {
           StorageLive(_1);
 -         _1 = <C as Call>::call() -> [return: bb1, unwind unreachable];
-+         _1 = <B<C> as Call>::call() -> [return: bb1, unwind unreachable];
++         _1 = <B<A> as Call>::call() -> [return: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff
index 8314526ee04..193ada05f02 100644
--- a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff
@@ -7,6 +7,10 @@
 +     scope 1 (inlined <C as Call>::call) {
 +         scope 2 (inlined <B<A> as Call>::call) {
 +             scope 3 (inlined <A as Call>::call) {
++                 scope 4 (inlined <B<C> as Call>::call) {
++                     scope 5 (inlined <C as Call>::call) {
++                     }
++                 }
 +             }
 +         }
 +     }
@@ -14,7 +18,7 @@
       bb0: {
           StorageLive(_1);
 -         _1 = <C as Call>::call() -> [return: bb1, unwind continue];
-+         _1 = <B<C> as Call>::call() -> [return: bb1, unwind continue];
++         _1 = <B<A> as Call>::call() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/unwrap_unchecked.rs b/tests/mir-opt/inline/unwrap_unchecked.rs
index be133706e5c..1adf2224d97 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.rs
+++ b/tests/mir-opt/inline/unwrap_unchecked.rs
@@ -2,7 +2,7 @@
 
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 // ignore-debug: the debug assertions prevent the inlining we are testing for
-// compile-flags: -Zmir-opt-level=2 -Zinline-mir
+// compile-flags: -Zmir-opt-level=2 -Zinline-mir -Cdebug-assertions=no
 
 // EMIT_MIR unwrap_unchecked.unwrap_unchecked.Inline.diff
 // EMIT_MIR unwrap_unchecked.unwrap_unchecked.PreCodegen.after.mir
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
index 2a36ad9230e..9358a64b4fa 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
@@ -7,41 +7,44 @@
       let mut _2: std::option::Option<T>;
 +     scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) {
 +         debug self => _2;
-+         let mut _3: &std::option::Option<T>;
-+         let mut _4: isize;
-+         let mut _5: bool;
++         let mut _3: isize;
 +         scope 2 {
 +             debug val => _0;
 +         }
 +         scope 3 {
-+             scope 5 (inlined unreachable_unchecked) {
-+                 scope 6 {
-+                     scope 7 (inlined unreachable_unchecked::runtime) {
-+                     }
++             scope 4 (inlined unreachable_unchecked) {
++                 let mut _4: bool;
++                 let _5: ();
++                 scope 5 {
 +                 }
 +             }
 +         }
-+         scope 4 (inlined Option::<T>::is_some) {
-+             debug self => _3;
-+         }
 +     }
   
       bb0: {
           StorageLive(_2);
           _2 = move _1;
 -         _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind unreachable];
--     }
-- 
--     bb1: {
 +         StorageLive(_3);
-+         StorageLive(_4);
 +         StorageLive(_5);
-+         _4 = discriminant(_2);
-+         _5 = Eq(_4, const 1_isize);
-+         assume(move _5);
++         _3 = discriminant(_2);
++         switchInt(move _3) -> [0: bb1, 1: bb3, otherwise: bb2];
+      }
+  
+      bb1: {
++         StorageLive(_4);
++         _4 = cfg!(debug_assertions);
++         assume(_4);
++         _5 = unreachable_unchecked::precondition_check() -> [return: bb2, unwind unreachable];
++     }
++ 
++     bb2: {
++         unreachable;
++     }
++ 
++     bb3: {
 +         _0 = move ((_2 as Some).0: T);
 +         StorageDead(_5);
-+         StorageDead(_4);
 +         StorageDead(_3);
           StorageDead(_2);
           return;
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
index 14c8c671d3f..ac33c126155 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
@@ -7,48 +7,51 @@
       let mut _2: std::option::Option<T>;
 +     scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) {
 +         debug self => _2;
-+         let mut _3: &std::option::Option<T>;
-+         let mut _4: isize;
-+         let mut _5: bool;
++         let mut _3: isize;
 +         scope 2 {
 +             debug val => _0;
 +         }
 +         scope 3 {
-+             scope 5 (inlined unreachable_unchecked) {
-+                 scope 6 {
-+                     scope 7 (inlined unreachable_unchecked::runtime) {
-+                     }
++             scope 4 (inlined unreachable_unchecked) {
++                 let mut _4: bool;
++                 let _5: ();
++                 scope 5 {
 +                 }
 +             }
 +         }
-+         scope 4 (inlined Option::<T>::is_some) {
-+             debug self => _3;
-+         }
 +     }
   
       bb0: {
           StorageLive(_2);
           _2 = move _1;
 -         _0 = Option::<T>::unwrap_unchecked(move _2) -> [return: bb1, unwind: bb2];
--     }
-- 
--     bb1: {
 +         StorageLive(_3);
-+         StorageLive(_4);
 +         StorageLive(_5);
-+         _4 = discriminant(_2);
-+         _5 = Eq(_4, const 1_isize);
-+         assume(move _5);
++         _3 = discriminant(_2);
++         switchInt(move _3) -> [0: bb1, 1: bb3, otherwise: bb2];
+      }
+  
+      bb1: {
+-         StorageDead(_2);
+-         return;
++         StorageLive(_4);
++         _4 = cfg!(debug_assertions);
++         assume(_4);
++         _5 = unreachable_unchecked::precondition_check() -> [return: bb2, unwind unreachable];
+      }
+  
+-     bb2 (cleanup): {
+-         resume;
++     bb2: {
++         unreachable;
++     }
++ 
++     bb3: {
 +         _0 = move ((_2 as Some).0: T);
 +         StorageDead(_5);
-+         StorageDead(_4);
 +         StorageDead(_3);
-          StorageDead(_2);
-          return;
--     }
-- 
--     bb2 (cleanup): {
--         resume;
++         StorageDead(_2);
++         return;
       }
   }
   
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
index d6a608476df..8ec65935c66 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
@@ -6,35 +6,39 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
     scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) {
         debug self => _1;
         let mut _2: isize;
-        let mut _3: bool;
-        let mut _4: &std::option::Option<T>;
         scope 2 {
             debug val => _0;
         }
         scope 3 {
-            scope 5 (inlined unreachable_unchecked) {
-                scope 6 {
-                    scope 7 (inlined unreachable_unchecked::runtime) {
-                    }
+            scope 4 (inlined unreachable_unchecked) {
+                let mut _3: bool;
+                let _4: ();
+                scope 5 {
                 }
             }
         }
-        scope 4 (inlined Option::<T>::is_some) {
-            debug self => _4;
-        }
     }
 
     bb0: {
-        StorageLive(_4);
         StorageLive(_2);
-        StorageLive(_3);
         _2 = discriminant(_1);
-        _3 = Eq(_2, const 1_isize);
-        assume(move _3);
+        switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3];
+    }
+
+    bb1: {
+        StorageLive(_3);
+        _3 = cfg!(debug_assertions);
+        assume(_3);
+        _4 = unreachable_unchecked::precondition_check() -> [return: bb3, unwind unreachable];
+    }
+
+    bb2: {
         _0 = ((_1 as Some).0: T);
-        StorageDead(_3);
         StorageDead(_2);
-        StorageDead(_4);
         return;
     }
+
+    bb3: {
+        unreachable;
+    }
 }
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
index d6a608476df..8ec65935c66 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
@@ -6,35 +6,39 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
     scope 1 (inlined #[track_caller] Option::<T>::unwrap_unchecked) {
         debug self => _1;
         let mut _2: isize;
-        let mut _3: bool;
-        let mut _4: &std::option::Option<T>;
         scope 2 {
             debug val => _0;
         }
         scope 3 {
-            scope 5 (inlined unreachable_unchecked) {
-                scope 6 {
-                    scope 7 (inlined unreachable_unchecked::runtime) {
-                    }
+            scope 4 (inlined unreachable_unchecked) {
+                let mut _3: bool;
+                let _4: ();
+                scope 5 {
                 }
             }
         }
-        scope 4 (inlined Option::<T>::is_some) {
-            debug self => _4;
-        }
     }
 
     bb0: {
-        StorageLive(_4);
         StorageLive(_2);
-        StorageLive(_3);
         _2 = discriminant(_1);
-        _3 = Eq(_2, const 1_isize);
-        assume(move _3);
+        switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3];
+    }
+
+    bb1: {
+        StorageLive(_3);
+        _3 = cfg!(debug_assertions);
+        assume(_3);
+        _4 = unreachable_unchecked::precondition_check() -> [return: bb3, unwind unreachable];
+    }
+
+    bb2: {
         _0 = ((_1 as Some).0: T);
-        StorageDead(_3);
         StorageDead(_2);
-        StorageDead(_4);
         return;
     }
+
+    bb3: {
+        unreachable;
+    }
 }
diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir
index ffb1aedd2ea..a10061ed941 100644
--- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir
@@ -1,8 +1,8 @@
 // MIR for `main` after built
 
 | User Type Annotations
-| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
-| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
 |
 fn main() -> () {
     let mut _0: ();
diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir
index ffb1aedd2ea..a10061ed941 100644
--- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir
@@ -1,8 +1,8 @@
 // MIR for `main` after built
 
 | User Type Annotations
-| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
-| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[22bb]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[22bb]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
+| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &ReStatic [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
 |
 fn main() -> () {
     let mut _0: ();
diff --git a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
index 0114309dbb5..7c038b0ee88 100644
--- a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
@@ -4,19 +4,31 @@ fn ub_if_b(_1: Thing) -> Thing {
     debug t => _1;
     let mut _0: Thing;
     let mut _2: isize;
-    let mut _3: bool;
     scope 1 (inlined unreachable_unchecked) {
+        let mut _3: bool;
+        let _4: ();
         scope 2 {
-            scope 3 (inlined unreachable_unchecked::runtime) {
-            }
         }
     }
 
     bb0: {
         _2 = discriminant(_1);
-        _3 = Eq(_2, const 0_isize);
-        assume(move _3);
+        switchInt(move _2) -> [0: bb1, 1: bb2, otherwise: bb3];
+    }
+
+    bb1: {
         _0 = move _1;
         return;
     }
+
+    bb2: {
+        StorageLive(_3);
+        _3 = cfg!(debug_assertions);
+        assume(_3);
+        _4 = unreachable_unchecked::precondition_check() -> [return: bb3, unwind unreachable];
+    }
+
+    bb3: {
+        unreachable;
+    }
 }
diff --git a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.panic-abort.mir
index 3ca24e152a4..3ca24e152a4 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.panic-abort.mir
diff --git a/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..3ca24e152a4
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/mem_replace.manual_replace.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,16 @@
+// MIR for `manual_replace` after PreCodegen
+
+fn manual_replace(_1: &mut u32, _2: u32) -> u32 {
+    debug r => _1;
+    debug v => _2;
+    let mut _0: u32;
+    scope 1 {
+        debug temp => _0;
+    }
+
+    bb0: {
+        _0 = (*_1);
+        (*_1) = _2;
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir
deleted file mode 100644
index f0cb4ca31fe..00000000000
--- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.mir
+++ /dev/null
@@ -1,66 +0,0 @@
-// MIR for `mem_replace` after PreCodegen
-
-fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
-    debug r => _1;
-    debug v => _2;
-    let mut _0: u32;
-    scope 1 (inlined std::mem::replace::<u32>) {
-        debug dest => _1;
-        debug src => _2;
-        scope 2 {
-            scope 3 {
-                debug result => _0;
-                scope 16 (inlined std::ptr::write::<u32>) {
-                    debug dst => _1;
-                    debug src => _2;
-                    scope 17 {
-                    }
-                }
-            }
-            scope 4 (inlined std::ptr::read::<u32>) {
-                debug src => _1;
-                let mut _3: *const u32;
-                scope 5 {
-                    scope 6 (inlined std::ptr::read::runtime::<u32>) {
-                        debug src => _3;
-                        scope 7 (inlined intrinsics::is_aligned_and_not_null::<u32>) {
-                            debug ptr => _3;
-                            scope 8 (inlined std::ptr::const_ptr::<impl *const u32>::is_null) {
-                                debug self => _3;
-                                let mut _4: *const u8;
-                                scope 9 {
-                                    scope 10 (inlined std::ptr::const_ptr::<impl *const T>::is_null::runtime_impl) {
-                                        debug ptr => _4;
-                                        scope 11 (inlined std::ptr::const_ptr::<impl *const u8>::addr) {
-                                            debug self => _4;
-                                            scope 12 {
-                                                scope 13 (inlined std::ptr::const_ptr::<impl *const u8>::cast::<()>) {
-                                                    debug self => _4;
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                            scope 14 (inlined std::ptr::const_ptr::<impl *const u32>::is_aligned) {
-                                debug self => _3;
-                                scope 15 (inlined align_of::<u32>) {
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    bb0: {
-        StorageLive(_3);
-        StorageLive(_4);
-        _0 = (*_1);
-        StorageDead(_4);
-        StorageDead(_3);
-        (*_1) = _2;
-        return;
-    }
-}
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
new file mode 100644
index 00000000000..26919dd98dd
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,33 @@
+// MIR for `mem_replace` after PreCodegen
+
+fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
+    debug r => _1;
+    debug v => _2;
+    let mut _0: u32;
+    scope 1 (inlined std::mem::replace::<u32>) {
+        debug dest => _1;
+        debug src => _2;
+        scope 2 {
+            scope 3 {
+                debug result => _0;
+                scope 6 (inlined std::ptr::write::<u32>) {
+                    debug dst => _1;
+                    debug src => _2;
+                    scope 7 {
+                    }
+                }
+            }
+            scope 4 (inlined std::ptr::read::<u32>) {
+                debug src => _1;
+                scope 5 {
+                }
+            }
+        }
+    }
+
+    bb0: {
+        _0 = (*_1);
+        (*_1) = _2;
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..26919dd98dd
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,33 @@
+// MIR for `mem_replace` after PreCodegen
+
+fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
+    debug r => _1;
+    debug v => _2;
+    let mut _0: u32;
+    scope 1 (inlined std::mem::replace::<u32>) {
+        debug dest => _1;
+        debug src => _2;
+        scope 2 {
+            scope 3 {
+                debug result => _0;
+                scope 6 (inlined std::ptr::write::<u32>) {
+                    debug dst => _1;
+                    debug src => _2;
+                    scope 7 {
+                    }
+                }
+            }
+            scope 4 (inlined std::ptr::read::<u32>) {
+                debug src => _1;
+                scope 5 {
+                }
+            }
+        }
+    }
+
+    bb0: {
+        _0 = (*_1);
+        (*_1) = _2;
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/mem_replace.rs b/tests/mir-opt/pre-codegen/mem_replace.rs
index 18c4653d4c6..551afea3ba5 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.rs
+++ b/tests/mir-opt/pre-codegen/mem_replace.rs
@@ -1,7 +1,8 @@
 // skip-filecheck
-// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
+// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 -Zinline-mir
 // only-64bit
 // ignore-debug the standard library debug assertions leak into this test
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
 #![crate_type = "lib"]
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index 26b2663fa35..4906c86f8ed 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -4,171 +4,165 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _17: std::option::Option<(usize, &T)>;
-    let mut _18: isize;
-    let mut _21: &impl Fn(usize, &T);
-    let mut _22: (usize, &T);
-    let _23: ();
+    let mut _15: std::slice::Iter<'_, T>;
+    let mut _16: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _17: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _18: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _19: std::option::Option<(usize, &T)>;
+    let mut _20: isize;
+    let mut _23: &impl Fn(usize, &T);
+    let mut _24: (usize, &T);
+    let _25: ();
     scope 1 {
-        debug iter => _15;
-        let _19: usize;
-        let _20: &T;
+        debug iter => _17;
+        let _21: usize;
+        let _22: &T;
         scope 2 {
-            debug i => _19;
-            debug x => _20;
+            debug i => _21;
+            debug x => _22;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         debug self => _1;
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             debug slice => _1;
-            let _4: *const T;
-            let mut _5: bool;
-            let mut _6: usize;
-            let mut _8: usize;
-            let mut _9: *mut T;
-            let mut _11: std::ptr::NonNull<T>;
-            let mut _12: *const T;
+            let _3: usize;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _10: bool;
+            let mut _11: *mut T;
+            let mut _12: *mut T;
+            let mut _14: *const T;
             scope 5 {
-                debug ptr => _4;
+                debug len => _3;
+                let _9: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _7: *const T;
+                    debug ptr => _9;
                     scope 7 {
-                        debug end_or_len => _7;
-                        scope 13 (inlined NonNull::<T>::new_unchecked) {
-                            debug ptr => _9;
-                            let mut _10: *const T;
-                            let mut _24: *mut T;
-                            scope 14 {
-                                scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) {
-                                    debug ptr => _24;
-                                    scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null) {
-                                        debug self => _24;
-                                        let mut _25: *mut u8;
-                                        scope 17 {
-                                            scope 18 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                debug ptr => _25;
-                                                scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                    debug self => _25;
-                                                    scope 20 {
-                                                        scope 21 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                            debug self => _25;
-                                                        }
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
+                        let _13: *const T;
+                        scope 8 {
+                            debug end_or_len => _13;
+                        }
+                        scope 14 (inlined invalid::<T>) {
+                            debug addr => _3;
+                            scope 15 {
                             }
                         }
-                    }
-                    scope 9 (inlined invalid::<T>) {
-                        debug addr => _8;
-                        scope 10 {
+                        scope 16 (inlined NonNull::<T>::as_ptr) {
+                            debug self => _9;
+                        }
+                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                            debug self => _11;
+                            debug count => _3;
+                            scope 18 {
+                            }
                         }
                     }
-                    scope 11 (inlined std::ptr::const_ptr::<impl *const T>::add) {
-                        debug self => _4;
-                        debug count => _6;
-                        scope 12 {
+                }
+                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                    debug reference => _1;
+                    let mut _4: *const [T];
+                    scope 10 {
+                    }
+                }
+                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                    debug self => _5;
+                    let mut _6: *mut [T];
+                    let mut _7: *mut T;
+                    let mut _8: *const T;
+                    scope 12 {
+                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
+                            debug self => _5;
                         }
                     }
                 }
             }
-            scope 8 (inlined core::slice::<impl [T]>::as_ptr) {
-                debug self => _1;
-                let mut _3: *const [T];
-            }
         }
     }
-    scope 22 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
-        debug self => _13;
-        scope 23 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
-            debug iter => _13;
+    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+        debug self => _15;
+        scope 20 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+            debug iter => _15;
         }
     }
-    scope 24 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
-        debug self => _14;
+    scope 21 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+        debug self => _16;
     }
 
     bb0: {
-        StorageLive(_13);
-        StorageLive(_4);
+        StorageLive(_15);
         StorageLive(_3);
-        _3 = &raw const (*_1);
-        _4 = move _3 as *const T (PtrToPtr);
-        StorageDead(_3);
-        StorageLive(_7);
+        StorageLive(_9);
+        StorageLive(_4);
+        StorageLive(_8);
+        _3 = Len((*_1));
         StorageLive(_5);
-        _5 = const _;
-        switchInt(move _5) -> [0: bb1, otherwise: bb2];
+        _4 = &raw const (*_1);
+        _5 = NonNull::<[T]> { pointer: _4 };
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = _4 as *mut [T] (PtrToPtr);
+        _7 = move _6 as *mut T (PtrToPtr);
+        _8 = move _7 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_6);
+        StorageDead(_7);
+        _9 = NonNull::<T> { pointer: _8 };
+        StorageDead(_5);
+        StorageLive(_13);
+        StorageLive(_10);
+        _10 = const _;
+        switchInt(move _10) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_6);
-        _6 = Len((*_1));
-        _7 = Offset(_4, _6);
-        StorageDead(_6);
+        StorageLive(_12);
+        StorageLive(_11);
+        _11 = _8 as *mut T (PtrToPtr);
+        _12 = Offset(_11, _3);
+        StorageDead(_11);
+        _13 = move _12 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_12);
         goto -> bb3;
     }
 
     bb2: {
-        StorageLive(_8);
-        _8 = Len((*_1));
-        _7 = _8 as *const T (Transmute);
-        StorageDead(_8);
+        _13 = _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageDead(_5);
-        StorageLive(_11);
-        StorageLive(_9);
-        _9 = _4 as *mut T (PtrToPtr);
-        StorageLive(_10);
-        StorageLive(_24);
-        StorageLive(_25);
-        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
-        _11 = NonNull::<T> { pointer: _10 };
-        StorageDead(_25);
-        StorageDead(_24);
         StorageDead(_10);
-        StorageDead(_9);
-        StorageLive(_12);
-        _12 = _7;
-        _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_7);
-        StorageDead(_4);
-        _14 = Enumerate::<std::slice::Iter<'_, T>> { iter: _13, count: const 0_usize };
+        StorageLive(_14);
+        _14 = _13;
+        _15 = std::slice::Iter::<'_, T> { ptr: _9, end_or_len: move _14, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_14);
         StorageDead(_13);
-        StorageLive(_15);
-        _15 = _14;
+        StorageDead(_8);
+        StorageDead(_4);
+        StorageDead(_9);
+        StorageDead(_3);
+        _16 = Enumerate::<std::slice::Iter<'_, T>> { iter: _15, count: const 0_usize };
+        StorageDead(_15);
+        StorageLive(_17);
+        _17 = _16;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_17);
-        StorageLive(_16);
-        _16 = &mut _15;
-        _17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind unreachable];
+        StorageLive(_19);
+        StorageLive(_18);
+        _18 = &mut _17;
+        _19 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _18) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
-        StorageDead(_16);
-        _18 = discriminant(_17);
-        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_18);
+        _20 = discriminant(_19);
+        switchInt(move _20) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
+        StorageDead(_19);
         StorageDead(_17);
-        StorageDead(_15);
         drop(_2) -> [return: bb7, unwind unreachable];
     }
 
@@ -177,19 +171,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb8: {
-        _19 = (((_17 as Some).0: (usize, &T)).0: usize);
-        _20 = (((_17 as Some).0: (usize, &T)).1: &T);
-        StorageLive(_21);
-        _21 = &_2;
-        StorageLive(_22);
-        _22 = (_19, _20);
-        _23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind unreachable];
+        _21 = (((_19 as Some).0: (usize, &T)).0: usize);
+        _22 = (((_19 as Some).0: (usize, &T)).1: &T);
+        StorageLive(_23);
+        _23 = &_2;
+        StorageLive(_24);
+        _24 = (_21, _22);
+        _25 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _23, move _24) -> [return: bb9, unwind unreachable];
     }
 
     bb9: {
-        StorageDead(_22);
-        StorageDead(_21);
-        StorageDead(_17);
+        StorageDead(_24);
+        StorageDead(_23);
+        StorageDead(_19);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index a055612bd5f..25a5ecdc6c3 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -4,171 +4,165 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _17: std::option::Option<(usize, &T)>;
-    let mut _18: isize;
-    let mut _21: &impl Fn(usize, &T);
-    let mut _22: (usize, &T);
-    let _23: ();
+    let mut _15: std::slice::Iter<'_, T>;
+    let mut _16: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _17: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _18: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _19: std::option::Option<(usize, &T)>;
+    let mut _20: isize;
+    let mut _23: &impl Fn(usize, &T);
+    let mut _24: (usize, &T);
+    let _25: ();
     scope 1 {
-        debug iter => _15;
-        let _19: usize;
-        let _20: &T;
+        debug iter => _17;
+        let _21: usize;
+        let _22: &T;
         scope 2 {
-            debug i => _19;
-            debug x => _20;
+            debug i => _21;
+            debug x => _22;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         debug self => _1;
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             debug slice => _1;
-            let _4: *const T;
-            let mut _5: bool;
-            let mut _6: usize;
-            let mut _8: usize;
-            let mut _9: *mut T;
-            let mut _11: std::ptr::NonNull<T>;
-            let mut _12: *const T;
+            let _3: usize;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _10: bool;
+            let mut _11: *mut T;
+            let mut _12: *mut T;
+            let mut _14: *const T;
             scope 5 {
-                debug ptr => _4;
+                debug len => _3;
+                let _9: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _7: *const T;
+                    debug ptr => _9;
                     scope 7 {
-                        debug end_or_len => _7;
-                        scope 13 (inlined NonNull::<T>::new_unchecked) {
-                            debug ptr => _9;
-                            let mut _10: *const T;
-                            let mut _24: *mut T;
-                            scope 14 {
-                                scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) {
-                                    debug ptr => _24;
-                                    scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null) {
-                                        debug self => _24;
-                                        let mut _25: *mut u8;
-                                        scope 17 {
-                                            scope 18 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                debug ptr => _25;
-                                                scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                    debug self => _25;
-                                                    scope 20 {
-                                                        scope 21 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                            debug self => _25;
-                                                        }
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
+                        let _13: *const T;
+                        scope 8 {
+                            debug end_or_len => _13;
+                        }
+                        scope 14 (inlined invalid::<T>) {
+                            debug addr => _3;
+                            scope 15 {
                             }
                         }
-                    }
-                    scope 9 (inlined invalid::<T>) {
-                        debug addr => _8;
-                        scope 10 {
+                        scope 16 (inlined NonNull::<T>::as_ptr) {
+                            debug self => _9;
+                        }
+                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                            debug self => _11;
+                            debug count => _3;
+                            scope 18 {
+                            }
                         }
                     }
-                    scope 11 (inlined std::ptr::const_ptr::<impl *const T>::add) {
-                        debug self => _4;
-                        debug count => _6;
-                        scope 12 {
+                }
+                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                    debug reference => _1;
+                    let mut _4: *const [T];
+                    scope 10 {
+                    }
+                }
+                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                    debug self => _5;
+                    let mut _6: *mut [T];
+                    let mut _7: *mut T;
+                    let mut _8: *const T;
+                    scope 12 {
+                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
+                            debug self => _5;
                         }
                     }
                 }
             }
-            scope 8 (inlined core::slice::<impl [T]>::as_ptr) {
-                debug self => _1;
-                let mut _3: *const [T];
-            }
         }
     }
-    scope 22 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
-        debug self => _13;
-        scope 23 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
-            debug iter => _13;
+    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+        debug self => _15;
+        scope 20 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+            debug iter => _15;
         }
     }
-    scope 24 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
-        debug self => _14;
+    scope 21 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+        debug self => _16;
     }
 
     bb0: {
-        StorageLive(_13);
-        StorageLive(_4);
+        StorageLive(_15);
         StorageLive(_3);
-        _3 = &raw const (*_1);
-        _4 = move _3 as *const T (PtrToPtr);
-        StorageDead(_3);
-        StorageLive(_7);
+        StorageLive(_9);
+        StorageLive(_4);
+        StorageLive(_8);
+        _3 = Len((*_1));
         StorageLive(_5);
-        _5 = const _;
-        switchInt(move _5) -> [0: bb1, otherwise: bb2];
+        _4 = &raw const (*_1);
+        _5 = NonNull::<[T]> { pointer: _4 };
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = _4 as *mut [T] (PtrToPtr);
+        _7 = move _6 as *mut T (PtrToPtr);
+        _8 = move _7 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_6);
+        StorageDead(_7);
+        _9 = NonNull::<T> { pointer: _8 };
+        StorageDead(_5);
+        StorageLive(_13);
+        StorageLive(_10);
+        _10 = const _;
+        switchInt(move _10) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_6);
-        _6 = Len((*_1));
-        _7 = Offset(_4, _6);
-        StorageDead(_6);
+        StorageLive(_12);
+        StorageLive(_11);
+        _11 = _8 as *mut T (PtrToPtr);
+        _12 = Offset(_11, _3);
+        StorageDead(_11);
+        _13 = move _12 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_12);
         goto -> bb3;
     }
 
     bb2: {
-        StorageLive(_8);
-        _8 = Len((*_1));
-        _7 = _8 as *const T (Transmute);
-        StorageDead(_8);
+        _13 = _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageDead(_5);
-        StorageLive(_11);
-        StorageLive(_9);
-        _9 = _4 as *mut T (PtrToPtr);
-        StorageLive(_10);
-        StorageLive(_24);
-        StorageLive(_25);
-        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
-        _11 = NonNull::<T> { pointer: _10 };
-        StorageDead(_25);
-        StorageDead(_24);
         StorageDead(_10);
-        StorageDead(_9);
-        StorageLive(_12);
-        _12 = _7;
-        _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_7);
-        StorageDead(_4);
-        _14 = Enumerate::<std::slice::Iter<'_, T>> { iter: _13, count: const 0_usize };
+        StorageLive(_14);
+        _14 = _13;
+        _15 = std::slice::Iter::<'_, T> { ptr: _9, end_or_len: move _14, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_14);
         StorageDead(_13);
-        StorageLive(_15);
-        _15 = _14;
+        StorageDead(_8);
+        StorageDead(_4);
+        StorageDead(_9);
+        StorageDead(_3);
+        _16 = Enumerate::<std::slice::Iter<'_, T>> { iter: _15, count: const 0_usize };
+        StorageDead(_15);
+        StorageLive(_17);
+        _17 = _16;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_17);
-        StorageLive(_16);
-        _16 = &mut _15;
-        _17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind: bb11];
+        StorageLive(_19);
+        StorageLive(_18);
+        _18 = &mut _17;
+        _19 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _18) -> [return: bb5, unwind: bb11];
     }
 
     bb5: {
-        StorageDead(_16);
-        _18 = discriminant(_17);
-        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_18);
+        _20 = discriminant(_19);
+        switchInt(move _20) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
+        StorageDead(_19);
         StorageDead(_17);
-        StorageDead(_15);
         drop(_2) -> [return: bb7, unwind continue];
     }
 
@@ -177,19 +171,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb8: {
-        _19 = (((_17 as Some).0: (usize, &T)).0: usize);
-        _20 = (((_17 as Some).0: (usize, &T)).1: &T);
-        StorageLive(_21);
-        _21 = &_2;
-        StorageLive(_22);
-        _22 = (_19, _20);
-        _23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
+        _21 = (((_19 as Some).0: (usize, &T)).0: usize);
+        _22 = (((_19 as Some).0: (usize, &T)).1: &T);
+        StorageLive(_23);
+        _23 = &_2;
+        StorageLive(_24);
+        _24 = (_21, _22);
+        _25 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _23, move _24) -> [return: bb9, unwind: bb11];
     }
 
     bb9: {
-        StorageDead(_22);
-        StorageDead(_21);
-        StorageDead(_17);
+        StorageDead(_24);
+        StorageDead(_23);
+        StorageDead(_19);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 471491108e0..133d6f53fce 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -4,159 +4,153 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::slice::Iter<'_, T>;
-    let mut _15: &mut std::slice::Iter<'_, T>;
-    let mut _16: std::option::Option<&T>;
-    let mut _17: isize;
-    let mut _19: &impl Fn(&T);
-    let mut _20: (&T,);
-    let _21: ();
+    let mut _15: std::slice::Iter<'_, T>;
+    let mut _16: std::slice::Iter<'_, T>;
+    let mut _17: &mut std::slice::Iter<'_, T>;
+    let mut _18: std::option::Option<&T>;
+    let mut _19: isize;
+    let mut _21: &impl Fn(&T);
+    let mut _22: (&T,);
+    let _23: ();
     scope 1 {
-        debug iter => _14;
-        let _18: &T;
+        debug iter => _16;
+        let _20: &T;
         scope 2 {
-            debug x => _18;
+            debug x => _20;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         debug self => _1;
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             debug slice => _1;
-            let _4: *const T;
-            let mut _5: bool;
-            let mut _6: usize;
-            let mut _8: usize;
-            let mut _9: *mut T;
-            let mut _11: std::ptr::NonNull<T>;
-            let mut _12: *const T;
+            let _3: usize;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _10: bool;
+            let mut _11: *mut T;
+            let mut _12: *mut T;
+            let mut _14: *const T;
             scope 5 {
-                debug ptr => _4;
+                debug len => _3;
+                let _9: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _7: *const T;
+                    debug ptr => _9;
                     scope 7 {
-                        debug end_or_len => _7;
-                        scope 13 (inlined NonNull::<T>::new_unchecked) {
-                            debug ptr => _9;
-                            let mut _10: *const T;
-                            let mut _22: *mut T;
-                            scope 14 {
-                                scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) {
-                                    debug ptr => _22;
-                                    scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null) {
-                                        debug self => _22;
-                                        let mut _23: *mut u8;
-                                        scope 17 {
-                                            scope 18 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                debug ptr => _23;
-                                                scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                    debug self => _23;
-                                                    scope 20 {
-                                                        scope 21 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                            debug self => _23;
-                                                        }
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
+                        let _13: *const T;
+                        scope 8 {
+                            debug end_or_len => _13;
+                        }
+                        scope 14 (inlined invalid::<T>) {
+                            debug addr => _3;
+                            scope 15 {
                             }
                         }
-                    }
-                    scope 9 (inlined invalid::<T>) {
-                        debug addr => _8;
-                        scope 10 {
+                        scope 16 (inlined NonNull::<T>::as_ptr) {
+                            debug self => _9;
+                        }
+                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                            debug self => _11;
+                            debug count => _3;
+                            scope 18 {
+                            }
                         }
                     }
-                    scope 11 (inlined std::ptr::const_ptr::<impl *const T>::add) {
-                        debug self => _4;
-                        debug count => _6;
-                        scope 12 {
+                }
+                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                    debug reference => _1;
+                    let mut _4: *const [T];
+                    scope 10 {
+                    }
+                }
+                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                    debug self => _5;
+                    let mut _6: *mut [T];
+                    let mut _7: *mut T;
+                    let mut _8: *const T;
+                    scope 12 {
+                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
+                            debug self => _5;
                         }
                     }
                 }
             }
-            scope 8 (inlined core::slice::<impl [T]>::as_ptr) {
-                debug self => _1;
-                let mut _3: *const [T];
-            }
         }
     }
-    scope 22 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
-        debug self => _13;
+    scope 19 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+        debug self => _15;
     }
 
     bb0: {
-        StorageLive(_4);
         StorageLive(_3);
-        _3 = &raw const (*_1);
-        _4 = move _3 as *const T (PtrToPtr);
-        StorageDead(_3);
-        StorageLive(_7);
+        StorageLive(_9);
+        StorageLive(_4);
+        StorageLive(_8);
+        _3 = Len((*_1));
         StorageLive(_5);
-        _5 = const _;
-        switchInt(move _5) -> [0: bb1, otherwise: bb2];
+        _4 = &raw const (*_1);
+        _5 = NonNull::<[T]> { pointer: _4 };
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = _4 as *mut [T] (PtrToPtr);
+        _7 = move _6 as *mut T (PtrToPtr);
+        _8 = move _7 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_6);
+        StorageDead(_7);
+        _9 = NonNull::<T> { pointer: _8 };
+        StorageDead(_5);
+        StorageLive(_13);
+        StorageLive(_10);
+        _10 = const _;
+        switchInt(move _10) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_6);
-        _6 = Len((*_1));
-        _7 = Offset(_4, _6);
-        StorageDead(_6);
+        StorageLive(_12);
+        StorageLive(_11);
+        _11 = _8 as *mut T (PtrToPtr);
+        _12 = Offset(_11, _3);
+        StorageDead(_11);
+        _13 = move _12 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_12);
         goto -> bb3;
     }
 
     bb2: {
-        StorageLive(_8);
-        _8 = Len((*_1));
-        _7 = _8 as *const T (Transmute);
-        StorageDead(_8);
+        _13 = _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageDead(_5);
-        StorageLive(_11);
-        StorageLive(_9);
-        _9 = _4 as *mut T (PtrToPtr);
-        StorageLive(_10);
-        StorageLive(_22);
-        StorageLive(_23);
-        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
-        _11 = NonNull::<T> { pointer: _10 };
-        StorageDead(_23);
-        StorageDead(_22);
         StorageDead(_10);
-        StorageDead(_9);
-        StorageLive(_12);
-        _12 = _7;
-        _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_7);
-        StorageDead(_4);
         StorageLive(_14);
         _14 = _13;
+        _15 = std::slice::Iter::<'_, T> { ptr: _9, end_or_len: move _14, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_14);
+        StorageDead(_13);
+        StorageDead(_8);
+        StorageDead(_4);
+        StorageDead(_9);
+        StorageDead(_3);
+        StorageLive(_16);
+        _16 = _15;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_16);
-        StorageLive(_15);
-        _15 = &mut _14;
-        _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind unreachable];
+        StorageLive(_18);
+        StorageLive(_17);
+        _17 = &mut _16;
+        _18 = <std::slice::Iter<'_, T> as Iterator>::next(move _17) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
-        StorageDead(_15);
-        _17 = discriminant(_16);
-        switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_17);
+        _19 = discriminant(_18);
+        switchInt(move _19) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
+        StorageDead(_18);
         StorageDead(_16);
-        StorageDead(_14);
         drop(_2) -> [return: bb7, unwind unreachable];
     }
 
@@ -165,18 +159,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _18 = ((_16 as Some).0: &T);
-        StorageLive(_19);
-        _19 = &_2;
-        StorageLive(_20);
-        _20 = (_18,);
-        _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind unreachable];
+        _20 = ((_18 as Some).0: &T);
+        StorageLive(_21);
+        _21 = &_2;
+        StorageLive(_22);
+        _22 = (_20,);
+        _23 = <impl Fn(&T) as Fn<(&T,)>>::call(move _21, move _22) -> [return: bb9, unwind unreachable];
     }
 
     bb9: {
-        StorageDead(_20);
-        StorageDead(_19);
-        StorageDead(_16);
+        StorageDead(_22);
+        StorageDead(_21);
+        StorageDead(_18);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index bbf38aba91f..4e74253e541 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -4,159 +4,153 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::slice::Iter<'_, T>;
-    let mut _15: &mut std::slice::Iter<'_, T>;
-    let mut _16: std::option::Option<&T>;
-    let mut _17: isize;
-    let mut _19: &impl Fn(&T);
-    let mut _20: (&T,);
-    let _21: ();
+    let mut _15: std::slice::Iter<'_, T>;
+    let mut _16: std::slice::Iter<'_, T>;
+    let mut _17: &mut std::slice::Iter<'_, T>;
+    let mut _18: std::option::Option<&T>;
+    let mut _19: isize;
+    let mut _21: &impl Fn(&T);
+    let mut _22: (&T,);
+    let _23: ();
     scope 1 {
-        debug iter => _14;
-        let _18: &T;
+        debug iter => _16;
+        let _20: &T;
         scope 2 {
-            debug x => _18;
+            debug x => _20;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         debug self => _1;
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             debug slice => _1;
-            let _4: *const T;
-            let mut _5: bool;
-            let mut _6: usize;
-            let mut _8: usize;
-            let mut _9: *mut T;
-            let mut _11: std::ptr::NonNull<T>;
-            let mut _12: *const T;
+            let _3: usize;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _10: bool;
+            let mut _11: *mut T;
+            let mut _12: *mut T;
+            let mut _14: *const T;
             scope 5 {
-                debug ptr => _4;
+                debug len => _3;
+                let _9: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _7: *const T;
+                    debug ptr => _9;
                     scope 7 {
-                        debug end_or_len => _7;
-                        scope 13 (inlined NonNull::<T>::new_unchecked) {
-                            debug ptr => _9;
-                            let mut _10: *const T;
-                            let mut _22: *mut T;
-                            scope 14 {
-                                scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) {
-                                    debug ptr => _22;
-                                    scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null) {
-                                        debug self => _22;
-                                        let mut _23: *mut u8;
-                                        scope 17 {
-                                            scope 18 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                debug ptr => _23;
-                                                scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                    debug self => _23;
-                                                    scope 20 {
-                                                        scope 21 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                            debug self => _23;
-                                                        }
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
+                        let _13: *const T;
+                        scope 8 {
+                            debug end_or_len => _13;
+                        }
+                        scope 14 (inlined invalid::<T>) {
+                            debug addr => _3;
+                            scope 15 {
                             }
                         }
-                    }
-                    scope 9 (inlined invalid::<T>) {
-                        debug addr => _8;
-                        scope 10 {
+                        scope 16 (inlined NonNull::<T>::as_ptr) {
+                            debug self => _9;
+                        }
+                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                            debug self => _11;
+                            debug count => _3;
+                            scope 18 {
+                            }
                         }
                     }
-                    scope 11 (inlined std::ptr::const_ptr::<impl *const T>::add) {
-                        debug self => _4;
-                        debug count => _6;
-                        scope 12 {
+                }
+                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                    debug reference => _1;
+                    let mut _4: *const [T];
+                    scope 10 {
+                    }
+                }
+                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                    debug self => _5;
+                    let mut _6: *mut [T];
+                    let mut _7: *mut T;
+                    let mut _8: *const T;
+                    scope 12 {
+                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
+                            debug self => _5;
                         }
                     }
                 }
             }
-            scope 8 (inlined core::slice::<impl [T]>::as_ptr) {
-                debug self => _1;
-                let mut _3: *const [T];
-            }
         }
     }
-    scope 22 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
-        debug self => _13;
+    scope 19 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+        debug self => _15;
     }
 
     bb0: {
-        StorageLive(_4);
         StorageLive(_3);
-        _3 = &raw const (*_1);
-        _4 = move _3 as *const T (PtrToPtr);
-        StorageDead(_3);
-        StorageLive(_7);
+        StorageLive(_9);
+        StorageLive(_4);
+        StorageLive(_8);
+        _3 = Len((*_1));
         StorageLive(_5);
-        _5 = const _;
-        switchInt(move _5) -> [0: bb1, otherwise: bb2];
+        _4 = &raw const (*_1);
+        _5 = NonNull::<[T]> { pointer: _4 };
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = _4 as *mut [T] (PtrToPtr);
+        _7 = move _6 as *mut T (PtrToPtr);
+        _8 = move _7 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_6);
+        StorageDead(_7);
+        _9 = NonNull::<T> { pointer: _8 };
+        StorageDead(_5);
+        StorageLive(_13);
+        StorageLive(_10);
+        _10 = const _;
+        switchInt(move _10) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_6);
-        _6 = Len((*_1));
-        _7 = Offset(_4, _6);
-        StorageDead(_6);
+        StorageLive(_12);
+        StorageLive(_11);
+        _11 = _8 as *mut T (PtrToPtr);
+        _12 = Offset(_11, _3);
+        StorageDead(_11);
+        _13 = move _12 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_12);
         goto -> bb3;
     }
 
     bb2: {
-        StorageLive(_8);
-        _8 = Len((*_1));
-        _7 = _8 as *const T (Transmute);
-        StorageDead(_8);
+        _13 = _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageDead(_5);
-        StorageLive(_11);
-        StorageLive(_9);
-        _9 = _4 as *mut T (PtrToPtr);
-        StorageLive(_10);
-        StorageLive(_22);
-        StorageLive(_23);
-        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
-        _11 = NonNull::<T> { pointer: _10 };
-        StorageDead(_23);
-        StorageDead(_22);
         StorageDead(_10);
-        StorageDead(_9);
-        StorageLive(_12);
-        _12 = _7;
-        _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_7);
-        StorageDead(_4);
         StorageLive(_14);
         _14 = _13;
+        _15 = std::slice::Iter::<'_, T> { ptr: _9, end_or_len: move _14, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_14);
+        StorageDead(_13);
+        StorageDead(_8);
+        StorageDead(_4);
+        StorageDead(_9);
+        StorageDead(_3);
+        StorageLive(_16);
+        _16 = _15;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_16);
-        StorageLive(_15);
-        _15 = &mut _14;
-        _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind: bb11];
+        StorageLive(_18);
+        StorageLive(_17);
+        _17 = &mut _16;
+        _18 = <std::slice::Iter<'_, T> as Iterator>::next(move _17) -> [return: bb5, unwind: bb11];
     }
 
     bb5: {
-        StorageDead(_15);
-        _17 = discriminant(_16);
-        switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_17);
+        _19 = discriminant(_18);
+        switchInt(move _19) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
+        StorageDead(_18);
         StorageDead(_16);
-        StorageDead(_14);
         drop(_2) -> [return: bb7, unwind continue];
     }
 
@@ -165,18 +159,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _18 = ((_16 as Some).0: &T);
-        StorageLive(_19);
-        _19 = &_2;
-        StorageLive(_20);
-        _20 = (_18,);
-        _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
+        _20 = ((_18 as Some).0: &T);
+        StorageLive(_21);
+        _21 = &_2;
+        StorageLive(_22);
+        _22 = (_20,);
+        _23 = <impl Fn(&T) as Fn<(&T,)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
     }
 
     bb9: {
-        StorageDead(_20);
-        StorageDead(_19);
-        StorageDead(_16);
+        StorageDead(_22);
+        StorageDead(_21);
+        StorageDead(_18);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index f9c8ab4db60..639e1a51430 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -4,174 +4,168 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _16: &mut std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _18: std::option::Option<&T>;
-    let mut _19: isize;
-    let mut _21: &impl Fn(&T);
-    let mut _22: (&T,);
-    let _23: ();
+    let mut _15: std::slice::Iter<'_, T>;
+    let mut _16: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _17: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _18: &mut std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _20: std::option::Option<&T>;
+    let mut _21: isize;
+    let mut _23: &impl Fn(&T);
+    let mut _24: (&T,);
+    let _25: ();
     scope 1 {
-        debug iter => _15;
-        let _20: &T;
+        debug iter => _17;
+        let _22: &T;
         scope 2 {
-            debug x => _20;
+            debug x => _22;
         }
-        scope 25 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
-            debug self => _16;
-            let mut _17: &mut std::slice::Iter<'_, T>;
+        scope 22 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+            debug self => _18;
+            let mut _19: &mut std::slice::Iter<'_, T>;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         debug self => _1;
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             debug slice => _1;
-            let _4: *const T;
-            let mut _5: bool;
-            let mut _6: usize;
-            let mut _8: usize;
-            let mut _9: *mut T;
-            let mut _11: std::ptr::NonNull<T>;
-            let mut _12: *const T;
+            let _3: usize;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _10: bool;
+            let mut _11: *mut T;
+            let mut _12: *mut T;
+            let mut _14: *const T;
             scope 5 {
-                debug ptr => _4;
+                debug len => _3;
+                let _9: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _7: *const T;
+                    debug ptr => _9;
                     scope 7 {
-                        debug end_or_len => _7;
-                        scope 13 (inlined NonNull::<T>::new_unchecked) {
-                            debug ptr => _9;
-                            let mut _10: *const T;
-                            let mut _24: *mut T;
-                            scope 14 {
-                                scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) {
-                                    debug ptr => _24;
-                                    scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null) {
-                                        debug self => _24;
-                                        let mut _25: *mut u8;
-                                        scope 17 {
-                                            scope 18 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                debug ptr => _25;
-                                                scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                    debug self => _25;
-                                                    scope 20 {
-                                                        scope 21 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                            debug self => _25;
-                                                        }
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
+                        let _13: *const T;
+                        scope 8 {
+                            debug end_or_len => _13;
+                        }
+                        scope 14 (inlined invalid::<T>) {
+                            debug addr => _3;
+                            scope 15 {
                             }
                         }
-                    }
-                    scope 9 (inlined invalid::<T>) {
-                        debug addr => _8;
-                        scope 10 {
+                        scope 16 (inlined NonNull::<T>::as_ptr) {
+                            debug self => _9;
+                        }
+                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                            debug self => _11;
+                            debug count => _3;
+                            scope 18 {
+                            }
                         }
                     }
-                    scope 11 (inlined std::ptr::const_ptr::<impl *const T>::add) {
-                        debug self => _4;
-                        debug count => _6;
-                        scope 12 {
+                }
+                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                    debug reference => _1;
+                    let mut _4: *const [T];
+                    scope 10 {
+                    }
+                }
+                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                    debug self => _5;
+                    let mut _6: *mut [T];
+                    let mut _7: *mut T;
+                    let mut _8: *const T;
+                    scope 12 {
+                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
+                            debug self => _5;
                         }
                     }
                 }
             }
-            scope 8 (inlined core::slice::<impl [T]>::as_ptr) {
-                debug self => _1;
-                let mut _3: *const [T];
-            }
         }
     }
-    scope 22 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
-        debug self => _13;
-        scope 23 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
-            debug iter => _13;
+    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+        debug self => _15;
+        scope 20 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+            debug iter => _15;
         }
     }
-    scope 24 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
-        debug self => _14;
+    scope 21 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+        debug self => _16;
     }
 
     bb0: {
-        StorageLive(_13);
-        StorageLive(_4);
+        StorageLive(_15);
         StorageLive(_3);
-        _3 = &raw const (*_1);
-        _4 = move _3 as *const T (PtrToPtr);
-        StorageDead(_3);
-        StorageLive(_7);
+        StorageLive(_9);
+        StorageLive(_4);
+        StorageLive(_8);
+        _3 = Len((*_1));
         StorageLive(_5);
-        _5 = const _;
-        switchInt(move _5) -> [0: bb1, otherwise: bb2];
+        _4 = &raw const (*_1);
+        _5 = NonNull::<[T]> { pointer: _4 };
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = _4 as *mut [T] (PtrToPtr);
+        _7 = move _6 as *mut T (PtrToPtr);
+        _8 = move _7 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_6);
+        StorageDead(_7);
+        _9 = NonNull::<T> { pointer: _8 };
+        StorageDead(_5);
+        StorageLive(_13);
+        StorageLive(_10);
+        _10 = const _;
+        switchInt(move _10) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_6);
-        _6 = Len((*_1));
-        _7 = Offset(_4, _6);
-        StorageDead(_6);
+        StorageLive(_12);
+        StorageLive(_11);
+        _11 = _8 as *mut T (PtrToPtr);
+        _12 = Offset(_11, _3);
+        StorageDead(_11);
+        _13 = move _12 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_12);
         goto -> bb3;
     }
 
     bb2: {
-        StorageLive(_8);
-        _8 = Len((*_1));
-        _7 = _8 as *const T (Transmute);
-        StorageDead(_8);
+        _13 = _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageDead(_5);
-        StorageLive(_11);
-        StorageLive(_9);
-        _9 = _4 as *mut T (PtrToPtr);
-        StorageLive(_10);
-        StorageLive(_24);
-        StorageLive(_25);
-        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
-        _11 = NonNull::<T> { pointer: _10 };
-        StorageDead(_25);
-        StorageDead(_24);
         StorageDead(_10);
-        StorageDead(_9);
-        StorageLive(_12);
-        _12 = _7;
-        _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_7);
-        StorageDead(_4);
-        _14 = Rev::<std::slice::Iter<'_, T>> { iter: _13 };
+        StorageLive(_14);
+        _14 = _13;
+        _15 = std::slice::Iter::<'_, T> { ptr: _9, end_or_len: move _14, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_14);
         StorageDead(_13);
-        StorageLive(_15);
-        _15 = _14;
+        StorageDead(_8);
+        StorageDead(_4);
+        StorageDead(_9);
+        StorageDead(_3);
+        _16 = Rev::<std::slice::Iter<'_, T>> { iter: _15 };
+        StorageDead(_15);
+        StorageLive(_17);
+        _17 = _16;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_18);
-        _16 = &mut _15;
-        StorageLive(_17);
-        _17 = &mut (_15.0: std::slice::Iter<'_, T>);
-        _18 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _17) -> [return: bb5, unwind unreachable];
+        StorageLive(_20);
+        _18 = &mut _17;
+        StorageLive(_19);
+        _19 = &mut (_17.0: std::slice::Iter<'_, T>);
+        _20 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _19) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
-        StorageDead(_17);
-        _19 = discriminant(_18);
-        switchInt(move _19) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_19);
+        _21 = discriminant(_20);
+        switchInt(move _21) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
-        StorageDead(_18);
-        StorageDead(_15);
+        StorageDead(_20);
+        StorageDead(_17);
         drop(_2) -> [return: bb7, unwind unreachable];
     }
 
@@ -180,18 +174,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _20 = ((_18 as Some).0: &T);
-        StorageLive(_21);
-        _21 = &_2;
-        StorageLive(_22);
-        _22 = (_20,);
-        _23 = <impl Fn(&T) as Fn<(&T,)>>::call(move _21, move _22) -> [return: bb9, unwind unreachable];
+        _22 = ((_20 as Some).0: &T);
+        StorageLive(_23);
+        _23 = &_2;
+        StorageLive(_24);
+        _24 = (_22,);
+        _25 = <impl Fn(&T) as Fn<(&T,)>>::call(move _23, move _24) -> [return: bb9, unwind unreachable];
     }
 
     bb9: {
-        StorageDead(_22);
-        StorageDead(_21);
-        StorageDead(_18);
+        StorageDead(_24);
+        StorageDead(_23);
+        StorageDead(_20);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index 65f423ac326..2237fd7dbd1 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -4,174 +4,168 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _13: std::slice::Iter<'_, T>;
-    let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _16: &mut std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _18: std::option::Option<&T>;
-    let mut _19: isize;
-    let mut _21: &impl Fn(&T);
-    let mut _22: (&T,);
-    let _23: ();
+    let mut _15: std::slice::Iter<'_, T>;
+    let mut _16: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _17: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _18: &mut std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _20: std::option::Option<&T>;
+    let mut _21: isize;
+    let mut _23: &impl Fn(&T);
+    let mut _24: (&T,);
+    let _25: ();
     scope 1 {
-        debug iter => _15;
-        let _20: &T;
+        debug iter => _17;
+        let _22: &T;
         scope 2 {
-            debug x => _20;
+            debug x => _22;
         }
-        scope 25 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
-            debug self => _16;
-            let mut _17: &mut std::slice::Iter<'_, T>;
+        scope 22 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+            debug self => _18;
+            let mut _19: &mut std::slice::Iter<'_, T>;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         debug self => _1;
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             debug slice => _1;
-            let _4: *const T;
-            let mut _5: bool;
-            let mut _6: usize;
-            let mut _8: usize;
-            let mut _9: *mut T;
-            let mut _11: std::ptr::NonNull<T>;
-            let mut _12: *const T;
+            let _3: usize;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _10: bool;
+            let mut _11: *mut T;
+            let mut _12: *mut T;
+            let mut _14: *const T;
             scope 5 {
-                debug ptr => _4;
+                debug len => _3;
+                let _9: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _7: *const T;
+                    debug ptr => _9;
                     scope 7 {
-                        debug end_or_len => _7;
-                        scope 13 (inlined NonNull::<T>::new_unchecked) {
-                            debug ptr => _9;
-                            let mut _10: *const T;
-                            let mut _24: *mut T;
-                            scope 14 {
-                                scope 15 (inlined NonNull::<T>::new_unchecked::runtime::<T>) {
-                                    debug ptr => _24;
-                                    scope 16 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null) {
-                                        debug self => _24;
-                                        let mut _25: *mut u8;
-                                        scope 17 {
-                                            scope 18 (inlined std::ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
-                                                debug ptr => _25;
-                                                scope 19 (inlined std::ptr::mut_ptr::<impl *mut u8>::addr) {
-                                                    debug self => _25;
-                                                    scope 20 {
-                                                        scope 21 (inlined std::ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
-                                                            debug self => _25;
-                                                        }
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
+                        let _13: *const T;
+                        scope 8 {
+                            debug end_or_len => _13;
+                        }
+                        scope 14 (inlined invalid::<T>) {
+                            debug addr => _3;
+                            scope 15 {
                             }
                         }
-                    }
-                    scope 9 (inlined invalid::<T>) {
-                        debug addr => _8;
-                        scope 10 {
+                        scope 16 (inlined NonNull::<T>::as_ptr) {
+                            debug self => _9;
+                        }
+                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                            debug self => _11;
+                            debug count => _3;
+                            scope 18 {
+                            }
                         }
                     }
-                    scope 11 (inlined std::ptr::const_ptr::<impl *const T>::add) {
-                        debug self => _4;
-                        debug count => _6;
-                        scope 12 {
+                }
+                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                    debug reference => _1;
+                    let mut _4: *const [T];
+                    scope 10 {
+                    }
+                }
+                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                    debug self => _5;
+                    let mut _6: *mut [T];
+                    let mut _7: *mut T;
+                    let mut _8: *const T;
+                    scope 12 {
+                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
+                            debug self => _5;
                         }
                     }
                 }
             }
-            scope 8 (inlined core::slice::<impl [T]>::as_ptr) {
-                debug self => _1;
-                let mut _3: *const [T];
-            }
         }
     }
-    scope 22 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
-        debug self => _13;
-        scope 23 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
-            debug iter => _13;
+    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+        debug self => _15;
+        scope 20 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+            debug iter => _15;
         }
     }
-    scope 24 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
-        debug self => _14;
+    scope 21 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+        debug self => _16;
     }
 
     bb0: {
-        StorageLive(_13);
-        StorageLive(_4);
+        StorageLive(_15);
         StorageLive(_3);
-        _3 = &raw const (*_1);
-        _4 = move _3 as *const T (PtrToPtr);
-        StorageDead(_3);
-        StorageLive(_7);
+        StorageLive(_9);
+        StorageLive(_4);
+        StorageLive(_8);
+        _3 = Len((*_1));
         StorageLive(_5);
-        _5 = const _;
-        switchInt(move _5) -> [0: bb1, otherwise: bb2];
+        _4 = &raw const (*_1);
+        _5 = NonNull::<[T]> { pointer: _4 };
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = _4 as *mut [T] (PtrToPtr);
+        _7 = move _6 as *mut T (PtrToPtr);
+        _8 = move _7 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_6);
+        StorageDead(_7);
+        _9 = NonNull::<T> { pointer: _8 };
+        StorageDead(_5);
+        StorageLive(_13);
+        StorageLive(_10);
+        _10 = const _;
+        switchInt(move _10) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_6);
-        _6 = Len((*_1));
-        _7 = Offset(_4, _6);
-        StorageDead(_6);
+        StorageLive(_12);
+        StorageLive(_11);
+        _11 = _8 as *mut T (PtrToPtr);
+        _12 = Offset(_11, _3);
+        StorageDead(_11);
+        _13 = move _12 as *const T (PointerCoercion(MutToConstPointer));
+        StorageDead(_12);
         goto -> bb3;
     }
 
     bb2: {
-        StorageLive(_8);
-        _8 = Len((*_1));
-        _7 = _8 as *const T (Transmute);
-        StorageDead(_8);
+        _13 = _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageDead(_5);
-        StorageLive(_11);
-        StorageLive(_9);
-        _9 = _4 as *mut T (PtrToPtr);
-        StorageLive(_10);
-        StorageLive(_24);
-        StorageLive(_25);
-        _10 = _9 as *const T (PointerCoercion(MutToConstPointer));
-        _11 = NonNull::<T> { pointer: _10 };
-        StorageDead(_25);
-        StorageDead(_24);
         StorageDead(_10);
-        StorageDead(_9);
-        StorageLive(_12);
-        _12 = _7;
-        _13 = std::slice::Iter::<'_, T> { ptr: move _11, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_12);
-        StorageDead(_11);
-        StorageDead(_7);
-        StorageDead(_4);
-        _14 = Rev::<std::slice::Iter<'_, T>> { iter: _13 };
+        StorageLive(_14);
+        _14 = _13;
+        _15 = std::slice::Iter::<'_, T> { ptr: _9, end_or_len: move _14, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_14);
         StorageDead(_13);
-        StorageLive(_15);
-        _15 = _14;
+        StorageDead(_8);
+        StorageDead(_4);
+        StorageDead(_9);
+        StorageDead(_3);
+        _16 = Rev::<std::slice::Iter<'_, T>> { iter: _15 };
+        StorageDead(_15);
+        StorageLive(_17);
+        _17 = _16;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_18);
-        _16 = &mut _15;
-        StorageLive(_17);
-        _17 = &mut (_15.0: std::slice::Iter<'_, T>);
-        _18 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _17) -> [return: bb5, unwind: bb11];
+        StorageLive(_20);
+        _18 = &mut _17;
+        StorageLive(_19);
+        _19 = &mut (_17.0: std::slice::Iter<'_, T>);
+        _20 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _19) -> [return: bb5, unwind: bb11];
     }
 
     bb5: {
-        StorageDead(_17);
-        _19 = discriminant(_18);
-        switchInt(move _19) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_19);
+        _21 = discriminant(_20);
+        switchInt(move _21) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
-        StorageDead(_18);
-        StorageDead(_15);
+        StorageDead(_20);
+        StorageDead(_17);
         drop(_2) -> [return: bb7, unwind continue];
     }
 
@@ -180,18 +174,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _20 = ((_18 as Some).0: &T);
-        StorageLive(_21);
-        _21 = &_2;
-        StorageLive(_22);
-        _22 = (_20,);
-        _23 = <impl Fn(&T) as Fn<(&T,)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
+        _22 = ((_20 as Some).0: &T);
+        StorageLive(_23);
+        _23 = &_2;
+        StorageLive(_24);
+        _24 = (_22,);
+        _25 = <impl Fn(&T) as Fn<(&T,)>>::call(move _23, move _24) -> [return: bb9, unwind: bb11];
     }
 
     bb9: {
-        StorageDead(_22);
-        StorageDead(_21);
-        StorageDead(_18);
+        StorageDead(_24);
+        StorageDead(_23);
+        StorageDead(_20);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/remove_storage_markers.rs b/tests/mir-opt/remove_storage_markers.rs
index 6666ff3b726..27661ab3254 100644
--- a/tests/mir-opt/remove_storage_markers.rs
+++ b/tests/mir-opt/remove_storage_markers.rs
@@ -1,4 +1,3 @@
-// skip-filecheck
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 // unit-test: RemoveStorageMarkers
 
@@ -8,6 +7,10 @@
 
 // EMIT_MIR remove_storage_markers.main.RemoveStorageMarkers.diff
 fn main() {
+    // CHECK-LABEL: fn main(
+
+    // CHECK-NOT: StorageDead
+    // CHECK-NOT: StorageLive
     let mut sum = 0;
     for i in 0..10 {
         sum += i;
diff --git a/tests/mir-opt/retag.rs b/tests/mir-opt/retag.rs
index 1e4b017dad5..554b8ece90f 100644
--- a/tests/mir-opt/retag.rs
+++ b/tests/mir-opt/retag.rs
@@ -28,7 +28,7 @@ impl Drop for Test {
 
 // EMIT_MIR retag.main.SimplifyCfg-elaborate-drops.after.mir
 // EMIT_MIR retag.main-{closure#0}.SimplifyCfg-elaborate-drops.after.mir
-fn main() {
+pub fn main() {
     let mut x = 0;
     {
         let v = Test(0).foo(&mut x); // just making sure we do not panic when there is a tuple struct ctor
diff --git a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
index e7280f14837..d2731615284 100644
--- a/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
+++ b/tests/mir-opt/separate_const_switch.identity.SeparateConstSwitch.diff
@@ -66,7 +66,7 @@
           _5 = ((_2 as Break).0: std::result::Result<std::convert::Infallible, i32>);
           StorageLive(_6);
           _6 = _5;
-          _12 = move ((_5 as Err).0: i32);
+          _12 = ((_5 as Err).0: i32);
           _0 = Result::<i32, i32>::Err(_12);
           StorageDead(_6);
           StorageDead(_2);
@@ -83,7 +83,7 @@
       }
   
       bb4: {
-          _10 = move ((_1 as Err).0: i32);
+          _10 = ((_1 as Err).0: i32);
           StorageLive(_11);
           _11 = Result::<Infallible, i32>::Err(_10);
           _2 = ControlFlow::<Result<Infallible, i32>, i32>::Break(move _11);
@@ -92,7 +92,7 @@
       }
   
       bb5: {
-          _9 = move ((_1 as Ok).0: i32);
+          _9 = ((_1 as Ok).0: i32);
           _2 = ControlFlow::<Result<Infallible, i32>, i32>::Continue(_9);
           goto -> bb3;
       }
diff --git a/tests/mir-opt/simplify_if.rs b/tests/mir-opt/simplify_if.rs
index 19b5806f720..f600c059581 100644
--- a/tests/mir-opt/simplify_if.rs
+++ b/tests/mir-opt/simplify_if.rs
@@ -1,10 +1,13 @@
-// skip-filecheck
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 #[inline(never)]
 fn noop() {}
 
 // EMIT_MIR simplify_if.main.SimplifyConstCondition-after-const-prop.diff
 fn main() {
+    // CHECK-LABEL: fn main(
+
+    // CHECK: bb0: {
+    // CHECK-NEXT: return;
     if false {
         noop();
     }
diff --git a/tests/mir-opt/slice_drop_shim.rs b/tests/mir-opt/slice_drop_shim.rs
index cac0a349128..037e048b3b7 100644
--- a/tests/mir-opt/slice_drop_shim.rs
+++ b/tests/mir-opt/slice_drop_shim.rs
@@ -1,6 +1,8 @@
 // skip-filecheck
-// compile-flags: -Zmir-opt-level=0
-
+// compile-flags: -Zmir-opt-level=0 -Clink-dead-code
+// mir-opt tests are always built as rlibs so that they seamlessly cross-compile,
+// so this test only produces MIR for the drop_in_place we're looking for
+// if we use -Clink-dead-code.
 
 // EMIT_MIR core.ptr-drop_in_place.[String].AddMovesForPackedDrops.before.mir
 fn main() {
diff --git a/tests/mir-opt/sroa/lifetimes.rs b/tests/mir-opt/sroa/lifetimes.rs
index cc5c0c9bbcd..ea04fac1571 100644
--- a/tests/mir-opt/sroa/lifetimes.rs
+++ b/tests/mir-opt/sroa/lifetimes.rs
@@ -1,4 +1,3 @@
-// skip-filecheck
 // unit-test: ScalarReplacementOfAggregates
 // compile-flags: -Cpanic=abort
 // no-prefer-dynamic
@@ -16,6 +15,10 @@ struct Foo<T: Err> {
 
 // EMIT_MIR lifetimes.foo.ScalarReplacementOfAggregates.diff
 fn foo<T: Err>() {
+    // CHECK-LABEL: fn foo(
+
+    // CHECK-NOT: [foo:_.*]: Foo
+    // CHECK-NOT: Box<dyn std::fmt::Display + 'static>
     let foo: Foo<T> = Foo {
         x: Ok(Box::new(5_u32)),
         y: 7_u32,
diff --git a/tests/mir-opt/sroa/structs.rs b/tests/mir-opt/sroa/structs.rs
index 73563e12c94..5ea3795b86e 100644
--- a/tests/mir-opt/sroa/structs.rs
+++ b/tests/mir-opt/sroa/structs.rs
@@ -1,4 +1,3 @@
-// skip-filecheck
 // unit-test: ScalarReplacementOfAggregates
 // compile-flags: -Cpanic=abort
 // no-prefer-dynamic
@@ -13,28 +12,68 @@ impl Drop for Tag {
     fn drop(&mut self) {}
 }
 
+/// Check that SROA excludes structs with a `Drop` implementation.
 pub fn dropping() {
+    // CHECK-LABEL: fn dropping(
+
+    // CHECK: [[aggregate:_[0-9]+]]: S;
+
+    // CHECK: bb0: {
+    // CHECK: [[aggregate]] = S
     S(Tag(0), Tag(1), Tag(2)).1;
 }
 
+/// Check that SROA excludes enums.
 pub fn enums(a: usize) -> usize {
+    // CHECK-LABEL: fn enums(
+
+    // CHECK: [[enum:_[0-9]+]]: std::option::Option<usize>;
+
+    // CHECK: bb0: {
+    // CHECK: [[enum]] = Option::<usize>::Some
+    // CHECK: _5 = (([[enum]] as Some).0: usize)
+    // CHECK: _0 = _5
     if let Some(a) = Some(a) { a } else { 0 }
 }
 
+/// Check that SROA destructures `U`.
 pub fn structs(a: f32) -> f32 {
+    // CHECK-LABEL: fn structs(
     struct U {
         _foo: usize,
         a: f32,
     }
-
+    // CHECK: [[ret:_0]]: f32;
+    // CHECK: [[struct:_[0-9]+]]: structs::U;
+    // CHECK: [[a_tmp:_[0-9]+]]: f32;
+    // CHECK: [[foo:_[0-9]+]]: usize;
+    // CHECK: [[a_ret:_[0-9]+]]: f32;
+
+    // CHECK: bb0: {
+    // CHECK-NOT: [[struct]]
+    // CHECK: [[a_tmp]] = _1;
+    // CHECK-NOT: [[struct]]
+    // CHECK: [[foo]] = const 0_usize;
+    // CHECK-NOT: [[struct]]
+    // CHECK: [[a_ret]] = move [[a_tmp]];
+    // CHECK-NOT: [[struct]]
+    // CHECK: _0 = [[a_ret]];
+    // CHECK-NOT: [[struct]]
     U { _foo: 0, a }.a
 }
 
+/// Check that SROA excludes unions.
 pub fn unions(a: f32) -> u32 {
+    // CHECK-LABEL: fn unions(
     union Repr {
         f: f32,
         u: u32,
     }
+    // CHECK: [[union:_[0-9]+]]: unions::Repr;
+
+    // CHECK: bb0: {
+    // CHECK: [[union]] = Repr {
+    // CHECK: _0 = ([[union]].1: u32)
     unsafe { Repr { f: a }.u }
 }
 
@@ -46,11 +85,21 @@ struct Foo {
     d: Option<isize>,
 }
 
-fn g() -> u32 {
-    3
-}
-
+/// Check that non-escaping uses of a struct are destructured.
 pub fn flat() {
+    // CHECK-LABEL: fn flat(
+
+    // CHECK: [[struct:_[0-9]+]]: Foo;
+
+    // CHECK: bb0: {
+    // CHECK: [[init_unit:_[0-9]+]] = ();
+    // CHECK: [[init_opt_isize:_[0-9]+]] = Option::<isize>::Some
+
+    // CHECK: [[destr_five:_[0-9]+]] = const 5_u8;
+    // CHECK: [[destr_unit:_[0-9]+]] = move [[init_unit]];
+    // CHECK: [[destr_a:_[0-9]+]] = const "a";
+    // CHECK: [[destr_opt_isize:_[0-9]+]] = move [[init_opt_isize]];
+
     let Foo { a, b, c, d } = Foo { a: 5, b: (), c: "a", d: Some(-4) };
     let _ = a;
     let _ = b;
@@ -65,6 +114,10 @@ struct Escaping {
     c: u32,
 }
 
+fn g() -> u32 {
+    3
+}
+
 fn f(a: *const u32) {
     println!("{}", unsafe { *a.add(2) });
 }
@@ -76,10 +129,38 @@ fn f(a: *const u32) {
 // of them to `f`. However, this would lead to a miscompilation because `b` and `c`
 // might no longer appear right after `a` in memory.
 pub fn escaping() {
+    // CHECK-LABEL: fn escaping(
+
+    // CHECK: [[ptr:_[0-9]+]]: *const u32;
+    // CHECK: [[ref:_[0-9]+]]: &u32;
+    // CHECK: [[struct:_[0-9]+]]: Escaping;
+    // CHECK: [[a:_[0-9]+]]: u32;
+
+    // CHECK: bb0: {
+    // CHECK: [[struct]] = Escaping {
+    // CHECK: [[ref]] = &([[struct]].0
+    // CHECK: [[ptr]] = &raw const (*[[ref]]);
     f(&Escaping { a: 1, b: 2, c: g() }.a);
 }
 
+/// Check that copies from an internal struct are destructured and reassigned to
+/// the original struct.
 fn copies(x: Foo) {
+    // CHECK-LABEL: fn copies(
+
+    // CHECK: [[external:_[0-9]+]]: Foo) ->
+    // CHECK: [[internal:_[0-9]+]]: Foo;
+    // CHECK: [[byte:_[0-9]+]]: u8;
+    // CHECK: [[unit:_[0-9]+]]: ();
+    // CHECK: [[str:_[0-9]+]]: &str;
+    // CHECK: [[opt_isize:_[0-9]+]]: std::option::Option<isize>;
+
+    // CHECK: bb0: {
+    // CHECK: [[byte]] = ([[external]].0
+    // CHECK: [[unit]] = ([[external]].1
+    // CHECK: [[str]] = ([[external]].2
+    // CHECK: [[opt_isize]] = ([[external]].3
+
     let y = x;
     let t = y.a;
     let u = y.c;
@@ -87,13 +168,44 @@ fn copies(x: Foo) {
     let a = z.b;
 }
 
+/// Check that copies from an internal struct are destructured and reassigned to
+/// the original struct.
 fn ref_copies(x: &Foo) {
+    // CHECK-LABEL: fn ref_copies(
+
+    // CHECK: [[external:_[0-9]+]]: &Foo) ->
+    // CHECK: [[internal:_[0-9]+]]: Foo;
+    // CHECK: [[byte:_[0-9]+]]: u8;
+    // CHECK: [[unit:_[0-9]+]]: ();
+    // CHECK: [[str:_[0-9]+]]: &str;
+    // CHECK: [[opt_isize:_[0-9]+]]: std::option::Option<isize>;
+
+    // CHECK: bb0: {
+    // CHECK: [[byte]] = ((*[[external]]).0
+    // CHECK: [[unit]] = ((*[[external]]).1
+    // CHECK: [[str]] = ((*[[external]]).2
+    // CHECK: [[opt_isize]] = ((*[[external]]).3
+
     let y = *x;
     let t = y.a;
     let u = y.c;
 }
 
+/// Check that deaggregated assignments from constants are placed after the constant's
+/// assignment. Also check that copying field accesses from the copy of the constant are
+/// reassigned to copy from the constant.
 fn constant() {
+    // CHECK-LABEL: constant(
+
+    // CHECK: [[constant:_[0-9]+]]: (usize, u8);
+    // CHECK: [[t:_[0-9]+]]: usize;
+    // CHECK: [[u:_[0-9]+]]: u8;
+
+    // CHECK: bb0: {
+    // CHECK-NOT: [[constant]]
+    // CHECK: [[constant]] = const
+    // CHECK: [[t]] = move ([[constant]].0: usize)
+    // CHECK: [[u]] = move ([[constant]].1: u8)
     const U: (usize, u8) = (5, 9);
     let y = U;
     let t = y.0;
@@ -101,6 +213,7 @@ fn constant() {
 }
 
 fn main() {
+    // CHECK-LABEL: fn main(
     dropping();
     enums(5);
     structs(5.);
diff --git a/tests/mir-opt/unusual_item_types.rs b/tests/mir-opt/unusual_item_types.rs
index 49b663b4f82..fa6ba515473 100644
--- a/tests/mir-opt/unusual_item_types.rs
+++ b/tests/mir-opt/unusual_item_types.rs
@@ -23,7 +23,7 @@ enum E {
     V = 5,
 }
 
-fn main() {
+pub fn main() {
     let f = Test::X as fn(usize) -> Test;
 // EMIT_MIR core.ptr-drop_in_place.Vec_i32_.AddMovesForPackedDrops.before.mir
     let v = Vec::<i32>::new();
diff --git a/tests/rustdoc-ui/issues/issue-102986.stderr b/tests/rustdoc-ui/issues/issue-102986.stderr
index 996eb41c492..d91f93f394a 100644
--- a/tests/rustdoc-ui/issues/issue-102986.stderr
+++ b/tests/rustdoc-ui/issues/issue-102986.stderr
@@ -6,8 +6,8 @@ LL |     y: (typeof("hey"),),
    |
 help: consider replacing `typeof(...)` with an actual type
    |
-LL |     y: (&'static str,),
-   |         ~~~~~~~~~~~~
+LL |     y: (&str,),
+   |         ~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/rustdoc-ui/issues/issue-120444-1.rs b/tests/rustdoc-ui/issues/issue-120444-1.rs
new file mode 100644
index 00000000000..25d0111a7b7
--- /dev/null
+++ b/tests/rustdoc-ui/issues/issue-120444-1.rs
@@ -0,0 +1,17 @@
+// compile-flags: --document-private-items
+
+#![deny(rustdoc::redundant_explicit_links)]
+
+mod webdavfs {
+    pub struct A;
+    pub struct B;
+}
+
+/// [`Vfs`][crate::Vfs]
+pub use webdavfs::A;
+//~^^ error: redundant explicit link target
+
+/// [`Vfs`]
+pub use webdavfs::B;
+
+pub struct Vfs;
diff --git a/tests/rustdoc-ui/issues/issue-120444-1.stderr b/tests/rustdoc-ui/issues/issue-120444-1.stderr
new file mode 100644
index 00000000000..7bc56b4263f
--- /dev/null
+++ b/tests/rustdoc-ui/issues/issue-120444-1.stderr
@@ -0,0 +1,22 @@
+error: redundant explicit link target
+  --> $DIR/issue-120444-1.rs:10:13
+   |
+LL | /// [`Vfs`][crate::Vfs]
+   |      -----  ^^^^^^^^^^ explicit target is redundant
+   |      |
+   |      because label contains path that resolves to same destination
+   |
+   = note: when a link's destination is not specified,
+           the label is used to resolve intra-doc links
+note: the lint level is defined here
+  --> $DIR/issue-120444-1.rs:3:9
+   |
+LL | #![deny(rustdoc::redundant_explicit_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: remove explicit link target
+   |
+LL | /// [`Vfs`]
+   |     ~~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/rustdoc-ui/issues/issue-120444-2.rs b/tests/rustdoc-ui/issues/issue-120444-2.rs
new file mode 100644
index 00000000000..d13bf884624
--- /dev/null
+++ b/tests/rustdoc-ui/issues/issue-120444-2.rs
@@ -0,0 +1,17 @@
+// compile-flags: --document-private-items
+
+#![deny(rustdoc::redundant_explicit_links)]
+
+pub mod webdavfs {
+    pub struct A;
+    pub struct B;
+}
+
+/// [`Vfs`][crate::Vfs]
+pub use webdavfs::A;
+//~^^ error: redundant explicit link target
+
+/// [`Vfs`]
+pub use webdavfs::B;
+
+pub struct Vfs;
diff --git a/tests/rustdoc-ui/issues/issue-120444-2.stderr b/tests/rustdoc-ui/issues/issue-120444-2.stderr
new file mode 100644
index 00000000000..310bf08e2b5
--- /dev/null
+++ b/tests/rustdoc-ui/issues/issue-120444-2.stderr
@@ -0,0 +1,22 @@
+error: redundant explicit link target
+  --> $DIR/issue-120444-2.rs:10:13
+   |
+LL | /// [`Vfs`][crate::Vfs]
+   |      -----  ^^^^^^^^^^ explicit target is redundant
+   |      |
+   |      because label contains path that resolves to same destination
+   |
+   = note: when a link's destination is not specified,
+           the label is used to resolve intra-doc links
+note: the lint level is defined here
+  --> $DIR/issue-120444-2.rs:3:9
+   |
+LL | #![deny(rustdoc::redundant_explicit_links)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: remove explicit link target
+   |
+LL | /// [`Vfs`]
+   |     ~~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/rustdoc/jump-to-non-local-method.rs b/tests/rustdoc/jump-to-non-local-method.rs
new file mode 100644
index 00000000000..7767b92fbe5
--- /dev/null
+++ b/tests/rustdoc/jump-to-non-local-method.rs
@@ -0,0 +1,48 @@
+// compile-flags: -Zunstable-options --generate-link-to-definition
+
+#![crate_name = "foo"]
+
+// @has 'src/foo/jump-to-non-local-method.rs.html'
+
+// @has - '//a[@href="{{channel}}/core/sync/atomic/struct.AtomicIsize.html"]' 'std::sync::atomic::AtomicIsize'
+use std::sync::atomic::AtomicIsize;
+// @has - '//a[@href="{{channel}}/std/io/trait.Read.html"]' 'std::io::Read'
+use std::io::Read;
+// @has - '//a[@href="{{channel}}/std/io/index.html"]' 'std::io'
+use std::io;
+// @has - '//a[@href="{{channel}}/std/process/fn.exit.html"]' 'std::process::exit'
+use std::process::exit;
+use std::cmp::Ordering;
+use std::marker::PhantomData;
+
+pub fn bar2<T: Read>(readable: T) {
+    // @has - '//a[@href="{{channel}}/std/io/trait.Read.html#tymethod.read"]' 'read'
+    let _ = readable.read(&mut []);
+}
+
+pub fn bar() {
+    // @has - '//a[@href="{{channel}}/core/sync/atomic/struct.AtomicIsize.html#method.new"]' 'AtomicIsize::new'
+    let _ = AtomicIsize::new(0);
+    // @has - '//a[@href="#48"]' 'local_private'
+    local_private();
+}
+
+pub fn extern_call() {
+    // @has - '//a[@href="{{channel}}/std/process/fn.exit.html"]' 'exit'
+    exit(0);
+}
+
+pub fn macro_call() -> Result<(), ()> {
+    // @has - '//a[@href="{{channel}}/core/macro.try.html"]' 'try!'
+    try!(Err(()));
+    Ok(())
+}
+
+pub fn variant() {
+    // @has - '//a[@href="{{channel}}/core/cmp/enum.Ordering.html#variant.Less"]' 'Ordering::Less'
+    let _ = Ordering::Less;
+    // @has - '//a[@href="{{channel}}/core/marker/struct.PhantomData.html"]' 'PhantomData'
+    let _: PhantomData::<usize> = PhantomData;
+}
+
+fn local_private() {}
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.rs b/tests/ui-fulldeps/internal-lints/diagnostics.rs
index ab42d3b8c1e..5a2099865d6 100644
--- a/tests/ui-fulldeps/internal-lints/diagnostics.rs
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.rs
@@ -14,7 +14,7 @@ extern crate rustc_span;
 
 use rustc_errors::{
     AddToDiagnostic, Diagnostic, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, DiagCtxt,
-    IntoDiagnostic, Level, SubdiagnosticMessage,
+    IntoDiagnostic, Level, SubdiagnosticMessageOp,
 };
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::Span;
@@ -55,9 +55,7 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for TranslatableInIntoDiagn
 pub struct UntranslatableInAddToDiagnostic;
 
 impl AddToDiagnostic for UntranslatableInAddToDiagnostic {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F)
     {
         diag.note("untranslatable diagnostic");
         //~^ ERROR diagnostics should be created using translatable messages
@@ -67,10 +65,7 @@ impl AddToDiagnostic for UntranslatableInAddToDiagnostic {
 pub struct TranslatableInAddToDiagnostic;
 
 impl AddToDiagnostic for TranslatableInAddToDiagnostic {
-    fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
-    where
-        F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
-    {
+    fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
         diag.note(crate::fluent_generated::no_crate_note);
     }
 }
diff --git a/tests/ui-fulldeps/internal-lints/diagnostics.stderr b/tests/ui-fulldeps/internal-lints/diagnostics.stderr
index f70240ecf17..108b7c8ea9c 100644
--- a/tests/ui-fulldeps/internal-lints/diagnostics.stderr
+++ b/tests/ui-fulldeps/internal-lints/diagnostics.stderr
@@ -11,13 +11,13 @@ LL | #![deny(rustc::untranslatable_diagnostic)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostics should be created using translatable messages
-  --> $DIR/diagnostics.rs:62:14
+  --> $DIR/diagnostics.rs:60:14
    |
 LL |         diag.note("untranslatable diagnostic");
    |              ^^^^
 
 error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
-  --> $DIR/diagnostics.rs:79:21
+  --> $DIR/diagnostics.rs:74:21
    |
 LL |     let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
    |                     ^^^^^^^^^^
@@ -29,13 +29,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
-  --> $DIR/diagnostics.rs:82:21
+  --> $DIR/diagnostics.rs:77:21
    |
 LL |     let _diag = dcx.struct_err("untranslatable diagnostic");
    |                     ^^^^^^^^^^
 
 error: diagnostics should be created using translatable messages
-  --> $DIR/diagnostics.rs:82:21
+  --> $DIR/diagnostics.rs:77:21
    |
 LL |     let _diag = dcx.struct_err("untranslatable diagnostic");
    |                     ^^^^^^^^^^
diff --git a/tests/ui-fulldeps/rustc_encodable_hygiene.rs b/tests/ui-fulldeps/rustc_encodable_hygiene.rs
index bec7930d462..36c684a131e 100644
--- a/tests/ui-fulldeps/rustc_encodable_hygiene.rs
+++ b/tests/ui-fulldeps/rustc_encodable_hygiene.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(rustc_private)]
 
diff --git a/tests/ui/anon-params/anon-params-deprecated.fixed b/tests/ui/anon-params/anon-params-deprecated.fixed
index c09e2077084..8ec1d41a709 100644
--- a/tests/ui/anon-params/anon-params-deprecated.fixed
+++ b/tests/ui/anon-params/anon-params-deprecated.fixed
@@ -5,6 +5,7 @@
 // edition:2015
 // run-rustfix
 
+#[allow(dead_code)]
 trait T {
     fn foo(_: i32); //~ WARNING anonymous parameters are deprecated
                  //~| WARNING this is accepted in the current edition
diff --git a/tests/ui/anon-params/anon-params-deprecated.rs b/tests/ui/anon-params/anon-params-deprecated.rs
index 6f7385da040..108ba60a02f 100644
--- a/tests/ui/anon-params/anon-params-deprecated.rs
+++ b/tests/ui/anon-params/anon-params-deprecated.rs
@@ -5,6 +5,7 @@
 // edition:2015
 // run-rustfix
 
+#[allow(dead_code)]
 trait T {
     fn foo(i32); //~ WARNING anonymous parameters are deprecated
                  //~| WARNING this is accepted in the current edition
diff --git a/tests/ui/anon-params/anon-params-deprecated.stderr b/tests/ui/anon-params/anon-params-deprecated.stderr
index 691e2c79512..541cb004b5b 100644
--- a/tests/ui/anon-params/anon-params-deprecated.stderr
+++ b/tests/ui/anon-params/anon-params-deprecated.stderr
@@ -1,5 +1,5 @@
 warning: anonymous parameters are deprecated and will be removed in the next edition
-  --> $DIR/anon-params-deprecated.rs:9:12
+  --> $DIR/anon-params-deprecated.rs:10:12
    |
 LL |     fn foo(i32);
    |            ^^^ help: try naming the parameter or explicitly ignoring it: `_: i32`
@@ -13,7 +13,7 @@ LL | #![warn(anonymous_parameters)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 warning: anonymous parameters are deprecated and will be removed in the next edition
-  --> $DIR/anon-params-deprecated.rs:12:30
+  --> $DIR/anon-params-deprecated.rs:13:30
    |
 LL |     fn bar_with_default_impl(String, String) {}
    |                              ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String`
@@ -22,7 +22,7 @@ LL |     fn bar_with_default_impl(String, String) {}
    = note: for more information, see issue #41686 <https://github.com/rust-lang/rust/issues/41686>
 
 warning: anonymous parameters are deprecated and will be removed in the next edition
-  --> $DIR/anon-params-deprecated.rs:12:38
+  --> $DIR/anon-params-deprecated.rs:13:38
    |
 LL |     fn bar_with_default_impl(String, String) {}
    |                                      ^^^^^^ help: try naming the parameter or explicitly ignoring it: `_: String`
diff --git a/tests/ui/asm/bad-template.aarch64.stderr b/tests/ui/asm/bad-template.aarch64.stderr
index 4ffcd2303b7..b18946d7c6d 100644
--- a/tests/ui/asm/bad-template.aarch64.stderr
+++ b/tests/ui/asm/bad-template.aarch64.stderr
@@ -1,5 +1,5 @@
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:27:15
+  --> $DIR/bad-template.rs:30:15
    |
 LL |         asm!("{}");
    |               ^^ from here
@@ -7,7 +7,7 @@ LL |         asm!("{}");
    = note: no arguments were given
 
 error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:29:15
+  --> $DIR/bad-template.rs:32:15
    |
 LL |         asm!("{1}", in(reg) foo);
    |               ^^^ from here
@@ -15,7 +15,7 @@ LL |         asm!("{1}", in(reg) foo);
    = note: there is 1 argument
 
 error: argument never used
-  --> $DIR/bad-template.rs:29:21
+  --> $DIR/bad-template.rs:32:21
    |
 LL |         asm!("{1}", in(reg) foo);
    |                     ^^^^^^^^^^^ argument never used
@@ -23,13 +23,13 @@ LL |         asm!("{1}", in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:32:16
+  --> $DIR/bad-template.rs:35:16
    |
 LL |         asm!("{a}");
    |                ^
 
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:34:15
+  --> $DIR/bad-template.rs:37:15
    |
 LL |         asm!("{}", a = in(reg) foo);
    |               ^^   --------------- named argument
@@ -38,13 +38,13 @@ LL |         asm!("{}", a = in(reg) foo);
    |
    = note: no positional arguments were given
 note: named arguments cannot be referenced by position
-  --> $DIR/bad-template.rs:34:20
+  --> $DIR/bad-template.rs:37:20
    |
 LL |         asm!("{}", a = in(reg) foo);
    |                    ^^^^^^^^^^^^^^^
 
 error: named argument never used
-  --> $DIR/bad-template.rs:34:20
+  --> $DIR/bad-template.rs:37:20
    |
 LL |         asm!("{}", a = in(reg) foo);
    |                    ^^^^^^^^^^^^^^^ named argument never used
@@ -52,7 +52,7 @@ LL |         asm!("{}", a = in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
 
 error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:37:15
+  --> $DIR/bad-template.rs:40:15
    |
 LL |         asm!("{1}", a = in(reg) foo);
    |               ^^^ from here
@@ -60,7 +60,7 @@ LL |         asm!("{1}", a = in(reg) foo);
    = note: no positional arguments were given
 
 error: named argument never used
-  --> $DIR/bad-template.rs:37:21
+  --> $DIR/bad-template.rs:40:21
    |
 LL |         asm!("{1}", a = in(reg) foo);
    |                     ^^^^^^^^^^^^^^^ named argument never used
@@ -68,7 +68,7 @@ LL |         asm!("{1}", a = in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
 
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:44:15
+  --> $DIR/bad-template.rs:47:15
    |
 LL |         asm!("{}", in("x0") foo);
    |               ^^   ------------ explicit register argument
@@ -77,24 +77,24 @@ LL |         asm!("{}", in("x0") foo);
    |
    = note: no positional arguments were given
 note: explicit register arguments cannot be used in the asm template
-  --> $DIR/bad-template.rs:44:20
+  --> $DIR/bad-template.rs:47:20
    |
 LL |         asm!("{}", in("x0") foo);
    |                    ^^^^^^^^^^^^
 help: use the register name directly in the assembly code
-  --> $DIR/bad-template.rs:44:20
+  --> $DIR/bad-template.rs:47:20
    |
 LL |         asm!("{}", in("x0") foo);
    |                    ^^^^^^^^^^^^
 
 error: asm template modifier must be a single character
-  --> $DIR/bad-template.rs:46:17
+  --> $DIR/bad-template.rs:49:17
    |
 LL |         asm!("{:foo}", in(reg) foo);
    |                 ^^^
 
 error: multiple unused asm arguments
-  --> $DIR/bad-template.rs:49:18
+  --> $DIR/bad-template.rs:52:18
    |
 LL |         asm!("", in(reg) 0, in(reg) 1);
    |                  ^^^^^^^^^  ^^^^^^^^^ argument never used
@@ -104,7 +104,7 @@ LL |         asm!("", in(reg) 0, in(reg) 1);
    = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
 
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:55:14
+  --> $DIR/bad-template.rs:58:14
    |
 LL | global_asm!("{}");
    |              ^^ from here
@@ -112,7 +112,7 @@ LL | global_asm!("{}");
    = note: no arguments were given
 
 error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:57:14
+  --> $DIR/bad-template.rs:60:14
    |
 LL | global_asm!("{1}", const FOO);
    |              ^^^ from here
@@ -120,7 +120,7 @@ LL | global_asm!("{1}", const FOO);
    = note: there is 1 argument
 
 error: argument never used
-  --> $DIR/bad-template.rs:57:20
+  --> $DIR/bad-template.rs:60:20
    |
 LL | global_asm!("{1}", const FOO);
    |                    ^^^^^^^^^ argument never used
@@ -128,13 +128,13 @@ LL | global_asm!("{1}", const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:60:15
+  --> $DIR/bad-template.rs:63:15
    |
 LL | global_asm!("{a}");
    |               ^
 
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:62:14
+  --> $DIR/bad-template.rs:65:14
    |
 LL | global_asm!("{}", a = const FOO);
    |              ^^   ------------- named argument
@@ -143,13 +143,13 @@ LL | global_asm!("{}", a = const FOO);
    |
    = note: no positional arguments were given
 note: named arguments cannot be referenced by position
-  --> $DIR/bad-template.rs:62:19
+  --> $DIR/bad-template.rs:65:19
    |
 LL | global_asm!("{}", a = const FOO);
    |                   ^^^^^^^^^^^^^
 
 error: named argument never used
-  --> $DIR/bad-template.rs:62:19
+  --> $DIR/bad-template.rs:65:19
    |
 LL | global_asm!("{}", a = const FOO);
    |                   ^^^^^^^^^^^^^ named argument never used
@@ -157,7 +157,7 @@ LL | global_asm!("{}", a = const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
 
 error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:65:14
+  --> $DIR/bad-template.rs:68:14
    |
 LL | global_asm!("{1}", a = const FOO);
    |              ^^^ from here
@@ -165,7 +165,7 @@ LL | global_asm!("{1}", a = const FOO);
    = note: no positional arguments were given
 
 error: named argument never used
-  --> $DIR/bad-template.rs:65:20
+  --> $DIR/bad-template.rs:68:20
    |
 LL | global_asm!("{1}", a = const FOO);
    |                    ^^^^^^^^^^^^^ named argument never used
@@ -173,13 +173,13 @@ LL | global_asm!("{1}", a = const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
 
 error: asm template modifier must be a single character
-  --> $DIR/bad-template.rs:68:16
+  --> $DIR/bad-template.rs:71:16
    |
 LL | global_asm!("{:foo}", const FOO);
    |                ^^^
 
 error: multiple unused asm arguments
-  --> $DIR/bad-template.rs:70:17
+  --> $DIR/bad-template.rs:73:17
    |
 LL | global_asm!("", const FOO, const FOO);
    |                 ^^^^^^^^^  ^^^^^^^^^ argument never used
@@ -189,7 +189,7 @@ LL | global_asm!("", const FOO, const FOO);
    = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/bad-template.rs:46:15
+  --> $DIR/bad-template.rs:49:15
    |
 LL |         asm!("{:foo}", in(reg) foo);
    |               ^^^^^^           --- for this argument
diff --git a/tests/ui/asm/bad-template.rs b/tests/ui/asm/bad-template.rs
index a6a233a36ec..b70da4921c2 100644
--- a/tests/ui/asm/bad-template.rs
+++ b/tests/ui/asm/bad-template.rs
@@ -21,6 +21,9 @@ macro_rules! global_asm {
 #[lang = "sized"]
 trait Sized {}
 
+#[lang = "copy"]
+trait Copy {}
+
 fn main() {
     let mut foo = 0;
     unsafe {
diff --git a/tests/ui/asm/bad-template.x86_64.stderr b/tests/ui/asm/bad-template.x86_64.stderr
index 52a7789b98c..2f584c30a32 100644
--- a/tests/ui/asm/bad-template.x86_64.stderr
+++ b/tests/ui/asm/bad-template.x86_64.stderr
@@ -1,5 +1,5 @@
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:27:15
+  --> $DIR/bad-template.rs:30:15
    |
 LL |         asm!("{}");
    |               ^^ from here
@@ -7,7 +7,7 @@ LL |         asm!("{}");
    = note: no arguments were given
 
 error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:29:15
+  --> $DIR/bad-template.rs:32:15
    |
 LL |         asm!("{1}", in(reg) foo);
    |               ^^^ from here
@@ -15,7 +15,7 @@ LL |         asm!("{1}", in(reg) foo);
    = note: there is 1 argument
 
 error: argument never used
-  --> $DIR/bad-template.rs:29:21
+  --> $DIR/bad-template.rs:32:21
    |
 LL |         asm!("{1}", in(reg) foo);
    |                     ^^^^^^^^^^^ argument never used
@@ -23,13 +23,13 @@ LL |         asm!("{1}", in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:32:16
+  --> $DIR/bad-template.rs:35:16
    |
 LL |         asm!("{a}");
    |                ^
 
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:34:15
+  --> $DIR/bad-template.rs:37:15
    |
 LL |         asm!("{}", a = in(reg) foo);
    |               ^^   --------------- named argument
@@ -38,13 +38,13 @@ LL |         asm!("{}", a = in(reg) foo);
    |
    = note: no positional arguments were given
 note: named arguments cannot be referenced by position
-  --> $DIR/bad-template.rs:34:20
+  --> $DIR/bad-template.rs:37:20
    |
 LL |         asm!("{}", a = in(reg) foo);
    |                    ^^^^^^^^^^^^^^^
 
 error: named argument never used
-  --> $DIR/bad-template.rs:34:20
+  --> $DIR/bad-template.rs:37:20
    |
 LL |         asm!("{}", a = in(reg) foo);
    |                    ^^^^^^^^^^^^^^^ named argument never used
@@ -52,7 +52,7 @@ LL |         asm!("{}", a = in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
 
 error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:37:15
+  --> $DIR/bad-template.rs:40:15
    |
 LL |         asm!("{1}", a = in(reg) foo);
    |               ^^^ from here
@@ -60,7 +60,7 @@ LL |         asm!("{1}", a = in(reg) foo);
    = note: no positional arguments were given
 
 error: named argument never used
-  --> $DIR/bad-template.rs:37:21
+  --> $DIR/bad-template.rs:40:21
    |
 LL |         asm!("{1}", a = in(reg) foo);
    |                     ^^^^^^^^^^^^^^^ named argument never used
@@ -68,7 +68,7 @@ LL |         asm!("{1}", a = in(reg) foo);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
 
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:41:15
+  --> $DIR/bad-template.rs:44:15
    |
 LL |         asm!("{}", in("eax") foo);
    |               ^^   ------------- explicit register argument
@@ -77,24 +77,24 @@ LL |         asm!("{}", in("eax") foo);
    |
    = note: no positional arguments were given
 note: explicit register arguments cannot be used in the asm template
-  --> $DIR/bad-template.rs:41:20
+  --> $DIR/bad-template.rs:44:20
    |
 LL |         asm!("{}", in("eax") foo);
    |                    ^^^^^^^^^^^^^
 help: use the register name directly in the assembly code
-  --> $DIR/bad-template.rs:41:20
+  --> $DIR/bad-template.rs:44:20
    |
 LL |         asm!("{}", in("eax") foo);
    |                    ^^^^^^^^^^^^^
 
 error: asm template modifier must be a single character
-  --> $DIR/bad-template.rs:46:17
+  --> $DIR/bad-template.rs:49:17
    |
 LL |         asm!("{:foo}", in(reg) foo);
    |                 ^^^
 
 error: multiple unused asm arguments
-  --> $DIR/bad-template.rs:49:18
+  --> $DIR/bad-template.rs:52:18
    |
 LL |         asm!("", in(reg) 0, in(reg) 1);
    |                  ^^^^^^^^^  ^^^^^^^^^ argument never used
@@ -104,7 +104,7 @@ LL |         asm!("", in(reg) 0, in(reg) 1);
    = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
 
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:55:14
+  --> $DIR/bad-template.rs:58:14
    |
 LL | global_asm!("{}");
    |              ^^ from here
@@ -112,7 +112,7 @@ LL | global_asm!("{}");
    = note: no arguments were given
 
 error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:57:14
+  --> $DIR/bad-template.rs:60:14
    |
 LL | global_asm!("{1}", const FOO);
    |              ^^^ from here
@@ -120,7 +120,7 @@ LL | global_asm!("{1}", const FOO);
    = note: there is 1 argument
 
 error: argument never used
-  --> $DIR/bad-template.rs:57:20
+  --> $DIR/bad-template.rs:60:20
    |
 LL | global_asm!("{1}", const FOO);
    |                    ^^^^^^^^^ argument never used
@@ -128,13 +128,13 @@ LL | global_asm!("{1}", const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {0} */"`
 
 error: there is no argument named `a`
-  --> $DIR/bad-template.rs:60:15
+  --> $DIR/bad-template.rs:63:15
    |
 LL | global_asm!("{a}");
    |               ^
 
 error: invalid reference to argument at index 0
-  --> $DIR/bad-template.rs:62:14
+  --> $DIR/bad-template.rs:65:14
    |
 LL | global_asm!("{}", a = const FOO);
    |              ^^   ------------- named argument
@@ -143,13 +143,13 @@ LL | global_asm!("{}", a = const FOO);
    |
    = note: no positional arguments were given
 note: named arguments cannot be referenced by position
-  --> $DIR/bad-template.rs:62:19
+  --> $DIR/bad-template.rs:65:19
    |
 LL | global_asm!("{}", a = const FOO);
    |                   ^^^^^^^^^^^^^
 
 error: named argument never used
-  --> $DIR/bad-template.rs:62:19
+  --> $DIR/bad-template.rs:65:19
    |
 LL | global_asm!("{}", a = const FOO);
    |                   ^^^^^^^^^^^^^ named argument never used
@@ -157,7 +157,7 @@ LL | global_asm!("{}", a = const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
 
 error: invalid reference to argument at index 1
-  --> $DIR/bad-template.rs:65:14
+  --> $DIR/bad-template.rs:68:14
    |
 LL | global_asm!("{1}", a = const FOO);
    |              ^^^ from here
@@ -165,7 +165,7 @@ LL | global_asm!("{1}", a = const FOO);
    = note: no positional arguments were given
 
 error: named argument never used
-  --> $DIR/bad-template.rs:65:20
+  --> $DIR/bad-template.rs:68:20
    |
 LL | global_asm!("{1}", a = const FOO);
    |                    ^^^^^^^^^^^^^ named argument never used
@@ -173,13 +173,13 @@ LL | global_asm!("{1}", a = const FOO);
    = help: if this argument is intentionally unused, consider using it in an asm comment: `"/* {a} */"`
 
 error: asm template modifier must be a single character
-  --> $DIR/bad-template.rs:68:16
+  --> $DIR/bad-template.rs:71:16
    |
 LL | global_asm!("{:foo}", const FOO);
    |                ^^^
 
 error: multiple unused asm arguments
-  --> $DIR/bad-template.rs:70:17
+  --> $DIR/bad-template.rs:73:17
    |
 LL | global_asm!("", const FOO, const FOO);
    |                 ^^^^^^^^^  ^^^^^^^^^ argument never used
@@ -189,7 +189,7 @@ LL | global_asm!("", const FOO, const FOO);
    = help: if these arguments are intentionally unused, consider using them in an asm comment: `"/* {0} {1} */"`
 
 warning: formatting may not be suitable for sub-register argument
-  --> $DIR/bad-template.rs:46:15
+  --> $DIR/bad-template.rs:49:15
    |
 LL |         asm!("{:foo}", in(reg) foo);
    |               ^^^^^^           --- for this argument
diff --git a/tests/ui/asm/naked-functions.rs b/tests/ui/asm/naked-functions.rs
index 2f3716ca77f..b18d01730f2 100644
--- a/tests/ui/asm/naked-functions.rs
+++ b/tests/ui/asm/naked-functions.rs
@@ -81,13 +81,15 @@ pub extern "C" fn missing_assembly() {
 #[naked]
 pub extern "C" fn too_many_asm_blocks() {
     //~^ ERROR naked functions must contain a single asm block
-    asm!("");
-    //~^ ERROR asm in naked functions must use `noreturn` option
-    asm!("");
-    //~^ ERROR asm in naked functions must use `noreturn` option
-    asm!("");
-    //~^ ERROR asm in naked functions must use `noreturn` option
-    asm!("", options(noreturn));
+    unsafe {
+        asm!("");
+        //~^ ERROR asm in naked functions must use `noreturn` option
+        asm!("");
+        //~^ ERROR asm in naked functions must use `noreturn` option
+        asm!("");
+        //~^ ERROR asm in naked functions must use `noreturn` option
+        asm!("", options(noreturn));
+    }
 }
 
 pub fn outer(x: u32) -> extern "C" fn(usize) -> usize {
diff --git a/tests/ui/asm/naked-functions.stderr b/tests/ui/asm/naked-functions.stderr
index f90967fbe6e..6613c3dfdba 100644
--- a/tests/ui/asm/naked-functions.stderr
+++ b/tests/ui/asm/naked-functions.stderr
@@ -1,23 +1,23 @@
 error: asm with the `pure` option must have at least one output
-  --> $DIR/naked-functions.rs:111:14
+  --> $DIR/naked-functions.rs:113:14
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:203:5
+  --> $DIR/naked-functions.rs:205:5
    |
 LL |     compile_error!("this is a user specified error")
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this is a user specified error
-  --> $DIR/naked-functions.rs:209:5
+  --> $DIR/naked-functions.rs:211:5
    |
 LL |     compile_error!("this is a user specified error");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: asm template must be a string literal
-  --> $DIR/naked-functions.rs:216:10
+  --> $DIR/naked-functions.rs:218:10
    |
 LL |     asm!(invalid_syntax)
    |          ^^^^^^^^^^^^^^
@@ -142,37 +142,37 @@ LL | pub extern "C" fn missing_assembly() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:84:5
+  --> $DIR/naked-functions.rs:85:9
    |
-LL |     asm!("");
-   |     ^^^^^^^^
+LL |         asm!("");
+   |         ^^^^^^^^
    |
 help: consider specifying that the asm block is responsible for returning from the function
    |
-LL |     asm!("", options(noreturn));
-   |            +++++++++++++++++++
+LL |         asm!("", options(noreturn));
+   |                +++++++++++++++++++
 
 error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:86:5
+  --> $DIR/naked-functions.rs:87:9
    |
-LL |     asm!("");
-   |     ^^^^^^^^
+LL |         asm!("");
+   |         ^^^^^^^^
    |
 help: consider specifying that the asm block is responsible for returning from the function
    |
-LL |     asm!("", options(noreturn));
-   |            +++++++++++++++++++
+LL |         asm!("", options(noreturn));
+   |                +++++++++++++++++++
 
 error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:88:5
+  --> $DIR/naked-functions.rs:89:9
    |
-LL |     asm!("");
-   |     ^^^^^^^^
+LL |         asm!("");
+   |         ^^^^^^^^
    |
 help: consider specifying that the asm block is responsible for returning from the function
    |
-LL |     asm!("", options(noreturn));
-   |            +++++++++++++++++++
+LL |         asm!("", options(noreturn));
+   |                +++++++++++++++++++
 
 error[E0787]: naked functions must contain a single asm block
   --> $DIR/naked-functions.rs:82:1
@@ -180,17 +180,17 @@ error[E0787]: naked functions must contain a single asm block
 LL | pub extern "C" fn too_many_asm_blocks() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 ...
-LL |     asm!("");
-   |     -------- multiple asm blocks are unsupported in naked functions
+LL |         asm!("");
+   |         -------- multiple asm blocks are unsupported in naked functions
 LL |
-LL |     asm!("");
-   |     -------- multiple asm blocks are unsupported in naked functions
+LL |         asm!("");
+   |         -------- multiple asm blocks are unsupported in naked functions
 LL |
-LL |     asm!("", options(noreturn));
-   |     --------------------------- multiple asm blocks are unsupported in naked functions
+LL |         asm!("", options(noreturn));
+   |         --------------------------- multiple asm blocks are unsupported in naked functions
 
 error: referencing function parameters is not allowed in naked functions
-  --> $DIR/naked-functions.rs:97:11
+  --> $DIR/naked-functions.rs:99:11
    |
 LL |         *&y
    |           ^
@@ -198,7 +198,7 @@ LL |         *&y
    = help: follow the calling convention in asm block to use parameters
 
 error[E0787]: naked functions must contain a single asm block
-  --> $DIR/naked-functions.rs:95:5
+  --> $DIR/naked-functions.rs:97:5
    |
 LL |     pub extern "C" fn inner(y: usize) -> usize {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -207,19 +207,19 @@ LL |         *&y
    |         --- non-asm is unsupported in naked functions
 
 error[E0787]: asm options unsupported in naked functions: `nomem`, `preserves_flags`
-  --> $DIR/naked-functions.rs:105:5
+  --> $DIR/naked-functions.rs:107:5
    |
 LL |     asm!("", options(nomem, preserves_flags, noreturn));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0787]: asm options unsupported in naked functions: `nostack`, `pure`, `readonly`
-  --> $DIR/naked-functions.rs:111:5
+  --> $DIR/naked-functions.rs:113:5
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0787]: asm in naked functions must use `noreturn` option
-  --> $DIR/naked-functions.rs:111:5
+  --> $DIR/naked-functions.rs:113:5
    |
 LL |     asm!("", options(readonly, nostack), options(pure));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -230,13 +230,13 @@ LL |     asm!("", options(noreturn), options(readonly, nostack), options(pure));
    |            +++++++++++++++++++
 
 error[E0787]: asm options unsupported in naked functions: `may_unwind`
-  --> $DIR/naked-functions.rs:119:5
+  --> $DIR/naked-functions.rs:121:5
    |
 LL |     asm!("", options(noreturn, may_unwind));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:124:1
+  --> $DIR/naked-functions.rs:126:1
    |
 LL | pub unsafe fn default_abi() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -244,43 +244,43 @@ LL | pub unsafe fn default_abi() {
    = note: `#[warn(undefined_naked_function_abi)]` on by default
 
 warning: Rust ABI is unsupported in naked functions
-  --> $DIR/naked-functions.rs:130:1
+  --> $DIR/naked-functions.rs:132:1
    |
 LL | pub unsafe fn rust_abi() {
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:170:1
+  --> $DIR/naked-functions.rs:172:1
    |
 LL | #[inline]
    | ^^^^^^^^^
 
 error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:177:1
+  --> $DIR/naked-functions.rs:179:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
 
 error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:184:1
+  --> $DIR/naked-functions.rs:186:1
    |
 LL | #[inline(never)]
    | ^^^^^^^^^^^^^^^^
 
 error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:191:1
+  --> $DIR/naked-functions.rs:193:1
    |
 LL | #[inline]
    | ^^^^^^^^^
 
 error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:193:1
+  --> $DIR/naked-functions.rs:195:1
    |
 LL | #[inline(always)]
    | ^^^^^^^^^^^^^^^^^
 
 error: naked functions cannot be inlined
-  --> $DIR/naked-functions.rs:195:1
+  --> $DIR/naked-functions.rs:197:1
    |
 LL | #[inline(never)]
    | ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/associated-consts/associated-const-outer-ty-refs.rs b/tests/ui/associated-consts/associated-const-outer-ty-refs.rs
index f32ca0cccfc..d5e9a2bde00 100644
--- a/tests/ui/associated-consts/associated-const-outer-ty-refs.rs
+++ b/tests/ui/associated-consts/associated-const-outer-ty-refs.rs
@@ -1,4 +1,5 @@
-// run-pass
+// check-pass
+
 trait Lattice {
     const BOTTOM: Self;
 }
diff --git a/tests/ui/associated-consts/associated-const-type-parameters.rs b/tests/ui/associated-consts/associated-const-type-parameters.rs
index b62d47458be..a233b09ff89 100644
--- a/tests/ui/associated-consts/associated-const-type-parameters.rs
+++ b/tests/ui/associated-consts/associated-const-type-parameters.rs
@@ -27,7 +27,7 @@ fn sub<A: Foo, B: Foo>() -> i32 {
     A::X - B::X
 }
 
-trait Bar: Foo {
+trait Bar: Foo { //~ WARN trait `Bar` is never used
     const Y: i32 = Self::X;
 }
 
diff --git a/tests/ui/associated-consts/associated-const-type-parameters.stderr b/tests/ui/associated-consts/associated-const-type-parameters.stderr
new file mode 100644
index 00000000000..6ee2a5de1b6
--- /dev/null
+++ b/tests/ui/associated-consts/associated-const-type-parameters.stderr
@@ -0,0 +1,10 @@
+warning: trait `Bar` is never used
+  --> $DIR/associated-const-type-parameters.rs:30:7
+   |
+LL | trait Bar: Foo {
+   |       ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-consts/issue-105330.rs b/tests/ui/associated-consts/issue-105330.rs
index 285e89cce49..6c6dae864f3 100644
--- a/tests/ui/associated-consts/issue-105330.rs
+++ b/tests/ui/associated-consts/issue-105330.rs
@@ -14,5 +14,6 @@ fn foo<A: TraitWAssocConst<A=32>>() { //~ ERROR E0658
 
 fn main<A: TraitWAssocConst<A=32>>() {
     //~^ ERROR E0658
+    //~| ERROR E0131
     foo::<Demo>();
 }
diff --git a/tests/ui/associated-consts/issue-105330.stderr b/tests/ui/associated-consts/issue-105330.stderr
index 452367bed12..b4c021d0f4f 100644
--- a/tests/ui/associated-consts/issue-105330.stderr
+++ b/tests/ui/associated-consts/issue-105330.stderr
@@ -43,7 +43,13 @@ LL | impl TraitWAssocConst for impl Demo {
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
-error: aborting due to 5 previous errors
+error[E0131]: `main` function is not allowed to have generic parameters
+  --> $DIR/issue-105330.rs:15:8
+   |
+LL | fn main<A: TraitWAssocConst<A=32>>() {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `main` cannot have generic parameters
+
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0404, E0562, E0658.
-For more information about an error, try `rustc --explain E0404`.
+Some errors have detailed explanations: E0131, E0404, E0562, E0658.
+For more information about an error, try `rustc --explain E0131`.
diff --git a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs
index d180de9be3b..1c48aadecce 100644
--- a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs
+++ b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs
@@ -1,5 +1,4 @@
-// NOTE: rustc cannot currently handle bounds of the form `for<'a> <Foo as Bar<'a>>::Assoc: Baz`.
-// This should hopefully be fixed with Chalk.
+// check-pass
 
 #![feature(associated_type_bounds)]
 
@@ -24,9 +23,6 @@ impl<'a, 'b> Lam<&'a &'b u8> for L2 {
 
 trait Case1 {
     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
-    //~^ ERROR `<<Self as Case1>::C as Iterator>::Item` is not an iterator
-    //~| ERROR `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
-    //~| ERROR `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
 }
 
 pub struct S1;
@@ -35,33 +31,17 @@ impl Case1 for S1 {
 }
 
 fn assume_case1<T: Case1>() {
-    fn assert_a<_0, A>()
-    where
-        A: Iterator<Item = _0>,
-        _0: Debug,
-    {
-    }
-    assert_a::<_, T::A>();
-
-    fn assert_b<_0, B>()
-    where
-        B: Iterator<Item = _0>,
-        _0: 'static,
-    {
-    }
-    assert_b::<_, T::B>();
-
-    fn assert_c<_0, _1, _2, C>()
+    fn assert_c<_1, _2, C>()
     where
         C: Clone + Iterator<Item = _2>,
         _2: Send + Iterator<Item = _1>,
-        _1: for<'a> Lam<&'a u8, App = _0>,
-        _0: Debug,
+        _1: for<'a> Lam<&'a u8>,
+        for<'a> <_1 as Lam<&'a u8>>::App: Debug,
     {
     }
-    assert_c::<_, _, _, T::C>();
+    assert_c::<_, _, T::C>();
 }
 
 fn main() {
-    assume_case1(S1);
+    assume_case1::<S1>();
 }
diff --git a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
deleted file mode 100644
index c23e54594ee..00000000000
--- a/tests/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr
+++ /dev/null
@@ -1,39 +0,0 @@
-error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:36
-   |
-LL |     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
-   |                                    ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be sent between threads safely
-   |
-   = help: the trait `Send` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Send {
-   |             ++++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: `<<Self as Case1>::C as Iterator>::Item` is not an iterator
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:43
-   |
-LL |     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
-   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `<<Self as Case1>::C as Iterator>::Item` is not an iterator
-   |
-   = help: the trait `Iterator` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Iterator {
-   |             ++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
-  --> $DIR/bad-bounds-on-assoc-in-trait.rs:26:93
-   |
-LL |     type C: Clone + Iterator<Item: Send + Iterator<Item: for<'a> Lam<&'a u8, App: Debug>> + Sync>;
-   |                                                                                             ^^^^ `<<Self as Case1>::C as Iterator>::Item` cannot be shared between threads safely
-   |
-   = help: the trait `Sync` is not implemented for `<<Self as Case1>::C as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait Case1 where <<Self as Case1>::C as Iterator>::Item: Sync {
-   |             ++++++++++++++++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs
index 23be735010b..7bc2970ade9 100644
--- a/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs
+++ b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs
@@ -1,3 +1,5 @@
+// check-pass
+
 #![feature(associated_type_bounds)]
 
 use std::fmt::Debug;
@@ -16,8 +18,6 @@ impl<'a, 'b> Lam<&'a &'b u8> for L2 { type App = u8; }
 
 trait Case1 {
     type A: Iterator<Item: Debug>;
-    //~^ ERROR `<<Self as Case1>::A as Iterator>::Item` doesn't implement `Debug`
-
     type B: Iterator<Item: 'static>;
 }
 
@@ -33,7 +33,6 @@ impl Case1 for S1 {
 // bounds of `Out`, but trait selection can't find the bound since it applies
 // to a type other than `Self::Out`.
 pub trait Foo { type Out: Baz<Assoc: Default>; }
-//~^ ERROR trait bound `<<Self as Foo>::Out as Baz>::Assoc: Default` is not satisfied
 pub trait Baz { type Assoc; }
 
 #[derive(Default)]
diff --git a/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr b/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr
deleted file mode 100644
index 4e2313bd4e4..00000000000
--- a/tests/ui/associated-type-bounds/bounds-on-assoc-in-trait.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error[E0277]: `<<Self as Case1>::A as Iterator>::Item` doesn't implement `Debug`
-  --> $DIR/bounds-on-assoc-in-trait.rs:18:28
-   |
-LL |     type A: Iterator<Item: Debug>;
-   |                            ^^^^^ `<<Self as Case1>::A as Iterator>::Item` cannot be formatted using `{:?}` because it doesn't implement `Debug`
-   |
-   = help: the trait `Debug` is not implemented for `<<Self as Case1>::A as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait Case1 where <<Self as Case1>::A as Iterator>::Item: Debug {
-   |             +++++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: the trait bound `<<Self as Foo>::Out as Baz>::Assoc: Default` is not satisfied
-  --> $DIR/bounds-on-assoc-in-trait.rs:35:38
-   |
-LL | pub trait Foo { type Out: Baz<Assoc: Default>; }
-   |                                      ^^^^^^^ the trait `Default` is not implemented for `<<Self as Foo>::Out as Baz>::Assoc`
-   |
-help: consider further restricting the associated type
-   |
-LL | pub trait Foo where <<Self as Foo>::Out as Baz>::Assoc: Default { type Out: Baz<Assoc: Default>; }
-   |               +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/associated-type-bounds/duplicate.rs b/tests/ui/associated-type-bounds/duplicate.rs
index 160b524c881..036f8ede1b3 100644
--- a/tests/ui/associated-type-bounds/duplicate.rs
+++ b/tests/ui/associated-type-bounds/duplicate.rs
@@ -251,13 +251,10 @@ where
 trait TRA1 {
     type A: Iterator<Item: Copy, Item: Send>;
     //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR `<<Self as TRA1>::A as Iterator>::Item` cannot be sent between threads safely
-    //~| ERROR the trait bound `<<Self as TRA1>::A as Iterator>::Item: Copy` is not satisfied
 }
 trait TRA2 {
     type A: Iterator<Item: Copy, Item: Copy>;
     //~^ ERROR the value of the associated type `Item` in trait `Iterator` is already specified [E0719]
-    //~| ERROR the trait bound `<<Self as TRA2>::A as Iterator>::Item: Copy` is not satisfied
 }
 trait TRA3 {
     type A: Iterator<Item: 'static, Item: 'static>;
diff --git a/tests/ui/associated-type-bounds/duplicate.stderr b/tests/ui/associated-type-bounds/duplicate.stderr
index accb366dd15..bf6aab96dc7 100644
--- a/tests/ui/associated-type-bounds/duplicate.stderr
+++ b/tests/ui/associated-type-bounds/duplicate.stderr
@@ -7,7 +7,7 @@ LL | struct SI1<T: Iterator<Item: Copy, Item: Send>> {
    |                        `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:267:40
+  --> $DIR/duplicate.rs:264:40
    |
 LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            ----------  ^^^^^^^^^^ re-bound here
@@ -15,7 +15,7 @@ LL | type TADyn1 = dyn Iterator<Item: Copy, Item: Send>;
    |                            `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:269:44
+  --> $DIR/duplicate.rs:266:44
    |
 LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                ----------  ^^^^^^^^^^ re-bound here
@@ -23,7 +23,7 @@ LL | type TADyn2 = Box<dyn Iterator<Item: Copy, Item: Copy>>;
    |                                `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:271:43
+  --> $DIR/duplicate.rs:268:43
    |
 LL | type TADyn3 = dyn Iterator<Item: 'static, Item: 'static>;
    |                            -------------  ^^^^^^^^^^^^^ re-bound here
@@ -523,7 +523,7 @@ LL |     type A: Iterator<Item: Copy, Item: Send>;
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:258:34
+  --> $DIR/duplicate.rs:256:34
    |
 LL |     type A: Iterator<Item: Copy, Item: Copy>;
    |                      ----------  ^^^^^^^^^^ re-bound here
@@ -531,7 +531,7 @@ LL |     type A: Iterator<Item: Copy, Item: Copy>;
    |                      `Item` bound here first
 
 error[E0719]: the value of the associated type `Item` in trait `Iterator` is already specified
-  --> $DIR/duplicate.rs:263:37
+  --> $DIR/duplicate.rs:260:37
    |
 LL |     type A: Iterator<Item: 'static, Item: 'static>;
    |                      -------------  ^^^^^^^^^^^^^ re-bound here
@@ -631,41 +631,7 @@ LL |     Self: Iterator<Item: 'static, Item: 'static>,
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error[E0277]: the trait bound `<<Self as TRA1>::A as Iterator>::Item: Copy` is not satisfied
-  --> $DIR/duplicate.rs:252:28
-   |
-LL |     type A: Iterator<Item: Copy, Item: Send>;
-   |                            ^^^^ the trait `Copy` is not implemented for `<<Self as TRA1>::A as Iterator>::Item`
-   |
-help: consider further restricting the associated type
-   |
-LL | trait TRA1 where <<Self as TRA1>::A as Iterator>::Item: Copy {
-   |            +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: `<<Self as TRA1>::A as Iterator>::Item` cannot be sent between threads safely
-  --> $DIR/duplicate.rs:252:40
-   |
-LL |     type A: Iterator<Item: Copy, Item: Send>;
-   |                                        ^^^^ `<<Self as TRA1>::A as Iterator>::Item` cannot be sent between threads safely
-   |
-   = help: the trait `Send` is not implemented for `<<Self as TRA1>::A as Iterator>::Item`
-help: consider further restricting the associated type
-   |
-LL | trait TRA1 where <<Self as TRA1>::A as Iterator>::Item: Send {
-   |            +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error[E0277]: the trait bound `<<Self as TRA2>::A as Iterator>::Item: Copy` is not satisfied
-  --> $DIR/duplicate.rs:258:28
-   |
-LL |     type A: Iterator<Item: Copy, Item: Copy>;
-   |                            ^^^^ the trait `Copy` is not implemented for `<<Self as TRA2>::A as Iterator>::Item`
-   |
-help: consider further restricting the associated type
-   |
-LL | trait TRA2 where <<Self as TRA2>::A as Iterator>::Item: Copy {
-   |            +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 78 previous errors
+error: aborting due to 75 previous errors
 
-Some errors have detailed explanations: E0277, E0282, E0719.
-For more information about an error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0282, E0719.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs b/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs
index a3f4717791a..079c44b3a59 100644
--- a/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs
+++ b/tests/ui/associated-type-bounds/dyn-impl-trait-type.rs
@@ -5,7 +5,7 @@
 use std::ops::Add;
 
 trait Tr1 { type As1; fn mk(&self) -> Self::As1; }
-trait Tr2<'a> { fn tr2(self) -> &'a Self; }
+trait Tr2<'a> { fn tr2(self) -> &'a Self; } //~ WARN method `tr2` is never used
 
 fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
 fn assert_static<T: 'static>(_: T) {}
diff --git a/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr b/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr
new file mode 100644
index 00000000000..2e26a434f5d
--- /dev/null
+++ b/tests/ui/associated-type-bounds/dyn-impl-trait-type.stderr
@@ -0,0 +1,12 @@
+warning: method `tr2` is never used
+  --> $DIR/dyn-impl-trait-type.rs:8:20
+   |
+LL | trait Tr2<'a> { fn tr2(self) -> &'a Self; }
+   |       ---          ^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs b/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs
index 52199124ea3..49e5e72f225 100644
--- a/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs
+++ b/tests/ui/associated-type-bounds/dyn-rpit-and-let.rs
@@ -7,7 +7,7 @@
 use std::ops::Add;
 
 trait Tr1 { type As1; fn mk(&self) -> Self::As1; }
-trait Tr2<'a> { fn tr2(self) -> &'a Self; }
+trait Tr2<'a> { fn tr2(self) -> &'a Self; } //~ WARN method `tr2` is never used
 
 fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
 fn assert_static<T: 'static>(_: T) {}
diff --git a/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr b/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr
new file mode 100644
index 00000000000..9eddbe46284
--- /dev/null
+++ b/tests/ui/associated-type-bounds/dyn-rpit-and-let.stderr
@@ -0,0 +1,12 @@
+warning: method `tr2` is never used
+  --> $DIR/dyn-rpit-and-let.rs:10:20
+   |
+LL | trait Tr2<'a> { fn tr2(self) -> &'a Self; }
+   |       ---          ^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/higher-ranked.rs b/tests/ui/associated-type-bounds/higher-ranked.rs
new file mode 100644
index 00000000000..2bd5f316811
--- /dev/null
+++ b/tests/ui/associated-type-bounds/higher-ranked.rs
@@ -0,0 +1,17 @@
+// check-pass
+
+#![feature(associated_type_bounds)]
+
+trait A<'a> {
+    type Assoc: ?Sized;
+}
+
+impl<'a> A<'a> for () {
+    type Assoc = &'a ();
+}
+
+fn hello() -> impl for<'a> A<'a, Assoc: Sized> {
+    ()
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/nested-bounds-dont-eliminate-alias-bounds.rs b/tests/ui/associated-type-bounds/nested-bounds-dont-eliminate-alias-bounds.rs
new file mode 100644
index 00000000000..05e4e323d87
--- /dev/null
+++ b/tests/ui/associated-type-bounds/nested-bounds-dont-eliminate-alias-bounds.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+#![feature(associated_type_bounds)]
+
+trait Trait1 {
+    type Assoc1: Bar;
+
+    fn assoc(self) -> Self::Assoc1;
+}
+
+impl Trait1 for () {
+    type Assoc1 = ();
+    fn assoc(self) {}
+}
+
+trait Foo {}
+impl Foo for () {}
+trait Bar {}
+impl Bar for () {}
+
+fn hello() -> impl Trait1<Assoc1: Foo> {
+    ()
+}
+
+fn world() {
+    // Tests that `Assoc1: Foo` bound in the RPIT doesn't disqualify
+    // the `Assoc1: Bar` bound in the item, as a nested RPIT desugaring
+    // would do.
+
+    fn is_foo(_: impl Foo) {}
+    is_foo(hello().assoc());
+
+    fn is_bar(_: impl Bar) {}
+    is_bar(hello().assoc());
+}
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/rpit.rs b/tests/ui/associated-type-bounds/rpit.rs
index 59c7733fbe4..557e63b5f71 100644
--- a/tests/ui/associated-type-bounds/rpit.rs
+++ b/tests/ui/associated-type-bounds/rpit.rs
@@ -5,7 +5,7 @@
 use std::ops::Add;
 
 trait Tr1 { type As1; fn mk(self) -> Self::As1; }
-trait Tr2<'a> { fn tr2(self) -> &'a Self; }
+trait Tr2<'a> { fn tr2(self) -> &'a Self; } //~ WARN method `tr2` is never used
 
 fn assert_copy<T: Copy>(x: T) { let _x = x; let _x = x; }
 fn assert_static<T: 'static>(_: T) {}
diff --git a/tests/ui/associated-type-bounds/rpit.stderr b/tests/ui/associated-type-bounds/rpit.stderr
new file mode 100644
index 00000000000..76bd75bd2ca
--- /dev/null
+++ b/tests/ui/associated-type-bounds/rpit.stderr
@@ -0,0 +1,12 @@
+warning: method `tr2` is never used
+  --> $DIR/rpit.rs:8:20
+   |
+LL | trait Tr2<'a> { fn tr2(self) -> &'a Self; }
+   |       ---          ^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.fixed b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.fixed
index b9f26a40219..128c7dfdda2 100644
--- a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.fixed
+++ b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 trait O {
     type M;
 }
diff --git a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.rs b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.rs
index abff6af73e2..6b6478419b4 100644
--- a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.rs
+++ b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 trait O {
     type M;
 }
diff --git a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr
index 7ca9aff4322..21bc37bb3ea 100644
--- a/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr
+++ b/tests/ui/associated-type-bounds/suggest-contraining-assoc-type-because-of-assoc-const.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/suggest-contraining-assoc-type-because-of-assoc-const.rs:12:21
+  --> $DIR/suggest-contraining-assoc-type-because-of-assoc-const.rs:13:21
    |
 LL |     const N: C::M = 4u8;
    |                     ^^^ expected associated type, found `u8`
diff --git a/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs
index 93a44c01ce0..60088e443f3 100644
--- a/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs
+++ b/tests/ui/associated-type-bounds/trait-alias-impl-trait.rs
@@ -1,5 +1,6 @@
 // run-pass
 
+#![allow(dead_code)]
 #![feature(associated_type_bounds)]
 #![feature(type_alias_impl_trait)]
 
diff --git a/tests/ui/associated-types/associated-types-eq-hr.rs b/tests/ui/associated-types/associated-types-eq-hr.rs
index dc653f7f2e9..b8a97b5c7dd 100644
--- a/tests/ui/associated-types/associated-types-eq-hr.rs
+++ b/tests/ui/associated-types/associated-types-eq-hr.rs
@@ -94,10 +94,18 @@ pub fn call_bar() {
 
 pub fn call_tuple_one() {
     tuple_one::<Tuple>();
+    //~^ ERROR not general enough
+    //~| ERROR not general enough
+    //~| ERROR not general enough
+    //~| ERROR not general enough
 }
 
 pub fn call_tuple_two() {
     tuple_two::<Tuple>();
+    //~^ ERROR not general enough
+    //~| ERROR not general enough
+    //~| ERROR mismatched types
+    //~| ERROR mismatched types
 }
 
 pub fn call_tuple_three() {
@@ -106,6 +114,8 @@ pub fn call_tuple_three() {
 
 pub fn call_tuple_four() {
     tuple_four::<Tuple>();
+    //~^ ERROR not general enough
+    //~| ERROR not general enough
 }
 
 fn main() {}
diff --git a/tests/ui/associated-types/associated-types-eq-hr.stderr b/tests/ui/associated-types/associated-types-eq-hr.stderr
index 3e1142d5d95..3a70189dd9f 100644
--- a/tests/ui/associated-types/associated-types-eq-hr.stderr
+++ b/tests/ui/associated-types/associated-types-eq-hr.stderr
@@ -42,6 +42,113 @@ LL | where
 LL |     T: for<'x> TheTrait<&'x isize, A = &'x usize>,
    |                                    ^^^^^^^^^^^^^ required by this bound in `bar`
 
-error: aborting due to 2 previous errors
+error: implementation of `TheTrait` is not general enough
+  --> $DIR/associated-types-eq-hr.rs:96:5
+   |
+LL |     tuple_one::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+   |
+   = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+
+error: implementation of `TheTrait` is not general enough
+  --> $DIR/associated-types-eq-hr.rs:96:5
+   |
+LL |     tuple_one::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+   |
+   = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: implementation of `TheTrait` is not general enough
+  --> $DIR/associated-types-eq-hr.rs:96:5
+   |
+LL |     tuple_one::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+   |
+   = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: implementation of `TheTrait` is not general enough
+  --> $DIR/associated-types-eq-hr.rs:96:5
+   |
+LL |     tuple_one::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+   |
+   = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: implementation of `TheTrait` is not general enough
+  --> $DIR/associated-types-eq-hr.rs:104:5
+   |
+LL |     tuple_two::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+   |
+   = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+
+error: implementation of `TheTrait` is not general enough
+  --> $DIR/associated-types-eq-hr.rs:104:5
+   |
+LL |     tuple_two::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+   |
+   = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0308]: mismatched types
+  --> $DIR/associated-types-eq-hr.rs:104:5
+   |
+LL |     tuple_two::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected reference `&'x _`
+              found reference `&'y _`
+note: the lifetime requirement is introduced here
+  --> $DIR/associated-types-eq-hr.rs:66:53
+   |
+LL |     T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>,
+   |                                                     ^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/associated-types-eq-hr.rs:104:5
+   |
+LL |     tuple_two::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected reference `&'x _`
+              found reference `&'y _`
+note: the lifetime requirement is introduced here
+  --> $DIR/associated-types-eq-hr.rs:66:53
+   |
+LL |     T: for<'x, 'y> TheTrait<(&'x isize, &'y isize), A = &'y isize>,
+   |                                                     ^^^^^^^^^^^^^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: implementation of `TheTrait` is not general enough
+  --> $DIR/associated-types-eq-hr.rs:116:5
+   |
+LL |     tuple_four::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+   |
+   = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+
+error: implementation of `TheTrait` is not general enough
+  --> $DIR/associated-types-eq-hr.rs:116:5
+   |
+LL |     tuple_four::<Tuple>();
+   |     ^^^^^^^^^^^^^^^^^^^^^ implementation of `TheTrait` is not general enough
+   |
+   = note: `Tuple` must implement `TheTrait<(&'0 isize, &'1 isize)>`, for any two lifetimes `'0` and `'1`...
+   = note: ...but it actually implements `TheTrait<(&'2 isize, &'2 isize)>`, for some specific lifetime `'2`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 12 previous errors
 
-For more information about this error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0271, E0308.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed b/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed
index 80bbef17469..adfba994f32 100644
--- a/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed
+++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 #![allow(unused_variables)]
 
 trait Get {
diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.rs b/tests/ui/associated-types/associated-types-for-unimpl-trait.rs
index 0f6cea8e69f..50478171d86 100644
--- a/tests/ui/associated-types/associated-types-for-unimpl-trait.rs
+++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 #![allow(unused_variables)]
 
 trait Get {
diff --git a/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr b/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr
index 17941b6bf1e..27014fa53d8 100644
--- a/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr
+++ b/tests/ui/associated-types/associated-types-for-unimpl-trait.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-for-unimpl-trait.rs:10:40
+  --> $DIR/associated-types-for-unimpl-trait.rs:11:40
    |
 LL |     fn uhoh<U:Get>(&self, foo: U, bar: <Self as Get>::Value) {}
    |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
diff --git a/tests/ui/associated-types/associated-types-in-bound-type-arg.rs b/tests/ui/associated-types/associated-types-in-bound-type-arg.rs
index 88bb5fe0afe..05e66a168d9 100644
--- a/tests/ui/associated-types/associated-types-in-bound-type-arg.rs
+++ b/tests/ui/associated-types/associated-types-in-bound-type-arg.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // Test the case where we resolve `C::Result` and the trait bound
 // itself includes a `Self::Item` shorthand.
 //
diff --git a/tests/ui/associated-types/associated-types-issue-20220.rs b/tests/ui/associated-types/associated-types-issue-20220.rs
index 19fa7a6085a..89efce19834 100644
--- a/tests/ui/associated-types/associated-types-issue-20220.rs
+++ b/tests/ui/associated-types/associated-types-issue-20220.rs
@@ -4,7 +4,7 @@
 
 use std::vec;
 
-trait IntoIteratorX {
+trait IntoIteratorX { //~ WARN trait `IntoIteratorX` is never used
     type Item;
     type IntoIter: Iterator<Item=Self::Item>;
 
diff --git a/tests/ui/associated-types/associated-types-issue-20220.stderr b/tests/ui/associated-types/associated-types-issue-20220.stderr
new file mode 100644
index 00000000000..c682f46e140
--- /dev/null
+++ b/tests/ui/associated-types/associated-types-issue-20220.stderr
@@ -0,0 +1,10 @@
+warning: trait `IntoIteratorX` is never used
+  --> $DIR/associated-types-issue-20220.rs:7:7
+   |
+LL | trait IntoIteratorX {
+   |       ^^^^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-types/associated-types-issue-20371.rs b/tests/ui/associated-types/associated-types-issue-20371.rs
index ae8a8767d27..cbec83d45b2 100644
--- a/tests/ui/associated-types/associated-types-issue-20371.rs
+++ b/tests/ui/associated-types/associated-types-issue-20371.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // Test that we are able to have an impl that defines an associated type
 // before the actual trait.
 
diff --git a/tests/ui/associated-types/associated-types-nested-projections.rs b/tests/ui/associated-types/associated-types-nested-projections.rs
index 76ba7496250..440f35c8bde 100644
--- a/tests/ui/associated-types/associated-types-nested-projections.rs
+++ b/tests/ui/associated-types/associated-types-nested-projections.rs
@@ -13,7 +13,7 @@ impl<'a> Bound for &'a i32 {}
 trait IntoIterator {
     type Iter: Iterator;
 
-    fn into_iter(self) -> Self::Iter;
+    fn into_iter(self) -> Self::Iter; //~ WARN method `into_iter` is never used
 }
 
 impl<'a, T> IntoIterator for &'a [T; 3] {
diff --git a/tests/ui/associated-types/associated-types-nested-projections.stderr b/tests/ui/associated-types/associated-types-nested-projections.stderr
new file mode 100644
index 00000000000..97d5a758573
--- /dev/null
+++ b/tests/ui/associated-types/associated-types-nested-projections.stderr
@@ -0,0 +1,13 @@
+warning: method `into_iter` is never used
+  --> $DIR/associated-types-nested-projections.rs:16:8
+   |
+LL | trait IntoIterator {
+   |       ------------ method in this trait
+...
+LL |     fn into_iter(self) -> Self::Iter;
+   |        ^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
index e09aa3663c6..6612598b1b8 100644
--- a/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
+++ b/tests/ui/associated-types/associated-types-normalize-in-bounds-ufcs.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 #![allow(unused_variables)]
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
diff --git a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs
index dcfae0f37e1..df0a82ee7ce 100644
--- a/tests/ui/associated-types/associated-types-normalize-in-bounds.rs
+++ b/tests/ui/associated-types/associated-types-normalize-in-bounds.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 #![allow(unused_variables)]
 // Test that we normalize associated types that appear in bounds; if
 // we didn't, the call to `self.split2()` fails to type check.
diff --git a/tests/ui/associated-types/associated-types-projection-bound-in-supertraits.rs b/tests/ui/associated-types/associated-types-projection-bound-in-supertraits.rs
index 107e6b4ce0c..e99d0112ec4 100644
--- a/tests/ui/associated-types/associated-types-projection-bound-in-supertraits.rs
+++ b/tests/ui/associated-types/associated-types-projection-bound-in-supertraits.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 #![allow(unused_variables)]
 // Test that we correctly handle projection bounds appearing in the
 // supertrait list (and in conjunction with overloaded operators). In
diff --git a/tests/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs b/tests/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs
index a59c327be21..e172c6e5611 100644
--- a/tests/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs
+++ b/tests/ui/associated-types/associated-types-projection-from-known-type-in-impl.rs
@@ -6,7 +6,7 @@ trait Int
 {
     type T;
 
-    fn dummy(&self) { }
+    fn dummy(&self) { } //~ WARN method `dummy` is never used
 }
 
 trait NonZero
diff --git a/tests/ui/associated-types/associated-types-projection-from-known-type-in-impl.stderr b/tests/ui/associated-types/associated-types-projection-from-known-type-in-impl.stderr
new file mode 100644
index 00000000000..c26ed79a026
--- /dev/null
+++ b/tests/ui/associated-types/associated-types-projection-from-known-type-in-impl.stderr
@@ -0,0 +1,13 @@
+warning: method `dummy` is never used
+  --> $DIR/associated-types-projection-from-known-type-in-impl.rs:9:8
+   |
+LL | trait Int
+   |       --- method in this trait
+...
+LL |     fn dummy(&self) { }
+   |        ^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed b/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed
index 9bc308465eb..01f49d52ee2 100644
--- a/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed
+++ b/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.fixed
@@ -2,6 +2,7 @@
 // Check that we get an error when you use `<Self as Get>::Value` in
 // the trait definition even if there is no default method.
 
+#![allow(dead_code)]
 trait Get {
     type Value;
 }
diff --git a/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs b/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs
index 549fc8fc618..7068a754a12 100644
--- a/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs
+++ b/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.rs
@@ -2,6 +2,7 @@
 // Check that we get an error when you use `<Self as Get>::Value` in
 // the trait definition even if there is no default method.
 
+#![allow(dead_code)]
 trait Get {
     type Value;
 }
diff --git a/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr b/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
index 64a88525af8..79200dc3acc 100644
--- a/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
+++ b/tests/ui/associated-types/associated-types-projection-to-unrelated-trait-in-method-without-default.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Self: Get` is not satisfied
-  --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:10:40
+  --> $DIR/associated-types-projection-to-unrelated-trait-in-method-without-default.rs:11:40
    |
 LL |     fn okay<U:Get>(&self, foo: U, bar: <Self as Get>::Value);
    |                                        ^^^^^^^^^^^^^^^^^^^^ the trait `Get` is not implemented for `Self`
diff --git a/tests/ui/associated-types/associated-types-projection-to-unrelated-trait.rs b/tests/ui/associated-types/associated-types-projection-to-unrelated-trait.rs
index 3b8c8c019e5..a2d6c9ff5a4 100644
--- a/tests/ui/associated-types/associated-types-projection-to-unrelated-trait.rs
+++ b/tests/ui/associated-types/associated-types-projection-to-unrelated-trait.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // Check that we do not get an error when you use `<Self as Get>::Value` in
 // the trait definition if there is no default method and for every impl,
 // `Self` does implement `Get`.
diff --git a/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs b/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs
index 3c830d37060..1768fd1687b 100644
--- a/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs
+++ b/tests/ui/associated-types/associated-types-qualified-path-with-trait-with-type-parameters.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo<T> {
diff --git a/tests/ui/associated-types/associated-types-resolve-lifetime.rs b/tests/ui/associated-types/associated-types-resolve-lifetime.rs
index 52f2324d72a..563d0c11822 100644
--- a/tests/ui/associated-types/associated-types-resolve-lifetime.rs
+++ b/tests/ui/associated-types/associated-types-resolve-lifetime.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Get<T> {
diff --git a/tests/ui/associated-types/hr-associated-type-bound-object.stderr b/tests/ui/associated-types/hr-associated-type-bound-object.stderr
index 8c91211b964..87a048d0a13 100644
--- a/tests/ui/associated-types/hr-associated-type-bound-object.stderr
+++ b/tests/ui/associated-types/hr-associated-type-bound-object.stderr
@@ -12,6 +12,10 @@ LL | trait X<'a>
 LL | where
 LL |     for<'b> <Self as X<'b>>::U: Clone,
    |                                 ^^^^^ required by this bound in `X`
+help: consider further restricting the associated type
+   |
+LL | fn f<'a, T: X<'a> + ?Sized>(x: &<T as X<'a>>::U) where for<'b> <T as X<'b>>::U: Clone {
+   |                                                  ++++++++++++++++++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/associated-types/impl-wf-cycle-5.fixed b/tests/ui/associated-types/impl-wf-cycle-5.fixed
index bff6ca90975..2b8f1e0d865 100644
--- a/tests/ui/associated-types/impl-wf-cycle-5.fixed
+++ b/tests/ui/associated-types/impl-wf-cycle-5.fixed
@@ -1,9 +1,11 @@
 // run-rustfix
 
+#[allow(dead_code)]
 trait Baz {}
 impl Baz for () {}
 impl<T> Baz for (T,) {}
 
+#[allow(dead_code)]
 trait Fiz {}
 impl Fiz for bool {}
 
diff --git a/tests/ui/associated-types/impl-wf-cycle-5.rs b/tests/ui/associated-types/impl-wf-cycle-5.rs
index a822e1fb008..e6de292ca5c 100644
--- a/tests/ui/associated-types/impl-wf-cycle-5.rs
+++ b/tests/ui/associated-types/impl-wf-cycle-5.rs
@@ -1,9 +1,11 @@
 // run-rustfix
 
+#[allow(dead_code)]
 trait Baz {}
 impl Baz for () {}
 impl<T> Baz for (T,) {}
 
+#[allow(dead_code)]
 trait Fiz {}
 impl Fiz for bool {}
 
diff --git a/tests/ui/associated-types/impl-wf-cycle-5.stderr b/tests/ui/associated-types/impl-wf-cycle-5.stderr
index 284a50bb9a3..61edf18b43d 100644
--- a/tests/ui/associated-types/impl-wf-cycle-5.stderr
+++ b/tests/ui/associated-types/impl-wf-cycle-5.stderr
@@ -1,5 +1,5 @@
 error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
-  --> $DIR/impl-wf-cycle-5.rs:20:1
+  --> $DIR/impl-wf-cycle-5.rs:22:1
    |
 LL | / impl<T> Grault for (T,)
 LL | |
@@ -12,7 +12,7 @@ LL |       type A = ();
    |       ------ associated type `<(T,) as Grault>::A` is specified here
    |
 note: required for `(T,)` to implement `Grault`
-  --> $DIR/impl-wf-cycle-5.rs:20:9
+  --> $DIR/impl-wf-cycle-5.rs:22:9
    |
 LL | impl<T> Grault for (T,)
    |         ^^^^^^     ^^^^
diff --git a/tests/ui/associated-types/impl-wf-cycle-6.fixed b/tests/ui/associated-types/impl-wf-cycle-6.fixed
index 73ed64f7ce3..5ddf1faefe0 100644
--- a/tests/ui/associated-types/impl-wf-cycle-6.fixed
+++ b/tests/ui/associated-types/impl-wf-cycle-6.fixed
@@ -1,9 +1,11 @@
 // run-rustfix
 
+#[allow(dead_code)]
 trait Baz {}
 impl Baz for () {}
 impl<T> Baz for (T,) {}
 
+#[allow(dead_code)]
 trait Fiz {}
 impl Fiz for bool {}
 
diff --git a/tests/ui/associated-types/impl-wf-cycle-6.rs b/tests/ui/associated-types/impl-wf-cycle-6.rs
index 20d635cac5d..28f6deb77ce 100644
--- a/tests/ui/associated-types/impl-wf-cycle-6.rs
+++ b/tests/ui/associated-types/impl-wf-cycle-6.rs
@@ -1,9 +1,11 @@
 // run-rustfix
 
+#[allow(dead_code)]
 trait Baz {}
 impl Baz for () {}
 impl<T> Baz for (T,) {}
 
+#[allow(dead_code)]
 trait Fiz {}
 impl Fiz for bool {}
 
diff --git a/tests/ui/associated-types/impl-wf-cycle-6.stderr b/tests/ui/associated-types/impl-wf-cycle-6.stderr
index c9b5d8060be..1c749503318 100644
--- a/tests/ui/associated-types/impl-wf-cycle-6.stderr
+++ b/tests/ui/associated-types/impl-wf-cycle-6.stderr
@@ -1,5 +1,5 @@
 error[E0275]: overflow evaluating the requirement `<(T,) as Grault>::A == _`
-  --> $DIR/impl-wf-cycle-6.rs:20:1
+  --> $DIR/impl-wf-cycle-6.rs:22:1
    |
 LL | / impl<T: Grault> Grault for (T,)
 LL | |
@@ -11,7 +11,7 @@ LL |       type A = ();
    |       ------ associated type `<(T,) as Grault>::A` is specified here
    |
 note: required for `(T,)` to implement `Grault`
-  --> $DIR/impl-wf-cycle-6.rs:20:17
+  --> $DIR/impl-wf-cycle-6.rs:22:17
    |
 LL | impl<T: Grault> Grault for (T,)
    |                 ^^^^^^     ^^^^
diff --git a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs b/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs
index 8d7dc6a276b..897def791fe 100644
--- a/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs
+++ b/tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs
@@ -2,20 +2,15 @@
 // edition:2021
 // run-pass
 
-// FIXME(async_closures): When `fn_sig_for_fn_abi` is fixed, remove this.
-// ignore-pass (test emits codegen-time warnings)
-
-#![feature(async_closure, async_fn_traits)]
+#![feature(async_closure)]
 
 extern crate block_on;
 
-use std::ops::AsyncFnMut;
-
 fn main() {
     block_on::block_on(async {
         let x = async || {};
 
-        async fn needs_async_fn_mut(mut x: impl AsyncFnMut()) {
+        async fn needs_async_fn_mut(mut x: impl async FnMut()) {
             x().await;
         }
         needs_async_fn_mut(x).await;
diff --git a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs
index 4afc43fe6bd..0e9b25e6d30 100644
--- a/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs
+++ b/tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs
@@ -2,20 +2,15 @@
 // edition:2021
 // run-pass
 
-// FIXME(async_closures): When `fn_sig_for_fn_abi` is fixed, remove this.
-// ignore-pass (test emits codegen-time warnings)
-
-#![feature(async_closure, async_fn_traits)]
+#![feature(async_closure)]
 
 extern crate block_on;
 
-use std::ops::AsyncFnOnce;
-
 fn main() {
     block_on::block_on(async {
         let x = async || {};
 
-        async fn needs_async_fn_once(x: impl AsyncFnOnce()) {
+        async fn needs_async_fn_once(x: impl async FnOnce()) {
             x().await;
         }
         needs_async_fn_once(x).await;
diff --git a/tests/ui/async-await/async-closures/auxiliary/block-on.rs b/tests/ui/async-await/async-closures/auxiliary/block-on.rs
index 3c27548b865..902e033cfe7 100644
--- a/tests/ui/async-await/async-closures/auxiliary/block-on.rs
+++ b/tests/ui/async-await/async-closures/auxiliary/block-on.rs
@@ -1,6 +1,6 @@
 // edition: 2021
 
-#![feature(async_closure, noop_waker, async_fn_traits)]
+#![feature(async_closure, noop_waker)]
 
 use std::future::Future;
 use std::pin::pin;
diff --git a/tests/ui/async-await/async-closures/brand.rs b/tests/ui/async-await/async-closures/brand.rs
index 3bda7737bb4..26d2ed5a6ef 100644
--- a/tests/ui/async-await/async-closures/brand.rs
+++ b/tests/ui/async-await/async-closures/brand.rs
@@ -2,19 +2,18 @@
 // edition:2021
 // build-pass
 
-#![feature(async_closure, async_fn_traits)]
+#![feature(async_closure)]
 
 extern crate block_on;
 
 use std::future::Future;
 use std::marker::PhantomData;
-use std::ops::AsyncFn;
 
 struct S;
 struct B<'b>(PhantomData<&'b mut &'b mut ()>);
 
 impl S {
-    async fn q<F: AsyncFn(B<'_>)>(self, f: F) {
+    async fn q<F: async Fn(B<'_>)>(self, f: F) {
         f(B(PhantomData)).await;
     }
 }
diff --git a/tests/ui/async-await/async-closures/drop.rs b/tests/ui/async-await/async-closures/drop.rs
index 1b7f2f8a600..a243d20774d 100644
--- a/tests/ui/async-await/async-closures/drop.rs
+++ b/tests/ui/async-await/async-closures/drop.rs
@@ -3,13 +3,11 @@
 // run-pass
 // check-run-results
 
-#![feature(async_closure, async_fn_traits)]
+#![feature(async_closure)]
 #![allow(unused)]
 
 extern crate block_on;
 
-use std::ops::AsyncFnOnce;
-
 struct DropMe(i32);
 
 impl Drop for DropMe {
@@ -18,7 +16,7 @@ impl Drop for DropMe {
     }
 }
 
-async fn call_once(f: impl AsyncFnOnce()) {
+async fn call_once(f: impl async FnOnce()) {
     println!("before call");
     let fut = Box::pin(f());
     println!("after call");
diff --git a/tests/ui/async-await/async-closures/mangle.rs b/tests/ui/async-await/async-closures/mangle.rs
index 98065c3c711..9d231d55176 100644
--- a/tests/ui/async-await/async-closures/mangle.rs
+++ b/tests/ui/async-await/async-closures/mangle.rs
@@ -8,20 +8,19 @@
 // FIXME(async_closures): When `fn_sig_for_fn_abi` is fixed, remove this.
 // ignore-pass (test emits codegen-time warnings)
 
-#![feature(async_closure, noop_waker, async_fn_traits)]
+#![feature(async_closure, noop_waker)]
 
 extern crate block_on;
 
 use std::future::Future;
-use std::ops::{AsyncFnMut, AsyncFnOnce};
 use std::pin::pin;
 use std::task::*;
 
-async fn call_mut(f: &mut impl AsyncFnMut()) {
+async fn call_mut(f: &mut impl async FnMut()) {
     f().await;
 }
 
-async fn call_once(f: impl AsyncFnOnce()) {
+async fn call_once(f: impl async FnOnce()) {
     f().await;
 }
 
diff --git a/tests/ui/async-await/async-closures/tainted-body.rs b/tests/ui/async-await/async-closures/tainted-body.rs
new file mode 100644
index 00000000000..62c28e7e585
--- /dev/null
+++ b/tests/ui/async-await/async-closures/tainted-body.rs
@@ -0,0 +1,13 @@
+// edition:2021
+
+#![feature(async_closure)]
+
+// Don't ICE in ByMove shim builder when MIR body is tainted by writeback errors
+
+fn main() {
+    let _ = async || {
+        used_fn();
+        //~^ ERROR cannot find function `used_fn` in this scope
+        0
+    };
+}
diff --git a/tests/ui/async-await/async-closures/tainted-body.stderr b/tests/ui/async-await/async-closures/tainted-body.stderr
new file mode 100644
index 00000000000..b06a896b81f
--- /dev/null
+++ b/tests/ui/async-await/async-closures/tainted-body.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find function `used_fn` in this scope
+  --> $DIR/tainted-body.rs:9:9
+   |
+LL |         used_fn();
+   |         ^^^^^^^ not found in this scope
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.rs b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
index 24828832531..f86cee3e070 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.rs
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
@@ -2,17 +2,15 @@
 
 // FIXME(async_closures): This needs a better error message!
 
-#![feature(async_closure, async_fn_traits)]
-
-use std::ops::AsyncFn;
+#![feature(async_closure)]
 
 fn main() {
-    fn needs_async_fn(_: impl AsyncFn()) {}
+    fn needs_async_fn(_: impl async Fn()) {}
 
     let mut x = 1;
     needs_async_fn(async || {
         //~^ ERROR i16: ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>
-        // FIXME: Should say "closure is AsyncFnMut but it needs AsyncFn" or sth.
+        // FIXME: Should say "closure is `async FnMut` but it needs `async Fn`" or sth.
         x += 1;
     });
 }
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
index ef95e6a211c..4ef8484cc34 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
@@ -1,21 +1,21 @@
 error[E0277]: the trait bound `i16: ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not satisfied
-  --> $DIR/wrong-fn-kind.rs:13:20
+  --> $DIR/wrong-fn-kind.rs:11:20
    |
 LL |       needs_async_fn(async || {
    |  _____--------------_^
    | |     |
    | |     required by a bound introduced by this call
 LL | |
-LL | |         // FIXME: Should say "closure is AsyncFnMut but it needs AsyncFn" or sth.
+LL | |         // FIXME: Should say "closure is `async FnMut` but it needs `async Fn`" or sth.
 LL | |         x += 1;
 LL | |     });
    | |_____^ the trait `ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not implemented for `i16`
    |
 note: required by a bound in `needs_async_fn`
-  --> $DIR/wrong-fn-kind.rs:10:31
+  --> $DIR/wrong-fn-kind.rs:8:31
    |
-LL |     fn needs_async_fn(_: impl AsyncFn()) {}
-   |                               ^^^^^^^^^ required by this bound in `needs_async_fn`
+LL |     fn needs_async_fn(_: impl async Fn()) {}
+   |                               ^^^^^^^^^^ required by this bound in `needs_async_fn`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs
index c5a9841029e..69871d0dca0 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs
+++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.rs
@@ -1,15 +1,18 @@
 // edition: 2021
+// check-pass
 
 use std::future::Future;
 use std::pin::Pin;
 
-trait MyTrait {
+#[allow(async_fn_in_trait)]
+pub trait MyTrait {
     async fn foo(&self) -> i32;
 }
 
 impl MyTrait for i32 {
+    #[warn(refining_impl_trait)]
     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
-        //~^ ERROR method `foo` should be async
+        //~^ WARN impl trait in impl method signature does not match trait method signature
         Box::pin(async { *self })
     }
 }
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr
index 1462c694e16..54aba77cc05 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr
+++ b/tests/ui/async-await/in-trait/async-example-desugared-boxed.stderr
@@ -1,11 +1,22 @@
-error: method `foo` should be async because the method from the trait is async
-  --> $DIR/async-example-desugared-boxed.rs:11:5
+warning: impl trait in impl method signature does not match trait method signature
+  --> $DIR/async-example-desugared-boxed.rs:14:22
    |
 LL |     async fn foo(&self) -> i32;
-   |     --------------------------- required because the trait method is async
+   |     --------------------------- return type from trait method defined here
 ...
 LL |     fn foo(&self) -> Pin<Box<dyn Future<Output = i32> + '_>> {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+note: the lint level is defined here
+  --> $DIR/async-example-desugared-boxed.rs:13:12
+   |
+LL |     #[warn(refining_impl_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^
+help: replace the return type so that it matches the trait
+   |
+LL |     fn foo(&self) -> impl Future<Output = i32> {
+   |                      ~~~~~~~~~~~~~~~~~~~~~~~~~
 
-error: aborting due to 1 previous error
+warning: 1 warning emitted
 
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs
index c287b9a5b84..c6e8f1ae906 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-manual.rs
+++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.rs
@@ -1,13 +1,15 @@
 // edition: 2021
+// check-pass
 
 use std::future::Future;
 use std::task::Poll;
 
-trait MyTrait {
+#[allow(async_fn_in_trait)]
+pub trait MyTrait {
     async fn foo(&self) -> i32;
 }
 
-struct MyFuture;
+pub struct MyFuture;
 impl Future for MyFuture {
     type Output = i32;
     fn poll(self: std::pin::Pin<&mut Self>, _: &mut std::task::Context<'_>) -> Poll<Self::Output> {
@@ -16,8 +18,9 @@ impl Future for MyFuture {
 }
 
 impl MyTrait for u32 {
+    #[warn(refining_impl_trait)]
     fn foo(&self) -> MyFuture {
-        //~^ ERROR method `foo` should be async
+        //~^ WARN impl trait in impl method signature does not match trait method signature
         MyFuture
     }
 }
diff --git a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr
index a2f1060e36f..d94afd92c56 100644
--- a/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr
+++ b/tests/ui/async-await/in-trait/async-example-desugared-manual.stderr
@@ -1,11 +1,22 @@
-error: method `foo` should be async because the method from the trait is async
-  --> $DIR/async-example-desugared-manual.rs:19:5
+warning: impl trait in impl method signature does not match trait method signature
+  --> $DIR/async-example-desugared-manual.rs:22:22
    |
 LL |     async fn foo(&self) -> i32;
-   |     --------------------------- required because the trait method is async
+   |     --------------------------- return type from trait method defined here
 ...
 LL |     fn foo(&self) -> MyFuture {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                      ^^^^^^^^
+   |
+   = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+note: the lint level is defined here
+  --> $DIR/async-example-desugared-manual.rs:21:12
+   |
+LL |     #[warn(refining_impl_trait)]
+   |            ^^^^^^^^^^^^^^^^^^^
+help: replace the return type so that it matches the trait
+   |
+LL |     fn foo(&self) -> impl Future<Output = i32> {
+   |                      ~~~~~~~~~~~~~~~~~~~~~~~~~
 
-error: aborting due to 1 previous error
+warning: 1 warning emitted
 
diff --git a/tests/ui/async-await/in-trait/auxiliary/bad-region.rs b/tests/ui/async-await/in-trait/auxiliary/bad-region.rs
new file mode 100644
index 00000000000..02dc25aaa16
--- /dev/null
+++ b/tests/ui/async-await/in-trait/auxiliary/bad-region.rs
@@ -0,0 +1,7 @@
+// edition:2021
+
+#[allow(async_fn_in_trait)]
+
+pub trait BleRadio<'a> {
+    async fn transmit(&mut self);
+}
diff --git a/tests/ui/async-await/in-trait/bad-region.rs b/tests/ui/async-await/in-trait/bad-region.rs
new file mode 100644
index 00000000000..444368e21a4
--- /dev/null
+++ b/tests/ui/async-await/in-trait/bad-region.rs
@@ -0,0 +1,17 @@
+// aux-build:bad-region.rs
+// edition:2021
+
+#![allow(async_fn_in_trait)]
+
+extern crate bad_region as jewel;
+
+use jewel::BleRadio;
+
+pub struct Radio {}
+
+impl BleRadio for Radio {
+//~^ ERROR implicit elided lifetime not allowed here
+    async fn transmit(&mut self) {}
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/in-trait/bad-region.stderr b/tests/ui/async-await/in-trait/bad-region.stderr
new file mode 100644
index 00000000000..9203fd790af
--- /dev/null
+++ b/tests/ui/async-await/in-trait/bad-region.stderr
@@ -0,0 +1,14 @@
+error[E0726]: implicit elided lifetime not allowed here
+  --> $DIR/bad-region.rs:12:6
+   |
+LL | impl BleRadio for Radio {
+   |      ^^^^^^^^ expected lifetime parameter
+   |
+help: indicate the anonymous lifetime
+   |
+LL | impl BleRadio<'_> for Radio {
+   |              ++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0726`.
diff --git a/tests/ui/async-await/in-trait/coherence-constrained.rs b/tests/ui/async-await/in-trait/coherence-constrained.rs
index 8e62b3e0e90..82c8724ca3e 100644
--- a/tests/ui/async-await/in-trait/coherence-constrained.rs
+++ b/tests/ui/async-await/in-trait/coherence-constrained.rs
@@ -12,7 +12,6 @@ impl Foo for Bar {
     type T = ();
 
     async fn foo(&self) {}
-    //~^ ERROR type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
 }
 
 impl Foo for Bar {
@@ -20,7 +19,6 @@ impl Foo for Bar {
     type T = ();
 
     async fn foo(&self) {}
-    //~^ ERROR type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
 }
 
 fn main() {}
diff --git a/tests/ui/async-await/in-trait/coherence-constrained.stderr b/tests/ui/async-await/in-trait/coherence-constrained.stderr
index 570a357ca8f..5c48a1fe98f 100644
--- a/tests/ui/async-await/in-trait/coherence-constrained.stderr
+++ b/tests/ui/async-await/in-trait/coherence-constrained.stderr
@@ -1,17 +1,5 @@
-error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
-  --> $DIR/coherence-constrained.rs:14:5
-   |
-LL |     async fn foo(&self) {}
-   |     ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`
-
-error[E0284]: type annotations needed: cannot satisfy `<Bar as Foo>::T == ()`
-  --> $DIR/coherence-constrained.rs:22:5
-   |
-LL |     async fn foo(&self) {}
-   |     ^^^^^^^^^^^^^^^^^^^ cannot satisfy `<Bar as Foo>::T == ()`
-
 error[E0119]: conflicting implementations of trait `Foo` for type `Bar`
-  --> $DIR/coherence-constrained.rs:18:1
+  --> $DIR/coherence-constrained.rs:17:1
    |
 LL | impl Foo for Bar {
    | ---------------- first implementation here
@@ -19,7 +7,6 @@ LL | impl Foo for Bar {
 LL | impl Foo for Bar {
    | ^^^^^^^^^^^^^^^^ conflicting implementation for `Bar`
 
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0119, E0284.
-For more information about an error, try `rustc --explain E0119`.
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/async-await/in-trait/fn-not-async-err.rs b/tests/ui/async-await/in-trait/fn-not-async-err.rs
index 60077a7e00c..ecd5737cf3c 100644
--- a/tests/ui/async-await/in-trait/fn-not-async-err.rs
+++ b/tests/ui/async-await/in-trait/fn-not-async-err.rs
@@ -8,7 +8,7 @@ trait MyTrait {
 
 impl MyTrait for i32 {
     fn foo(&self) -> i32 {
-        //~^ ERROR: method `foo` should be async
+        //~^ ERROR: method should be `async` or return a future, but it is synchronous
         *self
     }
 }
diff --git a/tests/ui/async-await/in-trait/fn-not-async-err.stderr b/tests/ui/async-await/in-trait/fn-not-async-err.stderr
index f75ccb65d15..8260cd5271e 100644
--- a/tests/ui/async-await/in-trait/fn-not-async-err.stderr
+++ b/tests/ui/async-await/in-trait/fn-not-async-err.stderr
@@ -1,11 +1,14 @@
-error: method `foo` should be async because the method from the trait is async
+error: method should be `async` or return a future, but it is synchronous
   --> $DIR/fn-not-async-err.rs:10:5
    |
-LL |     async fn foo(&self) -> i32;
-   |     --------------------------- required because the trait method is async
-...
 LL |     fn foo(&self) -> i32 {
    |     ^^^^^^^^^^^^^^^^^^^^
+   |
+note: this method is `async` so it expects a future to be returned
+  --> $DIR/fn-not-async-err.rs:6:5
+   |
+LL |     async fn foo(&self) -> i32;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr b/tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2015.stderr
index d4266814a7c..d4266814a7c 100644
--- a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2015.stderr
+++ b/tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2015.stderr
diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr b/tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2018.stderr
index fe104bfe445..fe104bfe445 100644
--- a/tests/ui/issues/issue-65634-raw-ident-suggestion.edition2018.stderr
+++ b/tests/ui/async-await/issue-65634-raw-ident-suggestion.edition2018.stderr
diff --git a/tests/ui/issues/issue-65634-raw-ident-suggestion.rs b/tests/ui/async-await/issue-65634-raw-ident-suggestion.rs
index 03dd0340c9d..03dd0340c9d 100644
--- a/tests/ui/issues/issue-65634-raw-ident-suggestion.rs
+++ b/tests/ui/async-await/issue-65634-raw-ident-suggestion.rs
diff --git a/tests/ui/async-await/issue-70935-complex-spans.rs b/tests/ui/async-await/issue-70935-complex-spans.rs
index 4af73739584..81f6961840c 100644
--- a/tests/ui/async-await/issue-70935-complex-spans.rs
+++ b/tests/ui/async-await/issue-70935-complex-spans.rs
@@ -14,6 +14,7 @@ async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
 
 fn foo(x: NotSync) -> impl Future + Send {
     //~^ ERROR `*mut ()` cannot be shared between threads safely
+    //~| ERROR `*mut ()` cannot be shared between threads safely
     async move {
         baz(|| async {
             foo(x.clone());
diff --git a/tests/ui/async-await/issue-70935-complex-spans.stderr b/tests/ui/async-await/issue-70935-complex-spans.stderr
index 36e297ed884..8dc3f476ec8 100644
--- a/tests/ui/async-await/issue-70935-complex-spans.stderr
+++ b/tests/ui/async-await/issue-70935-complex-spans.stderr
@@ -4,7 +4,7 @@ error[E0277]: `*mut ()` cannot be shared between threads safely
 LL | fn foo(x: NotSync) -> impl Future + Send {
    |                       ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
    |
-   = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`, which is required by `{async block@$DIR/issue-70935-complex-spans.rs:17:5: 21:6}: Send`
+   = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`, which is required by `{async block@$DIR/issue-70935-complex-spans.rs:18:5: 22:6}: Send`
 note: required because it appears within the type `PhantomData<*mut ()>`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
 note: required because it appears within the type `NotSync`
@@ -14,7 +14,7 @@ LL | struct NotSync(PhantomData<*mut ()>);
    |        ^^^^^^^
    = note: required for `&NotSync` to implement `Send`
 note: required because it's used within this closure
-  --> $DIR/issue-70935-complex-spans.rs:18:13
+  --> $DIR/issue-70935-complex-spans.rs:19:13
    |
 LL |         baz(|| async {
    |             ^^
@@ -27,7 +27,7 @@ LL | | }
    | |_^
    = note: required because it captures the following types: `impl Future<Output = ()>`
 note: required because it's used within this `async` block
-  --> $DIR/issue-70935-complex-spans.rs:17:5
+  --> $DIR/issue-70935-complex-spans.rs:18:5
    |
 LL | /     async move {
 LL | |         baz(|| async {
@@ -36,6 +36,45 @@ LL | |         }).await;
 LL | |     }
    | |_____^
 
-error: aborting due to 1 previous error
+error[E0277]: `*mut ()` cannot be shared between threads safely
+  --> $DIR/issue-70935-complex-spans.rs:15:23
+   |
+LL | fn foo(x: NotSync) -> impl Future + Send {
+   |                       ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
+   |
+   = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`, which is required by `{async block@$DIR/issue-70935-complex-spans.rs:18:5: 22:6}: Send`
+note: required because it appears within the type `PhantomData<*mut ()>`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+note: required because it appears within the type `NotSync`
+  --> $DIR/issue-70935-complex-spans.rs:9:8
+   |
+LL | struct NotSync(PhantomData<*mut ()>);
+   |        ^^^^^^^
+   = note: required for `&NotSync` to implement `Send`
+note: required because it's used within this closure
+  --> $DIR/issue-70935-complex-spans.rs:19:13
+   |
+LL |         baz(|| async {
+   |             ^^
+note: required because it's used within this `async` fn body
+  --> $DIR/issue-70935-complex-spans.rs:12:67
+   |
+LL |   async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
+   |  ___________________________________________________________________^
+LL | | }
+   | |_^
+   = note: required because it captures the following types: `impl Future<Output = ()>`
+note: required because it's used within this `async` block
+  --> $DIR/issue-70935-complex-spans.rs:18:5
+   |
+LL | /     async move {
+LL | |         baz(|| async {
+LL | |             foo(x.clone());
+LL | |         }).await;
+LL | |     }
+   | |_____^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr
index d2db6abe313..2e82a3fcdb4 100644
--- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr
+++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.current.stderr
@@ -1,5 +1,5 @@
 warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:7:12
+  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:6:12
    |
 LL | #![feature(return_type_notation)]
    |            ^^^^^^^^^^^^^^^^^^^^
@@ -7,29 +7,5 @@ LL | #![feature(return_type_notation)]
    = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error[E0277]: `impl Future<Output = ()> { <_ as Foo>::bar() }` cannot be sent between threads safely
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:22:11
-   |
-LL |     build(Bar);
-   |     ----- ^^^ `impl Future<Output = ()> { <_ as Foo>::bar() }` cannot be sent between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `for<'a> Send` is not implemented for `impl Future<Output = ()> { <_ as Foo>::bar() }`
-note: this is a known limitation of the trait solver that will be lifted in the future
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:22:11
-   |
-LL |     build(Bar);
-   |     ------^^^-
-   |     |     |
-   |     |     the trait solver is unable to infer the generic types that should be inferred from this argument
-   |     add turbofish arguments to this call to specify the types manually, even if it's redundant
-note: required by a bound in `build`
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:19:39
-   |
-LL | fn build<T>(_: T) where T: Foo<bar(): Send> {}
-   |                                       ^^^^ required by this bound in `build`
-
-error: aborting due to 1 previous error; 1 warning emitted
+warning: 1 warning emitted
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr
index 4837815fad4..2e82a3fcdb4 100644
--- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr
+++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.next.stderr
@@ -1,5 +1,5 @@
 warning: the feature `return_type_notation` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:7:12
+  --> $DIR/normalizing-self-auto-trait-issue-109924.rs:6:12
    |
 LL | #![feature(return_type_notation)]
    |            ^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs
index 6097c7f1073..5341c39a975 100644
--- a/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs
+++ b/tests/ui/async-await/return-type-notation/normalizing-self-auto-trait-issue-109924.rs
@@ -1,11 +1,10 @@
+// check-pass
 // revisions: current next
-//[current] known-bug: #109924
-//[next] check-pass
 //[next] compile-flags: -Znext-solver
 // edition:2021
 
 #![feature(return_type_notation)]
-//[next]~^ WARN the feature `return_type_notation` is incomplete
+//~^ WARN the feature `return_type_notation` is incomplete
 
 trait Foo {
     async fn bar(&self);
diff --git a/tests/ui/auto-traits/auto-trait-validation.fixed b/tests/ui/auto-traits/auto-trait-validation.fixed
index da878ac6222..e37fed9faab 100644
--- a/tests/ui/auto-traits/auto-trait-validation.fixed
+++ b/tests/ui/auto-traits/auto-trait-validation.fixed
@@ -1,4 +1,5 @@
 #![feature(auto_traits)]
+#![allow(dead_code)]
 
 // run-rustfix
 
diff --git a/tests/ui/auto-traits/auto-trait-validation.rs b/tests/ui/auto-traits/auto-trait-validation.rs
index d43055e270b..e209aa13220 100644
--- a/tests/ui/auto-traits/auto-trait-validation.rs
+++ b/tests/ui/auto-traits/auto-trait-validation.rs
@@ -1,4 +1,5 @@
 #![feature(auto_traits)]
+#![allow(dead_code)]
 
 // run-rustfix
 
diff --git a/tests/ui/auto-traits/auto-trait-validation.stderr b/tests/ui/auto-traits/auto-trait-validation.stderr
index 89b63d23d4c..a6e5ac54869 100644
--- a/tests/ui/auto-traits/auto-trait-validation.stderr
+++ b/tests/ui/auto-traits/auto-trait-validation.stderr
@@ -1,5 +1,5 @@
 error[E0567]: auto traits cannot have generic parameters
-  --> $DIR/auto-trait-validation.rs:5:19
+  --> $DIR/auto-trait-validation.rs:6:19
    |
 LL | auto trait Generic<T> {}
    |            -------^^^ help: remove the parameters
@@ -7,7 +7,7 @@ LL | auto trait Generic<T> {}
    |            auto trait cannot have generic parameters
 
 error[E0568]: auto traits cannot have super traits or lifetime bounds
-  --> $DIR/auto-trait-validation.rs:7:17
+  --> $DIR/auto-trait-validation.rs:8:17
    |
 LL | auto trait Bound : Copy {}
    |            -----^^^^^^^ help: remove the super traits or lifetime bounds
@@ -15,7 +15,7 @@ LL | auto trait Bound : Copy {}
    |            auto traits cannot have super traits or lifetime bounds
 
 error[E0568]: auto traits cannot have super traits or lifetime bounds
-  --> $DIR/auto-trait-validation.rs:9:25
+  --> $DIR/auto-trait-validation.rs:10:25
    |
 LL | auto trait LifetimeBound : 'static {}
    |            -------------^^^^^^^^^^ help: remove the super traits or lifetime bounds
@@ -23,7 +23,7 @@ LL | auto trait LifetimeBound : 'static {}
    |            auto traits cannot have super traits or lifetime bounds
 
 error[E0380]: auto traits cannot have associated items
-  --> $DIR/auto-trait-validation.rs:11:25
+  --> $DIR/auto-trait-validation.rs:12:25
    |
 LL | auto trait MyTrait { fn foo() {} }
    |            -------   ---^^^-----
diff --git a/tests/ui/auto-traits/auto-traits.rs b/tests/ui/auto-traits/auto-traits.rs
index 6d8e1a52ec1..1e0fbcc1fdf 100644
--- a/tests/ui/auto-traits/auto-traits.rs
+++ b/tests/ui/auto-traits/auto-traits.rs
@@ -19,8 +19,8 @@ fn take_auto_unsafe<T: AutoUnsafe>(_: T) {}
 
 fn main() {
     // Parse inside functions.
-    auto trait AutoInner {}
-    unsafe auto trait AutoUnsafeInner {}
+    auto trait AutoInner {} //~ WARN trait `AutoInner` is never used
+    unsafe auto trait AutoUnsafeInner {} //~ WARN trait `AutoUnsafeInner` is never used
 
     take_auto(0);
     take_auto(AutoBool(true));
diff --git a/tests/ui/auto-traits/auto-traits.stderr b/tests/ui/auto-traits/auto-traits.stderr
new file mode 100644
index 00000000000..34be8d3f67b
--- /dev/null
+++ b/tests/ui/auto-traits/auto-traits.stderr
@@ -0,0 +1,16 @@
+warning: trait `AutoInner` is never used
+  --> $DIR/auto-traits.rs:22:16
+   |
+LL |     auto trait AutoInner {}
+   |                ^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: trait `AutoUnsafeInner` is never used
+  --> $DIR/auto-traits.rs:23:23
+   |
+LL |     unsafe auto trait AutoUnsafeInner {}
+   |                       ^^^^^^^^^^^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs
index 98359ef51b7..c0ed1e00f3b 100644
--- a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs
+++ b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.rs
@@ -6,6 +6,7 @@ auto trait Magic : Sized where Option<Self> : Magic {} //~ ERROR E0568
 impl<T:Magic> Magic for T {}
 
 fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
+//~^ ERROR: use of moved value
 
 #[derive(Debug)]
 struct NoClone;
diff --git a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr
index 547b4bb5448..dcf1c02bcee 100644
--- a/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr
+++ b/tests/ui/auto-traits/typeck-auto-trait-no-supertraits-2.stderr
@@ -14,6 +14,21 @@ LL | auto trait Magic : Sized where Option<Self> : Magic {}
    |            |
    |            auto traits cannot have super traits or lifetime bounds
 
-error: aborting due to 2 previous errors
+error[E0382]: use of moved value: `x`
+  --> $DIR/typeck-auto-trait-no-supertraits-2.rs:8:41
+   |
+LL | fn copy<T: Magic>(x: T) -> (T, T) { (x, x) }
+   |                   -                  -  ^ value used here after move
+   |                   |                  |
+   |                   |                  value moved here
+   |                   move occurs because `x` has type `T`, which does not implement the `Copy` trait
+   |
+help: consider further restricting this bound
+   |
+LL | fn copy<T: Magic + Copy>(x: T) -> (T, T) { (x, x) }
+   |                  ++++++
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0568`.
+Some errors have detailed explanations: E0382, E0568.
+For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/binding/irrefutable-if-let-without-else.fixed b/tests/ui/binding/irrefutable-if-let-without-else.fixed
new file mode 100644
index 00000000000..3d7f4695ca8
--- /dev/null
+++ b/tests/ui/binding/irrefutable-if-let-without-else.fixed
@@ -0,0 +1,25 @@
+// run-rustfix
+enum Enum {
+    Variant(i32),
+}
+struct Struct(i32);
+
+fn foo(x: Enum) -> i32 {
+    let Enum::Variant(value) = x;
+        value
+}
+fn bar(x: Enum) -> i32 {
+    let Enum::Variant(value) = x;
+        let x = value + 1;
+        x
+}
+fn baz(x: Struct) -> i32 {
+    let Struct(value) = x;
+        let x = value + 1;
+        x
+}
+fn main() {
+    let _ = foo(Enum::Variant(42));
+    let _ = bar(Enum::Variant(42));
+    let _ = baz(Struct(42));
+}
diff --git a/tests/ui/binding/irrefutable-if-let-without-else.rs b/tests/ui/binding/irrefutable-if-let-without-else.rs
new file mode 100644
index 00000000000..5aaf4ace3f8
--- /dev/null
+++ b/tests/ui/binding/irrefutable-if-let-without-else.rs
@@ -0,0 +1,28 @@
+// run-rustfix
+enum Enum {
+    Variant(i32),
+}
+struct Struct(i32);
+
+fn foo(x: Enum) -> i32 {
+    if let Enum::Variant(value) = x { //~ ERROR `if` may be missing an `else` clause
+        value
+    }
+}
+fn bar(x: Enum) -> i32 {
+    if let Enum::Variant(value) = x { //~ ERROR `if` may be missing an `else` clause
+        let x = value + 1;
+        x
+    }
+}
+fn baz(x: Struct) -> i32 {
+    if let Struct(value) = x { //~ ERROR `if` may be missing an `else` clause
+        let x = value + 1;
+        x
+    }
+}
+fn main() {
+    let _ = foo(Enum::Variant(42));
+    let _ = bar(Enum::Variant(42));
+    let _ = baz(Struct(42));
+}
diff --git a/tests/ui/binding/irrefutable-if-let-without-else.stderr b/tests/ui/binding/irrefutable-if-let-without-else.stderr
new file mode 100644
index 00000000000..e234cfdd945
--- /dev/null
+++ b/tests/ui/binding/irrefutable-if-let-without-else.stderr
@@ -0,0 +1,61 @@
+error[E0317]: `if` may be missing an `else` clause
+  --> $DIR/irrefutable-if-let-without-else.rs:8:5
+   |
+LL |   fn foo(x: Enum) -> i32 {
+   |                      --- expected `i32` because of this return type
+LL | /     if let Enum::Variant(value) = x {
+LL | |         value
+LL | |     }
+   | |_____^ expected `i32`, found `()`
+   |
+   = note: `if` expressions without `else` evaluate to `()`
+   = help: consider adding an `else` block that evaluates to the expected type
+help: consider using an irrefutable `let` binding instead
+   |
+LL ~     let Enum::Variant(value) = x;
+LL ~         value
+   |
+
+error[E0317]: `if` may be missing an `else` clause
+  --> $DIR/irrefutable-if-let-without-else.rs:13:5
+   |
+LL |   fn bar(x: Enum) -> i32 {
+   |                      --- expected `i32` because of this return type
+LL | /     if let Enum::Variant(value) = x {
+LL | |         let x = value + 1;
+LL | |         x
+LL | |     }
+   | |_____^ expected `i32`, found `()`
+   |
+   = note: `if` expressions without `else` evaluate to `()`
+   = help: consider adding an `else` block that evaluates to the expected type
+help: consider using an irrefutable `let` binding instead
+   |
+LL ~     let Enum::Variant(value) = x;
+LL ~         let x = value + 1;
+LL ~         x
+   |
+
+error[E0317]: `if` may be missing an `else` clause
+  --> $DIR/irrefutable-if-let-without-else.rs:19:5
+   |
+LL |   fn baz(x: Struct) -> i32 {
+   |                        --- expected `i32` because of this return type
+LL | /     if let Struct(value) = x {
+LL | |         let x = value + 1;
+LL | |         x
+LL | |     }
+   | |_____^ expected `i32`, found `()`
+   |
+   = note: `if` expressions without `else` evaluate to `()`
+   = help: consider adding an `else` block that evaluates to the expected type
+help: consider using an irrefutable `let` binding instead
+   |
+LL ~     let Struct(value) = x;
+LL ~         let x = value + 1;
+LL ~         x
+   |
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0317`.
diff --git a/tests/ui/issues/issue-62375.rs b/tests/ui/binop/issue-62375.rs
index a2c8fe551bb..a2c8fe551bb 100644
--- a/tests/ui/issues/issue-62375.rs
+++ b/tests/ui/binop/issue-62375.rs
diff --git a/tests/ui/issues/issue-62375.stderr b/tests/ui/binop/issue-62375.stderr
index faca94a03f0..faca94a03f0 100644
--- a/tests/ui/issues/issue-62375.stderr
+++ b/tests/ui/binop/issue-62375.stderr
diff --git a/tests/ui/binop/issue-77910-1.rs b/tests/ui/binop/issue-77910-1.rs
index 95bbd6a60ec..4b7ee77b46d 100644
--- a/tests/ui/binop/issue-77910-1.rs
+++ b/tests/ui/binop/issue-77910-1.rs
@@ -1,6 +1,6 @@
 fn foo(s: &i32) -> &i32 {
     let xs;
-    xs
+    xs //~ ERROR: isn't initialized
 }
 fn main() {
     let y;
diff --git a/tests/ui/binop/issue-77910-1.stderr b/tests/ui/binop/issue-77910-1.stderr
index 263a35d9829..6402e568188 100644
--- a/tests/ui/binop/issue-77910-1.stderr
+++ b/tests/ui/binop/issue-77910-1.stderr
@@ -22,7 +22,20 @@ LL |     assert_eq!(foo, y);
    = help: use parentheses to call this function: `foo(/* &i32 */)`
    = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 2 previous errors
+error[E0381]: used binding `xs` isn't initialized
+  --> $DIR/issue-77910-1.rs:3:5
+   |
+LL |     let xs;
+   |         -- binding declared here but left uninitialized
+LL |     xs
+   |     ^^ `xs` used here but it isn't initialized
+   |
+help: consider assigning a value
+   |
+LL |     let xs = todo!();
+   |            +++++++++
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0277, E0369.
+Some errors have detailed explanations: E0277, E0369, E0381.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/binop/issue-77910-2.rs b/tests/ui/binop/issue-77910-2.rs
index 2bb48d36576..5ea03e82b2f 100644
--- a/tests/ui/binop/issue-77910-2.rs
+++ b/tests/ui/binop/issue-77910-2.rs
@@ -1,6 +1,6 @@
 fn foo(s: &i32) -> &i32 {
     let xs;
-    xs
+    xs //~ ERROR: isn't initialized
 }
 fn main() {
     let y;
diff --git a/tests/ui/binop/issue-77910-2.stderr b/tests/ui/binop/issue-77910-2.stderr
index e58ae0fad9b..a14560ff188 100644
--- a/tests/ui/binop/issue-77910-2.stderr
+++ b/tests/ui/binop/issue-77910-2.stderr
@@ -11,6 +11,20 @@ help: use parentheses to call this function
 LL |     if foo(/* &i32 */) == y {}
    |           ++++++++++++
 
-error: aborting due to 1 previous error
+error[E0381]: used binding `xs` isn't initialized
+  --> $DIR/issue-77910-2.rs:3:5
+   |
+LL |     let xs;
+   |         -- binding declared here but left uninitialized
+LL |     xs
+   |     ^^ `xs` used here but it isn't initialized
+   |
+help: consider assigning a value
+   |
+LL |     let xs = todo!();
+   |            +++++++++
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0369`.
+Some errors have detailed explanations: E0369, E0381.
+For more information about an error, try `rustc --explain E0369`.
diff --git a/tests/ui/box/unit/unique-object-noncopyable.stderr b/tests/ui/box/unit/unique-object-noncopyable.stderr
index 49547872d1a..8ea6edb48a7 100644
--- a/tests/ui/box/unit/unique-object-noncopyable.stderr
+++ b/tests/ui/box/unit/unique-object-noncopyable.stderr
@@ -12,6 +12,9 @@ LL |     let _z = y.clone();
            which is required by `Box<dyn Foo>: Clone`
            `dyn Foo: Clone`
            which is required by `Box<dyn Foo>: Clone`
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following trait defines an item `clone`, perhaps you need to implement it:
+           candidate #1: `Clone`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/box/unit/unique-pinned-nocopy.stderr b/tests/ui/box/unit/unique-pinned-nocopy.stderr
index d2bf72249c4..69428604b19 100644
--- a/tests/ui/box/unit/unique-pinned-nocopy.stderr
+++ b/tests/ui/box/unit/unique-pinned-nocopy.stderr
@@ -10,9 +10,6 @@ LL |     let _j = i.clone();
    = note: the following trait bounds were not satisfied:
            `R: Clone`
            which is required by `Box<R>: Clone`
-   = help: items from traits can only be used if the trait is implemented and in scope
-   = note: the following trait defines an item `clone`, perhaps you need to implement it:
-           candidate #1: `Clone`
 help: consider annotating `R` with `#[derive(Clone)]`
    |
 LL + #[derive(Clone)]
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata2.rs b/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata2.rs
index 2edc52c6f55..7e8820cb2c6 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata2.rs
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-in-metadata2.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![allow(unused_imports)]
 
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs b/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs
index 8d247715784..50914b1de53 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-simple2.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // Simple test case of implementing a trait with super-builtin-kinds.
 
 // pretty-expanded FIXME #23616
diff --git a/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs b/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs
index f999dfff786..0577acc572a 100644
--- a/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs
+++ b/tests/ui/builtin-superkinds/builtin-superkinds-typaram.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // Tests correct implementation of traits with super-builtin-kinds
 // using a bounded type parameter.
 
diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs
index 249481467e6..be6a6bb8b17 100644
--- a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs
+++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs
@@ -8,7 +8,7 @@ trait Foo<T> {
     fn foo(&self, _: T) -> u32 { 42 }
 }
 
-trait Bar {
+trait Bar { //~ WARN trait `Bar` is never used
     fn bar(&self) { println!("Bar!"); }
 }
 
diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr
new file mode 100644
index 00000000000..952687e98d0
--- /dev/null
+++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr
@@ -0,0 +1,10 @@
+warning: trait `Bar` is never used
+  --> $DIR/cast-rfc0401-vtable-kinds.rs:11:7
+   |
+LL | trait Bar {
+   |       ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/cast/enum-to-numeric-cast.rs b/tests/ui/cast/enum-to-numeric-cast.rs
new file mode 100644
index 00000000000..d5ab2a6a1fe
--- /dev/null
+++ b/tests/ui/cast/enum-to-numeric-cast.rs
@@ -0,0 +1,46 @@
+// Tests that `as` casts from enums to numeric types succeed
+// only if the enum type is "unit-only" or "fieldless" as
+// described here: https://doc.rust-lang.org/reference/items/enumerations.html#casting
+
+pub enum UnitOnly {
+    Foo,
+    Bar,
+    Baz,
+}
+
+pub enum Fieldless {
+    Tuple(),
+    Struct{},
+    Unit,
+}
+
+pub enum NotUnitOnlyOrFieldless {
+    Foo,
+    Bar(u8),
+    Baz
+}
+
+fn main() {
+    let unit_only = UnitOnly::Foo;
+
+    let _ = unit_only as isize;
+    let _ = unit_only as i32;
+    let _ = unit_only as usize;
+    let _ = unit_only as u32;
+
+
+    let fieldless = Fieldless::Struct{};
+
+    let _ = fieldless as isize;
+    let _ = fieldless as i32;
+    let _ = fieldless as usize;
+    let _ = fieldless as u32;
+
+
+    let not_unit_only_or_fieldless = NotUnitOnlyOrFieldless::Foo;
+
+    let _ = not_unit_only_or_fieldless as isize; //~ ERROR non-primitive cast: `NotUnitOnlyOrFieldless` as `isize`
+    let _ = not_unit_only_or_fieldless as i32; //~ ERROR non-primitive cast: `NotUnitOnlyOrFieldless` as `i32`
+    let _ = not_unit_only_or_fieldless as usize; //~ ERROR non-primitive cast: `NotUnitOnlyOrFieldless` as `usize`
+    let _ = not_unit_only_or_fieldless as u32; //~ ERROR non-primitive cast: `NotUnitOnlyOrFieldless` as `u32`
+}
diff --git a/tests/ui/cast/enum-to-numeric-cast.stderr b/tests/ui/cast/enum-to-numeric-cast.stderr
new file mode 100644
index 00000000000..1a49cb97451
--- /dev/null
+++ b/tests/ui/cast/enum-to-numeric-cast.stderr
@@ -0,0 +1,35 @@
+error[E0605]: non-primitive cast: `NotUnitOnlyOrFieldless` as `isize`
+  --> $DIR/enum-to-numeric-cast.rs:42:13
+   |
+LL |     let _ = not_unit_only_or_fieldless as isize;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can be used to convert enum types to numeric types only if the enum type is unit-only or field-less
+   |
+   = note: see https://doc.rust-lang.org/reference/items/enumerations.html#casting for more information
+
+error[E0605]: non-primitive cast: `NotUnitOnlyOrFieldless` as `i32`
+  --> $DIR/enum-to-numeric-cast.rs:43:13
+   |
+LL |     let _ = not_unit_only_or_fieldless as i32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can be used to convert enum types to numeric types only if the enum type is unit-only or field-less
+   |
+   = note: see https://doc.rust-lang.org/reference/items/enumerations.html#casting for more information
+
+error[E0605]: non-primitive cast: `NotUnitOnlyOrFieldless` as `usize`
+  --> $DIR/enum-to-numeric-cast.rs:44:13
+   |
+LL |     let _ = not_unit_only_or_fieldless as usize;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can be used to convert enum types to numeric types only if the enum type is unit-only or field-less
+   |
+   = note: see https://doc.rust-lang.org/reference/items/enumerations.html#casting for more information
+
+error[E0605]: non-primitive cast: `NotUnitOnlyOrFieldless` as `u32`
+  --> $DIR/enum-to-numeric-cast.rs:45:13
+   |
+LL |     let _ = not_unit_only_or_fieldless as u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ an `as` expression can be used to convert enum types to numeric types only if the enum type is unit-only or field-less
+   |
+   = note: see https://doc.rust-lang.org/reference/items/enumerations.html#casting for more information
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0605`.
diff --git a/tests/ui/cast/fat-ptr-cast-rpass.rs b/tests/ui/cast/fat-ptr-cast-rpass.rs
index f5747eb8b96..c79468caddd 100644
--- a/tests/ui/cast/fat-ptr-cast-rpass.rs
+++ b/tests/ui/cast/fat-ptr-cast-rpass.rs
@@ -3,7 +3,7 @@
 #![feature(ptr_metadata)]
 
 trait Foo {
-    fn foo(&self) {}
+    fn foo(&self) {} //~ WARN method `foo` is never used
 }
 
 struct Bar;
diff --git a/tests/ui/cast/fat-ptr-cast-rpass.stderr b/tests/ui/cast/fat-ptr-cast-rpass.stderr
new file mode 100644
index 00000000000..d01688e0cc3
--- /dev/null
+++ b/tests/ui/cast/fat-ptr-cast-rpass.stderr
@@ -0,0 +1,12 @@
+warning: method `foo` is never used
+  --> $DIR/fat-ptr-cast-rpass.rs:6:8
+   |
+LL | trait Foo {
+   |       --- method in this trait
+LL |     fn foo(&self) {}
+   |        ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/cast/issue-88621.stderr b/tests/ui/cast/issue-88621.stderr
index 0459ce5eabd..201651a207a 100644
--- a/tests/ui/cast/issue-88621.stderr
+++ b/tests/ui/cast/issue-88621.stderr
@@ -2,7 +2,9 @@ error[E0605]: non-primitive cast: `Kind2` as `u8`
   --> $DIR/issue-88621.rs:9:13
    |
 LL |     let _ = Kind2::Foo() as u8;
-   |             ^^^^^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+   |             ^^^^^^^^^^^^^^^^^^ an `as` expression can be used to convert enum types to numeric types only if the enum type is unit-only or field-less
+   |
+   = note: see https://doc.rust-lang.org/reference/items/enumerations.html#casting for more information
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs
new file mode 100644
index 00000000000..a6e68e1b710
--- /dev/null
+++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.rs
@@ -0,0 +1,12 @@
+// #120427
+// This test checks we won't suggest more than 3 span suggestions for cfg names
+//
+// check-pass
+// compile-flags: -Z unstable-options
+// compile-flags: --check-cfg=cfg(foo,values("value")) --check-cfg=cfg(bar,values("value")) --check-cfg=cfg(bee,values("value")) --check-cfg=cfg(cow,values("value"))
+
+#[cfg(value)]
+//~^ WARNING unexpected `cfg` condition name: `value`
+fn x() {}
+
+fn main() {}
diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr
new file mode 100644
index 00000000000..82d471d715b
--- /dev/null
+++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-duplicate.stderr
@@ -0,0 +1,13 @@
+warning: unexpected `cfg` condition name: `value`
+  --> $DIR/cfg-value-for-cfg-name-duplicate.rs:8:7
+   |
+LL | #[cfg(value)]
+   |       ^^^^^
+   |
+   = help: expected names are: `bar`, `bee`, `cow`, `debug_assertions`, `doc`, `doctest`, `foo`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(value)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs
new file mode 100644
index 00000000000..edde6244ed1
--- /dev/null
+++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.rs
@@ -0,0 +1,12 @@
+// #120427
+// This test checks that when a single cfg has a value for user's specified name
+//
+// check-pass
+// compile-flags: -Z unstable-options
+// compile-flags: --check-cfg=cfg(foo,values("my_value")) --check-cfg=cfg(bar,values("my_value"))
+
+#[cfg(my_value)]
+//~^ WARNING unexpected `cfg` condition name: `my_value`
+fn x() {}
+
+fn main() {}
diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr
new file mode 100644
index 00000000000..b88ee71a156
--- /dev/null
+++ b/tests/ui/check-cfg/cfg-value-for-cfg-name-multiple.stderr
@@ -0,0 +1,21 @@
+warning: unexpected `cfg` condition name: `my_value`
+  --> $DIR/cfg-value-for-cfg-name-multiple.rs:8:7
+   |
+LL | #[cfg(my_value)]
+   |       ^^^^^^^^
+   |
+   = help: expected names are: `bar`, `debug_assertions`, `doc`, `doctest`, `foo`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(my_value)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+help: found config with similar value
+   |
+LL | #[cfg(foo = "my_value")]
+   |       ~~~~~~~~~~~~~~~~
+help: found config with similar value
+   |
+LL | #[cfg(bar = "my_value")]
+   |       ~~~~~~~~~~~~~~~~
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name.rs b/tests/ui/check-cfg/cfg-value-for-cfg-name.rs
new file mode 100644
index 00000000000..7a0c345b7ca
--- /dev/null
+++ b/tests/ui/check-cfg/cfg-value-for-cfg-name.rs
@@ -0,0 +1,18 @@
+// #120427
+// This test checks that when a single cfg has a value for user's specified name
+// suggest to use `#[cfg(target_os = "linux")]` instead of `#[cfg(linux)]`
+//
+// check-pass
+// compile-flags: -Z unstable-options
+// compile-flags: --check-cfg=cfg()
+
+#[cfg(linux)]
+//~^ WARNING unexpected `cfg` condition name: `linux`
+fn x() {}
+
+// will not suggest if the cfg has a value
+#[cfg(linux = "os-name")]
+//~^ WARNING unexpected `cfg` condition name: `linux`
+fn y() {}
+
+fn main() {}
diff --git a/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr b/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr
new file mode 100644
index 00000000000..c0447551424
--- /dev/null
+++ b/tests/ui/check-cfg/cfg-value-for-cfg-name.stderr
@@ -0,0 +1,22 @@
+warning: unexpected `cfg` condition name: `linux`
+  --> $DIR/cfg-value-for-cfg-name.rs:9:7
+   |
+LL | #[cfg(linux)]
+   |       ^^^^^ help: found config with similar value: `target_os = "linux"`
+   |
+   = help: expected names are: `debug_assertions`, `doc`, `doctest`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `unix`, `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(linux)`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition name: `linux`
+  --> $DIR/cfg-value-for-cfg-name.rs:14:7
+   |
+LL | #[cfg(linux = "os-name")]
+   |       ^^^^^^^^^^^^^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(linux, values("os-name"))`
+   = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/class-cast-to-trait.rs b/tests/ui/class-cast-to-trait.rs
index 345d6efd2d9..ca98e4c9003 100644
--- a/tests/ui/class-cast-to-trait.rs
+++ b/tests/ui/class-cast-to-trait.rs
@@ -1,5 +1,5 @@
 trait Noisy {
-  fn speak(&self);
+  fn speak(&mut self);
 }
 
 struct Cat {
@@ -10,7 +10,7 @@ struct Cat {
 }
 
 impl Cat {
-  pub fn eat(&self) -> bool {
+  pub fn eat(&mut self) -> bool {
     if self.how_hungry > 0 {
         println!("OM NOM NOM");
         self.how_hungry -= 2;
@@ -24,12 +24,12 @@ impl Cat {
 }
 
 impl Noisy for Cat {
-  fn speak(&self) { self.meow(); }
+  fn speak(&mut self) { self.meow(); }
 
 }
 
 impl Cat {
-    fn meow(&self) {
+    fn meow(&mut self) {
       println!("Meow");
       self.meows += 1;
       if self.meows % 5 == 0 {
diff --git a/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs b/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs
index a2290d85020..16f7df1b363 100644
--- a/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs
+++ b/tests/ui/closures/2229_closure_analysis/diagnostics/borrowck/borrowck-4.rs
@@ -15,6 +15,6 @@ fn foo () -> impl FnMut()->() {
     c
 }
 fn main() {
-    let c = foo();
+    let mut c = foo();
     c();
 }
diff --git a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr
index c83ba41976b..8a2aaade665 100644
--- a/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr
+++ b/tests/ui/closures/2229_closure_analysis/match/match-edge-cases_1.stderr
@@ -5,8 +5,19 @@ LL |             NUMBER_POINTER => (),
    |             ^^^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: `#[warn(pointer_structural_match)]` on by default
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/match-edge-cases_1.rs:29:13
+   |
+LL |             NUMBER_POINTER => (),
+   |             ^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.min_exhaustive_patterns.stderr b/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.min_exhaustive_patterns.stderr
new file mode 100644
index 00000000000..b54341f82c7
--- /dev/null
+++ b/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.min_exhaustive_patterns.stderr
@@ -0,0 +1,11 @@
+warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/multivariant.rs:7:46
+   |
+LL | #![cfg_attr(min_exhaustive_patterns, 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
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs b/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs
index 72652ef6034..bc2386e5d23 100644
--- a/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs
+++ b/tests/ui/closures/2229_closure_analysis/run_pass/multivariant.rs
@@ -1,8 +1,11 @@
 // Test precise capture of a multi-variant enum (when remaining variants are
 // visibly uninhabited).
+// revisions: min_exhaustive_patterns exhaustive_patterns
 // edition:2021
 // run-pass
-#![feature(exhaustive_patterns)]
+#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
+#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
+//[min_exhaustive_patterns]~^ WARN the feature `min_exhaustive_patterns` is incomplete
 #![feature(never_type)]
 
 pub fn main() {
diff --git a/tests/ui/closures/binder/implicit-stuff.rs b/tests/ui/closures/binder/implicit-stuff.rs
index 09e4c747afe..c976c200b0c 100644
--- a/tests/ui/closures/binder/implicit-stuff.rs
+++ b/tests/ui/closures/binder/implicit-stuff.rs
@@ -24,4 +24,5 @@ fn main() {
                                                //~| ERROR `'_` cannot be used here
     let _ = for<'a> |x: &()| -> &'a () { x };  //~ ERROR `&` without an explicit lifetime name cannot be used here
     let _ = for<'a> |x: &'a ()| -> &() { x };  //~ ERROR `&` without an explicit lifetime name cannot be used here
+    //~^ ERROR: lifetime may not live long enough
 }
diff --git a/tests/ui/closures/binder/implicit-stuff.stderr b/tests/ui/closures/binder/implicit-stuff.stderr
index cec2a60ba28..330a05a79ba 100644
--- a/tests/ui/closures/binder/implicit-stuff.stderr
+++ b/tests/ui/closures/binder/implicit-stuff.stderr
@@ -102,6 +102,15 @@ LL |     let _ = for<'a> |x: &'a _, y, z: _| -> &'a _ {
    |             |
    |             `for<...>` is here
 
-error: aborting due to 15 previous errors
+error: lifetime may not live long enough
+  --> $DIR/implicit-stuff.rs:26:42
+   |
+LL |     let _ = for<'a> |x: &'a ()| -> &() { x };
+   |                 --                 -     ^ returning this value requires that `'a` must outlive `'1`
+   |                 |                  |
+   |                 |                  let's call the lifetime of this reference `'1`
+   |                 lifetime `'a` defined here
+
+error: aborting due to 16 previous errors
 
 For more information about this error, try `rustc --explain E0637`.
diff --git a/tests/ui/closures/issue-109188.rs b/tests/ui/closures/issue-109188.rs
index cae1ced9958..03c8b415774 100644
--- a/tests/ui/closures/issue-109188.rs
+++ b/tests/ui/closures/issue-109188.rs
@@ -7,13 +7,13 @@ struct X(Y);
 
 struct Y;
 
-fn consume_fnmut(f: &dyn FnMut()) {
+fn consume_fnmut(f: &mut dyn FnMut()) {
     f();
 }
 
 fn move_into_fnmut() {
     let x = move_into_fnmut();
-    consume_fnmut(&|| {
+    consume_fnmut(&mut || {
         let Either::One(_t) = x; //~ ERROR mismatched types
         let Either::Two(_t) = x; //~ ERROR mismatched types
     });
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs
index 6320d296373..72c14cd7a69 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.rs
@@ -2,8 +2,11 @@
 // needs-llvm-components: arm
 #![feature(cmse_nonsecure_entry, no_core, lang_items)]
 #![no_core]
-#[lang="sized"]
-trait Sized { }
+#[lang = "sized"]
+trait Sized {}
+
+#[lang = "copy"]
+trait Copy {}
 
 #[no_mangle]
 #[cmse_nonsecure_entry]
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr
index 4d34f0d7509..c3fae3d8bbb 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-entry/wrong-abi.stderr
@@ -1,5 +1,5 @@
 error[E0776]: `#[cmse_nonsecure_entry]` requires C ABI
-  --> $DIR/wrong-abi.rs:9:1
+  --> $DIR/wrong-abi.rs:12:1
    |
 LL | #[cmse_nonsecure_entry]
    | ^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/issues/issue-82833-slice-miscompile.rs b/tests/ui/codegen/issue-82833-slice-miscompile.rs
index 8cf6a3137e2..8cf6a3137e2 100644
--- a/tests/ui/issues/issue-82833-slice-miscompile.rs
+++ b/tests/ui/codegen/issue-82833-slice-miscompile.rs
diff --git a/tests/ui/coercion/issue-14589.rs b/tests/ui/coercion/issue-14589.rs
index f92385f8d72..6f95b30be06 100644
--- a/tests/ui/coercion/issue-14589.rs
+++ b/tests/ui/coercion/issue-14589.rs
@@ -19,6 +19,6 @@ impl<T> Test<T> {
     fn send(&self, _: T) {}
 }
 
-trait Foo { fn dummy(&self) { }}
+trait Foo { fn dummy(&self) { }} //~ WARN method `dummy` is never used
 struct Output(#[allow(dead_code)] isize);
 impl Foo for Output {}
diff --git a/tests/ui/coercion/issue-14589.stderr b/tests/ui/coercion/issue-14589.stderr
new file mode 100644
index 00000000000..37b7fce7462
--- /dev/null
+++ b/tests/ui/coercion/issue-14589.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/issue-14589.rs:22:16
+   |
+LL | trait Foo { fn dummy(&self) { }}
+   |       ---      ^^^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-26905-rpass.rs b/tests/ui/coercion/issue-26905-rpass.rs
index 2d5827f476b..2d5827f476b 100644
--- a/tests/ui/issues/issue-26905-rpass.rs
+++ b/tests/ui/coercion/issue-26905-rpass.rs
diff --git a/tests/ui/issues/issue-26905.rs b/tests/ui/coercion/issue-26905.rs
index 4c5c67d58bc..4c5c67d58bc 100644
--- a/tests/ui/issues/issue-26905.rs
+++ b/tests/ui/coercion/issue-26905.rs
diff --git a/tests/ui/issues/issue-26905.stderr b/tests/ui/coercion/issue-26905.stderr
index 86f6a14cd10..86f6a14cd10 100644
--- a/tests/ui/issues/issue-26905.stderr
+++ b/tests/ui/coercion/issue-26905.stderr
diff --git a/tests/ui/coherence/associated-type2.rs b/tests/ui/coherence/associated-type2.rs
new file mode 100644
index 00000000000..2aadfb04af0
--- /dev/null
+++ b/tests/ui/coherence/associated-type2.rs
@@ -0,0 +1,20 @@
+//! A regression test for #120343. The overlap error was previously
+//! silenced in coherence because projecting `<() as ToUnit>::Unit`
+//! failed. Then then silenced the missing items error in the `ToUnit`
+//! impl, causing us to not emit any errors and ICEing due to a
+//! `span_delay_bug`.
+
+trait ToUnit {
+    type Unit;
+}
+
+impl<T> ToUnit for *const T {}
+//~^ ERROR: not all trait items implemented
+
+trait Overlap<T> {}
+
+impl<T> Overlap<T> for T {}
+
+impl<T> Overlap<<*const T as ToUnit>::Unit> for T {}
+
+fn main() {}
diff --git a/tests/ui/coherence/associated-type2.stderr b/tests/ui/coherence/associated-type2.stderr
new file mode 100644
index 00000000000..62d3d8b8ebd
--- /dev/null
+++ b/tests/ui/coherence/associated-type2.stderr
@@ -0,0 +1,12 @@
+error[E0046]: not all trait items implemented, missing: `Unit`
+  --> $DIR/associated-type2.rs:11:1
+   |
+LL |     type Unit;
+   |     --------- `Unit` from trait
+...
+LL | impl<T> ToUnit for *const T {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Unit` in implementation
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
index 6a9db217373..cdec81271d0 100644
--- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
+++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.rs
@@ -22,6 +22,7 @@ struct MyType {
 impl MyTrait<MyType> for MyType {
 //~^ ERROR E0119
     fn get(&self) -> usize { (*self).clone() }
+    //~^ ERROR incompatible type
 }
 
 fn main() { }
diff --git a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
index ddb7474c289..471dfe1cae7 100644
--- a/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
+++ b/tests/ui/coherence/coherence-blanket-conflicts-with-specific-multidispatch.stderr
@@ -7,6 +7,24 @@ LL | impl<T> MyTrait<T> for T {
 LL | impl MyTrait<MyType> for MyType {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `MyType`
 
-error: aborting due to 1 previous error
+error[E0053]: method `get` has an incompatible type for trait
+  --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:24:22
+   |
+LL |     fn get(&self) -> usize { (*self).clone() }
+   |                      ^^^^^
+   |                      |
+   |                      expected `MyType`, found `usize`
+   |                      help: change the output type to match the trait: `MyType`
+   |
+note: type in trait
+  --> $DIR/coherence-blanket-conflicts-with-specific-multidispatch.rs:8:22
+   |
+LL |     fn get(&self) -> T;
+   |                      ^
+   = note: expected signature `fn(&MyType) -> MyType`
+              found signature `fn(&MyType) -> usize`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0053, E0119.
+For more information about an error, try `rustc --explain E0053`.
diff --git a/tests/ui/coherence/coherence-multidispatch-tuple.rs b/tests/ui/coherence/coherence-multidispatch-tuple.rs
index fa1d4bbb496..b04b2a296b5 100644
--- a/tests/ui/coherence/coherence-multidispatch-tuple.rs
+++ b/tests/ui/coherence/coherence-multidispatch-tuple.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 #![allow(unused_imports)]
 // pretty-expanded FIXME #23616
 
diff --git a/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs
index bed782203af..985cfe87161 100644
--- a/tests/ui/coherence/coherence-orphan.rs
+++ b/tests/ui/coherence/coherence-orphan.rs
@@ -9,10 +9,13 @@ struct TheType;
 
 impl TheTrait<usize> for isize { }
 //~^ ERROR E0117
+//~| ERROR not all trait items implemented
 
 impl TheTrait<TheType> for isize { }
+//~^ ERROR not all trait items implemented
 
 impl TheTrait<isize> for TheType { }
+//~^ ERROR not all trait items implemented
 
 impl !Send for Vec<isize> { } //~ ERROR E0117
 //~^ WARNING
diff --git a/tests/ui/coherence/coherence-orphan.stderr b/tests/ui/coherence/coherence-orphan.stderr
index 9ec1d0dc32a..78fad837647 100644
--- a/tests/ui/coherence/coherence-orphan.stderr
+++ b/tests/ui/coherence/coherence-orphan.stderr
@@ -11,7 +11,7 @@ LL | impl TheTrait<usize> for isize { }
    = note: define and implement a trait or new type instead
 
 error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate
-  --> $DIR/coherence-orphan.rs:17:1
+  --> $DIR/coherence-orphan.rs:20:1
    |
 LL | impl !Send for Vec<isize> { }
    | ^^^^^^^^^^^^^^^----------
@@ -22,7 +22,7 @@ LL | impl !Send for Vec<isize> { }
    = note: define and implement a trait or new type instead
 
 warning: cross-crate traits with a default impl, like `Send`, should not be specialized
-  --> $DIR/coherence-orphan.rs:17:1
+  --> $DIR/coherence-orphan.rs:20:1
    |
 LL | impl !Send for Vec<isize> { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -34,6 +34,31 @@ note: try using the same sequence of generic parameters as the struct definition
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
    = note: `#[warn(suspicious_auto_trait_impls)]` on by default
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error[E0046]: not all trait items implemented, missing: `the_fn`
+  --> $DIR/coherence-orphan.rs:10:1
+   |
+LL | impl TheTrait<usize> for isize { }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
+   |
+   = help: implement the missing item: `fn the_fn(&self) { todo!() }`
+
+error[E0046]: not all trait items implemented, missing: `the_fn`
+  --> $DIR/coherence-orphan.rs:14:1
+   |
+LL | impl TheTrait<TheType> for isize { }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
+   |
+   = help: implement the missing item: `fn the_fn(&self) { todo!() }`
+
+error[E0046]: not all trait items implemented, missing: `the_fn`
+  --> $DIR/coherence-orphan.rs:17:1
+   |
+LL | impl TheTrait<isize> for TheType { }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `the_fn` in implementation
+   |
+   = help: implement the missing item: `fn the_fn(&self) { todo!() }`
+
+error: aborting due to 5 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0117`.
+Some errors have detailed explanations: E0046, E0117.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/coherence/deep-bad-copy-reason.rs b/tests/ui/coherence/deep-bad-copy-reason.rs
index 97fd3f719bf..f1c2698bad5 100644
--- a/tests/ui/coherence/deep-bad-copy-reason.rs
+++ b/tests/ui/coherence/deep-bad-copy-reason.rs
@@ -5,12 +5,15 @@ extern "Rust" {
 }
 
 pub struct ListS<T> {
+    //~^ NOTE: required because it appears within the type
     len: usize,
     data: [T; 0],
     opaque: OpaqueListContents,
 }
 
 pub struct Interned<'a, T>(&'a T);
+//~^ NOTE: required by an implicit `Sized`
+//~| NOTE: required by the implicit `Sized`
 
 impl<'a, T> Clone for Interned<'a, T> {
     fn clone(&self) -> Self {
@@ -23,6 +26,8 @@ impl<'a, T> Copy for Interned<'a, T> {}
 pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
 //~^ NOTE this field does not implement `Copy`
 //~| NOTE the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
+//~| NOTE: doesn't have a size known at compile-time
+//~| ERROR: cannot be known at compilation time
 
 impl<'tcx, T> Clone for List<'tcx, T> {
     fn clone(&self) -> Self {
diff --git a/tests/ui/coherence/deep-bad-copy-reason.stderr b/tests/ui/coherence/deep-bad-copy-reason.stderr
index e79abe35597..fe5ae9b08b4 100644
--- a/tests/ui/coherence/deep-bad-copy-reason.stderr
+++ b/tests/ui/coherence/deep-bad-copy-reason.stderr
@@ -1,5 +1,5 @@
 error[E0204]: the trait `Copy` cannot be implemented for this type
-  --> $DIR/deep-bad-copy-reason.rs:33:24
+  --> $DIR/deep-bad-copy-reason.rs:38:24
    |
 LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
    |                          ------------------------ this field does not implement `Copy`
@@ -8,11 +8,34 @@ LL | impl<'tcx, T> Copy for List<'tcx, T> {}
    |                        ^^^^^^^^^^^^^
    |
 note: the `Copy` impl for `Interned<'tcx, ListS<T>>` requires that `OpaqueListContents: Sized`
-  --> $DIR/deep-bad-copy-reason.rs:23:26
+  --> $DIR/deep-bad-copy-reason.rs:26:26
    |
 LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0277]: the size for values of type `OpaqueListContents` cannot be known at compilation time
+  --> $DIR/deep-bad-copy-reason.rs:26:26
+   |
+LL | pub struct List<'tcx, T>(Interned<'tcx, ListS<T>>);
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: within `ListS<T>`, the trait `Sized` is not implemented for `OpaqueListContents`, which is required by `ListS<T>: Sized`
+note: required because it appears within the type `ListS<T>`
+  --> $DIR/deep-bad-copy-reason.rs:7:12
+   |
+LL | pub struct ListS<T> {
+   |            ^^^^^
+note: required by an implicit `Sized` bound in `Interned`
+  --> $DIR/deep-bad-copy-reason.rs:14:25
+   |
+LL | pub struct Interned<'a, T>(&'a T);
+   |                         ^ required by the implicit `Sized` requirement on this type parameter in `Interned`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL | pub struct Interned<'a, T: ?Sized>(&'a T);
+   |                          ++++++++
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0204`.
+Some errors have detailed explanations: E0204, E0277.
+For more information about an error, try `rustc --explain E0204`.
diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr
index 428ee902ea5..4ad8257d2c1 100644
--- a/tests/ui/coherence/occurs-check/opaques.next.stderr
+++ b/tests/ui/coherence/occurs-check/opaques.next.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Trait<Alias<_>>` for type `Alias<_>`
-  --> $DIR/opaques.rs:29:1
+  --> $DIR/opaques.rs:30:1
    |
 LL | impl<T> Trait<T> for T {
    | ---------------------- first implementation here
@@ -7,6 +7,13 @@ LL | impl<T> Trait<T> for T {
 LL | impl<T> Trait<T> for defining_scope::Alias<T> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Alias<_>`
 
-error: aborting due to 1 previous error
+error[E0282]: type annotations needed
+  --> $DIR/opaques.rs:13:20
+   |
+LL |     pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
+   |                    ^ cannot infer type for struct `Container<Alias<T>, T>`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0119, E0282.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs
index 2fa9dcebfde..73cd42bf3f2 100644
--- a/tests/ui/coherence/occurs-check/opaques.rs
+++ b/tests/ui/coherence/occurs-check/opaques.rs
@@ -11,6 +11,7 @@ mod defining_scope {
     pub type Alias<T> = impl Sized;
 
     pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
+        //[next]~^ ERROR type annotations needed
         x
     }
 }
diff --git a/tests/ui/const-generics/associated-type-bound.rs b/tests/ui/const-generics/associated-type-bound.rs
index 3044736b47e..0a57352c10d 100644
--- a/tests/ui/const-generics/associated-type-bound.rs
+++ b/tests/ui/const-generics/associated-type-bound.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 trait Bar<const N: usize> {}
 
 trait Foo<const N: usize> {
diff --git a/tests/ui/const-generics/condition-in-trait-const-arg.rs b/tests/ui/const-generics/condition-in-trait-const-arg.rs
index 6f85237cf0a..74a663a53ec 100644
--- a/tests/ui/const-generics/condition-in-trait-const-arg.rs
+++ b/tests/ui/const-generics/condition-in-trait-const-arg.rs
@@ -1,5 +1,5 @@
 // Checks that `impl Trait<{anon_const}> for Type` evaluates successfully.
-// run-pass
+// check-pass
 // revisions: full min
 
 #![cfg_attr(full, feature(generic_const_exprs))]
diff --git a/tests/ui/const-generics/dyn-supertraits.rs b/tests/ui/const-generics/dyn-supertraits.rs
index 3dee326a186..bb492452982 100644
--- a/tests/ui/const-generics/dyn-supertraits.rs
+++ b/tests/ui/const-generics/dyn-supertraits.rs
@@ -4,7 +4,7 @@ trait Foo<const N: usize> {
     fn myfun(&self) -> usize;
 }
 trait Bar<const N: usize> : Foo<N> {}
-trait Baz: Foo<3> {}
+trait Baz: Foo<3> {} //~ WARN trait `Baz` is never used
 
 struct FooType<const N: usize>;
 struct BarType<const N: usize>;
@@ -23,10 +23,10 @@ impl Foo<3> for BazType {
 impl Baz for BazType {}
 
 trait Foz {}
-trait Boz: Foo<3> + Foz {}
+trait Boz: Foo<3> + Foz {} //~ WARN trait `Boz` is never used
 trait Bok<const N: usize>: Foo<N> + Foz {}
 
-struct FozType;
+struct FozType; //~ WARN struct `FozType` is never constructed
 struct BozType;
 struct BokType<const N: usize>;
 
diff --git a/tests/ui/const-generics/dyn-supertraits.stderr b/tests/ui/const-generics/dyn-supertraits.stderr
new file mode 100644
index 00000000000..38b67ef4403
--- /dev/null
+++ b/tests/ui/const-generics/dyn-supertraits.stderr
@@ -0,0 +1,22 @@
+warning: trait `Baz` is never used
+  --> $DIR/dyn-supertraits.rs:7:7
+   |
+LL | trait Baz: Foo<3> {}
+   |       ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: trait `Boz` is never used
+  --> $DIR/dyn-supertraits.rs:26:7
+   |
+LL | trait Boz: Foo<3> + Foz {}
+   |       ^^^
+
+warning: struct `FozType` is never constructed
+  --> $DIR/dyn-supertraits.rs:29:8
+   |
+LL | struct FozType;
+   |        ^^^^^^^
+
+warning: 3 warnings emitted
+
diff --git a/tests/ui/const-generics/issues/issue-69654-run-pass.rs b/tests/ui/const-generics/issues/issue-69654-run-pass.rs
index 63d7fde78ac..21d6270b1fa 100644
--- a/tests/ui/const-generics/issues/issue-69654-run-pass.rs
+++ b/tests/ui/const-generics/issues/issue-69654-run-pass.rs
@@ -1,5 +1,5 @@
 // run-pass
-trait Bar<T> {}
+trait Bar<T> {} //~ WARN trait `Bar` is never used
 impl<T> Bar<T> for [u8; 7] {}
 
 struct Foo<const N: usize> {}
diff --git a/tests/ui/const-generics/issues/issue-69654-run-pass.stderr b/tests/ui/const-generics/issues/issue-69654-run-pass.stderr
new file mode 100644
index 00000000000..7b3cd4f375f
--- /dev/null
+++ b/tests/ui/const-generics/issues/issue-69654-run-pass.stderr
@@ -0,0 +1,10 @@
+warning: trait `Bar` is never used
+  --> $DIR/issue-69654-run-pass.rs:2:7
+   |
+LL | trait Bar<T> {}
+   |       ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/const-generics/issues/issue-90318.rs b/tests/ui/const-generics/issues/issue-90318.rs
index 909997340f3..cebc1ce2142 100644
--- a/tests/ui/const-generics/issues/issue-90318.rs
+++ b/tests/ui/const-generics/issues/issue-90318.rs
@@ -13,6 +13,7 @@ fn consume<T: 'static>(_val: T)
 where
     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
     //~^ overly complex generic constant
+    //~| ERROR: cannot call
 {
 }
 
@@ -20,6 +21,7 @@ fn test<T: 'static>()
 where
     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
     //~^ overly complex generic constant
+    //~| ERROR: cannot call
 {
 }
 
diff --git a/tests/ui/const-generics/issues/issue-90318.stderr b/tests/ui/const-generics/issues/issue-90318.stderr
index f13fd795d7a..471a6660ce0 100644
--- a/tests/ui/const-generics/issues/issue-90318.stderr
+++ b/tests/ui/const-generics/issues/issue-90318.stderr
@@ -10,7 +10,7 @@ LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
    = note: this operation may be supported in the future
 
 error: overly complex generic constant
-  --> $DIR/issue-90318.rs:21:8
+  --> $DIR/issue-90318.rs:22:8
    |
 LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
    |        ^^-----------------^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,5 +20,28 @@ LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
    = help: consider moving this anonymous constant into a `const` function
    = note: this operation may be supported in the future
 
-error: aborting due to 2 previous errors
+error[E0015]: cannot call non-const operator in constants
+  --> $DIR/issue-90318.rs:14:10
+   |
+LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error[E0015]: cannot call non-const operator in constants
+  --> $DIR/issue-90318.rs:22:10
+   |
+LL |     If<{ TypeId::of::<T>() != TypeId::of::<()>() }>: True,
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/any.rs:LL:COL
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error: aborting due to 4 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr
index 1fe0109771c..e42bb6e8cc5 100644
--- a/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr
+++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr
@@ -13,5 +13,37 @@ LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
    = help: consider moving this anonymous constant into a `const` function
    = note: this operation may be supported in the future
 
-error: aborting due to 2 previous errors
+error[E0391]: cycle detected when evaluating type-level constant
+  --> $DIR/late-bound-in-return-issue-77357.rs:9:46
+   |
+LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: ...which requires const-evaluating + checking `bug::{constant#0}`...
+  --> $DIR/late-bound-in-return-issue-77357.rs:9:46
+   |
+LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires caching mir of `bug::{constant#0}` for CTFE...
+  --> $DIR/late-bound-in-return-issue-77357.rs:9:46
+   |
+LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires elaborating drops for `bug::{constant#0}`...
+  --> $DIR/late-bound-in-return-issue-77357.rs:9:46
+   |
+LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires borrow-checking `bug::{constant#0}`...
+  --> $DIR/late-bound-in-return-issue-77357.rs:9:46
+   |
+LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> {
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...which requires normalizing `Binder { value: ConstEvaluatable(UnevaluatedConst { def: DefId(0:8 ~ late_bound_in_return_issue_77357[9394]::bug::{constant#0}), args: [T/#0] }: usize), bound_vars: [] }`...
+   = note: ...which again requires evaluating type-level constant, completing the cycle
+   = note: cycle used when normalizing `&dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]>`
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: aborting due to 3 previous errors
 
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/consts/const-block-item.rs b/tests/ui/consts/const-block-item.rs
index cf0d4441d4a..a04f4db263b 100644
--- a/tests/ui/consts/const-block-item.rs
+++ b/tests/ui/consts/const-block-item.rs
@@ -2,7 +2,7 @@
 #![allow(unused_imports)]
 
 mod foo {
-    pub trait Value {
+    pub trait Value { //~ WARN trait `Value` is never used
         fn value(&self) -> usize;
     }
 }
diff --git a/tests/ui/consts/const-block-item.stderr b/tests/ui/consts/const-block-item.stderr
new file mode 100644
index 00000000000..04658742b56
--- /dev/null
+++ b/tests/ui/consts/const-block-item.stderr
@@ -0,0 +1,10 @@
+warning: trait `Value` is never used
+  --> $DIR/const-block-item.rs:5:15
+   |
+LL |     pub trait Value {
+   |               ^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/consts/const-eval/raw-pointer-ub.rs b/tests/ui/consts/const-eval/raw-pointer-ub.rs
index 3341f3c78e0..47105de453c 100644
--- a/tests/ui/consts/const-eval/raw-pointer-ub.rs
+++ b/tests/ui/consts/const-eval/raw-pointer-ub.rs
@@ -1,4 +1,4 @@
-#![feature(const_mut_refs)]
+#![feature(const_mut_refs, const_intrinsic_copy)]
 
 
 const MISALIGNED_LOAD: () = unsafe {
diff --git a/tests/ui/consts/const-for-feature-gate.rs b/tests/ui/consts/const-for-feature-gate.rs
index bec7b808905..c834046c5b0 100644
--- a/tests/ui/consts/const-for-feature-gate.rs
+++ b/tests/ui/consts/const-for-feature-gate.rs
@@ -3,6 +3,9 @@
 const _: () = {
     for _ in 0..5 {}
     //~^ error: `for` is not allowed in a `const`
+    //~| ERROR: cannot convert
+    //~| ERROR: cannot call
+    //~| ERROR: mutable references
 };
 
 fn main() {}
diff --git a/tests/ui/consts/const-for-feature-gate.stderr b/tests/ui/consts/const-for-feature-gate.stderr
index df79c00f024..413d144ca0a 100644
--- a/tests/ui/consts/const-for-feature-gate.stderr
+++ b/tests/ui/consts/const-for-feature-gate.stderr
@@ -8,6 +8,37 @@ LL |     for _ in 0..5 {}
    = help: add `#![feature(const_for)]` 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: aborting due to 1 previous error
+error[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants
+  --> $DIR/const-for-feature-gate.rs:4:14
+   |
+LL |     for _ in 0..5 {}
+   |              ^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constants
+  --> $DIR/const-for-feature-gate.rs:4:14
+   |
+LL |     for _ in 0..5 {}
+   |              ^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` 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[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
+  --> $DIR/const-for-feature-gate.rs:4:14
+   |
+LL |     for _ in 0..5 {}
+   |              ^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0015, E0658.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/const-try-feature-gate.rs b/tests/ui/consts/const-try-feature-gate.rs
index 0839c23a0b9..1cc045bf612 100644
--- a/tests/ui/consts/const-try-feature-gate.rs
+++ b/tests/ui/consts/const-try-feature-gate.rs
@@ -3,6 +3,8 @@
 const fn t() -> Option<()> {
     Some(())?;
     //~^ error: `?` is not allowed in a `const fn`
+    //~| ERROR: cannot convert
+    //~| ERROR: cannot determine
     None
 }
 
diff --git a/tests/ui/consts/const-try-feature-gate.stderr b/tests/ui/consts/const-try-feature-gate.stderr
index c5aeed3317c..efa1fb107f6 100644
--- a/tests/ui/consts/const-try-feature-gate.stderr
+++ b/tests/ui/consts/const-try-feature-gate.stderr
@@ -8,6 +8,29 @@ LL |     Some(())?;
    = help: add `#![feature(const_try)]` 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: aborting due to 1 previous error
+error[E0015]: `?` cannot determine the branch of `Option<()>` in constant functions
+  --> $DIR/const-try-feature-gate.rs:4:5
+   |
+LL |     Some(())?;
+   |     ^^^^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error[E0015]: `?` cannot convert from residual of `Option<()>` in constant functions
+  --> $DIR/const-try-feature-gate.rs:4:5
+   |
+LL |     Some(())?;
+   |     ^^^^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0015, E0658.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/const_in_pattern/accept_structural.rs b/tests/ui/consts/const_in_pattern/accept_structural.rs
index 1f56f581c02..69b4e75c622 100644
--- a/tests/ui/consts/const_in_pattern/accept_structural.rs
+++ b/tests/ui/consts/const_in_pattern/accept_structural.rs
@@ -63,4 +63,18 @@ fn main() {
 
     const ADDR_OF: &OND = &None;
     match &None { ADDR_OF => dbg!(ADDR_OF),  _ => panic!("whoops"), };
+
+    // These ones are more subtle: the final value is fine, but statically analyzing the expression
+    // that computes the value would likely (incorrectly) have us conclude that this may match on
+    // values that do not have structural equality.
+    const INDEX: Option<NoDerive> = [None, Some(NoDerive(10))][0];
+    match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
+
+    const fn build() -> Option<NoDerive> { None }
+    const CALL: Option<NoDerive> = build();
+    match None { Some(_) => panic!("whoops"), CALL => dbg!(CALL), };
+
+    impl NoDerive { const fn none() -> Option<NoDerive> { None } }
+    const METHOD_CALL: Option<NoDerive> = NoDerive::none();
+    match None { Some(_) => panic!("whoops"), METHOD_CALL => dbg!(METHOD_CALL), };
 }
diff --git a/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs b/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs
index a38731ceb8a..ac89b7925ff 100644
--- a/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs
+++ b/tests/ui/consts/const_in_pattern/custom-eq-branch-pass.rs
@@ -12,6 +12,7 @@ impl PartialEq for CustomEq {
 }
 
 #[derive(PartialEq, Eq)]
+#[allow(unused)]
 enum Foo {
     Bar,
     Baz,
@@ -21,7 +22,7 @@ enum Foo {
 const BAR_BAZ: Foo = if 42 == 42 {
     Foo::Bar
 } else {
-    Foo::Baz
+    Foo::Qux(CustomEq) // dead arm
 };
 
 fn main() {
diff --git a/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.rs b/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.rs
deleted file mode 100644
index 34b1422dfb3..00000000000
--- a/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// check-pass
-
-struct CustomEq;
-
-impl Eq for CustomEq {}
-impl PartialEq for CustomEq {
-    fn eq(&self, _: &Self) -> bool {
-        false
-    }
-}
-
-#[derive(PartialEq, Eq)]
-enum Foo {
-    Bar,
-    Baz,
-    Qux(CustomEq),
-}
-
-// We know that `BAR_BAZ` will always be `Foo::Bar` and thus eligible for structural matching, but
-// dataflow will be more conservative.
-const BAR_BAZ: Foo = if 42 == 42 {
-    Foo::Bar
-} else {
-    Foo::Qux(CustomEq)
-};
-
-fn main() {
-    match Foo::Qux(CustomEq) {
-        BAR_BAZ => panic!(),
-        //~^ WARN must be annotated with `#[derive(PartialEq)]`
-        //~| NOTE the traits must be derived
-        //~| NOTE StructuralPartialEq.html for details
-        //~| WARN this was previously accepted
-        //~| NOTE see issue #73448
-        //~| NOTE `#[warn(nontrivial_structural_match)]` on by default
-        _ => {}
-    }
-}
diff --git a/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr b/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr
deleted file mode 100644
index c473c00f8db..00000000000
--- a/tests/ui/consts/const_in_pattern/custom-eq-branch-warn.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-warning: to use a constant of type `CustomEq` in a pattern, the constant's initializer must be trivial or `CustomEq` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/custom-eq-branch-warn.rs:29:9
-   |
-LL |         BAR_BAZ => panic!(),
-   |         ^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
-   = note: `#[warn(nontrivial_structural_match)]` on by default
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr
index 1546f23908c..bc1015c1734 100644
--- a/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr
+++ b/tests/ui/consts/const_in_pattern/issue-34784-match-on-non-int-raw-ptr.stderr
@@ -5,7 +5,7 @@ LL |         C => {}
    |         ^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 note: the lint level is defined here
   --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
    |
@@ -19,7 +19,7 @@ LL |         C_INNER => {}
    |         ^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:30:9
@@ -28,7 +28,7 @@ LL |         D => {}
    |         ^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:36:9
@@ -37,7 +37,67 @@ LL |         STR => {}
    |         ^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 error: aborting due to 4 previous errors
 
+Future incompatibility report: Future breakage diagnostic:
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:10:9
+   |
+LL |         C => {}
+   |         ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+note: the lint level is defined here
+  --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
+   |
+LL | #![deny(pointer_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:18:9
+   |
+LL |         C_INNER => {}
+   |         ^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+note: the lint level is defined here
+  --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
+   |
+LL | #![deny(pointer_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:30:9
+   |
+LL |         D => {}
+   |         ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+note: the lint level is defined here
+  --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
+   |
+LL | #![deny(pointer_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+error: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:36:9
+   |
+LL |         STR => {}
+   |         ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+note: the lint level is defined here
+  --> $DIR/issue-34784-match-on-non-int-raw-ptr.rs:1:9
+   |
+LL | #![deny(pointer_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/consts/const_in_pattern/issue-44333.stderr b/tests/ui/consts/const_in_pattern/issue-44333.stderr
index 441aeecbc6d..f5931f0cad0 100644
--- a/tests/ui/consts/const_in_pattern/issue-44333.stderr
+++ b/tests/ui/consts/const_in_pattern/issue-44333.stderr
@@ -5,7 +5,7 @@ LL |         FOO => println!("foo"),
    |         ^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 note: the lint level is defined here
   --> $DIR/issue-44333.rs:3:9
    |
@@ -19,7 +19,37 @@ LL |         BAR => println!("bar"),
    |         ^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: 2 warnings emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/issue-44333.rs:19:9
+   |
+LL |         FOO => println!("foo"),
+   |         ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+note: the lint level is defined here
+  --> $DIR/issue-44333.rs:3:9
+   |
+LL | #![warn(pointer_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/issue-44333.rs:21:9
+   |
+LL |         BAR => println!("bar"),
+   |         ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+note: the lint level is defined here
+  --> $DIR/issue-44333.rs:3:9
+   |
+LL | #![warn(pointer_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/consts/const_in_pattern/issue-73431.stderr b/tests/ui/consts/const_in_pattern/issue-73431.stderr
deleted file mode 100644
index c82dea4aa50..00000000000
--- a/tests/ui/consts/const_in_pattern/issue-73431.stderr
+++ /dev/null
@@ -1 +0,0 @@
-WARN rustc_mir_build::thir::pattern::const_to_pat MIR const-checker found novel structural match violation. See #73448.
diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.rs b/tests/ui/consts/const_in_pattern/reject_non_structural.rs
index 196930baed5..71d4138104d 100644
--- a/tests/ui/consts/const_in_pattern/reject_non_structural.rs
+++ b/tests/ui/consts/const_in_pattern/reject_non_structural.rs
@@ -100,5 +100,5 @@ fn main() {
     //~| NOTE the traits must be derived
     //~| NOTE StructuralPartialEq.html for details
     //~| WARN previously accepted by the compiler but is being phased out
-    //~| NOTE for more information, see issue #62411
+    //~| NOTE for more information, see
 }
diff --git a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
index da32b6d698b..2c7aaf89aa7 100644
--- a/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
+++ b/tests/ui/consts/const_in_pattern/reject_non_structural.stderr
@@ -86,7 +86,7 @@ LL |     match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops")
    |                             ^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 note: the lint level is defined here
@@ -97,3 +97,20 @@ LL | #![warn(indirect_structural_match)]
 
 error: aborting due to 9 previous errors; 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+  --> $DIR/reject_non_structural.rs:98:29
+   |
+LL |     match &Some(NoDerive) { ADDR_OF => dbg!(ADDR_OF), _ => panic!("whoops"), };
+   |                             ^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: the traits must be derived, manual `impl`s are not sufficient
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the lint level is defined here
+  --> $DIR/reject_non_structural.rs:14:9
+   |
+LL | #![warn(indirect_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/consts/const_in_pattern/warn_corner_cases.rs b/tests/ui/consts/const_in_pattern/warn_corner_cases.rs
deleted file mode 100644
index 75f1965921c..00000000000
--- a/tests/ui/consts/const_in_pattern/warn_corner_cases.rs
+++ /dev/null
@@ -1,41 +0,0 @@
-// run-pass
-
-// This test is checking our logic for structural match checking by enumerating
-// the different kinds of const expressions. This test is collecting cases where
-// we have accepted the const expression as a pattern in the past but we want
-// to begin warning the user that a future version of Rust may start rejecting
-// such const expressions.
-
-// The specific corner cases we are exploring here are instances where the
-// const-evaluator computes a value that *does* meet the conditions for
-// structural-match, but the const expression itself has abstractions (like
-// calls to const functions) that may fit better with a type-based analysis
-// rather than a commitment to a specific value.
-
-#![warn(indirect_structural_match)]
-
-#[derive(Copy, Clone, Debug)]
-struct NoDerive(#[allow(dead_code)] u32);
-
-// This impl makes `NoDerive` irreflexive.
-impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } }
-impl Eq for NoDerive { }
-
-fn main() {
-    const INDEX: Option<NoDerive> = [None, Some(NoDerive(10))][0];
-    match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
-    //~^ WARN must be annotated with `#[derive(PartialEq)]`
-    //~| WARN this was previously accepted
-
-    const fn build() -> Option<NoDerive> { None }
-    const CALL: Option<NoDerive> = build();
-    match None { Some(_) => panic!("whoops"), CALL => dbg!(CALL), };
-    //~^ WARN must be annotated with `#[derive(PartialEq)]`
-    //~| WARN this was previously accepted
-
-    impl NoDerive { const fn none() -> Option<NoDerive> { None } }
-    const METHOD_CALL: Option<NoDerive> = NoDerive::none();
-    match None { Some(_) => panic!("whoops"), METHOD_CALL => dbg!(METHOD_CALL), };
-    //~^ WARN must be annotated with `#[derive(PartialEq)]`
-    //~| WARN this was previously accepted
-}
diff --git a/tests/ui/consts/const_in_pattern/warn_corner_cases.stderr b/tests/ui/consts/const_in_pattern/warn_corner_cases.stderr
deleted file mode 100644
index 8ffd035ebec..00000000000
--- a/tests/ui/consts/const_in_pattern/warn_corner_cases.stderr
+++ /dev/null
@@ -1,36 +0,0 @@
-warning: to use a constant of type `NoDerive` in a pattern, the constant's initializer must be trivial or `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/warn_corner_cases.rs:26:47
-   |
-LL |     match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), };
-   |                                               ^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
-   = note: `#[warn(nontrivial_structural_match)]` on by default
-
-warning: to use a constant of type `NoDerive` in a pattern, the constant's initializer must be trivial or `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/warn_corner_cases.rs:32:47
-   |
-LL |     match None { Some(_) => panic!("whoops"), CALL => dbg!(CALL), };
-   |                                               ^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
-
-warning: to use a constant of type `NoDerive` in a pattern, the constant's initializer must be trivial or `NoDerive` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/warn_corner_cases.rs:38:47
-   |
-LL |     match None { Some(_) => panic!("whoops"), METHOD_CALL => dbg!(METHOD_CALL), };
-   |                                               ^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #73448 <https://github.com/rust-lang/rust/issues/73448>
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
-
-warning: 3 warnings emitted
-
diff --git a/tests/ui/consts/control-flow/loop.rs b/tests/ui/consts/control-flow/loop.rs
index 2b8561a2644..5b7f8d29df7 100644
--- a/tests/ui/consts/control-flow/loop.rs
+++ b/tests/ui/consts/control-flow/loop.rs
@@ -51,10 +51,16 @@ const _: i32 = {
     let mut x = 0;
 
     for i in 0..4 { //~ ERROR `for` is not allowed in a `const`
+        //~^ ERROR: cannot call
+        //~| ERROR: mutable references
+        //~| ERROR: cannot convert
         x += i;
     }
 
     for i in 0..4 { //~ ERROR `for` is not allowed in a `const`
+        //~^ ERROR: cannot call
+        //~| ERROR: mutable references
+        //~| ERROR: cannot convert
         x += i;
     }
 
diff --git a/tests/ui/consts/control-flow/loop.stderr b/tests/ui/consts/control-flow/loop.stderr
index 725adf72339..e162a404ace 100644
--- a/tests/ui/consts/control-flow/loop.stderr
+++ b/tests/ui/consts/control-flow/loop.stderr
@@ -2,6 +2,9 @@ error[E0658]: `for` is not allowed in a `const`
   --> $DIR/loop.rs:53:5
    |
 LL | /     for i in 0..4 {
+LL | |
+LL | |
+LL | |
 LL | |         x += i;
 LL | |     }
    | |_____^
@@ -11,9 +14,12 @@ LL | |     }
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `for` is not allowed in a `const`
-  --> $DIR/loop.rs:57:5
+  --> $DIR/loop.rs:60:5
    |
 LL | /     for i in 0..4 {
+LL | |
+LL | |
+LL | |
 LL | |         x += i;
 LL | |     }
    | |_____^
@@ -22,6 +28,67 @@ LL | |     }
    = help: add `#![feature(const_for)]` 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: aborting due to 2 previous errors
+error[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants
+  --> $DIR/loop.rs:53:14
+   |
+LL |     for i in 0..4 {
+   |              ^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constants
+  --> $DIR/loop.rs:53:14
+   |
+LL |     for i in 0..4 {
+   |              ^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` 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[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
+  --> $DIR/loop.rs:53:14
+   |
+LL |     for i in 0..4 {
+   |              ^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error[E0015]: cannot convert `std::ops::Range<i32>` into an iterator in constants
+  --> $DIR/loop.rs:60:14
+   |
+LL |     for i in 0..4 {
+   |              ^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error[E0658]: mutable references are not allowed in constants
+  --> $DIR/loop.rs:60:14
+   |
+LL |     for i in 0..4 {
+   |              ^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` 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[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants
+  --> $DIR/loop.rs:60:14
+   |
+LL |     for i in 0..4 {
+   |              ^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0015, E0658.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/control-flow/try.rs b/tests/ui/consts/control-flow/try.rs
index 7d85a412b47..5c6957df405 100644
--- a/tests/ui/consts/control-flow/try.rs
+++ b/tests/ui/consts/control-flow/try.rs
@@ -4,6 +4,8 @@
 const fn opt() -> Option<i32> {
     let x = Some(2);
     x?; //~ ERROR `?` is not allowed in a `const fn`
+    //~^ ERROR: cannot convert
+    //~| ERROR: cannot determine
     None
 }
 
diff --git a/tests/ui/consts/control-flow/try.stderr b/tests/ui/consts/control-flow/try.stderr
index f4b88de9dfa..f4c42c4d819 100644
--- a/tests/ui/consts/control-flow/try.stderr
+++ b/tests/ui/consts/control-flow/try.stderr
@@ -8,6 +8,29 @@ LL |     x?;
    = help: add `#![feature(const_try)]` 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: aborting due to 1 previous error
+error[E0015]: `?` cannot determine the branch of `Option<i32>` in constant functions
+  --> $DIR/try.rs:6:5
+   |
+LL |     x?;
+   |     ^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error[E0015]: `?` cannot convert from residual of `Option<i32>` in constant functions
+  --> $DIR/try.rs:6:5
+   |
+LL |     x?;
+   |     ^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0015, E0658.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/fn_trait_refs.stderr b/tests/ui/consts/fn_trait_refs.stderr
index e6ea4108f40..afe89461f03 100644
--- a/tests/ui/consts/fn_trait_refs.stderr
+++ b/tests/ui/consts/fn_trait_refs.stderr
@@ -74,6 +74,100 @@ LL |     T: ~const FnMut<()> + ~const Destruct,
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 11 previous errors
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/fn_trait_refs.rs:17:5
+   |
+LL |     f()
+   |     ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL |     T: ~const Fn<()> + ~const Destruct + ~const std::ops::Fn<()>,
+   |                                        +++++++++++++++++++++++++
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/fn_trait_refs.rs:13:23
+   |
+LL | const fn tester_fn<T>(f: T) -> T::Output
+   |                       ^ the destructor for this type cannot be evaluated in constant functions
+...
+LL | }
+   | - value is dropped here
+
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/fn_trait_refs.rs:24:5
+   |
+LL |     f()
+   |     ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL |     T: ~const FnMut<()> + ~const Destruct + ~const std::ops::FnMut<()>,
+   |                                           ++++++++++++++++++++++++++++
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/fn_trait_refs.rs:20:27
+   |
+LL | const fn tester_fn_mut<T>(mut f: T) -> T::Output
+   |                           ^^^^^ the destructor for this type cannot be evaluated in constant functions
+...
+LL | }
+   | - value is dropped here
+
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/fn_trait_refs.rs:31:5
+   |
+LL |     f()
+   |     ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL |     T: ~const FnOnce<()> + ~const std::ops::FnOnce<()>,
+   |                          +++++++++++++++++++++++++++++
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/fn_trait_refs.rs:34:21
+   |
+LL | const fn test_fn<T>(mut f: T) -> (T::Output, T::Output, T::Output)
+   |                     ^^^^^ the destructor for this type cannot be evaluated in constant functions
+...
+LL | }
+   | - value is dropped here
+
+error[E0493]: destructor of `T` cannot be evaluated at compile-time
+  --> $DIR/fn_trait_refs.rs:48:25
+   |
+LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
+   |                         ^^^^^ the destructor for this type cannot be evaluated in constant functions
+...
+LL | }
+   | - value is dropped here
+
+error[E0015]: cannot call non-const operator in constants
+  --> $DIR/fn_trait_refs.rs:72:17
+   |
+LL |         assert!(test_one == (1, 1, 1));
+   |                 ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error[E0015]: cannot call non-const operator in constants
+  --> $DIR/fn_trait_refs.rs:75:17
+   |
+LL |         assert!(test_two == (2, 2));
+   |                 ^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error: aborting due to 20 previous errors
 
-For more information about this error, try `rustc --explain E0635`.
+Some errors have detailed explanations: E0015, E0493, E0635.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/issue-89088.stderr b/tests/ui/consts/issue-89088.stderr
new file mode 100644
index 00000000000..d5c5f76b90a
--- /dev/null
+++ b/tests/ui/consts/issue-89088.stderr
@@ -0,0 +1,17 @@
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `Cow<'_, str>` in a pattern, `Cow<'_, str>` must be annotated with `#[derive(PartialEq)]`
+  --> $DIR/issue-89088.rs:19:9
+   |
+LL |         FOO => todo!(),
+   |         ^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: the traits must be derived, manual `impl`s are not sufficient
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the lint level is defined here
+  --> $DIR/issue-89088.rs:5:10
+   |
+LL | #![allow(indirect_structural_match)]
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/consts/promoted_const_call.stderr b/tests/ui/consts/promoted_const_call.stderr
index 1f6abc0ce7c..ace449fae9c 100644
--- a/tests/ui/consts/promoted_const_call.stderr
+++ b/tests/ui/consts/promoted_const_call.stderr
@@ -7,26 +7,6 @@ LL |     let _: &'static _ = &id(&Panic);
    |                              the destructor for this type cannot be evaluated in constants
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call.rs:11:26
-   |
-LL |     let _: &'static _ = &id(&Panic);
-   |            ----------    ^^^^^^^^^^ creates a temporary value which is freed while still in use
-   |            |
-   |            type annotation requires that borrow lasts for `'static`
-...
-LL | };
-   | - temporary value is freed at the end of this statement
-
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call.rs:11:30
-   |
-LL |     let _: &'static _ = &id(&Panic);
-   |            ----------        ^^^^^ - temporary value is freed at the end of this statement
-   |            |                 |
-   |            |                 creates a temporary value which is freed while still in use
-   |            type annotation requires that borrow lasts for `'static`
-
-error[E0716]: temporary value dropped while borrowed
   --> $DIR/promoted_const_call.rs:17:26
    |
 LL |     let _: &'static _ = &id(&Panic);
@@ -68,7 +48,7 @@ LL |     let _: &'static _ = &&(Panic, 0).1;
 LL | }
    | - temporary value is freed at the end of this statement
 
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0493, E0716.
 For more information about an error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/promoted_const_call3.rs b/tests/ui/consts/promoted_const_call3.rs
index 6d68a2de70e..dc05a3b5844 100644
--- a/tests/ui/consts/promoted_const_call3.rs
+++ b/tests/ui/consts/promoted_const_call3.rs
@@ -2,13 +2,14 @@ pub const fn id<T>(x: T) -> T { x }
 pub const C: () = {
     let _: &'static _ = &String::new();
     //~^ ERROR: destructor of `String` cannot be evaluated at compile-time
-    //~| ERROR: temporary value dropped while borrowed
+};
 
+pub const _: () = {
     let _: &'static _ = &id(&String::new());
     //~^ ERROR: destructor of `String` cannot be evaluated at compile-time
-    //~| ERROR: temporary value dropped while borrowed
-    //~| ERROR: temporary value dropped while borrowed
+};
 
+pub const _: () = {
     let _: &'static _ = &std::mem::ManuallyDrop::new(String::new());
     //~^ ERROR: temporary value dropped while borrowed
 };
diff --git a/tests/ui/consts/promoted_const_call3.stderr b/tests/ui/consts/promoted_const_call3.stderr
index af17457a10a..34c833d5bb7 100644
--- a/tests/ui/consts/promoted_const_call3.stderr
+++ b/tests/ui/consts/promoted_const_call3.stderr
@@ -1,53 +1,22 @@
 error[E0493]: destructor of `String` cannot be evaluated at compile-time
-  --> $DIR/promoted_const_call3.rs:7:30
-   |
-LL |     let _: &'static _ = &id(&String::new());
-   |                              ^^^^^^^^^^^^^ - value is dropped here
-   |                              |
-   |                              the destructor for this type cannot be evaluated in constants
-
-error[E0493]: destructor of `String` cannot be evaluated at compile-time
   --> $DIR/promoted_const_call3.rs:3:26
    |
 LL |     let _: &'static _ = &String::new();
    |                          ^^^^^^^^^^^^^ the destructor for this type cannot be evaluated in constants
-...
+LL |
 LL | };
    | - value is dropped here
 
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call3.rs:3:26
-   |
-LL |     let _: &'static _ = &String::new();
-   |            ----------    ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
-   |            |
-   |            type annotation requires that borrow lasts for `'static`
-...
-LL | };
-   | - temporary value is freed at the end of this statement
-
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call3.rs:7:26
-   |
-LL |     let _: &'static _ = &id(&String::new());
-   |            ----------    ^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
-   |            |
-   |            type annotation requires that borrow lasts for `'static`
-...
-LL | };
-   | - temporary value is freed at the end of this statement
-
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call3.rs:7:30
+error[E0493]: destructor of `String` cannot be evaluated at compile-time
+  --> $DIR/promoted_const_call3.rs:8:30
    |
 LL |     let _: &'static _ = &id(&String::new());
-   |            ----------        ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
-   |            |                 |
-   |            |                 creates a temporary value which is freed while still in use
-   |            type annotation requires that borrow lasts for `'static`
+   |                              ^^^^^^^^^^^^^ - value is dropped here
+   |                              |
+   |                              the destructor for this type cannot be evaluated in constants
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call3.rs:12:26
+  --> $DIR/promoted_const_call3.rs:13:26
    |
 LL |     let _: &'static _ = &std::mem::ManuallyDrop::new(String::new());
    |            ----------    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -58,7 +27,7 @@ LL | };
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call3.rs:17:26
+  --> $DIR/promoted_const_call3.rs:18:26
    |
 LL |     let _: &'static _ = &String::new();
    |            ----------    ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -69,7 +38,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call3.rs:20:26
+  --> $DIR/promoted_const_call3.rs:21:26
    |
 LL |     let _: &'static _ = &id(&String::new());
    |            ----------    ^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -80,7 +49,7 @@ LL | }
    | - temporary value is freed at the end of this statement
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call3.rs:20:30
+  --> $DIR/promoted_const_call3.rs:21:30
    |
 LL |     let _: &'static _ = &id(&String::new());
    |            ----------        ^^^^^^^^^^^^^ - temporary value is freed at the end of this statement
@@ -89,7 +58,7 @@ LL |     let _: &'static _ = &id(&String::new());
    |            type annotation requires that borrow lasts for `'static`
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call3.rs:24:26
+  --> $DIR/promoted_const_call3.rs:25:26
    |
 LL |     let _: &'static _ = &std::mem::ManuallyDrop::new(String::new());
    |            ----------    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
@@ -99,7 +68,7 @@ LL |
 LL | }
    | - temporary value is freed at the end of this statement
 
-error: aborting due to 10 previous errors
+error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0493, E0716.
 For more information about an error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/promoted_const_call5.rs b/tests/ui/consts/promoted_const_call5.rs
index 3ac8d358ce4..41b3988949e 100644
--- a/tests/ui/consts/promoted_const_call5.rs
+++ b/tests/ui/consts/promoted_const_call5.rs
@@ -25,9 +25,9 @@ pub const fn new_manually_drop<T>(t: T) -> std::mem::ManuallyDrop<T>  {
 const C: () = {
     let _: &'static _ = &id(&new_string());
     //~^ ERROR destructor of `String` cannot be evaluated at compile-time
-    //~| ERROR: temporary value dropped while borrowed
-    //~| ERROR: temporary value dropped while borrowed
+};
 
+const _: () = {
     let _: &'static _ = &new_manually_drop(new_string());
     //~^ ERROR: temporary value dropped while borrowed
 };
diff --git a/tests/ui/consts/promoted_const_call5.stderr b/tests/ui/consts/promoted_const_call5.stderr
index f736220b183..1b5fa435283 100644
--- a/tests/ui/consts/promoted_const_call5.stderr
+++ b/tests/ui/consts/promoted_const_call5.stderr
@@ -7,26 +7,6 @@ LL |     let _: &'static _ = &id(&new_string());
    |                              the destructor for this type cannot be evaluated in constants
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call5.rs:26:26
-   |
-LL |     let _: &'static _ = &id(&new_string());
-   |            ----------    ^^^^^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
-   |            |
-   |            type annotation requires that borrow lasts for `'static`
-...
-LL | };
-   | - temporary value is freed at the end of this statement
-
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/promoted_const_call5.rs:26:30
-   |
-LL |     let _: &'static _ = &id(&new_string());
-   |                          ----^^^^^^^^^^^^-- temporary value is freed at the end of this statement
-   |                          |   |
-   |                          |   creates a temporary value which is freed while still in use
-   |                          argument requires that borrow lasts for `'static`
-
-error[E0716]: temporary value dropped while borrowed
   --> $DIR/promoted_const_call5.rs:31:26
    |
 LL |     let _: &'static _ = &new_manually_drop(new_string());
@@ -68,7 +48,7 @@ LL |
 LL | }
    | - temporary value is freed at the end of this statement
 
-error: aborting due to 7 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0493, E0716.
 For more information about an error, try `rustc --explain E0493`.
diff --git a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs
index 852a5b3b46a..936931acbe2 100644
--- a/tests/ui/consts/transmute-size-mismatch-before-typeck.rs
+++ b/tests/ui/consts/transmute-size-mismatch-before-typeck.rs
@@ -5,7 +5,7 @@
 
 fn main() {
     match &b""[..] {
-        ZST => {}
+        ZST => {} //~ ERROR: could not evaluate constant pattern
     }
 }
 
diff --git a/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr b/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr
index 6bc7e7203aa..e0d658db997 100644
--- a/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr
+++ b/tests/ui/consts/transmute-size-mismatch-before-typeck.stderr
@@ -7,6 +7,12 @@ LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
    = note: source type: `usize` (word size)
    = note: target type: `&[u8]` (2 * word size)
 
-error: aborting due to 1 previous error
+error: could not evaluate constant pattern
+  --> $DIR/transmute-size-mismatch-before-typeck.rs:8:9
+   |
+LL |         ZST => {}
+   |         ^^^
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0512`.
diff --git a/tests/ui/consts/try-operator.stderr b/tests/ui/consts/try-operator.stderr
index bb8f606edf8..c19d1a6199d 100644
--- a/tests/ui/consts/try-operator.stderr
+++ b/tests/ui/consts/try-operator.stderr
@@ -4,6 +4,51 @@ error[E0635]: unknown feature `const_convert`
 LL | #![feature(const_convert)]
    |            ^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0015]: `?` cannot determine the branch of `Result<(), ()>` in constant functions
+  --> $DIR/try-operator.rs:10:9
+   |
+LL |         Err(())?;
+   |         ^^^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error[E0015]: `?` cannot convert from residual of `Result<bool, ()>` in constant functions
+  --> $DIR/try-operator.rs:10:9
+   |
+LL |         Err(())?;
+   |         ^^^^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/result.rs:LL:COL
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error[E0015]: `?` cannot determine the branch of `Option<()>` in constant functions
+  --> $DIR/try-operator.rs:18:9
+   |
+LL |         None?;
+   |         ^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error[E0015]: `?` cannot convert from residual of `Option<()>` in constant functions
+  --> $DIR/try-operator.rs:18:9
+   |
+LL |         None?;
+   |         ^^^^^
+   |
+note: impl defined here, but it is not `const`
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0635`.
+Some errors have detailed explanations: E0015, E0635.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/consts/underscore_const_names.rs b/tests/ui/consts/underscore_const_names.rs
index d0e625bf199..e2ae5a9d53a 100644
--- a/tests/ui/consts/underscore_const_names.rs
+++ b/tests/ui/consts/underscore_const_names.rs
@@ -2,12 +2,12 @@
 
 #![deny(unused)]
 
-trait Trt {}
+pub trait Trt {}
 pub struct Str {}
 impl Trt for Str {}
 
 macro_rules! check_impl {
-    ($struct:ident,$trait:ident) => {
+    ($struct:ident, $trait:ident) => {
         const _ : () = {
             use std::marker::PhantomData;
             struct ImplementsTrait<T: $trait>(PhantomData<T>);
diff --git a/tests/ui/consts/unstable-const-fn-in-libcore.stderr b/tests/ui/consts/unstable-const-fn-in-libcore.stderr
index 08147a4afaf..ee4a0f6a843 100644
--- a/tests/ui/consts/unstable-const-fn-in-libcore.stderr
+++ b/tests/ui/consts/unstable-const-fn-in-libcore.stderr
@@ -4,5 +4,38 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL |     const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
    |                                       ^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/unstable-const-fn-in-libcore.rs:24:26
+   |
+LL |             Opt::None => f(),
+   |                          ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL |     const fn unwrap_or_else<F: ~const FnOnce() -> T + ~const std::ops::FnOnce<()>>(self, f: F) -> T {
+   |                                                     +++++++++++++++++++++++++++++
+
+error[E0493]: destructor of `F` cannot be evaluated at compile-time
+  --> $DIR/unstable-const-fn-in-libcore.rs:19:60
+   |
+LL |     const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
+   |                                                            ^ the destructor for this type cannot be evaluated in constant functions
+...
+LL |     }
+   |     - value is dropped here
+
+error[E0493]: destructor of `Opt<T>` cannot be evaluated at compile-time
+  --> $DIR/unstable-const-fn-in-libcore.rs:19:54
+   |
+LL |     const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
+   |                                                      ^^^^ the destructor for this type cannot be evaluated in constant functions
+...
+LL |     }
+   |     - value is dropped here
+
+error: aborting due to 4 previous errors
 
+Some errors have detailed explanations: E0015, E0493.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/coroutine/polymorphize-args.rs b/tests/ui/coroutine/polymorphize-args.rs
new file mode 100644
index 00000000000..de44d667656
--- /dev/null
+++ b/tests/ui/coroutine/polymorphize-args.rs
@@ -0,0 +1,17 @@
+// compile-flags: -Zpolymorphize=on
+// build-pass
+
+#![feature(coroutines, coroutine_trait)]
+
+use std::ops::Coroutine;
+use std::pin::Pin;
+use std::thread;
+
+fn main() {
+    let mut foo = || yield;
+    thread::spawn(move || match Pin::new(&mut foo).resume(()) {
+        s => panic!("bad state: {:?}", s),
+    })
+    .join()
+    .unwrap();
+}
diff --git a/tests/ui/default-method-parsing.rs b/tests/ui/default-method-parsing.rs
index 9ffb8d94a59..5001d58f0a4 100644
--- a/tests/ui/default-method-parsing.rs
+++ b/tests/ui/default-method-parsing.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo {
diff --git a/tests/ui/delegation/target-expr-pass.rs b/tests/ui/delegation/target-expr-pass.rs
index 56068dfce01..4ccb81c292a 100644
--- a/tests/ui/delegation/target-expr-pass.rs
+++ b/tests/ui/delegation/target-expr-pass.rs
@@ -14,14 +14,14 @@ reuse to_reuse::foo {{
     x + self
 }}
 
-trait Trait {
+trait Trait { //~ WARN trait `Trait` is never used
     fn bar(&self, x: i32) -> i32 { x }
 }
 
-struct F;
+struct F; //~ WARN struct `F` is never constructed
 impl Trait for F {}
 
-struct S(F);
+struct S(F); //~ WARN struct `S` is never constructed
 impl Trait for S {
     reuse <F as Trait>::bar {
         #[allow(unused_imports)]
diff --git a/tests/ui/delegation/target-expr-pass.stderr b/tests/ui/delegation/target-expr-pass.stderr
index ea594f8a26a..dd1f3a14e0b 100644
--- a/tests/ui/delegation/target-expr-pass.stderr
+++ b/tests/ui/delegation/target-expr-pass.stderr
@@ -7,5 +7,25 @@ LL | #![feature(fn_delegation)]
    = note: see issue #118212 <https://github.com/rust-lang/rust/issues/118212> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-warning: 1 warning emitted
+warning: trait `Trait` is never used
+  --> $DIR/target-expr-pass.rs:17:7
+   |
+LL | trait Trait {
+   |       ^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: struct `F` is never constructed
+  --> $DIR/target-expr-pass.rs:21:8
+   |
+LL | struct F;
+   |        ^
+
+warning: struct `S` is never constructed
+  --> $DIR/target-expr-pass.rs:24:8
+   |
+LL | struct S(F);
+   |        ^
+
+warning: 4 warnings emitted
 
diff --git a/tests/ui/derives/derive-assoc-type-not-impl.stderr b/tests/ui/derives/derive-assoc-type-not-impl.stderr
index 61268ffc7f8..13ba80243a5 100644
--- a/tests/ui/derives/derive-assoc-type-not-impl.stderr
+++ b/tests/ui/derives/derive-assoc-type-not-impl.stderr
@@ -15,9 +15,6 @@ note: trait bound `NotClone: Clone` was not satisfied
    |
 LL | #[derive(Clone)]
    |          ^^^^^ unsatisfied trait bound introduced in this `derive` macro
-   = help: items from traits can only be used if the trait is implemented and in scope
-   = note: the following trait defines an item `clone`, perhaps you need to implement it:
-           candidate #1: `Clone`
 help: consider annotating `NotClone` with `#[derive(Clone)]`
    |
 LL + #[derive(Clone)]
diff --git a/tests/ui/deriving/deriving-bounds.rs b/tests/ui/deriving/deriving-bounds.rs
index f0b921d0e7c..f3e7cf99437 100644
--- a/tests/ui/deriving/deriving-bounds.rs
+++ b/tests/ui/deriving/deriving-bounds.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 #[derive(Copy, Clone)]
 struct Test;
 
diff --git a/tests/ui/diagnostic-width/tabs-trimming.rs b/tests/ui/diagnostic-width/tabs-trimming.rs
index ade21753b45..96babde33e9 100644
--- a/tests/ui/diagnostic-width/tabs-trimming.rs
+++ b/tests/ui/diagnostic-width/tabs-trimming.rs
@@ -8,6 +8,7 @@
 						match money {
 							v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
 							//~^ ERROR variable `v` is not bound in all patterns
+							//~| ERROR possibly-uninitialized
 							v => println!("Enough money {}", v),
 						}
 					}
diff --git a/tests/ui/diagnostic-width/tabs-trimming.stderr b/tests/ui/diagnostic-width/tabs-trimming.stderr
index 2aa4fc18c3d..85103fbf6f5 100644
--- a/tests/ui/diagnostic-width/tabs-trimming.stderr
+++ b/tests/ui/diagnostic-width/tabs-trimming.stderr
@@ -7,6 +7,18 @@ LL | ...   v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Lon
    |       |       pattern doesn't bind `v`
    |       variable not in all patterns
 
-error: aborting due to 1 previous error
+error[E0381]: used binding `v` is possibly-uninitialized
+  --> $DIR/tabs-trimming.rs:9:67
+   |
+LL | ...   v @ 1 | 2 | 3 => panic!("You gave me too little money {}", v), // Long text here: TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT...
+   |       -                                                          ^ `v` used here but it is possibly-uninitialized
+   |       |
+   |       binding initialized here in some conditions
+   |       binding declared here but left uninitialized
+   |
+   = note: this error originates in the macro `$crate::const_format_args` which comes from the expansion of the macro `panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0408`.
+Some errors have detailed explanations: E0381, E0408.
+For more information about an error, try `rustc --explain E0381`.
diff --git a/tests/ui/drop/drop-struct-as-object.rs b/tests/ui/drop/drop-struct-as-object.rs
index 377027a4fc5..1aa68777042 100644
--- a/tests/ui/drop/drop-struct-as-object.rs
+++ b/tests/ui/drop/drop-struct-as-object.rs
@@ -12,7 +12,7 @@ struct Cat {
 }
 
 trait Dummy {
-    fn get(&self) -> usize;
+    fn get(&self) -> usize; //~ WARN method `get` is never used
 }
 
 impl Dummy for Cat {
diff --git a/tests/ui/drop/drop-struct-as-object.stderr b/tests/ui/drop/drop-struct-as-object.stderr
new file mode 100644
index 00000000000..10527c968ed
--- /dev/null
+++ b/tests/ui/drop/drop-struct-as-object.stderr
@@ -0,0 +1,12 @@
+warning: method `get` is never used
+  --> $DIR/drop-struct-as-object.rs:15:8
+   |
+LL | trait Dummy {
+   |       ----- method in this trait
+LL |     fn get(&self) -> usize;
+   |        ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/drop/recursion-check-on-erroneous-impl.rs b/tests/ui/drop/recursion-check-on-erroneous-impl.rs
new file mode 100644
index 00000000000..733c8b0b085
--- /dev/null
+++ b/tests/ui/drop/recursion-check-on-erroneous-impl.rs
@@ -0,0 +1,11 @@
+// can't use build-fail, because this also fails check-fail, but
+// the ICE from #120787 only reproduces on build-fail.
+// compile-flags: --emit=mir
+
+struct PrintOnDrop<'a>(&'a str);
+
+impl Drop for PrintOnDrop<'_> {
+    fn drop() {} //~ ERROR method `drop` has a `&mut self` declaration in the trait
+}
+
+fn main() {}
diff --git a/tests/ui/drop/recursion-check-on-erroneous-impl.stderr b/tests/ui/drop/recursion-check-on-erroneous-impl.stderr
new file mode 100644
index 00000000000..831adb88cef
--- /dev/null
+++ b/tests/ui/drop/recursion-check-on-erroneous-impl.stderr
@@ -0,0 +1,11 @@
+error[E0186]: method `drop` has a `&mut self` declaration in the trait, but not in the impl
+  --> $DIR/recursion-check-on-erroneous-impl.rs:8:5
+   |
+LL |     fn drop() {}
+   |     ^^^^^^^^^ expected `&mut self` in impl
+   |
+   = note: `drop` from trait: `fn(&mut Self)`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0186`.
diff --git a/tests/ui/dyn-keyword/dyn-2018-edition-lint.rs b/tests/ui/dyn-keyword/dyn-2018-edition-lint.rs
index a074b5fa5f7..23ca36b71e0 100644
--- a/tests/ui/dyn-keyword/dyn-2018-edition-lint.rs
+++ b/tests/ui/dyn-keyword/dyn-2018-edition-lint.rs
@@ -6,14 +6,6 @@ fn function(x: &SomeTrait, y: Box<SomeTrait>) {
     //~| WARN this is accepted in the current edition
     //~| ERROR trait objects without an explicit `dyn` are deprecated
     //~| WARN this is accepted in the current edition
-    //~| ERROR trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-    //~| ERROR trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-    //~| ERROR trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
-    //~| ERROR trait objects without an explicit `dyn` are deprecated
-    //~| WARN this is accepted in the current edition
     let _x: &SomeTrait = todo!();
     //~^ ERROR trait objects without an explicit `dyn` are deprecated
     //~| WARN this is accepted in the current edition
diff --git a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
index 93178667214..65d44604dc9 100644
--- a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
+++ b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
@@ -30,7 +30,7 @@ LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
    |                                   +++
 
 error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/dyn-2018-edition-lint.rs:17:14
+  --> $DIR/dyn-2018-edition-lint.rs:9:14
    |
 LL |     let _x: &SomeTrait = todo!();
    |              ^^^^^^^^^
@@ -42,61 +42,5 @@ help: use `dyn`
 LL |     let _x: &dyn SomeTrait = todo!();
    |              +++
 
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/dyn-2018-edition-lint.rs:4:17
-   |
-LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-   |                 ^^^^^^^^^
-   |
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
-   |                 +++
-
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/dyn-2018-edition-lint.rs:4:17
-   |
-LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-   |                 ^^^^^^^^^
-   |
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
-   |                 +++
-
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/dyn-2018-edition-lint.rs:4:35
-   |
-LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-   |                                   ^^^^^^^^^
-   |
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
-   |                                   +++
-
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/dyn-2018-edition-lint.rs:4:35
-   |
-LL | fn function(x: &SomeTrait, y: Box<SomeTrait>) {
-   |                                   ^^^^^^^^^
-   |
-   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | fn function(x: &SomeTrait, y: Box<dyn SomeTrait>) {
-   |                                   +++
-
-error: aborting due to 7 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/dynamically-sized-types/dst-coercions.rs b/tests/ui/dynamically-sized-types/dst-coercions.rs
index 66688e93fb8..1efdf1de0e6 100644
--- a/tests/ui/dynamically-sized-types/dst-coercions.rs
+++ b/tests/ui/dynamically-sized-types/dst-coercions.rs
@@ -5,7 +5,7 @@
 // pretty-expanded FIXME #23616
 
 struct S;
-trait T { fn dummy(&self) { } }
+trait T { fn dummy(&self) { } } //~ WARN method `dummy` is never used
 impl T for S {}
 
 pub fn main() {
diff --git a/tests/ui/dynamically-sized-types/dst-coercions.stderr b/tests/ui/dynamically-sized-types/dst-coercions.stderr
new file mode 100644
index 00000000000..e4721ce50a0
--- /dev/null
+++ b/tests/ui/dynamically-sized-types/dst-coercions.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/dst-coercions.rs:8:14
+   |
+LL | trait T { fn dummy(&self) { } }
+   |       -      ^^^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/empty-type-parameter-list.rs b/tests/ui/empty-type-parameter-list.rs
index e168cd03b27..23d09fbf281 100644
--- a/tests/ui/empty-type-parameter-list.rs
+++ b/tests/ui/empty-type-parameter-list.rs
@@ -3,7 +3,7 @@
 // no type parameters at all
 
 struct S<>;
-trait T<> {}
+trait T<> {} //~ WARN trait `T` is never used
 enum E<> { V }
 impl<> T<> for S<> {}
 impl T for E {}
diff --git a/tests/ui/empty-type-parameter-list.stderr b/tests/ui/empty-type-parameter-list.stderr
new file mode 100644
index 00000000000..31a5015e993
--- /dev/null
+++ b/tests/ui/empty-type-parameter-list.stderr
@@ -0,0 +1,10 @@
+warning: trait `T` is never used
+  --> $DIR/empty-type-parameter-list.rs:6:7
+   |
+LL | trait T<> {}
+   |       ^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/enum/enum-and-module-in-same-scope.rs b/tests/ui/enum/enum-and-module-in-same-scope.rs
index cc6e199bd7c..8e69c89d792 100644
--- a/tests/ui/enum/enum-and-module-in-same-scope.rs
+++ b/tests/ui/enum/enum-and-module-in-same-scope.rs
@@ -5,6 +5,7 @@ enum Foo {
 mod Foo { //~ ERROR the name `Foo` is defined multiple times
     pub static X: isize = 42;
     fn f() { f() } // Check that this does not result in a resolution error
+    //~^ WARN cannot return without recursing
 }
 
 fn main() {}
diff --git a/tests/ui/enum/enum-and-module-in-same-scope.stderr b/tests/ui/enum/enum-and-module-in-same-scope.stderr
index 0293acd6201..f1c02af595f 100644
--- a/tests/ui/enum/enum-and-module-in-same-scope.stderr
+++ b/tests/ui/enum/enum-and-module-in-same-scope.stderr
@@ -9,6 +9,17 @@ LL | mod Foo {
    |
    = note: `Foo` must be defined only once in the type namespace of this module
 
-error: aborting due to 1 previous error
+warning: function cannot return without recursing
+  --> $DIR/enum-and-module-in-same-scope.rs:7:5
+   |
+LL |     fn f() { f() } // Check that this does not result in a resolution error
+   |     ^^^^^^   --- recursive call site
+   |     |
+   |     cannot return without recursing
+   |
+   = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
+
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0428`.
diff --git a/tests/ui/error-codes/E0117.rs b/tests/ui/error-codes/E0117.rs
index 406d24e3666..32b9863806c 100644
--- a/tests/ui/error-codes/E0117.rs
+++ b/tests/ui/error-codes/E0117.rs
@@ -1,4 +1,5 @@
 impl Drop for u32 {} //~ ERROR E0117
 //~| ERROR the `Drop` trait may only be implemented for local structs, enums, and unions
+//~| ERROR not all trait items implemented
 
 fn main() {}
diff --git a/tests/ui/error-codes/E0117.stderr b/tests/ui/error-codes/E0117.stderr
index f144aa9f72c..058a64b20d1 100644
--- a/tests/ui/error-codes/E0117.stderr
+++ b/tests/ui/error-codes/E0117.stderr
@@ -15,7 +15,15 @@ error[E0120]: the `Drop` trait may only be implemented for local structs, enums,
 LL | impl Drop for u32 {}
    |               ^^^ must be a struct, enum, or union in the current crate
 
-error: aborting due to 2 previous errors
+error[E0046]: not all trait items implemented, missing: `drop`
+  --> $DIR/E0117.rs:1:1
+   |
+LL | impl Drop for u32 {}
+   | ^^^^^^^^^^^^^^^^^ missing `drop` in implementation
+   |
+   = help: implement the missing item: `fn drop(&mut self) { todo!() }`
+
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0117, E0120.
-For more information about an error, try `rustc --explain E0117`.
+Some errors have detailed explanations: E0046, E0117, E0120.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/error-codes/E0120.rs b/tests/ui/error-codes/E0120.rs
index a0a301a06e2..35f544fddfb 100644
--- a/tests/ui/error-codes/E0120.rs
+++ b/tests/ui/error-codes/E0120.rs
@@ -3,6 +3,7 @@ trait MyTrait { fn foo() {} }
 impl Drop for dyn MyTrait {
               //~^ ERROR E0120
     fn drop(&mut self) {}
+
 }
 
 fn main() {}
diff --git a/tests/ui/error-codes/E0374.rs b/tests/ui/error-codes/E0374.rs
index 41fcedc328d..47b9bea978e 100644
--- a/tests/ui/error-codes/E0374.rs
+++ b/tests/ui/error-codes/E0374.rs
@@ -1,7 +1,7 @@
 #![feature(coerce_unsized)]
 use std::ops::CoerceUnsized;
 
-struct Foo<T: ?Sized> {
+struct Foo<T: ?Sized> { //~ ERROR `T` is never used
     a: i32,
 }
 
diff --git a/tests/ui/error-codes/E0374.stderr b/tests/ui/error-codes/E0374.stderr
index 148fa1348ab..77f351b28ef 100644
--- a/tests/ui/error-codes/E0374.stderr
+++ b/tests/ui/error-codes/E0374.stderr
@@ -7,6 +7,15 @@ LL | |     where T: CoerceUnsized<U> {}
    |
    = note: expected a single field to be coerced, none found
 
-error: aborting due to 1 previous error
+error[E0392]: type parameter `T` is never used
+  --> $DIR/E0374.rs:4:12
+   |
+LL | struct Foo<T: ?Sized> {
+   |            ^ unused type parameter
+   |
+   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0374`.
+Some errors have detailed explanations: E0374, E0392.
+For more information about an error, try `rustc --explain E0374`.
diff --git a/tests/ui/error-codes/E0375.rs b/tests/ui/error-codes/E0375.rs
index 0c03a8761df..eaf99dd3842 100644
--- a/tests/ui/error-codes/E0375.rs
+++ b/tests/ui/error-codes/E0375.rs
@@ -3,7 +3,7 @@ use std::ops::CoerceUnsized;
 
 struct Foo<T: ?Sized, U: ?Sized> {
     a: i32,
-    b: T,
+    b: T, //~ ERROR E0277
     c: U,
 }
 
diff --git a/tests/ui/error-codes/E0375.stderr b/tests/ui/error-codes/E0375.stderr
index 0a5e4128ae9..d5340022d68 100644
--- a/tests/ui/error-codes/E0375.stderr
+++ b/tests/ui/error-codes/E0375.stderr
@@ -7,6 +7,32 @@ LL | impl<T, U> CoerceUnsized<Foo<U, T>> for Foo<T, U> {}
    = note: `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
    = note: currently, 2 fields need coercions: `b` (`T` to `U`), `c` (`U` to `T`)
 
-error: aborting due to 1 previous error
+error[E0277]: the size for values of type `T` cannot be known at compilation time
+  --> $DIR/E0375.rs:6:8
+   |
+LL | struct Foo<T: ?Sized, U: ?Sized> {
+   |            - this type parameter needs to be `Sized`
+LL |     a: i32,
+LL |     b: T,
+   |        ^ doesn't have a size known at compile-time
+   |
+   = note: only the last field of a struct may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: consider removing the `?Sized` bound to make the type parameter `Sized`
+   |
+LL - struct Foo<T: ?Sized, U: ?Sized> {
+LL + struct Foo<T, U: ?Sized> {
+   |
+help: borrowed types always have a statically known size
+   |
+LL |     b: &T,
+   |        +
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |     b: Box<T>,
+   |        ++++ +
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0375`.
+Some errors have detailed explanations: E0277, E0375.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/error-codes/E0401.stderr b/tests/ui/error-codes/E0401.stderr
index d27fade487f..754867061c7 100644
--- a/tests/ui/error-codes/E0401.stderr
+++ b/tests/ui/error-codes/E0401.stderr
@@ -20,7 +20,7 @@ LL |     fn baz<U,
 LL |            (y: T) {
    |                ^ use of generic parameter from outer item
 
-error[E0401]: can't use generic parameters from outer item
+error[E0401]: can't use `Self` from outer item
   --> $DIR/E0401.rs:24:25
    |
 LL | impl<T> Iterator for A<T> {
@@ -29,7 +29,7 @@ LL | impl<T> Iterator for A<T> {
 LL |         fn helper(sel: &Self) -> u8 {
    |                         ^^^^
    |                         |
-   |                         use of generic parameter from outer item
+   |                         use of `Self` from outer item
    |                         refer to the type directly here instead
 
 error[E0283]: type annotations needed
diff --git a/tests/ui/error-codes/E0582.rs b/tests/ui/error-codes/E0582.rs
index ff25012d0f9..b6513170b13 100644
--- a/tests/ui/error-codes/E0582.rs
+++ b/tests/ui/error-codes/E0582.rs
@@ -19,7 +19,7 @@ fn mk_unexpected_char_err<'a>() -> Option<&'a i32> {
 }
 
 fn foo<'a>(data: &mut Chars<'a>) {
-    bar(mk_unexpected_char_err)
+    bar(mk_unexpected_char_err) //~ ERROR mismatched types
 }
 
 fn bar<F>(t: F)
diff --git a/tests/ui/error-codes/E0582.stderr b/tests/ui/error-codes/E0582.stderr
index 81a2f004653..64b527cdcc2 100644
--- a/tests/ui/error-codes/E0582.stderr
+++ b/tests/ui/error-codes/E0582.stderr
@@ -10,6 +10,21 @@ error[E0582]: binding for associated type `Item` references lifetime `'a`, which
 LL |     where F: for<'a> Iterator<Item=&'a i32>
    |                               ^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0308]: mismatched types
+  --> $DIR/E0582.rs:22:5
+   |
+LL |     bar(mk_unexpected_char_err)
+   |     ^^^ one type is more general than the other
+   |
+   = note: expected enum `Option<&_>`
+              found enum `Option<&'a _>`
+note: the lifetime requirement is introduced here
+  --> $DIR/E0582.rs:28:30
+   |
+LL |     where F: for<'a> Fn() -> Option<&'a i32>
+   |                              ^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0582`.
+Some errors have detailed explanations: E0308, E0582.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/error-codes/E0637.rs b/tests/ui/error-codes/E0637.rs
index 382ce3ed01f..e107ea9521b 100644
--- a/tests/ui/error-codes/E0637.rs
+++ b/tests/ui/error-codes/E0637.rs
@@ -2,9 +2,9 @@ fn underscore_lifetime<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str {
     //~^ ERROR: `'_` cannot be used here [E0637]
     //~| ERROR: missing lifetime specifier
     if str1.len() > str2.len() {
-        str1
+        str1 //~ ERROR: lifetime may not live long enough
     } else {
-        str2
+        str2 //~ ERROR: lifetime may not live long enough
     }
 }
 
diff --git a/tests/ui/error-codes/E0637.stderr b/tests/ui/error-codes/E0637.stderr
index d9db89ddb0c..217881b8e7c 100644
--- a/tests/ui/error-codes/E0637.stderr
+++ b/tests/ui/error-codes/E0637.stderr
@@ -27,7 +27,25 @@ help: consider introducing a higher-ranked lifetime here
 LL |     T: for<'a> Into<&'a u32>,
    |        +++++++       ++
 
-error: aborting due to 3 previous errors
+error: lifetime may not live long enough
+  --> $DIR/E0637.rs:5:9
+   |
+LL | fn underscore_lifetime<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str {
+   |                                  - let's call the lifetime of this reference `'1`
+...
+LL |         str1
+   |         ^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/E0637.rs:7:9
+   |
+LL | fn underscore_lifetime<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str {
+   |                                                 - let's call the lifetime of this reference `'2`
+...
+LL |         str2
+   |         ^^^^ returning this value requires that `'2` must outlive `'static`
+
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0106, E0637.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/explicit-tail-calls/return-mismatches.rs b/tests/ui/explicit-tail-calls/return-mismatches.rs
index 935a1a1d28b..8094a192913 100644
--- a/tests/ui/explicit-tail-calls/return-mismatches.rs
+++ b/tests/ui/explicit-tail-calls/return-mismatches.rs
@@ -13,7 +13,7 @@ fn _f1() {
     become _g1(); //~ error: mismatched types
 }
 
-fn _g1() -> ! {
+fn _g1() -> ! { //~ WARN: cannot return without recursing
     become _g1();
 }
 
diff --git a/tests/ui/explicit-tail-calls/return-mismatches.stderr b/tests/ui/explicit-tail-calls/return-mismatches.stderr
index 1dcc35797c1..31c7a46ded9 100644
--- a/tests/ui/explicit-tail-calls/return-mismatches.stderr
+++ b/tests/ui/explicit-tail-calls/return-mismatches.stderr
@@ -22,6 +22,17 @@ error[E0308]: mismatched types
 LL |     become _g2();
    |     ^^^^^^^^^^^^ expected `u32`, found `u16`
 
-error: aborting due to 3 previous errors
+warning: function cannot return without recursing
+  --> $DIR/return-mismatches.rs:16:1
+   |
+LL | fn _g1() -> ! {
+   | ^^^^^^^^^^^^^ cannot return without recursing
+LL |     become _g1();
+   |            ----- recursive call site
+   |
+   = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
+
+error: aborting due to 3 previous errors; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
index bb093a4af4a..3c71587c8e3 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 
+#![allow(dead_code)]
 #![allow(dropping_references)]
 
 struct Foo {
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
index 1a9f89c054f..075d4cbe02b 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 
+#![allow(dead_code)]
 #![allow(dropping_references)]
 
 struct Foo {
diff --git a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr
index d2d69ce6daf..13b6ee9987e 100644
--- a/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr
+++ b/tests/ui/explicit/explicit-call-to-supertrait-dtor.stderr
@@ -1,5 +1,5 @@
 error[E0040]: explicit use of destructor method
-  --> $DIR/explicit-call-to-supertrait-dtor.rs:22:14
+  --> $DIR/explicit-call-to-supertrait-dtor.rs:23:14
    |
 LL |         self.drop();
    |              ^^^^ explicit destructor calls not allowed
diff --git a/tests/ui/expr/if/if-no-match-bindings.rs b/tests/ui/expr/if/if-no-match-bindings.rs
index ca3df0fdde4..d36a436397b 100644
--- a/tests/ui/expr/if/if-no-match-bindings.rs
+++ b/tests/ui/expr/if/if-no-match-bindings.rs
@@ -6,6 +6,7 @@
 
 fn b_ref<'a>() -> &'a bool { &true }
 fn b_mut_ref<'a>() -> &'a mut bool { &mut true }
+//~^ ERROR: cannot return reference to temporary
 
 fn main() {
     // This is OK:
diff --git a/tests/ui/expr/if/if-no-match-bindings.stderr b/tests/ui/expr/if/if-no-match-bindings.stderr
index 737a5d60448..18f3b6b168e 100644
--- a/tests/ui/expr/if/if-no-match-bindings.stderr
+++ b/tests/ui/expr/if/if-no-match-bindings.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/if-no-match-bindings.rs:18:8
+  --> $DIR/if-no-match-bindings.rs:19:8
    |
 LL |     if b_ref() {}
    |        ^^^^^^^ expected `bool`, found `&bool`
@@ -10,7 +10,7 @@ LL |     if *b_ref() {}
    |        +
 
 error[E0308]: mismatched types
-  --> $DIR/if-no-match-bindings.rs:19:8
+  --> $DIR/if-no-match-bindings.rs:20:8
    |
 LL |     if b_mut_ref() {}
    |        ^^^^^^^^^^^ expected `bool`, found `&mut bool`
@@ -21,7 +21,7 @@ LL |     if *b_mut_ref() {}
    |        +
 
 error[E0308]: mismatched types
-  --> $DIR/if-no-match-bindings.rs:20:8
+  --> $DIR/if-no-match-bindings.rs:21:8
    |
 LL |     if &true {}
    |        ^^^^^ expected `bool`, found `&bool`
@@ -33,7 +33,7 @@ LL +     if true {}
    |
 
 error[E0308]: mismatched types
-  --> $DIR/if-no-match-bindings.rs:21:8
+  --> $DIR/if-no-match-bindings.rs:22:8
    |
 LL |     if &mut true {}
    |        ^^^^^^^^^ expected `bool`, found `&mut bool`
@@ -45,7 +45,7 @@ LL +     if true {}
    |
 
 error[E0308]: mismatched types
-  --> $DIR/if-no-match-bindings.rs:24:11
+  --> $DIR/if-no-match-bindings.rs:25:11
    |
 LL |     while b_ref() {}
    |           ^^^^^^^ expected `bool`, found `&bool`
@@ -56,7 +56,7 @@ LL |     while *b_ref() {}
    |           +
 
 error[E0308]: mismatched types
-  --> $DIR/if-no-match-bindings.rs:25:11
+  --> $DIR/if-no-match-bindings.rs:26:11
    |
 LL |     while b_mut_ref() {}
    |           ^^^^^^^^^^^ expected `bool`, found `&mut bool`
@@ -67,7 +67,7 @@ LL |     while *b_mut_ref() {}
    |           +
 
 error[E0308]: mismatched types
-  --> $DIR/if-no-match-bindings.rs:26:11
+  --> $DIR/if-no-match-bindings.rs:27:11
    |
 LL |     while &true {}
    |           ^^^^^ expected `bool`, found `&bool`
@@ -79,7 +79,7 @@ LL +     while true {}
    |
 
 error[E0308]: mismatched types
-  --> $DIR/if-no-match-bindings.rs:27:11
+  --> $DIR/if-no-match-bindings.rs:28:11
    |
 LL |     while &mut true {}
    |           ^^^^^^^^^ expected `bool`, found `&mut bool`
@@ -90,6 +90,16 @@ LL -     while &mut true {}
 LL +     while true {}
    |
 
-error: aborting due to 8 previous errors
+error[E0515]: cannot return reference to temporary value
+  --> $DIR/if-no-match-bindings.rs:8:38
+   |
+LL | fn b_mut_ref<'a>() -> &'a mut bool { &mut true }
+   |                                      ^^^^^----
+   |                                      |    |
+   |                                      |    temporary value created here
+   |                                      returns a reference to data owned by the current function
+
+error: aborting due to 9 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0308, E0515.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/extern-flag/empty-extern-arg.stderr b/tests/ui/extern-flag/empty-extern-arg.stderr
index 79efcc5d8b0..6ad3effe0e2 100644
--- a/tests/ui/extern-flag/empty-extern-arg.stderr
+++ b/tests/ui/extern-flag/empty-extern-arg.stderr
@@ -1,11 +1,6 @@
 error: extern location for std does not exist: 
 
-error: `#[panic_handler]` function required, but not found
+error: requires `sized` lang_item
 
-error: unwinding panics are not supported without std
-   |
-   = help: using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding
-   = note: since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/extern-mod-syntax.rs b/tests/ui/extern-mod-syntax.rs
deleted file mode 100644
index 65dfa6a0f57..00000000000
--- a/tests/ui/extern-mod-syntax.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// run-pass
-
-#![allow(unused_imports)]
-#![no_std]
-
-extern crate std;
-use std::ffi::c_void;
-
-pub fn main() {
-    std::println!("Hello world!");
-}
diff --git a/tests/ui/issues/issue-16250.rs b/tests/ui/extern/issue-16250.rs
index 436e2a6cee3..436e2a6cee3 100644
--- a/tests/ui/issues/issue-16250.rs
+++ b/tests/ui/extern/issue-16250.rs
diff --git a/tests/ui/issues/issue-16250.stderr b/tests/ui/extern/issue-16250.stderr
index 9d3e8811461..9d3e8811461 100644
--- a/tests/ui/issues/issue-16250.stderr
+++ b/tests/ui/extern/issue-16250.stderr
diff --git a/tests/ui/issues/issue-47725.rs b/tests/ui/extern/issue-47725.rs
index 9ec55be5872..9ec55be5872 100644
--- a/tests/ui/issues/issue-47725.rs
+++ b/tests/ui/extern/issue-47725.rs
diff --git a/tests/ui/issues/issue-47725.stderr b/tests/ui/extern/issue-47725.stderr
index 0d3b77b4608..0d3b77b4608 100644
--- a/tests/ui/issues/issue-47725.stderr
+++ b/tests/ui/extern/issue-47725.stderr
diff --git a/tests/ui/extern/no-mangle-associated-fn.rs b/tests/ui/extern/no-mangle-associated-fn.rs
index ecd44abbf26..56afd8b9092 100644
--- a/tests/ui/extern/no-mangle-associated-fn.rs
+++ b/tests/ui/extern/no-mangle-associated-fn.rs
@@ -12,7 +12,7 @@ impl Foo {
     }
 }
 
-trait Bar {
+trait Bar { //~ WARN trait `Bar` is never used
     fn qux() -> u8;
 }
 
diff --git a/tests/ui/extern/no-mangle-associated-fn.stderr b/tests/ui/extern/no-mangle-associated-fn.stderr
new file mode 100644
index 00000000000..772cbf6cf7d
--- /dev/null
+++ b/tests/ui/extern/no-mangle-associated-fn.stderr
@@ -0,0 +1,10 @@
+warning: trait `Bar` is never used
+  --> $DIR/no-mangle-associated-fn.rs:15:7
+   |
+LL | trait Bar {
+   |       ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
index 073599edad7..f87d3aab635 100644
--- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
+++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.rs
@@ -11,7 +11,6 @@ impl Tr1 for S1 { type As1 = S2; }
 trait _Tr3 {
     type A: Iterator<Item: Copy>;
     //~^ ERROR associated type bounds are unstable
-    //~| ERROR the trait bound `<<Self as _Tr3>::A as Iterator>::Item: Copy` is not satisfied
 
     type B: Iterator<Item: 'static>;
     //~^ ERROR associated type bounds are unstable
diff --git a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
index efab91f25f0..855a29953f1 100644
--- a/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
+++ b/tests/ui/feature-gates/feature-gate-associated_type_bounds.stderr
@@ -9,7 +9,7 @@ LL |     type A: Iterator<Item: Copy>;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:16:22
+  --> $DIR/feature-gate-associated_type_bounds.rs:15:22
    |
 LL |     type B: Iterator<Item: 'static>;
    |                      ^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL |     type B: Iterator<Item: 'static>;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:20:20
+  --> $DIR/feature-gate-associated_type_bounds.rs:19:20
    |
 LL | struct _St1<T: Tr1<As1: Tr2>> {
    |                    ^^^^^^^^
@@ -29,7 +29,7 @@ LL | struct _St1<T: Tr1<As1: Tr2>> {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:27:18
+  --> $DIR/feature-gate-associated_type_bounds.rs:26:18
    |
 LL | enum _En1<T: Tr1<As1: Tr2>> {
    |                  ^^^^^^^^
@@ -39,7 +39,7 @@ LL | enum _En1<T: Tr1<As1: Tr2>> {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:34:19
+  --> $DIR/feature-gate-associated_type_bounds.rs:33:19
    |
 LL | union _Un1<T: Tr1<As1: Tr2>> {
    |                   ^^^^^^^^
@@ -49,7 +49,7 @@ LL | union _Un1<T: Tr1<As1: Tr2>> {
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:41:37
+  --> $DIR/feature-gate-associated_type_bounds.rs:40:37
    |
 LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
    |                                     ^^^^^^^^^^
@@ -59,7 +59,7 @@ LL | type _TaWhere1<T> where T: Iterator<Item: Copy> = T;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:44:22
+  --> $DIR/feature-gate-associated_type_bounds.rs:43:22
    |
 LL | fn _apit(_: impl Tr1<As1: Copy>) {}
    |                      ^^^^^^^^^
@@ -69,7 +69,7 @@ LL | fn _apit(_: impl Tr1<As1: Copy>) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:46:26
+  --> $DIR/feature-gate-associated_type_bounds.rs:45:26
    |
 LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
    |                          ^^^^^^^^^
@@ -79,7 +79,7 @@ LL | fn _apit_dyn(_: &dyn Tr1<As1: Copy>) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:49:24
+  --> $DIR/feature-gate-associated_type_bounds.rs:48:24
    |
 LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
    |                        ^^^^^^^^^
@@ -89,7 +89,7 @@ LL | fn _rpit() -> impl Tr1<As1: Copy> { S1 }
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:52:31
+  --> $DIR/feature-gate-associated_type_bounds.rs:51:31
    |
 LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
    |                               ^^^^^^^^^
@@ -99,7 +99,7 @@ LL | fn _rpit_dyn() -> Box<dyn Tr1<As1: Copy>> { Box::new(S1) }
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:55:23
+  --> $DIR/feature-gate-associated_type_bounds.rs:54:23
    |
 LL | const _cdef: impl Tr1<As1: Copy> = S1;
    |                       ^^^^^^^^^
@@ -109,7 +109,7 @@ LL | const _cdef: impl Tr1<As1: Copy> = S1;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:61:24
+  --> $DIR/feature-gate-associated_type_bounds.rs:60:24
    |
 LL | static _sdef: impl Tr1<As1: Copy> = S1;
    |                        ^^^^^^^^^
@@ -119,7 +119,7 @@ LL | static _sdef: impl Tr1<As1: Copy> = S1;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: associated type bounds are unstable
-  --> $DIR/feature-gate-associated_type_bounds.rs:68:21
+  --> $DIR/feature-gate-associated_type_bounds.rs:67:21
    |
 LL |     let _: impl Tr1<As1: Copy> = S1;
    |                     ^^^^^^^^^
@@ -129,7 +129,7 @@ LL |     let _: impl Tr1<As1: Copy> = S1;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0562]: `impl Trait` is not allowed in const types
-  --> $DIR/feature-gate-associated_type_bounds.rs:55:14
+  --> $DIR/feature-gate-associated_type_bounds.rs:54:14
    |
 LL | const _cdef: impl Tr1<As1: Copy> = S1;
    |              ^^^^^^^^^^^^^^^^^^^
@@ -137,7 +137,7 @@ LL | const _cdef: impl Tr1<As1: Copy> = S1;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in static types
-  --> $DIR/feature-gate-associated_type_bounds.rs:61:15
+  --> $DIR/feature-gate-associated_type_bounds.rs:60:15
    |
 LL | static _sdef: impl Tr1<As1: Copy> = S1;
    |               ^^^^^^^^^^^^^^^^^^^
@@ -145,25 +145,14 @@ LL | static _sdef: impl Tr1<As1: Copy> = S1;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the type of variable bindings
-  --> $DIR/feature-gate-associated_type_bounds.rs:68:12
+  --> $DIR/feature-gate-associated_type_bounds.rs:67:12
    |
 LL |     let _: impl Tr1<As1: Copy> = S1;
    |            ^^^^^^^^^^^^^^^^^^^
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
-error[E0277]: the trait bound `<<Self as _Tr3>::A as Iterator>::Item: Copy` is not satisfied
-  --> $DIR/feature-gate-associated_type_bounds.rs:12:28
-   |
-LL |     type A: Iterator<Item: Copy>;
-   |                            ^^^^ the trait `Copy` is not implemented for `<<Self as _Tr3>::A as Iterator>::Item`
-   |
-help: consider further restricting the associated type
-   |
-LL | trait _Tr3 where <<Self as _Tr3>::A as Iterator>::Item: Copy {
-   |            +++++++++++++++++++++++++++++++++++++++++++++++++
-
-error: aborting due to 17 previous errors
+error: aborting due to 16 previous errors
 
-Some errors have detailed explanations: E0277, E0562, E0658.
-For more information about an error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0562, E0658.
+For more information about an error, try `rustc --explain E0562`.
diff --git a/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs b/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs
index b600ad23eee..801956c3339 100644
--- a/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs
+++ b/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.rs
@@ -13,4 +13,5 @@ extern "C" {
 
 fn main() {
     assert_eq!(FOO, 3);
+    //~^ ERROR extern static is unsafe
 }
diff --git a/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.stderr b/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.stderr
index 0e1fe5572a9..62b72e35059 100644
--- a/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.stderr
+++ b/tests/ui/feature-gates/feature-gate-cfg-target-thread-local.stderr
@@ -8,6 +8,15 @@ LL |     #[cfg_attr(target_thread_local, thread_local)]
    = help: add `#![feature(cfg_target_thread_local)]` 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: aborting due to 1 previous error
+error[E0133]: use of extern static is unsafe and requires unsafe function or block
+  --> $DIR/feature-gate-cfg-target-thread-local.rs:15:16
+   |
+LL |     assert_eq!(FOO, 3);
+   |                ^^^ use of extern static
+   |
+   = note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/feature-gates/feature-gate-custom_mir.rs b/tests/ui/feature-gates/feature-gate-custom_mir.rs
index 0126dde2f7d..e100df08ee7 100644
--- a/tests/ui/feature-gates/feature-gate-custom_mir.rs
+++ b/tests/ui/feature-gates/feature-gate-custom_mir.rs
@@ -1,10 +1,15 @@
 #![feature(core_intrinsics)]
 
 extern crate core;
+use core::intrinsics::mir::*; //~ custom_mir
 
 #[custom_mir(dialect = "built")] //~ ERROR the `#[custom_mir]` attribute is just used for the Rust test suite
 pub fn foo(_x: i32) -> i32 {
-    0
+    mir! {
+        {
+            Return() //~ custom_mir
+        }
+    }
 }
 
 fn main() {
diff --git a/tests/ui/feature-gates/feature-gate-custom_mir.stderr b/tests/ui/feature-gates/feature-gate-custom_mir.stderr
index 34899e5e66c..118eab144bf 100644
--- a/tests/ui/feature-gates/feature-gate-custom_mir.stderr
+++ b/tests/ui/feature-gates/feature-gate-custom_mir.stderr
@@ -1,5 +1,5 @@
 error[E0658]: the `#[custom_mir]` attribute is just used for the Rust test suite
-  --> $DIR/feature-gate-custom_mir.rs:5:1
+  --> $DIR/feature-gate-custom_mir.rs:6:1
    |
 LL | #[custom_mir(dialect = "built")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,6 +7,24 @@ LL | #[custom_mir(dialect = "built")]
    = help: add `#![feature(custom_mir)]` 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: aborting due to 1 previous error
+error[E0658]: use of unstable library feature 'custom_mir': MIR is an implementation detail and extremely unstable
+  --> $DIR/feature-gate-custom_mir.rs:4:5
+   |
+LL | use core::intrinsics::mir::*;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(custom_mir)]` 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]: use of unstable library feature 'custom_mir': MIR is an implementation detail and extremely unstable
+  --> $DIR/feature-gate-custom_mir.rs:10:13
+   |
+LL |             Return()
+   |             ^^^^^^
+   |
+   = help: add `#![feature(custom_mir)]` 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: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-ffi_returns_twice.rs b/tests/ui/feature-gates/feature-gate-ffi_returns_twice.rs
deleted file mode 100644
index f354534356c..00000000000
--- a/tests/ui/feature-gates/feature-gate-ffi_returns_twice.rs
+++ /dev/null
@@ -1,6 +0,0 @@
-#![crate_type = "lib"]
-
-extern "C" {
-    #[ffi_returns_twice] //~ ERROR the `#[ffi_returns_twice]` attribute is an experimental feature
-    pub fn foo();
-}
diff --git a/tests/ui/feature-gates/feature-gate-ffi_returns_twice.stderr b/tests/ui/feature-gates/feature-gate-ffi_returns_twice.stderr
deleted file mode 100644
index 8d19874c36a..00000000000
--- a/tests/ui/feature-gates/feature-gate-ffi_returns_twice.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: the `#[ffi_returns_twice]` attribute is an experimental feature
-  --> $DIR/feature-gate-ffi_returns_twice.rs:4:5
-   |
-LL |     #[ffi_returns_twice]
-   |     ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #58314 <https://github.com/rust-lang/rust/issues/58314> for more information
-   = help: add `#![feature(ffi_returns_twice)]` 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: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions.rs b/tests/ui/feature-gates/feature-gate-naked_functions.rs
index 8e93b194174..dc561234809 100644
--- a/tests/ui/feature-gates/feature-gate-naked_functions.rs
+++ b/tests/ui/feature-gates/feature-gate-naked_functions.rs
@@ -6,12 +6,14 @@ use std::arch::asm;
 //~^ the `#[naked]` attribute is an experimental feature
 extern "C" fn naked() {
     asm!("", options(noreturn))
+    //~^ ERROR: requires unsafe
 }
 
 #[naked]
 //~^ the `#[naked]` attribute is an experimental feature
 extern "C" fn naked_2() -> isize {
     asm!("", options(noreturn))
+    //~^ ERROR: requires unsafe
 }
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-naked_functions.stderr b/tests/ui/feature-gates/feature-gate-naked_functions.stderr
index e1b82658217..ffdf31e147a 100644
--- a/tests/ui/feature-gates/feature-gate-naked_functions.stderr
+++ b/tests/ui/feature-gates/feature-gate-naked_functions.stderr
@@ -9,7 +9,7 @@ LL | #[naked]
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the `#[naked]` attribute is an experimental feature
-  --> $DIR/feature-gate-naked_functions.rs:11:1
+  --> $DIR/feature-gate-naked_functions.rs:12:1
    |
 LL | #[naked]
    | ^^^^^^^^
@@ -18,6 +18,23 @@ LL | #[naked]
    = help: add `#![feature(naked_functions)]` 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: aborting due to 2 previous errors
+error[E0133]: use of inline assembly is unsafe and requires unsafe function or block
+  --> $DIR/feature-gate-naked_functions.rs:8:5
+   |
+LL |     asm!("", options(noreturn))
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of inline assembly
+   |
+   = note: inline assembly is entirely unchecked and can cause undefined behavior
+
+error[E0133]: use of inline assembly is unsafe and requires unsafe function or block
+  --> $DIR/feature-gate-naked_functions.rs:15:5
+   |
+LL |     asm!("", options(noreturn))
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ use of inline assembly
+   |
+   = note: inline assembly is entirely unchecked and can cause undefined behavior
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.rs b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.rs
index 1285cca6b8b..37b7d52fafc 100644
--- a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.rs
+++ b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.rs
@@ -8,7 +8,7 @@ fn main() {
         extern "rust-intrinsic" { //~ ERROR intrinsics are subject to change
             fn atomic_fence();
         }
-        atomic_fence();
+        atomic_fence(); //~ ERROR: is unsafe
         42
     });
 }
diff --git a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr
index b0ed6e60760..3dc11b5612c 100644
--- a/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr
+++ b/tests/ui/feature-gates/feature-gated-feature-in-macro-arg.stderr
@@ -7,6 +7,15 @@ LL |         extern "rust-intrinsic" {
    = help: add `#![feature(intrinsics)]` 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: aborting due to 1 previous error
+error[E0133]: call to unsafe function `main::atomic_fence` is unsafe and requires unsafe function or block
+  --> $DIR/feature-gated-feature-in-macro-arg.rs:11:9
+   |
+LL |         atomic_fence();
+   |         ^^^^^^^^^^^^^^ 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 E0658`.
+Some errors have detailed explanations: E0133, E0658.
+For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/ffi_returns_twice.rs b/tests/ui/ffi_returns_twice.rs
deleted file mode 100644
index 8195d0e4863..00000000000
--- a/tests/ui/ffi_returns_twice.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-#![feature(ffi_returns_twice)]
-#![crate_type = "lib"]
-
-#[ffi_returns_twice] //~ ERROR `#[ffi_returns_twice]` may only be used on foreign functions
-pub fn foo() {}
-
-#[ffi_returns_twice] //~ ERROR `#[ffi_returns_twice]` may only be used on foreign functions
-macro_rules! bar {
-    () => ()
-}
-
-extern "C" {
-    #[ffi_returns_twice] //~ ERROR `#[ffi_returns_twice]` may only be used on foreign functions
-    static INT: i32;
-}
diff --git a/tests/ui/ffi_returns_twice.stderr b/tests/ui/ffi_returns_twice.stderr
deleted file mode 100644
index 0abe7613f14..00000000000
--- a/tests/ui/ffi_returns_twice.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0724]: `#[ffi_returns_twice]` may only be used on foreign functions
-  --> $DIR/ffi_returns_twice.rs:4:1
-   |
-LL | #[ffi_returns_twice]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error[E0724]: `#[ffi_returns_twice]` may only be used on foreign functions
-  --> $DIR/ffi_returns_twice.rs:7:1
-   |
-LL | #[ffi_returns_twice]
-   | ^^^^^^^^^^^^^^^^^^^^
-
-error[E0724]: `#[ffi_returns_twice]` may only be used on foreign functions
-  --> $DIR/ffi_returns_twice.rs:13:5
-   |
-LL |     #[ffi_returns_twice]
-   |     ^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0724`.
diff --git a/tests/ui/fn/suggest-return-closure.rs b/tests/ui/fn/suggest-return-closure.rs
index 33daa1ea0b4..81f20272867 100644
--- a/tests/ui/fn/suggest-return-closure.rs
+++ b/tests/ui/fn/suggest-return-closure.rs
@@ -17,10 +17,16 @@ fn fn_mut() -> _ {
     //~| SUGGESTION impl FnMut(char)
     //~| NOTE for more information on `Fn` traits and closure types
     let x = String::new();
-    |c| {
+    //~^ HELP: consider changing this to be mutable
+    |c| { //~ NOTE: value captured here
         x.push(c);
+        //~^ ERROR: does not live long enough
+        //~| NOTE: does not live long enough
+        //~| NOTE: cannot borrow as mutable
+        //~| ERROR: not declared as mutable
     }
-}
+} //~ NOTE: borrow later used here
+//~^ NOTE: dropped here
 
 fn fun() -> _ {
     //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types [E0121]
diff --git a/tests/ui/fn/suggest-return-closure.stderr b/tests/ui/fn/suggest-return-closure.stderr
index 341044469ea..8e80a11fe1b 100644
--- a/tests/ui/fn/suggest-return-closure.stderr
+++ b/tests/ui/fn/suggest-return-closure.stderr
@@ -21,7 +21,7 @@ LL | fn fn_mut() -> _ {
    = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
-  --> $DIR/suggest-return-closure.rs:25:13
+  --> $DIR/suggest-return-closure.rs:31:13
    |
 LL | fn fun() -> _ {
    |             ^
@@ -31,6 +31,29 @@ LL | fn fun() -> _ {
    |
    = note: for more information on `Fn` traits and closure types, see https://doc.rust-lang.org/book/ch13-01-closures.html
 
-error: aborting due to 3 previous errors
+error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
+  --> $DIR/suggest-return-closure.rs:22:9
+   |
+LL |     let x = String::new();
+   |         - help: consider changing this to be mutable: `mut x`
+...
+LL |         x.push(c);
+   |         ^ cannot borrow as mutable
+
+error[E0597]: `x` does not live long enough
+  --> $DIR/suggest-return-closure.rs:22:9
+   |
+LL |     |c| {
+   |     --- value captured here
+LL |         x.push(c);
+   |         ^ borrowed value does not live long enough
+...
+LL | }
+   | -- borrow later used here
+   | |
+   | `x` dropped here while still borrowed
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0121`.
+Some errors have detailed explanations: E0121, E0596, E0597.
+For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-88460.rs b/tests/ui/generic-associated-types/bugs/issue-88460.rs
index 224e696ad2c..3d2b225f0cd 100644
--- a/tests/ui/generic-associated-types/bugs/issue-88460.rs
+++ b/tests/ui/generic-associated-types/bugs/issue-88460.rs
@@ -1,7 +1,4 @@
-// check-fail
-// known-bug: #88460
-
-// This should pass, but has a missed normalization due to HRTB.
+// check-pass
 
 pub trait Marker {}
 
diff --git a/tests/ui/generic-associated-types/bugs/issue-88460.stderr b/tests/ui/generic-associated-types/bugs/issue-88460.stderr
deleted file mode 100644
index 74418a0c0bd..00000000000
--- a/tests/ui/generic-associated-types/bugs/issue-88460.stderr
+++ /dev/null
@@ -1,29 +0,0 @@
-error[E0277]: the trait bound `for<'a> <_ as Trait>::Assoc<'a>: Marker` is not satisfied
-  --> $DIR/issue-88460.rs:28:10
-   |
-LL |     test(Foo);
-   |     ---- ^^^ the trait `for<'a> Marker` is not implemented for `<_ as Trait>::Assoc<'a>`
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Marker` is implemented for `()`
-note: this is a known limitation of the trait solver that will be lifted in the future
-  --> $DIR/issue-88460.rs:28:10
-   |
-LL |     test(Foo);
-   |     -----^^^-
-   |     |    |
-   |     |    the trait solver is unable to infer the generic types that should be inferred from this argument
-   |     add turbofish arguments to this call to specify the types manually, even if it's redundant
-note: required by a bound in `test`
-  --> $DIR/issue-88460.rs:15:27
-   |
-LL | fn test<T>(value: T)
-   |    ---- required by a bound in this function
-...
-LL |     for<'a> T::Assoc<'a>: Marker,
-   |                           ^^^^^^ required by this bound in `test`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/extended/lending_iterator.base.stderr b/tests/ui/generic-associated-types/extended/lending_iterator.base.stderr
index 84210eeb1a6..b19280b45c2 100644
--- a/tests/ui/generic-associated-types/extended/lending_iterator.base.stderr
+++ b/tests/ui/generic-associated-types/extended/lending_iterator.base.stderr
@@ -7,6 +7,12 @@ LL |     fn from_iter<T: for<'x> LendingIterator<Item<'x> = A>>(iter: T) -> Self
 LL |     fn from_iter<I: for<'x> LendingIterator<Item<'x> = A>>(mut iter: I) -> Self {
    |                                             ^^^^^^^^^^^^ impl has extra requirement `I: 'x`
 
-error: aborting due to 1 previous error
+error: `Self` does not live long enough
+  --> $DIR/lending_iterator.rs:34:9
+   |
+LL |         <B as FromLendingIterator<A>>::from_iter(self)
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0276`.
diff --git a/tests/ui/generic-associated-types/extended/lending_iterator.rs b/tests/ui/generic-associated-types/extended/lending_iterator.rs
index 247761dd04b..8bec78d6ecd 100644
--- a/tests/ui/generic-associated-types/extended/lending_iterator.rs
+++ b/tests/ui/generic-associated-types/extended/lending_iterator.rs
@@ -32,6 +32,7 @@ pub trait LendingIterator {
         Self: for<'q> LendingIterator<Item<'q> = A>,
     {
         <B as FromLendingIterator<A>>::from_iter(self)
+        //[base]~^ ERROR: does not live long enough
     }
 }
 
diff --git a/tests/ui/generic-associated-types/issue-70304.rs b/tests/ui/generic-associated-types/issue-70304.rs
index 8898d4c7d13..935d3f7a4ba 100644
--- a/tests/ui/generic-associated-types/issue-70304.rs
+++ b/tests/ui/generic-associated-types/issue-70304.rs
@@ -52,4 +52,5 @@ fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> {
 pub fn main() {
     let doc = create_doc();
     let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc);
+    //~^ ERROR: `doc` does not live long enough
 }
diff --git a/tests/ui/generic-associated-types/issue-70304.stderr b/tests/ui/generic-associated-types/issue-70304.stderr
index 9b02c1b0768..8e012cc6d93 100644
--- a/tests/ui/generic-associated-types/issue-70304.stderr
+++ b/tests/ui/generic-associated-types/issue-70304.stderr
@@ -27,7 +27,21 @@ LL |     type Cursor<'a>: DocCursor<'a>;
    = note: this bound is currently required to ensure that impls have maximum flexibility
    = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
 
-error: aborting due to 3 previous errors
+error[E0597]: `doc` does not live long enough
+  --> $DIR/issue-70304.rs:54:59
+   |
+LL |     let doc = create_doc();
+   |         --- binding `doc` declared here
+LL |     let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc);
+   |                                               ------------^^^^-
+   |                                               |           |
+   |                                               |           borrowed value does not live long enough
+   |                                               argument requires that `doc` is borrowed for `'static`
+LL |
+LL | }
+   | - `doc` dropped here while still borrowed
+
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0106, E0637.
+Some errors have detailed explanations: E0106, E0597, E0637.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/generic-associated-types/issue-74684-2.rs b/tests/ui/generic-associated-types/issue-74684-2.rs
index ff243af2cb3..96cdb01be3b 100644
--- a/tests/ui/generic-associated-types/issue-74684-2.rs
+++ b/tests/ui/generic-associated-types/issue-74684-2.rs
@@ -10,7 +10,7 @@ impl <T> Fun for T {
 
 fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(t: Box<T>) -> &'static T::F<'a> {
     let a = [0; 1];
-    let x = T::identity(&a);
+    let x = T::identity(&a); //~ ERROR: does not live long enough
     todo!()
 }
 
diff --git a/tests/ui/generic-associated-types/issue-74684-2.stderr b/tests/ui/generic-associated-types/issue-74684-2.stderr
index e50e3df85b3..d39513ec523 100644
--- a/tests/ui/generic-associated-types/issue-74684-2.stderr
+++ b/tests/ui/generic-associated-types/issue-74684-2.stderr
@@ -17,6 +17,23 @@ note: required by a bound in `bug`
 LL | fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(t: Box<T>) -> &'static T::F<'a> {
    |                            ^^^^^^^^^^^^ required by this bound in `bug`
 
-error: aborting due to 1 previous error
+error[E0597]: `a` does not live long enough
+  --> $DIR/issue-74684-2.rs:13:25
+   |
+LL | fn bug<'a, T: ?Sized + Fun<F<'a> = [u8]>>(t: Box<T>) -> &'static T::F<'a> {
+   |        -- lifetime `'a` defined here
+LL |     let a = [0; 1];
+   |         - binding `a` declared here
+LL |     let x = T::identity(&a);
+   |             ------------^^-
+   |             |           |
+   |             |           borrowed value does not live long enough
+   |             argument requires that `a` is borrowed for `'a`
+LL |     todo!()
+LL | }
+   | - `a` dropped here while still borrowed
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0271, E0597.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/generic-associated-types/issue-80433.rs b/tests/ui/generic-associated-types/issue-80433.rs
index bdba78c2ccd..6d23427f16f 100644
--- a/tests/ui/generic-associated-types/issue-80433.rs
+++ b/tests/ui/generic-associated-types/issue-80433.rs
@@ -22,11 +22,12 @@ fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
   //~^ ERROR missing generics for associated type
 {
     for n in 0i16..100 {
-        *dst.test_mut() = n.into();
+        *dst.test_mut() = n.into(); //~ ERROR: cannot borrow
+        //~^ ERROR: borrowed data escapes outside of function
     }
 }
 
 fn main() {
     let mut t1: E<f32> = Default::default();
-    test_simpler(&mut t1);
+    test_simpler(&mut t1); //~ ERROR does not live long enough
 }
diff --git a/tests/ui/generic-associated-types/issue-80433.stderr b/tests/ui/generic-associated-types/issue-80433.stderr
index ab1fb794418..2bbf87ff1ff 100644
--- a/tests/ui/generic-associated-types/issue-80433.stderr
+++ b/tests/ui/generic-associated-types/issue-80433.stderr
@@ -25,6 +25,43 @@ LL |     type Output<'a>;
    = note: this bound is currently required to ensure that impls have maximum flexibility
    = note: we are soliciting feedback, see issue #87479 <https://github.com/rust-lang/rust/issues/87479> for more information
 
-error: aborting due to 2 previous errors
+error[E0499]: cannot borrow `*dst` as mutable more than once at a time
+  --> $DIR/issue-80433.rs:25:10
+   |
+LL |         *dst.test_mut() = n.into();
+   |          ^^^-----------
+   |          |
+   |          `*dst` was mutably borrowed here in the previous iteration of the loop
+   |          argument requires that `*dst` is borrowed for `'static`
+
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/issue-80433.rs:25:10
+   |
+LL | fn test_simpler<'a>(dst: &'a mut impl TestMut<Output = &'a mut f32>)
+   |                 --  --- `dst` is a reference that is only valid in the function body
+   |                 |
+   |                 lifetime `'a` defined here
+...
+LL |         *dst.test_mut() = n.into();
+   |          ^^^^^^^^^^^^^^
+   |          |
+   |          `dst` escapes the function body here
+   |          argument requires that `'a` must outlive `'static`
+
+error[E0597]: `t1` does not live long enough
+  --> $DIR/issue-80433.rs:32:18
+   |
+LL |     let mut t1: E<f32> = Default::default();
+   |         ------ binding `t1` declared here
+LL |     test_simpler(&mut t1);
+   |     -------------^^^^^^^-
+   |     |            |
+   |     |            borrowed value does not live long enough
+   |     argument requires that `t1` is borrowed for `'static`
+LL | }
+   | - `t1` dropped here while still borrowed
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0107, E0499, E0521, E0597.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/generic-associated-types/issue-88360.fixed b/tests/ui/generic-associated-types/issue-88360.fixed
index 3dea8bf7ac8..6fb1e2559c0 100644
--- a/tests/ui/generic-associated-types/issue-88360.fixed
+++ b/tests/ui/generic-associated-types/issue-88360.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait GatTrait {
     type Gat<'a> where Self: 'a;
diff --git a/tests/ui/generic-associated-types/issue-88360.rs b/tests/ui/generic-associated-types/issue-88360.rs
index 4d4c7ea3180..c8f07955b61 100644
--- a/tests/ui/generic-associated-types/issue-88360.rs
+++ b/tests/ui/generic-associated-types/issue-88360.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait GatTrait {
     type Gat<'a> where Self: 'a;
diff --git a/tests/ui/generic-associated-types/issue-88360.stderr b/tests/ui/generic-associated-types/issue-88360.stderr
index 49d36acadd6..488e50d2843 100644
--- a/tests/ui/generic-associated-types/issue-88360.stderr
+++ b/tests/ui/generic-associated-types/issue-88360.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-88360.rs:15:9
+  --> $DIR/issue-88360.rs:16:9
    |
 LL | trait SuperTrait<T>
    |                  - found this type parameter
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 add4d58f86a..92ce4a0970f 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
@@ -5,7 +5,7 @@ trait X {
     type Y<T>;
 }
 
-trait M {
+trait M { //~ NOTE
     fn f(&self) {}
 }
 
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 1dd463f996c..61512dd4658 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
@@ -14,6 +14,12 @@ LL | impl<T: X<Y<i32> = i32>> M for T {}
    |           ^^^^^^^^^^^^   -     -
    |           |
    |           unsatisfied trait bound introduced here
+   = help: items from traits can only be used if the trait is implemented and in scope
+note: `M` defines an item `f`, perhaps you need to implement it
+  --> $DIR/method-unsatisfied-assoc-type-predicate.rs:8:1
+   |
+LL | trait M {
+   | ^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/generics/generic-extern.rs b/tests/ui/generics/generic-extern.rs
index 3690d6fd07d..36fa5eaafd6 100644
--- a/tests/ui/generics/generic-extern.rs
+++ b/tests/ui/generics/generic-extern.rs
@@ -3,5 +3,5 @@ extern "C" {
 }
 
 fn main() {
-    foo::<i32>();
+    foo::<i32>(); //~ ERROR requires unsafe
 }
diff --git a/tests/ui/generics/generic-extern.stderr b/tests/ui/generics/generic-extern.stderr
index 4d9f6fedef1..a3f28825316 100644
--- a/tests/ui/generics/generic-extern.stderr
+++ b/tests/ui/generics/generic-extern.stderr
@@ -6,6 +6,15 @@ LL |     fn foo<T>();
    |
    = help: replace the type parameters with concrete types like `u32`
 
-error: aborting due to 1 previous error
+error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
+  --> $DIR/generic-extern.rs:6:5
+   |
+LL |     foo::<i32>();
+   |     ^^^^^^^^^^^^ 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 E0044`.
+Some errors have detailed explanations: E0044, E0133.
+For more information about an error, try `rustc --explain E0044`.
diff --git a/tests/ui/generics/generic-no-mangle.fixed b/tests/ui/generics/generic-no-mangle.fixed
index aa6d6310f5f..f51040358c0 100644
--- a/tests/ui/generics/generic-no-mangle.fixed
+++ b/tests/ui/generics/generic-no-mangle.fixed
@@ -1,5 +1,5 @@
 // run-rustfix
-
+#![allow(dead_code)]
 #![deny(no_mangle_generic_items)]
 
 
diff --git a/tests/ui/generics/generic-no-mangle.rs b/tests/ui/generics/generic-no-mangle.rs
index 8a59ca75aaf..02015331c57 100644
--- a/tests/ui/generics/generic-no-mangle.rs
+++ b/tests/ui/generics/generic-no-mangle.rs
@@ -1,5 +1,5 @@
 // run-rustfix
-
+#![allow(dead_code)]
 #![deny(no_mangle_generic_items)]
 
 #[no_mangle]
diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs
index dac97347349..99de7845d7b 100644
--- a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs
+++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.rs
@@ -4,4 +4,5 @@ fn main() {
     let xs = [13, 1, 5, 2, 3, 1, 21, 8];
     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
     //~^ `X..` patterns in slices are experimental
+    //~| ERROR: refutable pattern
 }
diff --git a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
index 8ae8f052e5b..b011044f4dd 100644
--- a/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
+++ b/tests/ui/half-open-range-patterns/feature-gate-half-open-range-patterns-in-slices.stderr
@@ -8,6 +8,21 @@ LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
    = help: add `#![feature(half_open_range_patterns_in_slices)]` 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: aborting due to 1 previous error
+error[E0005]: refutable pattern in local binding
+  --> $DIR/feature-gate-half-open-range-patterns-in-slices.rs:5:9
+   |
+LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `[i32::MIN..=2_i32, ..]` 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 `[i32; 8]`
+help: you might want to use `let else` to handle the variant that isn't matched
+   |
+LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { todo!() };
+   |                                               ++++++++++++++++
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0005, E0658.
+For more information about an error, try `rustc --explain E0005`.
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs
index 526a797e9d6..33506a5c444 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs
@@ -23,6 +23,7 @@ fn syntax2() {
     macro_rules! mac {
         ($e:expr) => {
             let ...$e; //~ ERROR range-to patterns with `...` are not allowed
+            //~^ ERROR refutable pattern in local binding
         }
     }
 
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
index ddffeaf9780..6832f21f25e 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-dotdotdot-bad-syntax.stderr
@@ -33,5 +33,24 @@ LL |     mac!(0);
    |
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 5 previous errors
+error[E0005]: refutable pattern in local binding
+  --> $DIR/half-open-range-pats-inclusive-dotdotdot-bad-syntax.rs:25:17
+   |
+LL |             let ...$e;
+   |                 ^^^^^ pattern `1_i32..=i32::MAX` not covered
+...
+LL |     mac!(0);
+   |     ------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |             if let ...$e; { todo!() }
+   |             ++            +++++++++++
+
+error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0005`.
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.rs
index 30173b1b4be..cff0c42eb52 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.rs
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.rs
@@ -1,6 +1,9 @@
 fn main() {
     let x = 42;
     match x {
+        //~^ ERROR: non-exhaustive patterns
+        //~| NOTE: not covered
+        //~| NOTE: matched value is of type
         0..=73 => {},
         74..=> {},
         //~^ ERROR unexpected `>` after inclusive range
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.stderr
index 8dfc46069f1..ecb43e83c70 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.stderr
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-match-arrow.stderr
@@ -1,5 +1,5 @@
 error: unexpected `>` after inclusive range
-  --> $DIR/half-open-range-pats-inclusive-match-arrow.rs:5:14
+  --> $DIR/half-open-range-pats-inclusive-match-arrow.rs:8:14
    |
 LL |         74..=> {},
    |           ---^
@@ -11,5 +11,19 @@ help: add a space between the pattern and `=>`
 LL |         74.. => {},
    |             +
 
-error: aborting due to 1 previous error
+error[E0004]: non-exhaustive patterns: `i32::MIN..=-1_i32` not covered
+  --> $DIR/half-open-range-pats-inclusive-match-arrow.rs:3:11
+   |
+LL |     match x {
+   |           ^ pattern `i32::MIN..=-1_i32` not covered
+   |
+   = note: the matched value is of type `i32`
+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 ~         74..=> {},
+LL ~         i32::MIN..=-1_i32 => todo!(),
+   |
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs
index 6567c8cc67c..2f1ec658972 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.rs
@@ -16,7 +16,9 @@ fn bar() {
     macro_rules! mac {
         ($e:expr) => {
             let $e...; //~ ERROR inclusive range with no end
+            //~^ ERROR: refutable pattern
             let $e..=; //~ ERROR inclusive range with no end
+            //~^ ERROR: refutable pattern
         }
     }
 
diff --git a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
index 3ad84b0ef26..cb9e48e70e3 100644
--- a/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
+++ b/tests/ui/half-open-range-patterns/half-open-range-pats-inclusive-no-end.stderr
@@ -43,7 +43,7 @@ LL |     mac!(0);
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0586]: inclusive range with no end
-  --> $DIR/half-open-range-pats-inclusive-no-end.rs:19:19
+  --> $DIR/half-open-range-pats-inclusive-no-end.rs:20:19
    |
 LL |             let $e..=;
    |                   ^^^ help: use `..` instead
@@ -54,6 +54,43 @@ LL |     mac!(0);
    = note: inclusive ranges must be bounded at the end (`..=b` or `a..=b`)
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 6 previous errors
+error[E0005]: refutable pattern in local binding
+  --> $DIR/half-open-range-pats-inclusive-no-end.rs:18:17
+   |
+LL |             let $e...;
+   |                 ^^^^^ pattern `i32::MIN..=-1_i32` not covered
+...
+LL |     mac!(0);
+   |     ------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |             if let $e...; { todo!() }
+   |             ++            +++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/half-open-range-pats-inclusive-no-end.rs:20:17
+   |
+LL |             let $e..=;
+   |                 ^^^^^ pattern `i32::MIN..=-1_i32` not covered
+...
+LL |     mac!(0);
+   |     ------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |             if let $e..=; { todo!() }
+   |             ++            +++++++++++
+
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0586`.
+Some errors have detailed explanations: E0005, E0586.
+For more information about an error, try `rustc --explain E0005`.
diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs
index c37af75b8fb..cd381544372 100644
--- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs
+++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.rs
@@ -5,4 +5,5 @@ fn main() {
     //~^ `X..` patterns in slices are experimental
     //~| exclusive range pattern syntax is experimental
     //~| exclusive range pattern syntax is experimental
+    //~| ERROR: refutable pattern
 }
diff --git a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
index be8f3aa5051..fc549eb65c0 100644
--- a/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
+++ b/tests/ui/half-open-range-patterns/slice_pattern_syntax_problem1.stderr
@@ -30,6 +30,21 @@ LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
    = 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 3 previous errors
+error[E0005]: refutable pattern in local binding
+  --> $DIR/slice_pattern_syntax_problem1.rs:4:9
+   |
+LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `[i32::MIN..=2_i32, ..]` 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 `[i32; 8]`
+help: you might want to use `let else` to handle the variant that isn't matched
+   |
+LL |     let [a @ 3.., b @ ..3, c @ 4..6, ..] = xs else { todo!() };
+   |                                               ++++++++++++++++
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0005, E0658.
+For more information about an error, try `rustc --explain E0005`.
diff --git a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs
index bd4533e0433..dc865605ed3 100644
--- a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs
+++ b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.rs
@@ -12,10 +12,12 @@ fn hr_subtype<'c>(f: for<'a, 'b> fn(Inv<'a>, Inv<'a>)) {
 
 fn simple1<'c>(x: (&'c i32,)) {
     let _x: (&'static i32,) = x;
+    //~^ ERROR: lifetime may not live long enough
 }
 
 fn simple2<'c>(x: (&'c i32,)) {
     let _: (&'static i32,) = x;
+    //~^ ERROR: lifetime may not live long enough
 }
 
 fn main() {
diff --git a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr
index c6d6f508328..39d43181ed7 100644
--- a/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr
+++ b/tests/ui/higher-ranked/subtype/placeholder-pattern-fail.stderr
@@ -9,6 +9,22 @@ LL |     let _: for<'a, 'b> fn(Inv<'a>, Inv<'b>) = sub;
    = note: expected fn pointer `for<'a, 'b> fn(Inv<'a>, Inv<'b>)`
               found fn pointer `for<'a> fn(Inv<'a>, Inv<'a>)`
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/placeholder-pattern-fail.rs:14:13
+   |
+LL | fn simple1<'c>(x: (&'c i32,)) {
+   |            -- lifetime `'c` defined here
+LL |     let _x: (&'static i32,) = x;
+   |             ^^^^^^^^^^^^^^^ type annotation requires that `'c` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/placeholder-pattern-fail.rs:19:12
+   |
+LL | fn simple2<'c>(x: (&'c i32,)) {
+   |            -- lifetime `'c` defined here
+LL |     let _: (&'static i32,) = x;
+   |            ^^^^^^^^^^^^^^^ type annotation requires that `'c` must outlive `'static`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs
index 48ebe5017aa..33e0ec4635b 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs
@@ -18,7 +18,7 @@ fn want_foo_for_some_tcx<'x,F>(f: &'x F)
     want_foo_for_any_tcx(f); //~ ERROR not satisfied
 }
 
-fn want_foo_for_any_tcx<F>(f: &F)
+fn want_foo_for_any_tcx<F>(f: &F) //~ WARN cannot return without recursing
     where F : for<'tcx> Foo<'tcx>
 {
     want_foo_for_some_tcx(f);
@@ -35,7 +35,7 @@ fn want_bar_for_some_ccx<'x,B>(b: &B)
     want_bar_for_any_ccx(b); //~ ERROR not satisfied
 }
 
-fn want_bar_for_any_ccx<B>(b: &B)
+fn want_bar_for_any_ccx<B>(b: &B) //~ WARN cannot return without recursing
     where B : for<'ccx> Bar<'ccx>
 {
     want_foo_for_some_tcx(b);
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr
index 7f96909b6e7..f220ba6f338 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr
@@ -38,6 +38,31 @@ help: consider further restricting this bound
 LL |     where B : Bar<'x> + for<'ccx> Bar<'ccx>
    |                       +++++++++++++++++++++
 
-error: aborting due to 2 previous errors
+warning: function cannot return without recursing
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:21:1
+   |
+LL | / fn want_foo_for_any_tcx<F>(f: &F)
+LL | |     where F : for<'tcx> Foo<'tcx>
+   | |_________________________________^ cannot return without recursing
+...
+LL |       want_foo_for_any_tcx(f);
+   |       ----------------------- recursive call site
+   |
+   = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
+
+warning: function cannot return without recursing
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:38:1
+   |
+LL | / fn want_bar_for_any_ccx<B>(b: &B)
+LL | |     where B : for<'ccx> Bar<'ccx>
+   | |_________________________________^ cannot return without recursing
+...
+LL |       want_bar_for_any_ccx(b);
+   |       ----------------------- recursive call site
+   |
+   = help: a `loop` may express intention better if this is on purpose
+
+error: aborting due to 2 previous errors; 2 warnings emitted
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
index 73870703cfb..699a4ecc42b 100644
--- a/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
@@ -15,6 +15,12 @@ note: the following trait bounds were not satisfied:
    |
 LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
    |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
+   = help: items from traits can only be used if the trait is implemented and in scope
+note: `StreamExt` defines an item `filterx`, perhaps you need to implement it
+  --> $DIR/issue-30786.rs:66:1
+   |
+LL | pub trait StreamExt
+   | ^^^^^^^^^^^^^^^^^^^
 
 error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, fn(&u64) -> &u64 {identity::<u64>}>, {closure@issue-30786.rs:131:30}>`, but its trait bounds were not satisfied
   --> $DIR/issue-30786.rs:132:24
@@ -33,6 +39,12 @@ note: the following trait bounds were not satisfied:
    |
 LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
    |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
+   = help: items from traits can only be used if the trait is implemented and in scope
+note: `StreamExt` defines an item `countx`, perhaps you need to implement it
+  --> $DIR/issue-30786.rs:66:1
+   |
+LL | pub trait StreamExt
+   | ^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs
index ab9d9a7ce6f..7072f41066b 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.rs
@@ -1,5 +1,4 @@
-// check-fail
-// known-bug: #90950
+// check-pass
 
 trait Yokeable<'a>: 'static {
     type Output: 'a;
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr
deleted file mode 100644
index 075e422e29c..00000000000
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/issue-90950.stderr
+++ /dev/null
@@ -1,29 +0,0 @@
-error[E0277]: the trait bound `for<'a> <_ as Yokeable<'a>>::Output: IsCovariant<'a>` is not satisfied
-  --> $DIR/issue-90950.rs:50:12
-   |
-LL |     upcast(y)
-   |     ------ ^ the trait `for<'a> IsCovariant<'a>` is not implemented for `<_ as Yokeable<'a>>::Output`
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `IsCovariant<'a>` is implemented for `std::borrow::Cow<'a, T>`
-note: this is a known limitation of the trait solver that will be lifted in the future
-  --> $DIR/issue-90950.rs:50:12
-   |
-LL |     upcast(y)
-   |     -------^-
-   |     |      |
-   |     |      the trait solver is unable to infer the generic types that should be inferred from this argument
-   |     add turbofish arguments to this call to specify the types manually, even if it's redundant
-note: required by a bound in `upcast`
-  --> $DIR/issue-90950.rs:27:42
-   |
-LL | fn upcast<Y>(x: Yoke<Y>) -> Yoke<Box<dyn IsCovariant<'static> + 'static>> where
-   |    ------ required by a bound in this function
-LL |     Y: for<'a> Yokeable<'a>,
-LL |     for<'a> <Y as Yokeable<'a>>::Output: IsCovariant<'a>
-   |                                          ^^^^^^^^^^^^^^^ required by this bound in `upcast`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
index 7693b118247..58ca5b0c187 100644
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
+++ b/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.rs
@@ -1,5 +1,4 @@
-// check-fail
-// known-bug: #89196
+// check-pass
 
 // Should pass, but we normalize and check bounds before we resolve the generics
 // of the function (which we know because of the return type).
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
deleted file mode 100644
index f42fc59536c..00000000000
--- a/tests/ui/higher-ranked/trait-bounds/normalize-under-binder/norm-before-method-resolution.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0277]: the trait bound `for<'a> <_ as Trait<'a>>::Out: Copy` is not satisfied
-  --> $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`
-   |
-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
-note: required by a bound in `weird_bound`
-  --> $DIR/norm-before-method-resolution.rs:18:40
-   |
-LL | fn weird_bound<X>() -> X
-   |    ----------- required by a bound in this function
-...
-LL |         for<'a> <X as Trait<'a>>::Out: Copy
-   |                                        ^^^^ required by this bound in `weird_bound`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/hygiene/panic-location.run.stderr b/tests/ui/hygiene/panic-location.run.stderr
index 5824ef31211..5c552411da7 100644
--- a/tests/ui/hygiene/panic-location.run.stderr
+++ b/tests/ui/hygiene/panic-location.run.stderr
@@ -1,3 +1,3 @@
-thread 'main' panicked at library/alloc/src/raw_vec.rs:570:5:
+thread 'main' panicked at library/alloc/src/raw_vec.rs:571:5:
 capacity overflow
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
index 1011fc4163b..0e3cd2ff060 100644
--- a/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
+++ b/tests/ui/impl-trait/equality-in-canonical-query.clone.stderr
@@ -1,4 +1,4 @@
-note: no errors encountered even though `span_delayed_bug` issued
+note: no errors encountered even though delayed bugs were created
 
 note: those delayed bugs will now be shown as internal compiler errors
 
diff --git a/tests/ui/impl-trait/example-st.rs b/tests/ui/impl-trait/example-st.rs
index 4e1aa3a0859..1e6ebc52365 100644
--- a/tests/ui/impl-trait/example-st.rs
+++ b/tests/ui/impl-trait/example-st.rs
@@ -3,7 +3,7 @@
 struct State;
 type Error = ();
 
-trait Bind<F> {
+trait Bind<F> { //~ WARN trait `Bind` is never used
     type Output;
     fn bind(self, f: F) -> Self::Output;
 }
diff --git a/tests/ui/impl-trait/example-st.stderr b/tests/ui/impl-trait/example-st.stderr
new file mode 100644
index 00000000000..f722d7f6582
--- /dev/null
+++ b/tests/ui/impl-trait/example-st.stderr
@@ -0,0 +1,10 @@
+warning: trait `Bind` is never used
+  --> $DIR/example-st.rs:6:7
+   |
+LL | trait Bind<F> {
+   |       ^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs
index 57d68849251..e1aba8eda1b 100644
--- a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs
+++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.rs
@@ -4,10 +4,6 @@
 
 fn ice() -> impl AsRef<Fn(&())> {
     //~^ 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 (Rust 2015) but is a hard error in Rust 2021!
-    //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
     Foo
 }
diff --git a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
index d3c2d5d5b9f..84aaedf1838 100644
--- a/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
+++ b/tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr
@@ -12,33 +12,5 @@ help: use `dyn`
 LL | fn ice() -> impl AsRef<dyn Fn(&())> {
    |                        +++
 
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24
-   |
-LL | fn ice() -> impl AsRef<Fn(&())> {
-   |                        ^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | fn ice() -> impl AsRef<dyn Fn(&())> {
-   |                        +++
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/fresh-lifetime-from-bare-trait-obj-114664.rs:5:24
-   |
-LL | fn ice() -> impl AsRef<Fn(&())> {
-   |                        ^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | fn ice() -> impl AsRef<dyn Fn(&())> {
-   |                        +++
-
-warning: 3 warnings emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed
index 8dc8e045d47..ecc8488a152 100644
--- a/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed
+++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.fixed
@@ -1,6 +1,7 @@
 // edition:2021
 // run-rustfix
 
+#![allow(dead_code)]
 trait Trait {
     #[allow(async_fn_in_trait)]
     async fn foo();
diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.rs b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs
index 30b04d87b9a..860fea07df9 100644
--- a/tests/ui/impl-trait/in-trait/suggest-missing-item.rs
+++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.rs
@@ -1,6 +1,7 @@
 // edition:2021
 // run-rustfix
 
+#![allow(dead_code)]
 trait Trait {
     #[allow(async_fn_in_trait)]
     async fn foo();
diff --git a/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr
index cf68ed87030..45fd79badb3 100644
--- a/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr
+++ b/tests/ui/impl-trait/in-trait/suggest-missing-item.stderr
@@ -1,5 +1,5 @@
 error[E0046]: not all trait items implemented, missing: `foo`, `bar`, `test`, `baz`
-  --> $DIR/suggest-missing-item.rs:19:1
+  --> $DIR/suggest-missing-item.rs:20:1
    |
 LL |     async fn foo();
    |     --------------- `foo` from trait
diff --git a/tests/ui/impl-trait/must_outlive_least_region_or_bound.rs b/tests/ui/impl-trait/must_outlive_least_region_or_bound.rs
index 18404f98603..9762ac98272 100644
--- a/tests/ui/impl-trait/must_outlive_least_region_or_bound.rs
+++ b/tests/ui/impl-trait/must_outlive_least_region_or_bound.rs
@@ -16,12 +16,16 @@ fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
 //~^ ERROR explicit lifetime required in the type of `x`
 
 fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
+//~^ ERROR: lifetime may not live long enough
 
 fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
+//~^ ERROR: lifetime may not live long enough
 
 fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
+//~^ ERROR: lifetime may not live long enough
 
 fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
+//~^ ERROR: lifetime may not live long enough
 
 fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
 //~^ ERROR lifetime may not live long enough
diff --git a/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr
index c60fe08c5d7..273f51ddbe3 100644
--- a/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr
+++ b/tests/ui/impl-trait/must_outlive_least_region_or_bound.stderr
@@ -67,7 +67,7 @@ LL | fn foo<'a>(x: &i32) -> impl Copy + 'a { x }
    |               help: add explicit lifetime `'a` to the type of `x`: `&'a i32`
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:26:55
+  --> $DIR/must_outlive_least_region_or_bound.rs:30:55
    |
 LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) }
    |               -                                       ^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
@@ -84,7 +84,7 @@ LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x)
    |                                                    ++++
 
 error: lifetime may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:32:69
+  --> $DIR/must_outlive_least_region_or_bound.rs:36:69
    |
 LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x }
    |               -- lifetime `'a` defined here                         ^ returning this value requires that `'a` must outlive `'static`
@@ -99,12 +99,12 @@ LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x
    |                      ~~~~~~~~~~~~
 
 error[E0700]: hidden type for `impl Fn(&'a u32)` captures lifetime that does not appear in bounds
-  --> $DIR/must_outlive_least_region_or_bound.rs:38:5
+  --> $DIR/must_outlive_least_region_or_bound.rs:42:5
    |
 LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) {
    |                              --                             ---------------- opaque type defined here
    |                              |
-   |                              hidden type `{closure@$DIR/must_outlive_least_region_or_bound.rs:38:5: 38:13}` captures the lifetime `'b` as defined here
+   |                              hidden type `{closure@$DIR/must_outlive_least_region_or_bound.rs:42:5: 42:13}` captures the lifetime `'b` as defined here
 LL |     move |_| println!("{}", y)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
@@ -114,7 +114,7 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32
    |                                                                              ++++
 
 error[E0310]: the parameter type `T` may not live long enough
-  --> $DIR/must_outlive_least_region_or_bound.rs:43:5
+  --> $DIR/must_outlive_least_region_or_bound.rs:47:5
    |
 LL |     x
    |     ^
@@ -127,7 +127,63 @@ help: consider adding an explicit lifetime bound
 LL | fn ty_param_wont_outlive_static<T:Debug + 'static>(x: T) -> impl Debug + 'static {
    |                                         +++++++++
 
-error: aborting due to 9 previous errors
+error: lifetime may not live long enough
+  --> $DIR/must_outlive_least_region_or_bound.rs:18:41
+   |
+LL | fn elided3(x: &i32) -> Box<dyn Debug> { Box::new(x) }
+   |               -                         ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |               |
+   |               let's call the lifetime of this reference `'1`
+   |
+help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound
+   |
+LL | fn elided3(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
+   |                                      ++++
+
+error: lifetime may not live long enough
+  --> $DIR/must_outlive_least_region_or_bound.rs:21:50
+   |
+LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug> { Box::new(x) }
+   |              -- lifetime `'a` defined here       ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+   |
+help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound
+   |
+LL | fn explicit3<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
+   |                                               ++++
+
+error: lifetime may not live long enough
+  --> $DIR/must_outlive_least_region_or_bound.rs:24:51
+   |
+LL | fn elided4(x: &i32) -> Box<dyn Debug + 'static> { Box::new(x) }
+   |               -                                   ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+   |               |
+   |               let's call the lifetime of this reference `'1`
+   |
+help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
+   |
+LL | fn elided4(x: &i32) -> Box<dyn Debug + '_> { Box::new(x) }
+   |                                        ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn elided4(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
+   |               ~~~~~~~~~~~~
+
+error: lifetime may not live long enough
+  --> $DIR/must_outlive_least_region_or_bound.rs:27:60
+   |
+LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'static> { Box::new(x) }
+   |              -- lifetime `'a` defined here                 ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
+   |
+help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x`
+   |
+LL | fn explicit4<'a>(x: &'a i32) -> Box<dyn Debug + 'a> { Box::new(x) }
+   |                                                 ~~
+help: alternatively, add an explicit `'static` bound to this reference
+   |
+LL | fn explicit4<'a>(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) }
+   |                     ~~~~~~~~~~~~
+
+error: aborting due to 13 previous errors
 
 Some errors have detailed explanations: E0310, E0621, E0700.
 For more information about an error, try `rustc --explain E0310`.
diff --git a/tests/ui/impl-trait/normalize-tait-in-const.stderr b/tests/ui/impl-trait/normalize-tait-in-const.stderr
index 7fd2ec57b14..f77b4bd517f 100644
--- a/tests/ui/impl-trait/normalize-tait-in-const.stderr
+++ b/tests/ui/impl-trait/normalize-tait-in-const.stderr
@@ -4,5 +4,29 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
    |                                          ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/normalize-tait-in-const.rs:26:5
+   |
+LL |     fun(filter_positive());
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct + ~const std::ops::Fn<(&Alias<'_>,)>>(fun: F) {
+   |                                                                              ++++++++++++++++++++++++++++++++++++
+
+error[E0493]: destructor of `F` cannot be evaluated at compile-time
+  --> $DIR/normalize-tait-in-const.rs:25:79
+   |
+LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
+   |                                                                               ^^^ the destructor for this type cannot be evaluated in constant functions
+LL |     fun(filter_positive());
+LL | }
+   | - value is dropped here
+
+error: aborting due to 3 previous errors
 
+Some errors have detailed explanations: E0015, E0493.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/impl-trait/type-alias-generic-param.rs b/tests/ui/impl-trait/type-alias-generic-param.rs
index 1211625dac9..e4b2e412420 100644
--- a/tests/ui/impl-trait/type-alias-generic-param.rs
+++ b/tests/ui/impl-trait/type-alias-generic-param.rs
@@ -5,7 +5,7 @@
 // run-pass
 #![feature(impl_trait_in_assoc_type)]
 
-trait Meow {
+trait Meow { //~ WARN trait `Meow` is never used
     type MeowType;
     fn meow(self) -> Self::MeowType;
 }
diff --git a/tests/ui/impl-trait/type-alias-generic-param.stderr b/tests/ui/impl-trait/type-alias-generic-param.stderr
new file mode 100644
index 00000000000..e4115dc1319
--- /dev/null
+++ b/tests/ui/impl-trait/type-alias-generic-param.stderr
@@ -0,0 +1,10 @@
+warning: trait `Meow` is never used
+  --> $DIR/type-alias-generic-param.rs:8:7
+   |
+LL | trait Meow {
+   |       ^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/imports/empty-import-prefix-pass-2015.rs b/tests/ui/imports/empty-import-prefix-pass-2015.rs
new file mode 100644
index 00000000000..a3278007c11
--- /dev/null
+++ b/tests/ui/imports/empty-import-prefix-pass-2015.rs
@@ -0,0 +1,10 @@
+// check-pass
+// edition:2015
+
+use {};
+use {{}};
+
+use ::{};
+use {::{}};
+
+fn main() {}
diff --git a/tests/ui/imports/empty-import-prefix-pass.rs b/tests/ui/imports/empty-import-prefix-pass.rs
new file mode 100644
index 00000000000..d76c0da4bd8
--- /dev/null
+++ b/tests/ui/imports/empty-import-prefix-pass.rs
@@ -0,0 +1,10 @@
+// check-pass
+// edition:2018
+
+use {};
+use {{}};
+
+use ::{};
+use {::{}};
+
+fn main() {}
diff --git a/tests/ui/infinite/infinite-tag-type-recursion.rs b/tests/ui/infinite/infinite-tag-type-recursion.rs
index 87a9e08dd38..1b5cb55b4e4 100644
--- a/tests/ui/infinite/infinite-tag-type-recursion.rs
+++ b/tests/ui/infinite/infinite-tag-type-recursion.rs
@@ -1,4 +1,5 @@
 enum MList { Cons(isize, MList), Nil }
 //~^ ERROR recursive type `MList` has infinite size
+//~| ERROR cycle
 
 fn main() { let a = MList::Cons(10, MList::Cons(11, MList::Nil)); }
diff --git a/tests/ui/infinite/infinite-tag-type-recursion.stderr b/tests/ui/infinite/infinite-tag-type-recursion.stderr
index 4ca408260b8..8745224a45e 100644
--- a/tests/ui/infinite/infinite-tag-type-recursion.stderr
+++ b/tests/ui/infinite/infinite-tag-type-recursion.stderr
@@ -9,6 +9,17 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
 LL | enum MList { Cons(isize, Box<MList>), Nil }
    |                          ++++     +
 
-error: aborting due to 1 previous error
+error[E0391]: cycle detected when computing when `MList` needs drop
+  --> $DIR/infinite-tag-type-recursion.rs:1:1
+   |
+LL | enum MList { Cons(isize, MList), Nil }
+   | ^^^^^^^^^^
+   |
+   = note: ...which immediately requires computing when `MList` needs drop again
+   = note: cycle used when computing whether `MList` needs drop
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0072`.
+Some errors have detailed explanations: E0072, E0391.
+For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/inner-static-type-parameter.stderr b/tests/ui/inner-static-type-parameter.stderr
index 6c7f1ffbe16..88d33b44c59 100644
--- a/tests/ui/inner-static-type-parameter.stderr
+++ b/tests/ui/inner-static-type-parameter.stderr
@@ -5,6 +5,8 @@ LL | fn foo<T>() {
    |        - type parameter from outer item
 LL |     static a: Bar<T> = Bar::What;
    |                   ^ use of generic parameter from outer item
+   |
+   = note: a `static` is a separate item from the item that contains it
 
 error[E0392]: type parameter `T` is never used
   --> $DIR/inner-static-type-parameter.rs:3:10
diff --git a/tests/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs b/tests/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs
index 06cf8c0f0f6..8ea4eac1a61 100644
--- a/tests/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs
+++ b/tests/ui/invalid/invalid_rustc_layout_scalar_valid_range.rs
@@ -26,5 +26,7 @@ fn main() {
     let _ = A(0);
     let _ = B(0);
     let _ = C(0);
-    let _ = E::X;
+    unsafe {
+        let _ = E::X;
+    }
 }
diff --git a/tests/ui/issues/issue-11374.rs b/tests/ui/issues/issue-11374.rs
index 7519ba2826e..60ee256c65a 100644
--- a/tests/ui/issues/issue-11374.rs
+++ b/tests/ui/issues/issue-11374.rs
@@ -18,6 +18,7 @@ impl<'a> Container<'a> {
 pub fn for_stdin<'a>() -> Container<'a> {
     let mut r = io::stdin();
     Container::wrap(&mut r as &mut dyn io::Read)
+    //~^ ERROR cannot return value referencing local variable
 }
 
 fn main() {
diff --git a/tests/ui/issues/issue-11374.stderr b/tests/ui/issues/issue-11374.stderr
index 275a0e6b5d7..3ae5cfc79f8 100644
--- a/tests/ui/issues/issue-11374.stderr
+++ b/tests/ui/issues/issue-11374.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-11374.rs:26:15
+  --> $DIR/issue-11374.rs:27:15
    |
 LL |     c.read_to(v);
    |       ------- ^ expected `&mut [u8]`, found `Vec<_>`
@@ -18,6 +18,16 @@ help: consider mutably borrowing here
 LL |     c.read_to(&mut v);
    |               ++++
 
-error: aborting due to 1 previous error
+error[E0515]: cannot return value referencing local variable `r`
+  --> $DIR/issue-11374.rs:20:5
+   |
+LL |     Container::wrap(&mut r as &mut dyn io::Read)
+   |     ^^^^^^^^^^^^^^^^------^^^^^^^^^^^^^^^^^^^^^^
+   |     |               |
+   |     |               `r` is borrowed here
+   |     returns a value referencing data owned by the current function
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0308, E0515.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/issues/issue-13497.rs b/tests/ui/issues/issue-13497.rs
index 4b2795aa841..7f786a54b9f 100644
--- a/tests/ui/issues/issue-13497.rs
+++ b/tests/ui/issues/issue-13497.rs
@@ -3,6 +3,7 @@ fn read_lines_borrowed1() -> Vec<
 > {
     let rawLines: Vec<String> = vec!["foo  ".to_string(), "  bar".to_string()];
     rawLines.iter().map(|l| l.trim()).collect()
+    //~^ ERROR: cannot return value referencing
 }
 
 fn main() {}
diff --git a/tests/ui/issues/issue-13497.stderr b/tests/ui/issues/issue-13497.stderr
index fb3de637a79..7630848f6a5 100644
--- a/tests/ui/issues/issue-13497.stderr
+++ b/tests/ui/issues/issue-13497.stderr
@@ -14,6 +14,16 @@ help: instead, you are more likely to want to return an owned value
 LL |     String
    |     ~~~~~~
 
-error: aborting due to 1 previous error
+error[E0515]: cannot return value referencing local variable `rawLines`
+  --> $DIR/issue-13497.rs:5:5
+   |
+LL |     rawLines.iter().map(|l| l.trim()).collect()
+   |     --------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |
+   |     returns a value referencing data owned by the current function
+   |     `rawLines` is borrowed here
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0106`.
+Some errors have detailed explanations: E0106, E0515.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/issues/issue-14399.rs b/tests/ui/issues/issue-14399.rs
index 7b32bf8e4cb..0c6c4d8dc6b 100644
--- a/tests/ui/issues/issue-14399.rs
+++ b/tests/ui/issues/issue-14399.rs
@@ -9,7 +9,7 @@
 #[derive(Clone)]
 struct B1;
 
-trait A { fn foo(&self) {} }
+trait A { fn foo(&self) {} } //~ WARN method `foo` is never used
 impl A for B1 {}
 
 fn main() {
diff --git a/tests/ui/issues/issue-14399.stderr b/tests/ui/issues/issue-14399.stderr
new file mode 100644
index 00000000000..d226ece6fb0
--- /dev/null
+++ b/tests/ui/issues/issue-14399.stderr
@@ -0,0 +1,12 @@
+warning: method `foo` is never used
+  --> $DIR/issue-14399.rs:12:14
+   |
+LL | trait A { fn foo(&self) {} }
+   |       -      ^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-15858.rs b/tests/ui/issues/issue-15858.rs
index 77941c07671..e3e3c293d7a 100644
--- a/tests/ui/issues/issue-15858.rs
+++ b/tests/ui/issues/issue-15858.rs
@@ -2,7 +2,7 @@
 static mut DROP_RAN: bool = false;
 
 trait Bar {
-    fn do_something(&mut self);
+    fn do_something(&mut self); //~ WARN method `do_something` is never used
 }
 
 struct BarImpl;
diff --git a/tests/ui/issues/issue-15858.stderr b/tests/ui/issues/issue-15858.stderr
new file mode 100644
index 00000000000..f36bcc21bd7
--- /dev/null
+++ b/tests/ui/issues/issue-15858.stderr
@@ -0,0 +1,12 @@
+warning: method `do_something` is never used
+  --> $DIR/issue-15858.rs:5:8
+   |
+LL | trait Bar {
+   |       --- method in this trait
+LL |     fn do_something(&mut self);
+   |        ^^^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-17351.rs b/tests/ui/issues/issue-17351.rs
index 62f6bcf15e3..12bb8a73b7b 100644
--- a/tests/ui/issues/issue-17351.rs
+++ b/tests/ui/issues/issue-17351.rs
@@ -1,7 +1,7 @@
 // run-pass
 // pretty-expanded FIXME #23616
 
-trait Str { fn foo(&self) {} }
+trait Str { fn foo(&self) {} } //~ WARN method `foo` is never used
 impl Str for str {}
 impl<'a, S: ?Sized> Str for &'a S where S: Str {}
 
diff --git a/tests/ui/issues/issue-17351.stderr b/tests/ui/issues/issue-17351.stderr
new file mode 100644
index 00000000000..3242d578dab
--- /dev/null
+++ b/tests/ui/issues/issue-17351.stderr
@@ -0,0 +1,12 @@
+warning: method `foo` is never used
+  --> $DIR/issue-17351.rs:4:16
+   |
+LL | trait Str { fn foo(&self) {} }
+   |       ---      ^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-18173.rs b/tests/ui/issues/issue-18173.rs
index 11468040ee5..010efee9f8a 100644
--- a/tests/ui/issues/issue-18173.rs
+++ b/tests/ui/issues/issue-18173.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 trait Foo {
     type T;
 }
diff --git a/tests/ui/issues/issue-20055-box-trait.rs b/tests/ui/issues/issue-20055-box-trait.rs
index 772cd9d7eda..36f597450ad 100644
--- a/tests/ui/issues/issue-20055-box-trait.rs
+++ b/tests/ui/issues/issue-20055-box-trait.rs
@@ -8,7 +8,7 @@
 // statement surrounding the `match`.
 
 trait Boo {
-    fn dummy(&self) { }
+    fn dummy(&self) { } //~ WARN method `dummy` is never used
 }
 
 impl Boo for [i8; 1] { }
diff --git a/tests/ui/issues/issue-20055-box-trait.stderr b/tests/ui/issues/issue-20055-box-trait.stderr
new file mode 100644
index 00000000000..db9d359e225
--- /dev/null
+++ b/tests/ui/issues/issue-20055-box-trait.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/issue-20055-box-trait.rs:11:8
+   |
+LL | trait Boo {
+   |       --- method in this trait
+LL |     fn dummy(&self) { }
+   |        ^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-21909.rs b/tests/ui/issues/issue-21909.rs
index 7cb558d9a4f..6a6cdcfee15 100644
--- a/tests/ui/issues/issue-21909.rs
+++ b/tests/ui/issues/issue-21909.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait A<X> {
diff --git a/tests/ui/issues/issue-23485.rs b/tests/ui/issues/issue-23485.rs
index 1dd3d9293bc..07ed0f1b00d 100644
--- a/tests/ui/issues/issue-23485.rs
+++ b/tests/ui/issues/issue-23485.rs
@@ -17,7 +17,7 @@ trait Iterator {
 
     fn next(&mut self) -> Option<Self::Item>;
 
-    fn clone_first(mut self) -> Option<<Self::Item as Deref>::Target> where
+    fn clone_first(mut self) -> Option<<Self::Item as Deref>::Target> where //~ WARN method `clone_first` is never used
         Self: Sized,
         Self::Item: Deref,
         <Self::Item as Deref>::Target: Clone,
diff --git a/tests/ui/issues/issue-23485.stderr b/tests/ui/issues/issue-23485.stderr
new file mode 100644
index 00000000000..ed2d2400d0d
--- /dev/null
+++ b/tests/ui/issues/issue-23485.stderr
@@ -0,0 +1,13 @@
+warning: method `clone_first` is never used
+  --> $DIR/issue-23485.rs:20:8
+   |
+LL | trait Iterator {
+   |       -------- method in this trait
+...
+LL |     fn clone_first(mut self) -> Option<<Self::Item as Deref>::Target> where
+   |        ^^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-2848.rs b/tests/ui/issues/issue-2848.rs
index e0049bf8fbb..34181acdd05 100644
--- a/tests/ui/issues/issue-2848.rs
+++ b/tests/ui/issues/issue-2848.rs
@@ -12,6 +12,7 @@ fn main() {
     use bar::foo::{alpha, charlie};
     match alpha {
       alpha | beta => {} //~  ERROR variable `beta` is not bound in all patterns
+      //~^ ERROR: `beta` is named the same as one of the variants
       charlie => {}
     }
 }
diff --git a/tests/ui/issues/issue-2848.stderr b/tests/ui/issues/issue-2848.stderr
index 873f7efcd73..1cef27c3463 100644
--- a/tests/ui/issues/issue-2848.stderr
+++ b/tests/ui/issues/issue-2848.stderr
@@ -6,6 +6,15 @@ LL |       alpha | beta => {}
    |       |
    |       pattern doesn't bind `beta`
 
-error: aborting due to 1 previous error
+error[E0170]: pattern binding `beta` is named the same as one of the variants of the type `bar::foo`
+  --> $DIR/issue-2848.rs:14:15
+   |
+LL |       alpha | beta => {}
+   |               ^^^^ help: to match on the variant, qualify the path: `bar::foo::beta`
+   |
+   = note: `#[deny(bindings_with_variant_name)]` on by default
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0408`.
+Some errors have detailed explanations: E0170, E0408.
+For more information about an error, try `rustc --explain E0170`.
diff --git a/tests/ui/issues/issue-28971.rs b/tests/ui/issues/issue-28971.rs
index f0a1e2d0061..8e7a2fe0ef2 100644
--- a/tests/ui/issues/issue-28971.rs
+++ b/tests/ui/issues/issue-28971.rs
@@ -13,4 +13,5 @@ fn main(){
 
 fn foo<F>(f: F) where F: FnMut() {
     f();
+    //~^ ERROR: cannot borrow
 }
diff --git a/tests/ui/issues/issue-28971.stderr b/tests/ui/issues/issue-28971.stderr
index 8fd3c7ffc30..26057cbc2d1 100644
--- a/tests/ui/issues/issue-28971.stderr
+++ b/tests/ui/issues/issue-28971.stderr
@@ -10,6 +10,18 @@ LL |             Foo::Baz(..) => (),
    |                  variant or associated item not found in `Foo`
    |                  help: there is a variant with a similar name: `Bar`
 
-error: aborting due to 1 previous error
+error[E0596]: cannot borrow `f` as mutable, as it is not declared as mutable
+  --> $DIR/issue-28971.rs:15:5
+   |
+LL |     f();
+   |     ^ cannot borrow as mutable
+   |
+help: consider changing this to be mutable
+   |
+LL | fn foo<F>(mut f: F) where F: FnMut() {
+   |           +++
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0599`.
+Some errors have detailed explanations: E0596, E0599.
+For more information about an error, try `rustc --explain E0596`.
diff --git a/tests/ui/issues/issue-2989.rs b/tests/ui/issues/issue-2989.rs
index c0b67374370..a9586751407 100644
--- a/tests/ui/issues/issue-2989.rs
+++ b/tests/ui/issues/issue-2989.rs
@@ -1,8 +1,8 @@
 // run-pass
 #![allow(non_camel_case_types)]
 
-trait methods {
-    fn to_bytes(&self) -> Vec<u8> ;
+trait methods { //~ WARN trait `methods` is never used
+    fn to_bytes(&self) -> Vec<u8>;
 }
 
 impl methods for () {
diff --git a/tests/ui/issues/issue-2989.stderr b/tests/ui/issues/issue-2989.stderr
new file mode 100644
index 00000000000..57181607cec
--- /dev/null
+++ b/tests/ui/issues/issue-2989.stderr
@@ -0,0 +1,10 @@
+warning: trait `methods` is never used
+  --> $DIR/issue-2989.rs:4:7
+   |
+LL | trait methods {
+   |       ^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-34074.rs b/tests/ui/issues/issue-34074.rs
index 0600d3937c1..ca7d7b49a04 100644
--- a/tests/ui/issues/issue-34074.rs
+++ b/tests/ui/issues/issue-34074.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // Make sure several unnamed function parameters don't conflict with each other
 
 trait Tr {
diff --git a/tests/ui/issues/issue-34503.rs b/tests/ui/issues/issue-34503.rs
index 26e7358408f..d2c95d990ec 100644
--- a/tests/ui/issues/issue-34503.rs
+++ b/tests/ui/issues/issue-34503.rs
@@ -2,7 +2,7 @@
 fn main() {
     struct X;
     trait Foo<T> {
-        fn foo(&self) where (T, Option<T>): Ord {}
+        fn foo(&self) where (T, Option<T>): Ord {} //~ WARN methods `foo` and `bar` are never used
         fn bar(&self, x: &Option<T>) -> bool
         where Option<T>: Ord { *x < *x }
     }
diff --git a/tests/ui/issues/issue-34503.stderr b/tests/ui/issues/issue-34503.stderr
new file mode 100644
index 00000000000..60d8d76a619
--- /dev/null
+++ b/tests/ui/issues/issue-34503.stderr
@@ -0,0 +1,14 @@
+warning: methods `foo` and `bar` are never used
+  --> $DIR/issue-34503.rs:5:12
+   |
+LL |     trait Foo<T> {
+   |           --- methods in this trait
+LL |         fn foo(&self) where (T, Option<T>): Ord {}
+   |            ^^^
+LL |         fn bar(&self, x: &Option<T>) -> bool
+   |            ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-3563-3.rs b/tests/ui/issues/issue-3563-3.rs
index bedfdab97d5..6346b82167c 100644
--- a/tests/ui/issues/issue-3563-3.rs
+++ b/tests/ui/issues/issue-3563-3.rs
@@ -112,7 +112,7 @@ trait Canvas {
 
     // Unlike interfaces traits support default implementations.
     // Got an ICE as soon as I added this method.
-    fn add_points(&mut self, shapes: &[Point]) {
+    fn add_points(&mut self, shapes: &[Point]) { //~ WARN method `add_points` is never used
         for pt in shapes {self.add_point(*pt)};
     }
 }
diff --git a/tests/ui/issues/issue-3563-3.stderr b/tests/ui/issues/issue-3563-3.stderr
new file mode 100644
index 00000000000..bd65c1e3fd5
--- /dev/null
+++ b/tests/ui/issues/issue-3563-3.stderr
@@ -0,0 +1,13 @@
+warning: method `add_points` is never used
+  --> $DIR/issue-3563-3.rs:115:8
+   |
+LL | trait Canvas {
+   |       ------ method in this trait
+...
+LL |     fn add_points(&mut self, shapes: &[Point]) {
+   |        ^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-3878.rs b/tests/ui/issues/issue-3878.rs
deleted file mode 100644
index 6de3405af0d..00000000000
--- a/tests/ui/issues/issue-3878.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-// run-pass
-// pretty-expanded FIXME #23616
-
-#![allow(path_statements)]
-
-pub fn main() {
-    let y: Box<_> = Box::new(1);
-    y;
-}
diff --git a/tests/ui/issues/issue-50571.fixed b/tests/ui/issues/issue-50571.fixed
index 2f8c925b853..13c830cd0d4 100644
--- a/tests/ui/issues/issue-50571.fixed
+++ b/tests/ui/issues/issue-50571.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 
+#![allow(dead_code)]
 trait Foo {
     fn foo(_: [i32; 2]) {}
     //~^ ERROR: patterns aren't allowed in methods without bodies
diff --git a/tests/ui/issues/issue-50571.rs b/tests/ui/issues/issue-50571.rs
index 56f422e7d58..6fe13e3f707 100644
--- a/tests/ui/issues/issue-50571.rs
+++ b/tests/ui/issues/issue-50571.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 
+#![allow(dead_code)]
 trait Foo {
     fn foo([a, b]: [i32; 2]) {}
     //~^ ERROR: patterns aren't allowed in methods without bodies
diff --git a/tests/ui/issues/issue-50571.stderr b/tests/ui/issues/issue-50571.stderr
index fe47790f1dd..12256ded1c0 100644
--- a/tests/ui/issues/issue-50571.stderr
+++ b/tests/ui/issues/issue-50571.stderr
@@ -1,5 +1,5 @@
 error[E0642]: patterns aren't allowed in methods without bodies
-  --> $DIR/issue-50571.rs:4:12
+  --> $DIR/issue-50571.rs:5:12
    |
 LL |     fn foo([a, b]: [i32; 2]) {}
    |            ^^^^^^
diff --git a/tests/ui/issues/issue-67535.rs b/tests/ui/issues/issue-67535.rs
index 24f50621310..153b95a1674 100644
--- a/tests/ui/issues/issue-67535.rs
+++ b/tests/ui/issues/issue-67535.rs
@@ -2,21 +2,21 @@ fn main() {}
 
 impl std::ops::AddAssign for () {
     //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
-    fn add_assign(&self, other: ()) -> () {
+    fn add_assign(&self, other: ()) -> () { //~ ERROR incompatible type
         ()
     }
 }
 
 impl std::ops::AddAssign for [(); 1] {
     //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
-    fn add_assign(&self, other: [(); 1]) -> [(); 1] {
+    fn add_assign(&self, other: [(); 1]) -> [(); 1] { //~ ERROR incompatible type
         [()]
     }
 }
 
 impl std::ops::AddAssign for &[u8] {
     //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types
-    fn add_assign(&self, other: &[u8]) -> &[u8] {
+    fn add_assign(&self, other: &[u8]) -> &[u8] { //~ ERROR incompatible type
         self
     }
 }
diff --git a/tests/ui/issues/issue-67535.stderr b/tests/ui/issues/issue-67535.stderr
index 4d7a02a5096..c8bde2cb88c 100644
--- a/tests/ui/issues/issue-67535.stderr
+++ b/tests/ui/issues/issue-67535.stderr
@@ -34,6 +34,43 @@ LL | impl std::ops::AddAssign for &[u8] {
    |
    = note: define and implement a trait or new type instead
 
-error: aborting due to 3 previous errors
+error[E0053]: method `add_assign` has an incompatible type for trait
+  --> $DIR/issue-67535.rs:5:19
+   |
+LL |     fn add_assign(&self, other: ()) -> () {
+   |                   ^^^^^
+   |                   |
+   |                   types differ in mutability
+   |                   help: change the self-receiver type to match the trait: `&mut self`
+   |
+   = note: expected signature `fn(&mut (), ())`
+              found signature `fn(&(), ())`
+
+error[E0053]: method `add_assign` has an incompatible type for trait
+  --> $DIR/issue-67535.rs:12:19
+   |
+LL |     fn add_assign(&self, other: [(); 1]) -> [(); 1] {
+   |                   ^^^^^
+   |                   |
+   |                   types differ in mutability
+   |                   help: change the self-receiver type to match the trait: `&mut self`
+   |
+   = note: expected signature `fn(&mut _, _)`
+              found signature `fn(&_, _) -> [(); 1]`
+
+error[E0053]: method `add_assign` has an incompatible type for trait
+  --> $DIR/issue-67535.rs:19:19
+   |
+LL |     fn add_assign(&self, other: &[u8]) -> &[u8] {
+   |                   ^^^^^
+   |                   |
+   |                   types differ in mutability
+   |                   help: change the self-receiver type to match the trait: `&mut self`
+   |
+   = note: expected signature `fn(&mut &_, &_)`
+              found signature `fn(&&_, &_) -> &[u8]`
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0117`.
+Some errors have detailed explanations: E0053, E0117.
+For more information about an error, try `rustc --explain E0053`.
diff --git a/tests/ui/issues/issue-7575.rs b/tests/ui/issues/issue-7575.rs
index ac69f2b1c80..0074f660c4e 100644
--- a/tests/ui/issues/issue-7575.rs
+++ b/tests/ui/issues/issue-7575.rs
@@ -1,6 +1,6 @@
 // run-pass
 
-trait Foo {
+trait Foo { //~ WARN trait `Foo` is never used
     fn new() -> bool { false }
     fn dummy(&self) { }
 }
diff --git a/tests/ui/issues/issue-7575.stderr b/tests/ui/issues/issue-7575.stderr
new file mode 100644
index 00000000000..2f987d19c80
--- /dev/null
+++ b/tests/ui/issues/issue-7575.stderr
@@ -0,0 +1,10 @@
+warning: trait `Foo` is never used
+  --> $DIR/issue-7575.rs:3:7
+   |
+LL | trait Foo {
+   |       ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-7911.rs b/tests/ui/issues/issue-7911.rs
index d4db3b0776b..114574b9009 100644
--- a/tests/ui/issues/issue-7911.rs
+++ b/tests/ui/issues/issue-7911.rs
@@ -4,7 +4,7 @@
 
 #![allow(unused_variables)] // unused foobar_immut + foobar_mut
 trait FooBar {
-    fn dummy(&self) { }
+    fn dummy(&self) { } //~ WARN method `dummy` is never used
 }
 struct Bar(#[allow(dead_code)] i32);
 struct Foo { bar: Bar }
diff --git a/tests/ui/issues/issue-7911.stderr b/tests/ui/issues/issue-7911.stderr
new file mode 100644
index 00000000000..ead7ee191ac
--- /dev/null
+++ b/tests/ui/issues/issue-7911.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/issue-7911.rs:7:8
+   |
+LL | trait FooBar {
+   |       ------ method in this trait
+LL |     fn dummy(&self) { }
+   |        ^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-8248.rs b/tests/ui/issues/issue-8248.rs
index 31a305c31be..94b1a5203b4 100644
--- a/tests/ui/issues/issue-8248.rs
+++ b/tests/ui/issues/issue-8248.rs
@@ -2,7 +2,7 @@
 // pretty-expanded FIXME #23616
 
 trait A {
-    fn dummy(&self) { }
+    fn dummy(&self) { } //~ WARN method `dummy` is never used
 }
 struct B;
 impl A for B {}
diff --git a/tests/ui/issues/issue-8248.stderr b/tests/ui/issues/issue-8248.stderr
new file mode 100644
index 00000000000..a0098bcb771
--- /dev/null
+++ b/tests/ui/issues/issue-8248.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/issue-8248.rs:5:8
+   |
+LL | trait A {
+   |       - method in this trait
+LL |     fn dummy(&self) { }
+   |        ^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-9951.rs b/tests/ui/issues/issue-9951.rs
index 2698a3b17c6..5db3f74efaa 100644
--- a/tests/ui/issues/issue-9951.rs
+++ b/tests/ui/issues/issue-9951.rs
@@ -4,7 +4,7 @@
 #![allow(unused_variables)]
 
 trait Bar {
-  fn noop(&self);
+  fn noop(&self); //~ WARN method `noop` is never used
 }
 impl Bar for u8 {
   fn noop(&self) {}
diff --git a/tests/ui/issues/issue-9951.stderr b/tests/ui/issues/issue-9951.stderr
new file mode 100644
index 00000000000..475f2817914
--- /dev/null
+++ b/tests/ui/issues/issue-9951.stderr
@@ -0,0 +1,12 @@
+warning: method `noop` is never used
+  --> $DIR/issue-9951.rs:7:6
+   |
+LL | trait Bar {
+   |       --- method in this trait
+LL |   fn noop(&self);
+   |      ^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/kindck/kindck-impl-type-params.rs b/tests/ui/kindck/kindck-impl-type-params.rs
index 72a6599c326..707c5dbaec3 100644
--- a/tests/ui/kindck/kindck-impl-type-params.rs
+++ b/tests/ui/kindck/kindck-impl-type-params.rs
@@ -28,6 +28,7 @@ fn g<T>(val: T) {
 fn foo<'a>() {
     let t: S<&'a isize> = S(marker::PhantomData);
     let a = &t as &dyn Gettable<&'a isize>;
+    //~^ ERROR: lifetime may not live long enough
 }
 
 fn foo2<'a>() {
diff --git a/tests/ui/kindck/kindck-impl-type-params.stderr b/tests/ui/kindck/kindck-impl-type-params.stderr
index fe03ac422d2..aad020e4ec9 100644
--- a/tests/ui/kindck/kindck-impl-type-params.stderr
+++ b/tests/ui/kindck/kindck-impl-type-params.stderr
@@ -75,7 +75,7 @@ LL | fn g<T: std::marker::Copy>(val: T) {
    |       +++++++++++++++++++
 
 error[E0277]: the trait bound `String: Copy` is not satisfied
-  --> $DIR/kindck-impl-type-params.rs:35:13
+  --> $DIR/kindck-impl-type-params.rs:36:13
    |
 LL |     let a = t as Box<dyn Gettable<String>>;
    |             ^ the trait `Copy` is not implemented for `String`, which is required by `S<String>: Gettable<String>`
@@ -91,7 +91,7 @@ LL | impl<T: Send + Copy + 'static> Gettable<T> for S<T> {}
    = note: required for the cast from `Box<S<String>>` to `Box<dyn Gettable<String>>`
 
 error[E0277]: the trait bound `Foo: Copy` is not satisfied
-  --> $DIR/kindck-impl-type-params.rs:43:37
+  --> $DIR/kindck-impl-type-params.rs:44:37
    |
 LL |     let a: Box<dyn Gettable<Foo>> = t;
    |                                     ^ the trait `Copy` is not implemented for `Foo`, which is required by `S<Foo>: Gettable<Foo>`
@@ -111,6 +111,15 @@ LL +     #[derive(Copy)]
 LL |     struct Foo; // does not impl Copy
    |
 
-error: aborting due to 6 previous errors
+error: lifetime may not live long enough
+  --> $DIR/kindck-impl-type-params.rs:30:13
+   |
+LL | fn foo<'a>() {
+   |        -- lifetime `'a` defined here
+LL |     let t: S<&'a isize> = S(marker::PhantomData);
+LL |     let a = &t as &dyn Gettable<&'a isize>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/kindck/kindck-send-object1.rs b/tests/ui/kindck/kindck-send-object1.rs
index 787d0f8f6cb..0ce3995dccc 100644
--- a/tests/ui/kindck/kindck-send-object1.rs
+++ b/tests/ui/kindck/kindck-send-object1.rs
@@ -12,6 +12,7 @@ fn test51<'a>() {
 }
 fn test52<'a>() {
     assert_send::<&'a (dyn Dummy + Sync)>();
+    //~^ ERROR: lifetime may not live long enough
 }
 
 // ...unless they are properly bounded
diff --git a/tests/ui/kindck/kindck-send-object1.stderr b/tests/ui/kindck/kindck-send-object1.stderr
index 771c54dce0d..39343b9993b 100644
--- a/tests/ui/kindck/kindck-send-object1.stderr
+++ b/tests/ui/kindck/kindck-send-object1.stderr
@@ -13,7 +13,7 @@ LL | fn assert_send<T:Send+'static>() { }
    |                  ^^^^ required by this bound in `assert_send`
 
 error[E0277]: `(dyn Dummy + 'a)` cannot be sent between threads safely
-  --> $DIR/kindck-send-object1.rs:28:19
+  --> $DIR/kindck-send-object1.rs:29:19
    |
 LL |     assert_send::<Box<dyn Dummy + 'a>>();
    |                   ^^^^^^^^^^^^^^^^^^^ `(dyn Dummy + 'a)` cannot be sent between threads safely
@@ -28,6 +28,14 @@ note: required by a bound in `assert_send`
 LL | fn assert_send<T:Send+'static>() { }
    |                  ^^^^ required by this bound in `assert_send`
 
-error: aborting due to 2 previous errors
+error: lifetime may not live long enough
+  --> $DIR/kindck-send-object1.rs:14:5
+   |
+LL | fn test52<'a>() {
+   |           -- lifetime `'a` defined here
+LL |     assert_send::<&'a (dyn Dummy + Sync)>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/lifetimes/issue-17728.rs b/tests/ui/lifetimes/issue-17728.rs
index 6aca159c47e..ff8783029ff 100644
--- a/tests/ui/lifetimes/issue-17728.rs
+++ b/tests/ui/lifetimes/issue-17728.rs
@@ -12,7 +12,7 @@ trait TraversesWorld {
         let direction = str_to_direction(directionStr);
         let maybe_room = room.direction_to_room.get(&direction);
         match maybe_room {
-            Some(entry) => Ok(entry),
+            Some(entry) => Ok(entry), //~ ERROR: lifetime may not live long enough
             _ => Err("Direction does not exist in room.")
         }
     }
diff --git a/tests/ui/lifetimes/issue-17728.stderr b/tests/ui/lifetimes/issue-17728.stderr
index fb1c7cf7ad3..23547f722a1 100644
--- a/tests/ui/lifetimes/issue-17728.stderr
+++ b/tests/ui/lifetimes/issue-17728.stderr
@@ -16,6 +16,22 @@ LL | |     }
    = note: expected enum `RoomDirection`
               found enum `Option<_>`
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/issue-17728.rs:15:28
+   |
+LL |     fn attemptTraverse(&self, room: &Room, directionStr: &str) -> Result<&Room, &str> {
+   |                        -            - let's call the lifetime of this reference `'1`
+   |                        |
+   |                        let's call the lifetime of this reference `'2`
+...
+LL |             Some(entry) => Ok(entry),
+   |                            ^^^^^^^^^ method was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1`
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL |     fn attemptTraverse<'a>(&'a self, room: &'a Room, directionStr: &str) -> Result<&Room, &str> {
+   |                       ++++  ++              ++
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs
index d6c918843c7..56f89b70410 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs
+++ b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs
@@ -1,5 +1,7 @@
 fn foo(x: &i32, y: &i32) -> &i32 { //~ ERROR missing lifetime
     if x > y { x } else { y }
+    //~^ ERROR: lifetime may not live long enough
+    //~| ERROR: lifetime may not live long enough
 }
 
 fn main() {}
diff --git a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
index 62b0a8a04bf..db5b039d1c2 100644
--- a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
+++ b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr
@@ -10,6 +10,22 @@ help: consider introducing a named lifetime parameter
 LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 {
    |       ++++     ++          ++          ++
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/ex1b-return-no-names-if-else.rs:2:16
+   |
+LL | fn foo(x: &i32, y: &i32) -> &i32 {
+   |           - let's call the lifetime of this reference `'1`
+LL |     if x > y { x } else { y }
+   |                ^ returning this value requires that `'1` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/ex1b-return-no-names-if-else.rs:2:27
+   |
+LL | fn foo(x: &i32, y: &i32) -> &i32 {
+   |                    - let's call the lifetime of this reference `'2`
+LL |     if x > y { x } else { y }
+   |                           ^ returning this value requires that `'2` must outlive `'static`
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/lint/dead-code/associated-type.rs b/tests/ui/lint/dead-code/associated-type.rs
index 1cf66e75a95..25106a66e7e 100644
--- a/tests/ui/lint/dead-code/associated-type.rs
+++ b/tests/ui/lint/dead-code/associated-type.rs
@@ -15,5 +15,5 @@ impl Foo for Ex {
 }
 
 pub fn main() {
-    let _x = Ex;
+    let _x: &dyn Foo<Bar = <Ex as Foo>::Bar> = &Ex;
 }
diff --git a/tests/ui/lint/dead-code/issue-41883.rs b/tests/ui/lint/dead-code/issue-41883.rs
new file mode 100644
index 00000000000..e165861e893
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-41883.rs
@@ -0,0 +1,29 @@
+#![deny(dead_code)]
+
+enum Category {
+    Dead, //~ ERROR variant `Dead` is never constructed
+    Used,
+}
+
+trait UnusedTrait { //~ ERROR trait `UnusedTrait` is never used
+    fn this_is_unused(&self) -> Category {
+        Category::Dead
+    }
+}
+
+struct UnusedStruct; //~ ERROR struct `UnusedStruct` is never constructed
+
+impl UnusedTrait for UnusedStruct {
+    fn this_is_unused(&self) -> Category {
+        Category::Used
+    }
+}
+
+mod private {
+    #[derive(Debug)]
+    struct UnusedStruct; //~ ERROR struct `UnusedStruct` is never constructed
+}
+
+fn main() {
+    let _c = Category::Used;
+}
diff --git a/tests/ui/lint/dead-code/issue-41883.stderr b/tests/ui/lint/dead-code/issue-41883.stderr
new file mode 100644
index 00000000000..cf079e4dda3
--- /dev/null
+++ b/tests/ui/lint/dead-code/issue-41883.stderr
@@ -0,0 +1,36 @@
+error: variant `Dead` is never constructed
+  --> $DIR/issue-41883.rs:4:5
+   |
+LL | enum Category {
+   |      -------- variant in this enum
+LL |     Dead,
+   |     ^^^^
+   |
+note: the lint level is defined here
+  --> $DIR/issue-41883.rs:1:9
+   |
+LL | #![deny(dead_code)]
+   |         ^^^^^^^^^
+
+error: trait `UnusedTrait` is never used
+  --> $DIR/issue-41883.rs:8:7
+   |
+LL | trait UnusedTrait {
+   |       ^^^^^^^^^^^
+
+error: struct `UnusedStruct` is never constructed
+  --> $DIR/issue-41883.rs:14:8
+   |
+LL | struct UnusedStruct;
+   |        ^^^^^^^^^^^^
+
+error: struct `UnusedStruct` is never constructed
+  --> $DIR/issue-41883.rs:24:12
+   |
+LL |     struct UnusedStruct;
+   |            ^^^^^^^^^^^^
+   |
+   = note: `UnusedStruct` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
index 942c5516500..2d6364aa0cd 100644
--- a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
+++ b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.rs
@@ -17,7 +17,7 @@ struct Bar {
 
 // Issue 119267: this should not ICE.
 #[derive(Debug)]
-struct Foo(usize, #[allow(unused)] usize); //~ WARN field `0` is never read
+struct Foo(usize, #[allow(unused)] usize); //~ WARN struct `Foo` is never constructed
 
 fn main() {
     Bar {
diff --git a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
index 06f9b229c18..b992005318f 100644
--- a/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
+++ b/tests/ui/lint/dead-code/multiple-dead-codes-in-the-same-struct.stderr
@@ -51,19 +51,13 @@ note: the lint level is defined here
 LL |     #[forbid(dead_code)]
    |              ^^^^^^^^^
 
-warning: field `0` is never read
-  --> $DIR/multiple-dead-codes-in-the-same-struct.rs:20:12
+warning: struct `Foo` is never constructed
+  --> $DIR/multiple-dead-codes-in-the-same-struct.rs:20:8
    |
 LL | struct Foo(usize, #[allow(unused)] usize);
-   |        --- ^^^^^
-   |        |
-   |        field in this struct
+   |        ^^^
    |
    = note: `Foo` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
-help: consider changing the field to be of unit type to suppress this warning while preserving the field numbering, or remove the field
-   |
-LL | struct Foo((), #[allow(unused)] usize);
-   |            ~~
 
 error: aborting due to 2 previous errors; 2 warnings emitted
 
diff --git a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs
index 631a8cb2f08..9b1edba41aa 100644
--- a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs
+++ b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.rs
@@ -10,9 +10,5 @@ pub trait SomeTrait {}
 pub fn function(_x: Box<SomeTrait>) {}
 //~^ WARN trait objects without an explicit `dyn` are deprecated
 //~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
 
 fn main() {}
diff --git a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
index ecdc625015e..e9b7b248e61 100644
--- a/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/allowed-group-warn-by-default-lint.stderr
@@ -12,33 +12,5 @@ help: use `dyn`
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
 
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/allowed-group-warn-by-default-lint.rs:10:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/allowed-group-warn-by-default-lint.rs:10:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: 3 warnings emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/lint/force-warn/cap-lints-allow.rs b/tests/ui/lint/force-warn/cap-lints-allow.rs
index fdba7f4105e..9609ea99431 100644
--- a/tests/ui/lint/force-warn/cap-lints-allow.rs
+++ b/tests/ui/lint/force-warn/cap-lints-allow.rs
@@ -8,9 +8,5 @@ pub trait SomeTrait {}
 pub fn function(_x: Box<SomeTrait>) {}
 //~^ WARN trait objects without an explicit `dyn` are deprecated
 //~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
 
 fn main() {}
diff --git a/tests/ui/lint/force-warn/cap-lints-allow.stderr b/tests/ui/lint/force-warn/cap-lints-allow.stderr
index 5f5f2ff52b6..e569b2f9f1a 100644
--- a/tests/ui/lint/force-warn/cap-lints-allow.stderr
+++ b/tests/ui/lint/force-warn/cap-lints-allow.stderr
@@ -12,33 +12,5 @@ help: use `dyn`
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
 
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/cap-lints-allow.rs:8:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/cap-lints-allow.rs:8:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: 3 warnings emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs
index 7ad7462ddc5..9736027452a 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs
+++ b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.rs
@@ -8,9 +8,5 @@ pub trait SomeTrait {}
 pub fn function(_x: Box<SomeTrait>) {}
 //~^ WARN trait objects without an explicit `dyn` are deprecated
 //~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
 
 fn main() {}
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
index 3a0b1201b0c..c971e4d0d4d 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/lint-group-allowed-cli-warn-by-default-lint.stderr
@@ -13,33 +13,5 @@ help: use `dyn`
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
 
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/lint-group-allowed-cli-warn-by-default-lint.rs:8:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: 3 warnings emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.rs b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.rs
index ee5a18c3829..99cad614c25 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.rs
+++ b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.rs
@@ -10,9 +10,5 @@ pub trait SomeTrait {}
 pub fn function(_x: Box<SomeTrait>) {}
 //~^ WARN trait objects without an explicit `dyn` are deprecated
 //~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
 
 fn main() {}
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
index 92555eda2a7..97b8694984d 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
+++ b/tests/ui/lint/force-warn/lint-group-allowed-lint-group.stderr
@@ -13,33 +13,5 @@ help: use `dyn`
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
 
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/lint-group-allowed-lint-group.rs:10:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/lint-group-allowed-lint-group.rs:10:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: 3 warnings emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs
index 248aece6fe7..f0aacd77340 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs
+++ b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.rs
@@ -10,9 +10,5 @@ pub trait SomeTrait {}
 pub fn function(_x: Box<SomeTrait>) {}
 //~^ WARN trait objects without an explicit `dyn` are deprecated
 //~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
-//~| WARN trait objects without an explicit `dyn` are deprecated
-//~| WARN this is accepted in the current edition
 
 fn main() {}
diff --git a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
index c14c7957a25..cd030cc1fcd 100644
--- a/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
+++ b/tests/ui/lint/force-warn/lint-group-allowed-warn-by-default-lint.stderr
@@ -13,33 +13,5 @@ help: use `dyn`
 LL | pub fn function(_x: Box<dyn SomeTrait>) {}
    |                         +++
 
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/lint-group-allowed-warn-by-default-lint.rs:10:25
-   |
-LL | pub fn function(_x: Box<SomeTrait>) {}
-   |                         ^^^^^^^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | pub fn function(_x: Box<dyn SomeTrait>) {}
-   |                         +++
-
-warning: 3 warnings emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/lint/future-incompat-json-test.stderr b/tests/ui/lint/future-incompat-json-test.stderr
index c4ab5a00d16..18fc3f17f00 100644
--- a/tests/ui/lint/future-incompat-json-test.stderr
+++ b/tests/ui/lint/future-incompat-json-test.stderr
@@ -1,4 +1,4 @@
-{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`-A unused-variables` implied by `-A unused`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"to override `-A unused` add `#[allow(unused_variables)]`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MachineApplicable","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x`
+{"$message_type":"future_incompat","future_incompat_report":[{"diagnostic":{"$message_type":"diagnostic","message":"unused variable: `x`","code":{"code":"unused_variables","explanation":null},"level":"warning","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":null,"suggestion_applicability":null,"expansion":null}],"children":[{"message":"`-A unused-variables` implied by `-A unused`","code":null,"level":"note","spans":[],"children":[],"rendered":null},{"message":"to override `-A unused` add `#[allow(unused_variables)]`","code":null,"level":"help","spans":[],"children":[],"rendered":null},{"message":"if this is intentional, prefix it with an underscore","code":null,"level":"help","spans":[{"file_name":"$DIR/future-incompat-json-test.rs","byte_start":338,"byte_end":339,"line_start":9,"line_end":9,"column_start":9,"column_end":10,"is_primary":true,"text":[{"text":"    let x = 1;","highlight_start":9,"highlight_end":10}],"label":null,"suggested_replacement":"_x","suggestion_applicability":"MaybeIncorrect","expansion":null}],"children":[],"rendered":null}],"rendered":"warning: unused variable: `x`
   --> $DIR/future-incompat-json-test.rs:9:9
    |
 LL |     let x = 1;
diff --git a/tests/ui/lint/issue-20343.rs b/tests/ui/lint/issue-20343.rs
index 000b6398442..f0f4eccc676 100644
--- a/tests/ui/lint/issue-20343.rs
+++ b/tests/ui/lint/issue-20343.rs
@@ -22,6 +22,8 @@ impl B {
 
     // test for unused code in generics
     fn baz<A: T<D>>() {}
+
+    fn foz<A: T<D>>(a: A) { a.dummy(D); }
 }
 
 pub fn main() {
@@ -29,4 +31,5 @@ pub fn main() {
     B::foo(b);
     B::bar();
     B::baz::<()>();
+    B::foz::<()>(());
 }
diff --git a/tests/ui/lint/lint-stability-deprecated.rs b/tests/ui/lint/lint-stability-deprecated.rs
index a56a37228e5..80bc85ff557 100644
--- a/tests/ui/lint/lint-stability-deprecated.rs
+++ b/tests/ui/lint/lint-stability-deprecated.rs
@@ -96,13 +96,10 @@ mod cross_crate {
         struct S1<T: TraitWithAssociatedTypes>(T::TypeUnstable);
         struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
         //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
-        //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
         type A = dyn TraitWithAssociatedTypes<
             TypeUnstable = u8,
             TypeDeprecated = u16,
             //~^ WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`
-            //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`
-            //~| WARN use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`
         >;
 
         let _ = DeprecatedStruct { //~ WARN use of deprecated struct `lint_stability::DeprecatedStruct`
diff --git a/tests/ui/lint/lint-stability-deprecated.stderr b/tests/ui/lint/lint-stability-deprecated.stderr
index 609fc56a8ae..51205ff4340 100644
--- a/tests/ui/lint/lint-stability-deprecated.stderr
+++ b/tests/ui/lint/lint-stability-deprecated.stderr
@@ -77,241 +77,241 @@ LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated struct `lint_stability::DeprecatedStruct`: text
-  --> $DIR/lint-stability-deprecated.rs:108:17
+  --> $DIR/lint-stability-deprecated.rs:105:17
    |
 LL |         let _ = DeprecatedStruct {
    |                 ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated struct `lint_stability::DeprecatedUnstableStruct`: text
-  --> $DIR/lint-stability-deprecated.rs:111:17
+  --> $DIR/lint-stability-deprecated.rs:108:17
    |
 LL |         let _ = DeprecatedUnstableStruct {
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated unit struct `lint_stability::DeprecatedUnitStruct`: text
-  --> $DIR/lint-stability-deprecated.rs:118:17
+  --> $DIR/lint-stability-deprecated.rs:115:17
    |
 LL |         let _ = DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated unit struct `lint_stability::DeprecatedUnstableUnitStruct`: text
-  --> $DIR/lint-stability-deprecated.rs:119:17
+  --> $DIR/lint-stability-deprecated.rs:116:17
    |
 LL |         let _ = DeprecatedUnstableUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated unit variant `lint_stability::Enum::DeprecatedVariant`: text
-  --> $DIR/lint-stability-deprecated.rs:123:23
+  --> $DIR/lint-stability-deprecated.rs:120:23
    |
 LL |         let _ = Enum::DeprecatedVariant;
    |                       ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated unit variant `lint_stability::Enum::DeprecatedUnstableVariant`: text
-  --> $DIR/lint-stability-deprecated.rs:124:23
+  --> $DIR/lint-stability-deprecated.rs:121:23
    |
 LL |         let _ = Enum::DeprecatedUnstableVariant;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated tuple struct `lint_stability::DeprecatedTupleStruct`: text
-  --> $DIR/lint-stability-deprecated.rs:128:17
+  --> $DIR/lint-stability-deprecated.rs:125:17
    |
 LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated tuple struct `lint_stability::DeprecatedUnstableTupleStruct`: text
-  --> $DIR/lint-stability-deprecated.rs:129:17
+  --> $DIR/lint-stability-deprecated.rs:126:17
    |
 LL |         let _ = DeprecatedUnstableTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `lint_stability::deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:138:25
+  --> $DIR/lint-stability-deprecated.rs:135:25
    |
 LL |         macro_test_arg!(deprecated_text());
    |                         ^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `lint_stability::deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:139:25
+  --> $DIR/lint-stability-deprecated.rs:136:25
    |
 LL |         macro_test_arg!(deprecated_unstable_text());
    |                         ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `lint_stability::deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:140:41
+  --> $DIR/lint-stability-deprecated.rs:137:41
    |
 LL |         macro_test_arg!(macro_test_arg!(deprecated_text()));
    |                                         ^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:145:16
+  --> $DIR/lint-stability-deprecated.rs:142:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:147:25
+  --> $DIR/lint-stability-deprecated.rs:144:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |                         ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:149:16
+  --> $DIR/lint-stability-deprecated.rs:146:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:151:25
+  --> $DIR/lint-stability-deprecated.rs:148:25
    |
 LL |         <Foo as Trait>::trait_deprecated_text(&foo);
    |                         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
-  --> $DIR/lint-stability-deprecated.rs:153:16
+  --> $DIR/lint-stability-deprecated.rs:150:16
    |
 LL |         Trait::trait_deprecated_unstable(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
-  --> $DIR/lint-stability-deprecated.rs:155:25
+  --> $DIR/lint-stability-deprecated.rs:152:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable(&foo);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:157:16
+  --> $DIR/lint-stability-deprecated.rs:154:16
    |
 LL | ...   Trait::trait_deprecated_unstable_text(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:159:25
+  --> $DIR/lint-stability-deprecated.rs:156:25
    |
 LL | ...   <Foo as Trait>::trait_deprecated_unstable_text(&foo);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text
-  --> $DIR/lint-stability-deprecated.rs:187:10
+  --> $DIR/lint-stability-deprecated.rs:184:10
    |
 LL |     impl DeprecatedTrait for S {}
    |          ^^^^^^^^^^^^^^^
 
 warning: use of deprecated trait `lint_stability::DeprecatedTrait`: text
-  --> $DIR/lint-stability-deprecated.rs:189:25
+  --> $DIR/lint-stability-deprecated.rs:186:25
    |
 LL |     trait LocalTrait2 : DeprecatedTrait { }
    |                         ^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `inheritance::inherited_stability::unstable_mod::deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:208:23
+  --> $DIR/lint-stability-deprecated.rs:205:23
    |
 LL |         unstable_mod::deprecated();
    |                       ^^^^^^^^^^
 
 warning: use of deprecated function `this_crate::deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:330:9
+  --> $DIR/lint-stability-deprecated.rs:327:9
    |
 LL |         deprecated();
    |         ^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:335:16
+  --> $DIR/lint-stability-deprecated.rs:332:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:337:25
+  --> $DIR/lint-stability-deprecated.rs:334:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |                         ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `this_crate::deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:339:9
+  --> $DIR/lint-stability-deprecated.rs:336:9
    |
 LL |         deprecated_text();
    |         ^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:344:16
+  --> $DIR/lint-stability-deprecated.rs:341:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:346:25
+  --> $DIR/lint-stability-deprecated.rs:343:25
    |
 LL |         <Foo as Trait>::trait_deprecated_text(&foo);
    |                         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated struct `this_crate::DeprecatedStruct`: text
-  --> $DIR/lint-stability-deprecated.rs:384:17
+  --> $DIR/lint-stability-deprecated.rs:381:17
    |
 LL |         let _ = DeprecatedStruct {
    |                 ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated unit struct `this_crate::DeprecatedUnitStruct`: text
-  --> $DIR/lint-stability-deprecated.rs:391:17
+  --> $DIR/lint-stability-deprecated.rs:388:17
    |
 LL |         let _ = DeprecatedUnitStruct;
    |                 ^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated unit variant `this_crate::Enum::DeprecatedVariant`: text
-  --> $DIR/lint-stability-deprecated.rs:395:23
+  --> $DIR/lint-stability-deprecated.rs:392:23
    |
 LL |         let _ = Enum::DeprecatedVariant;
    |                       ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated tuple struct `this_crate::DeprecatedTupleStruct`: text
-  --> $DIR/lint-stability-deprecated.rs:399:17
+  --> $DIR/lint-stability-deprecated.rs:396:17
    |
 LL |         let _ = DeprecatedTupleStruct (1);
    |                 ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:406:16
+  --> $DIR/lint-stability-deprecated.rs:403:16
    |
 LL |         Trait::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:408:25
+  --> $DIR/lint-stability-deprecated.rs:405:25
    |
 LL |         <Foo as Trait>::trait_deprecated(&foo);
    |                         ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:410:16
+  --> $DIR/lint-stability-deprecated.rs:407:16
    |
 LL |         Trait::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:412:25
+  --> $DIR/lint-stability-deprecated.rs:409:25
    |
 LL |         <Foo as Trait>::trait_deprecated_text(&foo);
    |                         ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `this_crate::test_fn_body::fn_in_body`: text
-  --> $DIR/lint-stability-deprecated.rs:439:9
+  --> $DIR/lint-stability-deprecated.rs:436:9
    |
 LL |         fn_in_body();
    |         ^^^^^^^^^^
 
 warning: use of deprecated trait `this_crate::DeprecatedTrait`: text
-  --> $DIR/lint-stability-deprecated.rs:459:10
+  --> $DIR/lint-stability-deprecated.rs:456:10
    |
 LL |     impl DeprecatedTrait for S { }
    |          ^^^^^^^^^^^^^^^
 
 warning: use of deprecated trait `this_crate::DeprecatedTrait`: text
-  --> $DIR/lint-stability-deprecated.rs:461:24
+  --> $DIR/lint-stability-deprecated.rs:458:24
    |
 LL |     trait LocalTrait : DeprecatedTrait { }
    |                        ^^^^^^^^^^^^^^^
 
 warning: use of deprecated function `this_crate::MethodTester::test_method_body::fn_in_body`: text
-  --> $DIR/lint-stability-deprecated.rs:447:13
+  --> $DIR/lint-stability-deprecated.rs:444:13
    |
 LL |             fn_in_body();
    |             ^^^^^^^^^^
@@ -323,7 +323,7 @@ LL |         struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
    |                                                ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:102:13
+  --> $DIR/lint-stability-deprecated.rs:101:13
    |
 LL |             TypeDeprecated = u16,
    |             ^^^^^^^^^^^^^^^^^^^^
@@ -449,214 +449,190 @@ LL | ...   <Foo>::trait_deprecated_unstable_text(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated field `lint_stability::DeprecatedStruct::i`: text
-  --> $DIR/lint-stability-deprecated.rs:109:13
+  --> $DIR/lint-stability-deprecated.rs:106:13
    |
 LL |             i: 0
    |             ^^^^
 
 warning: use of deprecated field `lint_stability::DeprecatedUnstableStruct::i`: text
-  --> $DIR/lint-stability-deprecated.rs:113:13
+  --> $DIR/lint-stability-deprecated.rs:110:13
    |
 LL |             i: 0
    |             ^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:144:13
+  --> $DIR/lint-stability-deprecated.rs:141:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:146:16
+  --> $DIR/lint-stability-deprecated.rs:143:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:148:13
+  --> $DIR/lint-stability-deprecated.rs:145:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:150:16
+  --> $DIR/lint-stability-deprecated.rs:147:16
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
-  --> $DIR/lint-stability-deprecated.rs:152:13
+  --> $DIR/lint-stability-deprecated.rs:149:13
    |
 LL |         foo.trait_deprecated_unstable();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
-  --> $DIR/lint-stability-deprecated.rs:154:16
+  --> $DIR/lint-stability-deprecated.rs:151:16
    |
 LL |         <Foo>::trait_deprecated_unstable(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:156:13
+  --> $DIR/lint-stability-deprecated.rs:153:13
    |
 LL | ...   foo.trait_deprecated_unstable_text();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:158:16
+  --> $DIR/lint-stability-deprecated.rs:155:16
    |
 LL | ...   <Foo>::trait_deprecated_unstable_text(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:175:13
+  --> $DIR/lint-stability-deprecated.rs:172:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:176:13
+  --> $DIR/lint-stability-deprecated.rs:173:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable`: text
-  --> $DIR/lint-stability-deprecated.rs:177:13
+  --> $DIR/lint-stability-deprecated.rs:174:13
    |
 LL |         foo.trait_deprecated_unstable();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `lint_stability::Trait::trait_deprecated_unstable_text`: text
-  --> $DIR/lint-stability-deprecated.rs:178:13
+  --> $DIR/lint-stability-deprecated.rs:175:13
    |
 LL | ...   foo.trait_deprecated_unstable_text();
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::MethodTester::method_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:331:13
+  --> $DIR/lint-stability-deprecated.rs:328:13
    |
 LL |         foo.method_deprecated();
    |             ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::MethodTester::method_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:332:14
+  --> $DIR/lint-stability-deprecated.rs:329:14
    |
 LL |         Foo::method_deprecated(&foo);
    |              ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::MethodTester::method_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:333:16
+  --> $DIR/lint-stability-deprecated.rs:330:16
    |
 LL |         <Foo>::method_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:334:13
+  --> $DIR/lint-stability-deprecated.rs:331:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:336:16
+  --> $DIR/lint-stability-deprecated.rs:333:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:340:13
+  --> $DIR/lint-stability-deprecated.rs:337:13
    |
 LL |         foo.method_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:341:14
+  --> $DIR/lint-stability-deprecated.rs:338:14
    |
 LL |         Foo::method_deprecated_text(&foo);
    |              ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::MethodTester::method_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:342:16
+  --> $DIR/lint-stability-deprecated.rs:339:16
    |
 LL |         <Foo>::method_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:343:13
+  --> $DIR/lint-stability-deprecated.rs:340:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:345:16
+  --> $DIR/lint-stability-deprecated.rs:342:16
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated field `this_crate::DeprecatedStruct::i`: text
-  --> $DIR/lint-stability-deprecated.rs:386:13
+  --> $DIR/lint-stability-deprecated.rs:383:13
    |
 LL |             i: 0
    |             ^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:405:13
+  --> $DIR/lint-stability-deprecated.rs:402:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:407:16
+  --> $DIR/lint-stability-deprecated.rs:404:16
    |
 LL |         <Foo>::trait_deprecated(&foo);
    |                ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:409:13
+  --> $DIR/lint-stability-deprecated.rs:406:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:411:16
+  --> $DIR/lint-stability-deprecated.rs:408:16
    |
 LL |         <Foo>::trait_deprecated_text(&foo);
    |                ^^^^^^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:428:13
+  --> $DIR/lint-stability-deprecated.rs:425:13
    |
 LL |         foo.trait_deprecated();
    |             ^^^^^^^^^^^^^^^^
 
 warning: use of deprecated method `this_crate::Trait::trait_deprecated_text`: text
-  --> $DIR/lint-stability-deprecated.rs:429:13
+  --> $DIR/lint-stability-deprecated.rs:426:13
    |
 LL |         foo.trait_deprecated_text();
    |             ^^^^^^^^^^^^^^^^^^^^^
 
-warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:97:48
-   |
-LL |         struct S2<T: TraitWithAssociatedTypes>(T::TypeDeprecated);
-   |                                                ^^^^^^^^^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:102:13
-   |
-LL |             TypeDeprecated = u16,
-   |             ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning: use of deprecated associated type `lint_stability::TraitWithAssociatedTypes::TypeDeprecated`: text
-  --> $DIR/lint-stability-deprecated.rs:102:13
-   |
-LL |             TypeDeprecated = u16,
-   |             ^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning: 108 warnings emitted
+warning: 105 warnings emitted
 
diff --git a/tests/ui/liveness/liveness-forgot-ret.rs b/tests/ui/liveness/liveness-forgot-ret.rs
index b8c2bc73438..3ba2f2d276e 100644
--- a/tests/ui/liveness/liveness-forgot-ret.rs
+++ b/tests/ui/liveness/liveness-forgot-ret.rs
@@ -1,4 +1,5 @@
 fn god_exists(a: isize) -> bool { return god_exists(a); }
+//~^ WARN function cannot return without recursing
 
 fn f(a: isize) -> isize { if god_exists(a) { return 5; }; }
 //~^ ERROR mismatched types
diff --git a/tests/ui/liveness/liveness-forgot-ret.stderr b/tests/ui/liveness/liveness-forgot-ret.stderr
index a5adadca26e..f72a30fc4e9 100644
--- a/tests/ui/liveness/liveness-forgot-ret.stderr
+++ b/tests/ui/liveness/liveness-forgot-ret.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/liveness-forgot-ret.rs:3:19
+  --> $DIR/liveness-forgot-ret.rs:4:19
    |
 LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; }
    |    -              ^^^^^ expected `isize`, found `()`
@@ -11,6 +11,17 @@ help: consider returning the local binding `a`
 LL | fn f(a: isize) -> isize { if god_exists(a) { return 5; }; a }
    |                                                           +
 
-error: aborting due to 1 previous error
+warning: function cannot return without recursing
+  --> $DIR/liveness-forgot-ret.rs:1:1
+   |
+LL | fn god_exists(a: isize) -> bool { return god_exists(a); }
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^          ------------- recursive call site
+   | |
+   | cannot return without recursing
+   |
+   = help: a `loop` may express intention better if this is on purpose
+   = note: `#[warn(unconditional_recursion)]` on by default
+
+error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/loops/loop-else-break-with-value.rs b/tests/ui/loops/loop-else-break-with-value.rs
index 670d8a145c0..7ccf71b2edf 100644
--- a/tests/ui/loops/loop-else-break-with-value.rs
+++ b/tests/ui/loops/loop-else-break-with-value.rs
@@ -1,6 +1,11 @@
 fn main() {
     let Some(1) = loop {
         //~^ NOTE `else` is attached to this loop
+        //~| ERROR refutable pattern in local binding
+        //~| NOTE not covered
+        //~| NOTE for more information
+        //~| NOTE matched value is of type
+        //~| NOTE require an "irrefutable pattern"
         break Some(1)
     } else {
         //~^ ERROR `loop...else` loops are not supported
diff --git a/tests/ui/loops/loop-else-break-with-value.stderr b/tests/ui/loops/loop-else-break-with-value.stderr
index c933e0d0cd8..13d4c5faf73 100644
--- a/tests/ui/loops/loop-else-break-with-value.stderr
+++ b/tests/ui/loops/loop-else-break-with-value.stderr
@@ -1,5 +1,5 @@
 error: `loop...else` loops are not supported
-  --> $DIR/loop-else-break-with-value.rs:5:7
+  --> $DIR/loop-else-break-with-value.rs:10:7
    |
 LL |       let Some(1) = loop {
    |                     ---- `else` is attached to this loop
@@ -14,5 +14,24 @@ LL | |     };
    |
    = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
 
-error: aborting due to 1 previous error
+error[E0005]: refutable pattern in local binding
+  --> $DIR/loop-else-break-with-value.rs:2:9
+   |
+LL |     let Some(1) = loop {
+   |         ^^^^^^^ pattern `None` 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 `Option<i32>`
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL ~     if let Some(1) = loop {
+LL |
+ ...
+LL |         return;
+LL ~     } { todo!() };
+   |
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0005`.
diff --git a/tests/ui/auxiliary/hello_macro.rs b/tests/ui/macros/auxiliary/hello_macro.rs
index a05b8d54dc1..a05b8d54dc1 100644
--- a/tests/ui/auxiliary/hello_macro.rs
+++ b/tests/ui/macros/auxiliary/hello_macro.rs
diff --git a/tests/ui/macros/issue-22463.rs b/tests/ui/macros/issue-22463.rs
index fdf5a2fca72..8f7b27cb9a0 100644
--- a/tests/ui/macros/issue-22463.rs
+++ b/tests/ui/macros/issue-22463.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 macro_rules! items {
     () => {
         type A = ();
diff --git a/tests/ui/issues/issue-46438.rs b/tests/ui/macros/issue-46438.rs
index d78b958463f..d78b958463f 100644
--- a/tests/ui/issues/issue-46438.rs
+++ b/tests/ui/macros/issue-46438.rs
diff --git a/tests/ui/issues/issue-46438.stderr b/tests/ui/macros/issue-46438.stderr
index aff2d77a0c8..aff2d77a0c8 100644
--- a/tests/ui/issues/issue-46438.stderr
+++ b/tests/ui/macros/issue-46438.stderr
diff --git a/tests/ui/macro-quote-test.rs b/tests/ui/macros/macro-quote-test.rs
index 2ba61acadcb..2ba61acadcb 100644
--- a/tests/ui/macro-quote-test.rs
+++ b/tests/ui/macros/macro-quote-test.rs
diff --git a/tests/ui/marker_trait_attr/override-item-on-marker-trait.rs b/tests/ui/marker_trait_attr/override-item-on-marker-trait.rs
index 5376fc89d4f..d91a8055aa1 100644
--- a/tests/ui/marker_trait_attr/override-item-on-marker-trait.rs
+++ b/tests/ui/marker_trait_attr/override-item-on-marker-trait.rs
@@ -3,7 +3,9 @@
 #[marker]
 trait Marker {
     const N: usize = 0;
+    //~^ ERROR marker traits cannot have associated items
     fn do_something() {}
+    //~^ ERROR marker traits cannot have associated items
 }
 
 struct OverrideConst;
diff --git a/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr b/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr
index 1d30c6d5667..92a54cff7f5 100644
--- a/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr
+++ b/tests/ui/marker_trait_attr/override-item-on-marker-trait.stderr
@@ -1,15 +1,28 @@
 error[E0715]: impls for marker traits cannot contain items
-  --> $DIR/override-item-on-marker-trait.rs:10:1
+  --> $DIR/override-item-on-marker-trait.rs:12:1
    |
 LL | impl Marker for OverrideConst {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0715]: impls for marker traits cannot contain items
-  --> $DIR/override-item-on-marker-trait.rs:16:1
+  --> $DIR/override-item-on-marker-trait.rs:18:1
    |
 LL | impl Marker for OverrideFn {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error[E0714]: marker traits cannot have associated items
+  --> $DIR/override-item-on-marker-trait.rs:5:5
+   |
+LL |     const N: usize = 0;
+   |     ^^^^^^^^^^^^^^
+
+error[E0714]: marker traits cannot have associated items
+  --> $DIR/override-item-on-marker-trait.rs:7:5
+   |
+LL |     fn do_something() {}
+   |     ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0715`.
+Some errors have detailed explanations: E0714, E0715.
+For more information about an error, try `rustc --explain E0714`.
diff --git a/tests/ui/methods/assign-to-method.rs b/tests/ui/methods/assign-to-method.rs
index 71e40759c84..58dcca77e62 100644
--- a/tests/ui/methods/assign-to-method.rs
+++ b/tests/ui/methods/assign-to-method.rs
@@ -6,7 +6,7 @@ struct Cat {
 }
 
 impl Cat {
-    pub fn speak(&self) { self.meows += 1; }
+    pub fn speak(&mut self) { self.meows += 1; }
 }
 
 fn cat(in_x : usize, in_y : isize) -> Cat {
diff --git a/tests/ui/methods/method-call-err-msg.stderr b/tests/ui/methods/method-call-err-msg.stderr
index f4310857454..6df49e432a1 100644
--- a/tests/ui/methods/method-call-err-msg.stderr
+++ b/tests/ui/methods/method-call-err-msg.stderr
@@ -63,8 +63,9 @@ LL | |      .take()
 note: the trait `Iterator` must be implemented
   --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
    = help: items from traits can only be used if the trait is implemented and in scope
-   = note: the following trait defines an item `take`, perhaps you need to implement it:
-           candidate #1: `Iterator`
+   = note: the following traits define an item `take`, perhaps you need to implement one of them:
+           candidate #1: `std::io::Read`
+           candidate #2: `Iterator`
 
 error[E0061]: this method takes 3 arguments but 0 arguments were supplied
   --> $DIR/method-call-err-msg.rs:21:7
diff --git a/tests/ui/methods/method-lookup-order.rs b/tests/ui/methods/method-lookup-order.rs
index 986fe103cdc..5a46cf35dec 100644
--- a/tests/ui/methods/method-lookup-order.rs
+++ b/tests/ui/methods/method-lookup-order.rs
@@ -1,6 +1,7 @@
 // ignore-tidy-linelength
 
 // run-pass
+#![allow(dead_code)]
 
 // There are five cfg's below. I explored the set of all non-empty combinations
 // of the below five cfg's, which is 2^5 - 1 = 31 combinations.
diff --git a/tests/ui/methods/method-recursive-blanket-impl.rs b/tests/ui/methods/method-recursive-blanket-impl.rs
index a2db75b4e85..e7e83cbec77 100644
--- a/tests/ui/methods/method-recursive-blanket-impl.rs
+++ b/tests/ui/methods/method-recursive-blanket-impl.rs
@@ -11,7 +11,7 @@
 use std::marker::Sized;
 
 // Note: this must be generic for the problem to show up
-trait Foo<A> {
+trait Foo<A> { //~ WARN trait `Foo` is never used
     fn foo(&self, a: A);
 }
 
diff --git a/tests/ui/methods/method-recursive-blanket-impl.stderr b/tests/ui/methods/method-recursive-blanket-impl.stderr
new file mode 100644
index 00000000000..9797a8f6c83
--- /dev/null
+++ b/tests/ui/methods/method-recursive-blanket-impl.stderr
@@ -0,0 +1,10 @@
+warning: trait `Foo` is never used
+  --> $DIR/method-recursive-blanket-impl.rs:14:7
+   |
+LL | trait Foo<A> {
+   |       ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/methods/method-two-trait-defer-resolution-2.rs b/tests/ui/methods/method-two-trait-defer-resolution-2.rs
index fc5766da971..d6076126732 100644
--- a/tests/ui/methods/method-two-trait-defer-resolution-2.rs
+++ b/tests/ui/methods/method-two-trait-defer-resolution-2.rs
@@ -14,7 +14,7 @@ trait Foo {
     fn foo(&self) -> isize;
 }
 
-trait MyCopy { fn foo(&self) { } }
+trait MyCopy { fn foo(&self) { } } //~ WARN method `foo` is never used
 impl MyCopy for i32 { }
 
 impl<T:MyCopy> Foo for Vec<T> {
diff --git a/tests/ui/methods/method-two-trait-defer-resolution-2.stderr b/tests/ui/methods/method-two-trait-defer-resolution-2.stderr
new file mode 100644
index 00000000000..4501ea5d243
--- /dev/null
+++ b/tests/ui/methods/method-two-trait-defer-resolution-2.stderr
@@ -0,0 +1,12 @@
+warning: method `foo` is never used
+  --> $DIR/method-two-trait-defer-resolution-2.rs:17:19
+   |
+LL | trait MyCopy { fn foo(&self) { } }
+   |       ------      ^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs
index d820d2ad08a..2fd6c3bfab8 100644
--- a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs
+++ b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.rs
@@ -4,7 +4,7 @@
 
 // pretty-expanded FIXME #23616
 
-trait A {
+trait A { //~ WARN trait `A` is never used
     fn foo(self);
 }
 
diff --git a/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr
new file mode 100644
index 00000000000..0a60c6242bb
--- /dev/null
+++ b/tests/ui/methods/method-two-traits-distinguished-via-where-clause.stderr
@@ -0,0 +1,10 @@
+warning: trait `A` is never used
+  --> $DIR/method-two-traits-distinguished-via-where-clause.rs:7:7
+   |
+LL | trait A {
+   |       ^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/mir/drop-elaboration-after-borrowck-error.rs b/tests/ui/mir/drop-elaboration-after-borrowck-error.rs
index 624b464ecef..cbca3eebf19 100644
--- a/tests/ui/mir/drop-elaboration-after-borrowck-error.rs
+++ b/tests/ui/mir/drop-elaboration-after-borrowck-error.rs
@@ -6,7 +6,6 @@ static A: () = {
     //~^ ERROR destructor of
     a[0] = String::new();
     //~^ ERROR destructor of
-    //~| ERROR binding `a` isn't initialized
 };
 
 struct B<T>([T; 1]);
@@ -17,7 +16,6 @@ impl<T> B<T> {
         //~^ ERROR destructor of
         self.0[0] = other;
         //~^ ERROR destructor of
-        //~| ERROR use of moved value
         self
     }
 }
diff --git a/tests/ui/mir/drop-elaboration-after-borrowck-error.stderr b/tests/ui/mir/drop-elaboration-after-borrowck-error.stderr
index d961061729d..22d05fa4dda 100644
--- a/tests/ui/mir/drop-elaboration-after-borrowck-error.stderr
+++ b/tests/ui/mir/drop-elaboration-after-borrowck-error.stderr
@@ -16,22 +16,8 @@ LL |     let a: [String; 1];
 LL | };
    | - value is dropped here
 
-error[E0381]: used binding `a` isn't initialized
-  --> $DIR/drop-elaboration-after-borrowck-error.rs:7:5
-   |
-LL |     let a: [String; 1];
-   |         - binding declared here but left uninitialized
-LL |
-LL |     a[0] = String::new();
-   |     ^^^^ `a` used here but it isn't initialized
-   |
-help: consider assigning a value
-   |
-LL |     let a: [String; 1] = todo!();
-   |                        +++++++++
-
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/drop-elaboration-after-borrowck-error.rs:18:9
+  --> $DIR/drop-elaboration-after-borrowck-error.rs:17:9
    |
 LL |         self.0[0] = other;
    |         ^^^^^^^^^
@@ -40,7 +26,7 @@ LL |         self.0[0] = other;
    |         value is dropped here
 
 error[E0493]: destructor of `B<T>` cannot be evaluated at compile-time
-  --> $DIR/drop-elaboration-after-borrowck-error.rs:16:13
+  --> $DIR/drop-elaboration-after-borrowck-error.rs:15:13
    |
 LL |         let _this = self;
    |             ^^^^^ the destructor for this type cannot be evaluated in constant functions
@@ -48,18 +34,6 @@ LL |         let _this = self;
 LL |     }
    |     - value is dropped here
 
-error[E0382]: use of moved value: `self.0`
-  --> $DIR/drop-elaboration-after-borrowck-error.rs:18:9
-   |
-LL |     pub const fn f(mut self, other: T) -> Self {
-   |                    -------- move occurs because `self` has type `B<T>`, which does not implement the `Copy` trait
-LL |         let _this = self;
-   |                     ---- value moved here
-LL |
-LL |         self.0[0] = other;
-   |         ^^^^^^^^^ value used here after move
-
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0381, E0382, E0493.
-For more information about an error, try `rustc --explain E0381`.
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/mir/mir_raw_fat_ptr.rs b/tests/ui/mir/mir_raw_fat_ptr.rs
index 8e5a2043dc6..e141aa03aa9 100644
--- a/tests/ui/mir/mir_raw_fat_ptr.rs
+++ b/tests/ui/mir/mir_raw_fat_ptr.rs
@@ -98,7 +98,7 @@ fn assert_inorder<T: Copy>(a: &[T],
     }
 }
 
-trait Foo { fn foo(&self) -> usize; }
+trait Foo { fn foo(&self) -> usize; } //~ WARN method `foo` is never used
 impl<T> Foo for T {
     fn foo(&self) -> usize {
         mem::size_of::<T>()
diff --git a/tests/ui/mir/mir_raw_fat_ptr.stderr b/tests/ui/mir/mir_raw_fat_ptr.stderr
new file mode 100644
index 00000000000..a9e9dd66ebd
--- /dev/null
+++ b/tests/ui/mir/mir_raw_fat_ptr.stderr
@@ -0,0 +1,12 @@
+warning: method `foo` is never used
+  --> $DIR/mir_raw_fat_ptr.rs:101:16
+   |
+LL | trait Foo { fn foo(&self) -> usize; }
+   |       ---      ^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/mir/validate/error-body.rs b/tests/ui/mir/validate/error-body.rs
new file mode 100644
index 00000000000..5b2fbb0b046
--- /dev/null
+++ b/tests/ui/mir/validate/error-body.rs
@@ -0,0 +1,9 @@
+// compile-flags: -Zvalidate-mir
+
+fn _test() {
+    let x = || 45;
+    missing();
+    //~^ ERROR cannot find function `missing` in this scope
+}
+
+fn main() {}
diff --git a/tests/ui/mir/validate/error-body.stderr b/tests/ui/mir/validate/error-body.stderr
new file mode 100644
index 00000000000..1dfeaf0b7e2
--- /dev/null
+++ b/tests/ui/mir/validate/error-body.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find function `missing` in this scope
+  --> $DIR/error-body.rs:5:5
+   |
+LL |     missing();
+   |     ^^^^^^^ not found in this scope
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch.rs b/tests/ui/mismatched_types/closure-arg-type-mismatch.rs
index 98abb0ba979..e73a33dfded 100644
--- a/tests/ui/mismatched_types/closure-arg-type-mismatch.rs
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch.rs
@@ -8,4 +8,7 @@ fn main() {
 fn baz<F: Fn(*mut &u32)>(_: F) {}
 fn _test<'a>(f: fn(*mut &'a u32)) {
     baz(f);
+    //~^ ERROR: mismatched types
+    //~| ERROR: borrowed data escapes
+    //~| ERROR: not general enough
 }
diff --git a/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr b/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr
index e9808b86991..e63d3f6a075 100644
--- a/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr
+++ b/tests/ui/mismatched_types/closure-arg-type-mismatch.stderr
@@ -41,6 +41,52 @@ LL |     a.iter().map(|_: (u16, u16)| 45);
 note: required by a bound in `map`
   --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
 
-error: aborting due to 3 previous errors
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/closure-arg-type-mismatch.rs:10:5
+   |
+LL | fn _test<'a>(f: fn(*mut &'a u32)) {
+   |          --  - `f` is a reference that is only valid in the function body
+   |          |
+   |          lifetime `'a` defined here
+LL |     baz(f);
+   |     ^^^^^^
+   |     |
+   |     `f` escapes the function body here
+   |     argument requires that `'a` must outlive `'static`
+   |
+   = note: requirement occurs because of a mutable pointer to `&u32`
+   = note: mutable pointers are invariant over their type parameter
+   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+  --> $DIR/closure-arg-type-mismatch.rs:8:11
+   |
+LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
+   |           ^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/closure-arg-type-mismatch.rs:10:5
+   |
+LL |     baz(f);
+   |     ^^^^^^ one type is more general than the other
+   |
+   = note: expected trait `for<'a> Fn(*mut &'a u32)`
+              found trait `Fn(*mut &u32)`
+note: the lifetime requirement is introduced here
+  --> $DIR/closure-arg-type-mismatch.rs:8:11
+   |
+LL | fn baz<F: Fn(*mut &u32)>(_: F) {}
+   |           ^^^^^^^^^^^^^
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/closure-arg-type-mismatch.rs:10:5
+   |
+LL |     baz(f);
+   |     ^^^^^^ implementation of `FnOnce` is not general enough
+   |
+   = note: `fn(*mut &'2 u32)` must implement `FnOnce<(*mut &'1 u32,)>`, for any lifetime `'1`...
+   = note: ...but it actually implements `FnOnce<(*mut &'2 u32,)>`, for some specific lifetime `'2`
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0631`.
+Some errors have detailed explanations: E0308, E0521, E0631.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/moves/issue-22536-copy-mustnt-zero.rs b/tests/ui/moves/issue-22536-copy-mustnt-zero.rs
index 017f36484c1..b3fc1a56f88 100644
--- a/tests/ui/moves/issue-22536-copy-mustnt-zero.rs
+++ b/tests/ui/moves/issue-22536-copy-mustnt-zero.rs
@@ -5,7 +5,7 @@
 
 trait Resources {
     type Buffer: Copy;
-    fn foo(&self) {}
+    fn foo(&self) {} //~ WARN method `foo` is never used
 }
 
 struct BufferHandle<R: Resources> {
diff --git a/tests/ui/moves/issue-22536-copy-mustnt-zero.stderr b/tests/ui/moves/issue-22536-copy-mustnt-zero.stderr
new file mode 100644
index 00000000000..b1fcdfa44c3
--- /dev/null
+++ b/tests/ui/moves/issue-22536-copy-mustnt-zero.stderr
@@ -0,0 +1,13 @@
+warning: method `foo` is never used
+  --> $DIR/issue-22536-copy-mustnt-zero.rs:8:8
+   |
+LL | trait Resources {
+   |       --------- method in this trait
+LL |     type Buffer: Copy;
+LL |     fn foo(&self) {}
+   |        ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/nll/continue-after-missing-main.rs b/tests/ui/nll/continue-after-missing-main.rs
index 778639158d7..59683648789 100644
--- a/tests/ui/nll/continue-after-missing-main.rs
+++ b/tests/ui/nll/continue-after-missing-main.rs
@@ -26,4 +26,6 @@ fn create_and_solve_subproblems<'data_provider, 'original_data, MP>(
     tableau: Tableau<'data_provider, AdaptedMatrixProvider<'original_data, MP>>,
 ) {
     let _: AdaptedMatrixProvider<'original_data, MP> = tableau.provider().clone_with_extra_bound();
+    //~^ ERROR: lifetime may not live long enough
+    //~| ERROR: `tableau` does not live long enough
 } //~ ERROR `main` function not found in crate
diff --git a/tests/ui/nll/continue-after-missing-main.stderr b/tests/ui/nll/continue-after-missing-main.stderr
index 960503e8fd5..5178d1b7ee2 100644
--- a/tests/ui/nll/continue-after-missing-main.stderr
+++ b/tests/ui/nll/continue-after-missing-main.stderr
@@ -1,9 +1,39 @@
 error[E0601]: `main` function not found in crate `continue_after_missing_main`
-  --> $DIR/continue-after-missing-main.rs:29:2
+  --> $DIR/continue-after-missing-main.rs:31:2
    |
 LL | }
    |  ^ consider adding a `main` function to `$DIR/continue-after-missing-main.rs`
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/continue-after-missing-main.rs:28:12
+   |
+LL | fn create_and_solve_subproblems<'data_provider, 'original_data, MP>(
+   |                                 --------------  -------------- lifetime `'original_data` defined here
+   |                                 |
+   |                                 lifetime `'data_provider` defined here
+...
+LL |     let _: AdaptedMatrixProvider<'original_data, MP> = tableau.provider().clone_with_extra_bound();
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'data_provider` must outlive `'original_data`
+   |
+   = help: consider adding the following bound: `'data_provider: 'original_data`
+
+error[E0597]: `tableau` does not live long enough
+  --> $DIR/continue-after-missing-main.rs:28:56
+   |
+LL | fn create_and_solve_subproblems<'data_provider, 'original_data, MP>(
+   |                                                 -------------- lifetime `'original_data` defined here
+LL |     tableau: Tableau<'data_provider, AdaptedMatrixProvider<'original_data, MP>>,
+   |     ------- binding `tableau` declared here
+LL | ) {
+LL |     let _: AdaptedMatrixProvider<'original_data, MP> = tableau.provider().clone_with_extra_bound();
+   |            -----------------------------------------   ^^^^^^^ borrowed value does not live long enough
+   |            |
+   |            type annotation requires that `tableau` is borrowed for `'original_data`
+...
+LL | }
+   |  - `tableau` dropped here while still borrowed
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0601`.
+Some errors have detailed explanations: E0597, E0601.
+For more information about an error, try `rustc --explain E0597`.
diff --git a/tests/ui/object-safety/assoc_type_bounds_implicit_sized.fixed b/tests/ui/object-safety/assoc_type_bounds_implicit_sized.fixed
index 45c7e07a264..52046a8ab69 100644
--- a/tests/ui/object-safety/assoc_type_bounds_implicit_sized.fixed
+++ b/tests/ui/object-safety/assoc_type_bounds_implicit_sized.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 trait TraitWithAType {
     type Item: ?Sized;
 }
diff --git a/tests/ui/object-safety/assoc_type_bounds_implicit_sized.rs b/tests/ui/object-safety/assoc_type_bounds_implicit_sized.rs
index c3e958f4983..96620c0abda 100644
--- a/tests/ui/object-safety/assoc_type_bounds_implicit_sized.rs
+++ b/tests/ui/object-safety/assoc_type_bounds_implicit_sized.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 trait TraitWithAType {
     type Item;
 }
diff --git a/tests/ui/object-safety/assoc_type_bounds_implicit_sized.stderr b/tests/ui/object-safety/assoc_type_bounds_implicit_sized.stderr
index cd2aa9fdbe3..9bb770ce431 100644
--- a/tests/ui/object-safety/assoc_type_bounds_implicit_sized.stderr
+++ b/tests/ui/object-safety/assoc_type_bounds_implicit_sized.stderr
@@ -1,12 +1,12 @@
 error[E0277]: the size for values of type `(dyn Trait + 'static)` cannot be known at compilation time
-  --> $DIR/assoc_type_bounds_implicit_sized.rs:8:17
+  --> $DIR/assoc_type_bounds_implicit_sized.rs:9:17
    |
 LL |     type Item = dyn Trait;
    |                 ^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `(dyn Trait + 'static)`
 note: required by a bound in `TraitWithAType::Item`
-  --> $DIR/assoc_type_bounds_implicit_sized.rs:3:5
+  --> $DIR/assoc_type_bounds_implicit_sized.rs:4:5
    |
 LL |     type Item;
    |     ^^^^^^^^^^ required by this bound in `TraitWithAType::Item`
diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.rs b/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.rs
index 800624e3124..34daa81e48e 100644
--- a/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.rs
+++ b/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.rs
@@ -8,8 +8,6 @@ trait Foo {
 
 fn foo(_: &dyn Foo<Bar = ()>) {}
 //~^ WARN: unnecessary associated type bound for not object safe associated type
-//~| WARN: unnecessary associated type bound for not object safe associated type
-//~| WARN: unnecessary associated type bound for not object safe associated type
 
 #[allow(unused_associated_type_bounds)]
 fn bar(_: &dyn Foo<Bar = ()>) {}
diff --git a/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr b/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr
index 659679e4440..f2bc8bd8400 100644
--- a/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr
+++ b/tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr
@@ -7,23 +7,5 @@ LL | fn foo(_: &dyn Foo<Bar = ()>) {}
    = note: this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
    = note: `#[warn(unused_associated_type_bounds)]` on by default
 
-warning: unnecessary associated type bound for not object safe associated type
-  --> $DIR/assoc_type_bounds_sized_unnecessary.rs:9:20
-   |
-LL | fn foo(_: &dyn Foo<Bar = ()>) {}
-   |                    ^^^^^^^^ help: remove this bound
-   |
-   = note: this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning: unnecessary associated type bound for not object safe associated type
-  --> $DIR/assoc_type_bounds_sized_unnecessary.rs:9:20
-   |
-LL | fn foo(_: &dyn Foo<Bar = ()>) {}
-   |                    ^^^^^^^^ help: remove this bound
-   |
-   = note: this associated type has a `where Self: Sized` bound. Thus, while the associated type can be specified, it cannot be used in any way, because trait objects are not `Sized`.
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-warning: 3 warnings emitted
+warning: 1 warning emitted
 
diff --git a/tests/ui/or-patterns/missing-bindings.rs b/tests/ui/or-patterns/missing-bindings.rs
index 7c26012c0e9..20844c17ec1 100644
--- a/tests/ui/or-patterns/missing-bindings.rs
+++ b/tests/ui/or-patterns/missing-bindings.rs
@@ -17,8 +17,10 @@ fn check_handling_of_paths() {
 
     use bar::foo::{alpha, charlie};
     let (alpha | beta | charlie) = alpha; //~  ERROR variable `beta` is not bound in all patterns
-    match Some(alpha) {
+    //~^ ERROR: `beta` is named the same as one of the variants
+    match Some(alpha) { //~ ERROR `None` not covered
         Some(alpha | beta) => {} //~ ERROR variable `beta` is not bound in all patterns
+        //~^ ERROR: `beta` is named the same as one of the variants
     }
 }
 
diff --git a/tests/ui/or-patterns/missing-bindings.stderr b/tests/ui/or-patterns/missing-bindings.stderr
index 7f182a85787..677b40a7f0d 100644
--- a/tests/ui/or-patterns/missing-bindings.stderr
+++ b/tests/ui/or-patterns/missing-bindings.stderr
@@ -8,7 +8,7 @@ LL |     let (alpha | beta | charlie) = alpha;
    |          pattern doesn't bind `beta`
 
 error[E0408]: variable `beta` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:21:14
+  --> $DIR/missing-bindings.rs:22:14
    |
 LL |         Some(alpha | beta) => {}
    |              ^^^^^   ---- variable not in all patterns
@@ -16,7 +16,7 @@ LL |         Some(alpha | beta) => {}
    |              pattern doesn't bind `beta`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:33:20
+  --> $DIR/missing-bindings.rs:35:20
    |
 LL |     let (A(a, _) | _) = X;
    |            -       ^ pattern doesn't bind `a`
@@ -24,7 +24,7 @@ LL |     let (A(a, _) | _) = X;
    |            variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:34:10
+  --> $DIR/missing-bindings.rs:36:10
    |
 LL |     let (_ | B(a)) = X;
    |          ^     - variable not in all patterns
@@ -32,7 +32,7 @@ LL |     let (_ | B(a)) = X;
    |          pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:35:10
+  --> $DIR/missing-bindings.rs:37:10
    |
 LL |     let (A(..) | B(a)) = X;
    |          ^^^^^     - variable not in all patterns
@@ -40,7 +40,7 @@ LL |     let (A(..) | B(a)) = X;
    |          pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:36:20
+  --> $DIR/missing-bindings.rs:38:20
    |
 LL |     let (A(a, _) | B(_)) = X;
    |            -       ^^^^ pattern doesn't bind `a`
@@ -48,7 +48,7 @@ LL |     let (A(a, _) | B(_)) = X;
    |            variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:37:20
+  --> $DIR/missing-bindings.rs:39:20
    |
 LL |     let (A(_, a) | B(_)) = X;
    |               -    ^^^^ pattern doesn't bind `a`
@@ -56,7 +56,7 @@ LL |     let (A(_, a) | B(_)) = X;
    |               variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:38:20
+  --> $DIR/missing-bindings.rs:40:20
    |
 LL |     let (A(a, b) | B(a)) = X;
    |               -    ^^^^ pattern doesn't bind `b`
@@ -64,7 +64,7 @@ LL |     let (A(a, b) | B(a)) = X;
    |               variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:42:10
+  --> $DIR/missing-bindings.rs:44:10
    |
 LL |     let (A(A(..) | B(_), _) | B(a)) = Y;
    |          ^^^^^^^^^^^^^^^^^^     - variable not in all patterns
@@ -72,7 +72,7 @@ LL |     let (A(A(..) | B(_), _) | B(a)) = Y;
    |          pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:43:12
+  --> $DIR/missing-bindings.rs:45:12
    |
 LL |     let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
    |            ^^^^^     - variable not in all patterns
@@ -80,7 +80,7 @@ LL |     let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
    |            pattern doesn't bind `a`
 
 error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:12
+  --> $DIR/missing-bindings.rs:47:12
    |
 LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |            ^^^^^^^     - variable not in all patterns
@@ -88,7 +88,7 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |            pattern doesn't bind `c`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:22
+  --> $DIR/missing-bindings.rs:47:22
    |
 LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |              -       ^^^^ pattern doesn't bind `a`
@@ -96,7 +96,7 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |              variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:22
+  --> $DIR/missing-bindings.rs:47:22
    |
 LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 -    ^^^^ pattern doesn't bind `b`
@@ -104,7 +104,7 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 variable not in all patterns
 
 error[E0408]: variable `e` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:10
+  --> $DIR/missing-bindings.rs:47:10
    |
 LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |          ^^^^^^^^^^^^^^^^^^^^     - variable not in all patterns
@@ -112,7 +112,7 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |          pattern doesn't bind `e`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:33
+  --> $DIR/missing-bindings.rs:47:33
    |
 LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |              -                  ^^^^ pattern doesn't bind `a`
@@ -120,7 +120,7 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |              variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:33
+  --> $DIR/missing-bindings.rs:47:33
    |
 LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 -               ^^^^ pattern doesn't bind `b`
@@ -128,7 +128,7 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                 variable not in all patterns
 
 error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:33
+  --> $DIR/missing-bindings.rs:47:33
    |
 LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                        -        ^^^^ pattern doesn't bind `c`
@@ -136,7 +136,7 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                        variable not in all patterns
 
 error[E0408]: variable `d` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:45:33
+  --> $DIR/missing-bindings.rs:47:33
    |
 LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                            -    ^^^^ pattern doesn't bind `d`
@@ -144,7 +144,7 @@ LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
    |                            variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:61:29
+  --> $DIR/missing-bindings.rs:63:29
    |
 LL |                     Ok(a) | Err(_),
    |                        -    ^^^^^^ pattern doesn't bind `a`
@@ -152,7 +152,7 @@ LL |                     Ok(a) | Err(_),
    |                        variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:68:21
+  --> $DIR/missing-bindings.rs:70:21
    |
 LL |                     A(_, a) |
    |                     ^^^^^^^ pattern doesn't bind `b`
@@ -160,7 +160,7 @@ LL |                     B(b),
    |                       - variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:69:21
+  --> $DIR/missing-bindings.rs:71:21
    |
 LL |                     A(_, a) |
    |                          - variable not in all patterns
@@ -168,7 +168,7 @@ LL |                     B(b),
    |                     ^^^^ pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:72:17
+  --> $DIR/missing-bindings.rs:74:17
    |
 LL |                     A(_, a) |
    |                          - variable not in all patterns
@@ -177,7 +177,7 @@ LL |                 B(_)
    |                 ^^^^ pattern doesn't bind `a`
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:72:17
+  --> $DIR/missing-bindings.rs:74:17
    |
 LL |                     B(b),
    |                       - variable not in all patterns
@@ -186,7 +186,7 @@ LL |                 B(_)
    |                 ^^^^ pattern doesn't bind `b`
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:57:13
+  --> $DIR/missing-bindings.rs:59:13
    |
 LL | /             V1(
 LL | |
@@ -204,7 +204,7 @@ LL |               V3(c),
    |               ^^^^^ pattern doesn't bind `b`
 
 error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:57:13
+  --> $DIR/missing-bindings.rs:59:13
    |
 LL | /             V1(
 LL | |
@@ -226,7 +226,7 @@ LL |               V3(c),
    |                  - variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:76:13
+  --> $DIR/missing-bindings.rs:78:13
    |
 LL |                 B(Ok(a) | Err(a))
    |                               - variable not in all patterns
@@ -237,6 +237,38 @@ LL |                     A(_, a) |
 LL |             V3(c),
    |             ^^^^^ pattern doesn't bind `a`
 
-error: aborting due to 26 previous errors
+error[E0170]: pattern binding `beta` is named the same as one of the variants of the type `check_handling_of_paths::bar::foo`
+  --> $DIR/missing-bindings.rs:19:18
+   |
+LL |     let (alpha | beta | charlie) = alpha;
+   |                  ^^^^
+   |
+   = note: `#[deny(bindings_with_variant_name)]` on by default
+
+error[E0170]: pattern binding `beta` is named the same as one of the variants of the type `check_handling_of_paths::bar::foo`
+  --> $DIR/missing-bindings.rs:22:22
+   |
+LL |         Some(alpha | beta) => {}
+   |                      ^^^^ help: to match on the variant, qualify the path: `check_handling_of_paths::bar::foo::beta`
+
+error[E0004]: non-exhaustive patterns: `None` not covered
+  --> $DIR/missing-bindings.rs:21:11
+   |
+LL |     match Some(alpha) {
+   |           ^^^^^^^^^^^ pattern `None` not covered
+   |
+note: `Option<foo>` 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<foo>`
+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 |         Some(alpha | beta) => {}, None => todo!()
+   |                                 +++++++++++++++++
+
+error: aborting due to 29 previous errors
 
-For more information about this error, try `rustc --explain E0408`.
+Some errors have detailed explanations: E0004, E0170, E0408.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/overloaded/issue-14958.rs b/tests/ui/overloaded/issue-14958.rs
index a12564ca9c0..80abf5e4e76 100644
--- a/tests/ui/overloaded/issue-14958.rs
+++ b/tests/ui/overloaded/issue-14958.rs
@@ -3,7 +3,7 @@
 
 #![feature(fn_traits, unboxed_closures)]
 
-trait Foo { fn dummy(&self) { }}
+trait Foo { fn dummy(&self) { }} //~ WARN method `dummy` is never used
 
 struct Bar;
 
diff --git a/tests/ui/overloaded/issue-14958.stderr b/tests/ui/overloaded/issue-14958.stderr
new file mode 100644
index 00000000000..cc97730239c
--- /dev/null
+++ b/tests/ui/overloaded/issue-14958.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/issue-14958.rs:6:16
+   |
+LL | trait Foo { fn dummy(&self) { }}
+   |       ---      ^^^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/overloaded/overloaded-index-in-field.rs b/tests/ui/overloaded/overloaded-index-in-field.rs
index 8a1fa7deb99..0dc45ea8ca2 100644
--- a/tests/ui/overloaded/overloaded-index-in-field.rs
+++ b/tests/ui/overloaded/overloaded-index-in-field.rs
@@ -27,7 +27,7 @@ impl Index<isize> for Foo {
 
 trait Int {
     fn get(self) -> isize;
-    fn get_from_ref(&self) -> isize;
+    fn get_from_ref(&self) -> isize; //~ WARN methods `get_from_ref` and `inc` are never used
     fn inc(&mut self);
 }
 
diff --git a/tests/ui/overloaded/overloaded-index-in-field.stderr b/tests/ui/overloaded/overloaded-index-in-field.stderr
new file mode 100644
index 00000000000..10c0a3faeb5
--- /dev/null
+++ b/tests/ui/overloaded/overloaded-index-in-field.stderr
@@ -0,0 +1,15 @@
+warning: methods `get_from_ref` and `inc` are never used
+  --> $DIR/overloaded-index-in-field.rs:30:8
+   |
+LL | trait Int {
+   |       --- methods in this trait
+LL |     fn get(self) -> isize;
+LL |     fn get_from_ref(&self) -> isize;
+   |        ^^^^^^^^^^^^
+LL |     fn inc(&mut self);
+   |        ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.rs b/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.rs
new file mode 100644
index 00000000000..148a59240f9
--- /dev/null
+++ b/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.rs
@@ -0,0 +1,16 @@
+// compile-flags: -Z threads=16
+// build-fail
+
+#![crate_type="rlib"]
+#![allow(warnings)]
+
+#[export_name="fail"]
+pub fn a() {
+}
+
+#[export_name="fail"]
+pub fn b() {
+//~^ Error symbol `fail` is already defined
+}
+
+fn main() {}
diff --git a/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.stderr b/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.stderr
new file mode 100644
index 00000000000..7963165e31b
--- /dev/null
+++ b/tests/ui/parallel-rustc/cache-after-waiting-issue-111528.stderr
@@ -0,0 +1,8 @@
+error: symbol `fail` is already defined
+  --> $DIR/cache-after-waiting-issue-111528.rs:12:1
+   |
+LL | pub fn b() {
+   | ^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parallel-rustc/export-symbols-deadlock-issue-118205-2.rs b/tests/ui/parallel-rustc/export-symbols-deadlock-issue-118205-2.rs
new file mode 100644
index 00000000000..8240b249018
--- /dev/null
+++ b/tests/ui/parallel-rustc/export-symbols-deadlock-issue-118205-2.rs
@@ -0,0 +1,7 @@
+// compile-flags:-C extra-filename=-1 -Z threads=16
+// no-prefer-dynamic
+// build-pass
+#![crate_name = "crateresolve1"]
+#![crate_type = "lib"]
+
+pub fn f() -> isize { 10 }
diff --git a/tests/ui/parallel-rustc/export-symbols-deadlock-issue-118205.rs b/tests/ui/parallel-rustc/export-symbols-deadlock-issue-118205.rs
new file mode 100644
index 00000000000..691c36cfc9e
--- /dev/null
+++ b/tests/ui/parallel-rustc/export-symbols-deadlock-issue-118205.rs
@@ -0,0 +1,22 @@
+// compile-flags: -Z threads=16
+// build-pass
+
+pub static GLOBAL: isize = 3;
+
+static GLOBAL0: isize = 4;
+
+pub static GLOBAL2: &'static isize = &GLOBAL0;
+
+pub fn verify_same(a: &'static isize) {
+    let a = a as *const isize as usize;
+    let b = &GLOBAL as *const isize as usize;
+    assert_eq!(a, b);
+}
+
+pub fn verify_same2(a: &'static isize) {
+    let a = a as *const isize as usize;
+    let b = GLOBAL2 as *const isize as usize;
+    assert_eq!(a, b);
+}
+
+fn main() {}
diff --git a/tests/ui/parallel-rustc/hello_world.rs b/tests/ui/parallel-rustc/hello_world.rs
new file mode 100644
index 00000000000..53e95c890ef
--- /dev/null
+++ b/tests/ui/parallel-rustc/hello_world.rs
@@ -0,0 +1,6 @@
+// compile-flags: -Z threads=8
+// run-pass
+
+fn main() {
+    println!("Hello world!");
+}
diff --git a/tests/ui/parallel-rustc/read-stolen-value-issue-111520.rs b/tests/ui/parallel-rustc/read-stolen-value-issue-111520.rs
new file mode 100644
index 00000000000..1907348cf09
--- /dev/null
+++ b/tests/ui/parallel-rustc/read-stolen-value-issue-111520.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Z threads=16
+// run-pass
+
+#[repr(transparent)]
+struct Sched {
+    i: i32,
+}
+impl Sched {
+    extern "C" fn get(self) -> i32 { self.i }
+}
+
+fn main() {
+    let s = Sched { i: 4 };
+    let f = || -> i32 {
+        s.get()
+    };
+    println!("f: {}", f());
+}
diff --git a/tests/ui/parser/bad-let-else-statement.rs b/tests/ui/parser/bad-let-else-statement.rs
index a42e8c41c2e..c3126a493e5 100644
--- a/tests/ui/parser/bad-let-else-statement.rs
+++ b/tests/ui/parser/bad-let-else-statement.rs
@@ -5,6 +5,7 @@
 
 fn a() {
     let foo = {
+        //~^ WARN irrefutable `let...else` pattern
         1
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -23,6 +24,7 @@ fn b() {
 
 fn c() {
     let foo = if true {
+        //~^ WARN irrefutable `let...else` pattern
         1
     } else {
         0
@@ -43,6 +45,7 @@ fn d() {
 
 fn e() {
     let foo = match true {
+        //~^ WARN irrefutable `let...else` pattern
         true => 1,
         false => 0
     } else {
@@ -54,6 +57,7 @@ fn e() {
 struct X {a: i32}
 fn f() {
     let foo = X {
+        //~^ WARN irrefutable `let...else` pattern
         a: 1
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -72,6 +76,7 @@ fn g() {
 
 fn h() {
     let foo = const {
+        //~^ WARN irrefutable `let...else` pattern
         1
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -81,6 +86,7 @@ fn h() {
 
 fn i() {
     let foo = &{
+        //~^ WARN irrefutable `let...else` pattern
         1
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -90,7 +96,8 @@ fn i() {
 
 fn j() {
     let bar = 0;
-    let foo = bar = {
+    let foo = bar = { //~ ERROR: cannot assign twice
+        //~^ WARN irrefutable `let...else` pattern
         1
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -100,6 +107,7 @@ fn j() {
 
 fn k() {
     let foo = 1 + {
+        //~^ WARN irrefutable `let...else` pattern
         1
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -109,6 +117,7 @@ fn k() {
 
 fn l() {
     let foo = 1..{
+        //~^ WARN irrefutable `let...else` pattern
         1
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -118,6 +127,7 @@ fn l() {
 
 fn m() {
     let foo = return {
+        //~^ WARN irrefutable `let...else` pattern
         ()
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -127,6 +137,7 @@ fn m() {
 
 fn n() {
     let foo = -{
+        //~^ WARN irrefutable `let...else` pattern
         1
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -136,6 +147,7 @@ fn n() {
 
 fn o() -> Result<(), ()> {
     let foo = do yeet {
+        //~^ WARN irrefutable `let...else` pattern
         ()
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -145,6 +157,7 @@ fn o() -> Result<(), ()> {
 
 fn p() {
     let foo = become {
+        //~^ WARN irrefutable `let...else` pattern
         ()
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -154,6 +167,7 @@ fn p() {
 
 fn q() {
     let foo = |x: i32| {
+        //~^ WARN irrefutable `let...else` pattern
         x
     } else {
         //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
@@ -163,14 +177,18 @@ fn q() {
 
 fn r() {
     let ok = format_args!("") else { return; };
+    //~^ WARN irrefutable `let...else` pattern
 
     let bad = format_args! {""} else { return; };
     //~^ ERROR right curly brace `}` before `else` in a `let...else` statement not allowed
+    //~| WARN irrefutable `let...else` pattern
 }
 
 fn s() {
     macro_rules! a {
         () => { {} }
+        //~^ WARN irrefutable `let...else` pattern
+        //~| WARN irrefutable `let...else` pattern
     }
 
     macro_rules! b {
diff --git a/tests/ui/parser/bad-let-else-statement.stderr b/tests/ui/parser/bad-let-else-statement.stderr
index 887455913d8..12df8f849ab 100644
--- a/tests/ui/parser/bad-let-else-statement.stderr
+++ b/tests/ui/parser/bad-let-else-statement.stderr
@@ -1,5 +1,5 @@
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:9:5
+  --> $DIR/bad-let-else-statement.rs:10:5
    |
 LL |     } else {
    |     ^
@@ -7,12 +7,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = ({
+LL |
 LL |         1
 LL ~     }) else {
    |
 
 error: `for...else` loops are not supported
-  --> $DIR/bad-let-else-statement.rs:18:7
+  --> $DIR/bad-let-else-statement.rs:19:7
    |
 LL |       let foo = for i in 1..2 {
    |                 --- `else` is attached to this loop
@@ -27,7 +28,7 @@ LL | |     };
    = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:29:5
+  --> $DIR/bad-let-else-statement.rs:31:5
    |
 LL |     } else {
    |     ^
@@ -35,14 +36,14 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = (if true {
-LL |         1
-LL |     } else {
+LL |
+ ...
 LL |         0
 LL ~     }) else {
    |
 
 error: `loop...else` loops are not supported
-  --> $DIR/bad-let-else-statement.rs:38:7
+  --> $DIR/bad-let-else-statement.rs:40:7
    |
 LL |       let foo = loop {
    |                 ---- `else` is attached to this loop
@@ -57,7 +58,7 @@ LL | |     };
    = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:48:5
+  --> $DIR/bad-let-else-statement.rs:51:5
    |
 LL |     } else {
    |     ^
@@ -65,13 +66,14 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = (match true {
+LL |
 LL |         true => 1,
 LL |         false => 0
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:58:5
+  --> $DIR/bad-let-else-statement.rs:62:5
    |
 LL |     } else {
    |     ^
@@ -79,12 +81,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = (X {
+LL |
 LL |         a: 1
 LL ~     }) else {
    |
 
 error: `while...else` loops are not supported
-  --> $DIR/bad-let-else-statement.rs:67:7
+  --> $DIR/bad-let-else-statement.rs:71:7
    |
 LL |       let foo = while false {
    |                 ----- `else` is attached to this loop
@@ -99,7 +102,7 @@ LL | |     };
    = note: consider moving this `else` clause to a separate `if` statement and use a `bool` variable to control if it should run
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:76:5
+  --> $DIR/bad-let-else-statement.rs:81:5
    |
 LL |     } else {
    |     ^
@@ -107,12 +110,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = (const {
+LL |
 LL |         1
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:85:5
+  --> $DIR/bad-let-else-statement.rs:91:5
    |
 LL |     } else {
    |     ^
@@ -120,12 +124,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = &({
+LL |
 LL |         1
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:95:5
+  --> $DIR/bad-let-else-statement.rs:102:5
    |
 LL |     } else {
    |     ^
@@ -133,12 +138,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = bar = ({
+LL |
 LL |         1
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:104:5
+  --> $DIR/bad-let-else-statement.rs:112:5
    |
 LL |     } else {
    |     ^
@@ -146,12 +152,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = 1 + ({
+LL |
 LL |         1
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:113:5
+  --> $DIR/bad-let-else-statement.rs:122:5
    |
 LL |     } else {
    |     ^
@@ -159,12 +166,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = 1..({
+LL |
 LL |         1
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:122:5
+  --> $DIR/bad-let-else-statement.rs:132:5
    |
 LL |     } else {
    |     ^
@@ -172,12 +180,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = return ({
+LL |
 LL |         ()
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:131:5
+  --> $DIR/bad-let-else-statement.rs:142:5
    |
 LL |     } else {
    |     ^
@@ -185,12 +194,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = -({
+LL |
 LL |         1
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:140:5
+  --> $DIR/bad-let-else-statement.rs:152:5
    |
 LL |     } else {
    |     ^
@@ -198,12 +208,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = do yeet ({
+LL |
 LL |         ()
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:149:5
+  --> $DIR/bad-let-else-statement.rs:162:5
    |
 LL |     } else {
    |     ^
@@ -211,12 +222,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = become ({
+LL |
 LL |         ()
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:158:5
+  --> $DIR/bad-let-else-statement.rs:172:5
    |
 LL |     } else {
    |     ^
@@ -224,12 +236,13 @@ LL |     } else {
 help: wrap the expression in parentheses
    |
 LL ~     let foo = |x: i32| ({
+LL |
 LL |         x
 LL ~     }) else {
    |
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:167:31
+  --> $DIR/bad-let-else-statement.rs:182:31
    |
 LL |     let bad = format_args! {""} else { return; };
    |                               ^
@@ -240,7 +253,7 @@ LL |     let bad = format_args! ("") else { return; };
    |                            ~  ~
 
 error: right curly brace `}` before `else` in a `let...else` statement not allowed
-  --> $DIR/bad-let-else-statement.rs:181:25
+  --> $DIR/bad-let-else-statement.rs:199:25
    |
 LL |             let x = a! {} else { return; };
    |                         ^
@@ -254,5 +267,251 @@ help: use parentheses instead of braces for this macro
 LL |             let x = a! () else { return; };
    |                        ~~
 
-error: aborting due to 19 previous errors
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:7:5
+   |
+LL | /     let foo = {
+LL | |
+LL | |         1
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:26:5
+   |
+LL | /     let foo = if true {
+LL | |
+LL | |         1
+LL | |     } else {
+LL | |         0
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:47:5
+   |
+LL | /     let foo = match true {
+LL | |
+LL | |         true => 1,
+LL | |         false => 0
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:59:5
+   |
+LL | /     let foo = X {
+LL | |
+LL | |         a: 1
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:78:5
+   |
+LL | /     let foo = const {
+LL | |
+LL | |         1
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:88:5
+   |
+LL | /     let foo = &{
+LL | |
+LL | |         1
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:99:5
+   |
+LL | /     let foo = bar = {
+LL | |
+LL | |         1
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+error[E0384]: cannot assign twice to immutable variable `bar`
+  --> $DIR/bad-let-else-statement.rs:99:15
+   |
+LL |       let bar = 0;
+   |           ---
+   |           |
+   |           first assignment to `bar`
+   |           help: consider making this binding mutable: `mut bar`
+LL |       let foo = bar = {
+   |  _______________^
+LL | |
+LL | |         1
+LL | |     } else {
+   | |_____^ cannot assign twice to immutable variable
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:109:5
+   |
+LL | /     let foo = 1 + {
+LL | |
+LL | |         1
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:119:5
+   |
+LL | /     let foo = 1..{
+LL | |
+LL | |         1
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:129:5
+   |
+LL | /     let foo = return {
+LL | |
+LL | |         ()
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:139:5
+   |
+LL | /     let foo = -{
+LL | |
+LL | |         1
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:149:5
+   |
+LL | /     let foo = do yeet {
+LL | |
+LL | |         ()
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:159:5
+   |
+LL | /     let foo = become {
+LL | |
+LL | |         ()
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:169:5
+   |
+LL | /     let foo = |x: i32| {
+LL | |
+LL | |         x
+LL | |     } else {
+   | |_____^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:179:5
+   |
+LL |     let ok = format_args!("") else { return; };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:182:5
+   |
+LL |     let bad = format_args! {""} else { return; };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:189:19
+   |
+LL |           () => { {} }
+   |  ___________________^
+LL | |
+LL | |
+LL | |     }
+...  |
+LL | |         (1) => {
+LL | |             let x = a!() else { return; };
+   | |____________^
+...
+LL |       b!(1); b!(2);
+   |       ----- in this macro invocation
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+   = note: this warning originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: irrefutable `let...else` pattern
+  --> $DIR/bad-let-else-statement.rs:189:19
+   |
+LL |           () => { {} }
+   |  ___________________^
+LL | |
+LL | |
+LL | |     }
+...  |
+LL | |         (2) => {
+LL | |             let x = a! {} else { return; };
+   | |____________^
+...
+LL |       b!(1); b!(2);
+   |              ----- in this macro invocation
+   |
+   = note: this pattern will always match, so the `else` clause is useless
+   = help: consider removing the `else` clause
+   = note: this warning originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 20 previous errors; 18 warnings emitted
 
+For more information about this error, try `rustc --explain E0384`.
diff --git a/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs b/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs
index 3d110adef3e..c1c847d92d0 100644
--- a/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs
+++ b/tests/ui/parser/issues/issue-35813-postfix-after-cast.rs
@@ -129,6 +129,7 @@ pub fn inside_block() {
 
 static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]);
 //~^ ERROR: cast cannot be followed by indexing
+//~| ERROR: cannot call non-const operator in statics
 
 static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
 //~^ ERROR: expected one of
diff --git a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr
index d313c888e51..6a8cbd9389b 100644
--- a/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr
+++ b/tests/ui/parser/issues/issue-35813-postfix-after-cast.stderr
@@ -235,13 +235,13 @@ LL | static bar: &[i32] = &((&[1,2,3] as &[i32])[0..1]);
    |                        +                  +
 
 error: expected one of `)`, `,`, `.`, `?`, or an operator, found `:`
-  --> $DIR/issue-35813-postfix-after-cast.rs:133:36
+  --> $DIR/issue-35813-postfix-after-cast.rs:134:36
    |
 LL | static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
    |                                    ^ expected one of `)`, `,`, `.`, `?`, or an operator
 
 error: cast cannot be followed by `?`
-  --> $DIR/issue-35813-postfix-after-cast.rs:138:5
+  --> $DIR/issue-35813-postfix-after-cast.rs:139:5
    |
 LL |     Err(0u64) as Result<u64,u64>?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -252,13 +252,13 @@ LL |     (Err(0u64) as Result<u64,u64>)?;
    |     +                            +
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:`
-  --> $DIR/issue-35813-postfix-after-cast.rs:140:14
+  --> $DIR/issue-35813-postfix-after-cast.rs:141:14
    |
 LL |     Err(0u64): Result<u64,u64>?;
    |              ^ expected one of `.`, `;`, `?`, `}`, or an operator
 
 error: expected identifier, found `:`
-  --> $DIR/issue-35813-postfix-after-cast.rs:152:13
+  --> $DIR/issue-35813-postfix-after-cast.rs:153:13
    |
 LL |     drop_ptr: F();
    |             ^ expected identifier
@@ -266,13 +266,13 @@ LL |     drop_ptr: F();
    = note: type ascription syntax has been removed, see issue #101728 <https://github.com/rust-lang/rust/issues/101728>
 
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `:`
-  --> $DIR/issue-35813-postfix-after-cast.rs:159:13
+  --> $DIR/issue-35813-postfix-after-cast.rs:160:13
    |
 LL |     drop_ptr: fn(u8);
    |             ^ expected one of 8 possible tokens
 
 error: cast cannot be followed by a function call
-  --> $DIR/issue-35813-postfix-after-cast.rs:165:5
+  --> $DIR/issue-35813-postfix-after-cast.rs:166:5
    |
 LL |     drop as fn(u8)(0);
    |     ^^^^^^^^^^^^^^
@@ -283,13 +283,13 @@ LL |     (drop as fn(u8))(0);
    |     +              +
 
 error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `:`
-  --> $DIR/issue-35813-postfix-after-cast.rs:167:13
+  --> $DIR/issue-35813-postfix-after-cast.rs:168:13
    |
 LL |     drop_ptr: fn(u8)(0);
    |             ^ expected one of 8 possible tokens
 
 error: cast cannot be followed by `.await`
-  --> $DIR/issue-35813-postfix-after-cast.rs:172:5
+  --> $DIR/issue-35813-postfix-after-cast.rs:173:5
    |
 LL |     Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>.await;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -300,13 +300,13 @@ LL |     (Box::pin(noop()) as Pin<Box<dyn Future<Output = ()>>>).await;
    |     +                                                     +
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:`
-  --> $DIR/issue-35813-postfix-after-cast.rs:175:21
+  --> $DIR/issue-35813-postfix-after-cast.rs:176:21
    |
 LL |     Box::pin(noop()): Pin<Box<_>>.await;
    |                     ^ expected one of `.`, `;`, `?`, `}`, or an operator
 
 error: cast cannot be followed by a field access
-  --> $DIR/issue-35813-postfix-after-cast.rs:187:5
+  --> $DIR/issue-35813-postfix-after-cast.rs:188:5
    |
 LL |     Foo::default() as Foo.bar;
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -317,7 +317,7 @@ LL |     (Foo::default() as Foo).bar;
    |     +                     +
 
 error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:`
-  --> $DIR/issue-35813-postfix-after-cast.rs:189:19
+  --> $DIR/issue-35813-postfix-after-cast.rs:190:19
    |
 LL |     Foo::default(): Foo.bar;
    |                   ^ expected one of `.`, `;`, `?`, `}`, or an operator
@@ -340,11 +340,22 @@ LL |         if true { 33 } else { 44 }: i32.max(0)
    |                                   ^ expected one of `,`, `.`, `?`, or an operator
 
 error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
-  --> $DIR/issue-35813-postfix-after-cast.rs:150:13
+  --> $DIR/issue-35813-postfix-after-cast.rs:151:13
    |
 LL |     drop as F();
    |             ^^^ only `Fn` traits may use parentheses
 
-error: aborting due to 39 previous errors
+error[E0015]: cannot call non-const operator in statics
+  --> $DIR/issue-35813-postfix-after-cast.rs:130:42
+   |
+LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]);
+   |                                          ^^^^^^
+   |
+   = note: calls in statics are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
+
+error: aborting due to 40 previous errors
 
-For more information about this error, try `rustc --explain E0214`.
+Some errors have detailed explanations: E0015, E0214.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/parser/issues/issue-87086-colon-path-sep.rs b/tests/ui/parser/issues/issue-87086-colon-path-sep.rs
index e1ea38f2795..d081c06044f 100644
--- a/tests/ui/parser/issues/issue-87086-colon-path-sep.rs
+++ b/tests/ui/parser/issues/issue-87086-colon-path-sep.rs
@@ -37,9 +37,10 @@ fn g1() {
         //~| HELP: maybe write a path separator here
         _ => {}
     }
-    if let Foo:Bar = f() {
+    if let Foo:Bar = f() { //~ WARN: irrefutable `if let` pattern
     //~^ ERROR: expected one of
     //~| HELP: maybe write a path separator here
+    //~| HELP: consider replacing the `if let` with a `let`
     }
 }
 
diff --git a/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr b/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr
index 63b072ac4cd..b6e24faf5da 100644
--- a/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr
+++ b/tests/ui/parser/issues/issue-87086-colon-path-sep.stderr
@@ -64,7 +64,7 @@ LL |     if let Foo::Bar = f() {
    |               ~~
 
 error: expected one of `@` or `|`, found `:`
-  --> $DIR/issue-87086-colon-path-sep.rs:48:16
+  --> $DIR/issue-87086-colon-path-sep.rs:49:16
    |
 LL |         ref qux: Foo::Baz => {}
    |                ^ -------- specifying the type of a pattern isn't supported
@@ -77,7 +77,7 @@ LL |         ref qux::Foo::Baz => {}
    |                ~~
 
 error: expected one of `@` or `|`, found `:`
-  --> $DIR/issue-87086-colon-path-sep.rs:57:16
+  --> $DIR/issue-87086-colon-path-sep.rs:58:16
    |
 LL |         mut qux: Foo::Baz => {}
    |                ^ -------- specifying the type of a pattern isn't supported
@@ -90,7 +90,7 @@ LL |         mut qux::Foo::Baz => {}
    |                ~~
 
 error: expected one of `@` or `|`, found `:`
-  --> $DIR/issue-87086-colon-path-sep.rs:68:12
+  --> $DIR/issue-87086-colon-path-sep.rs:69:12
    |
 LL |         Foo:Bar::Baz => {}
    |            ^-------- specifying the type of a pattern isn't supported
@@ -103,7 +103,7 @@ LL |         Foo::Bar::Baz => {}
    |            ~~
 
 error: expected one of `@` or `|`, found `:`
-  --> $DIR/issue-87086-colon-path-sep.rs:74:12
+  --> $DIR/issue-87086-colon-path-sep.rs:75:12
    |
 LL |         Foo:Bar => {}
    |            ^--- specifying the type of a pattern isn't supported
@@ -115,5 +115,15 @@ help: maybe write a path separator here
 LL |         Foo::Bar => {}
    |            ~~
 
-error: aborting due to 9 previous errors
+warning: irrefutable `if let` pattern
+  --> $DIR/issue-87086-colon-path-sep.rs:40:8
+   |
+LL |     if let Foo:Bar = f() {
+   |        ^^^^^^^^^^^^^^^^^
+   |
+   = note: this pattern will always match, so the `if let` is useless
+   = help: consider replacing the `if let` with a `let`
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
+
+error: aborting due to 9 previous errors; 1 warning emitted
 
diff --git a/tests/ui/parser/parse-assoc-type-lt.rs b/tests/ui/parser/parse-assoc-type-lt.rs
index d3fe6079a5d..913fcd920bd 100644
--- a/tests/ui/parser/parse-assoc-type-lt.rs
+++ b/tests/ui/parser/parse-assoc-type-lt.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo {
diff --git a/tests/ui/parser/recover/recover-range-pats.rs b/tests/ui/parser/recover/recover-range-pats.rs
index 156c7ad94d3..3dc525cd6e1 100644
--- a/tests/ui/parser/recover/recover-range-pats.rs
+++ b/tests/ui/parser/recover/recover-range-pats.rs
@@ -134,10 +134,13 @@ fn with_macro_expr_var() {
     macro_rules! mac2 {
         ($e1:expr, $e2:expr) => {
             let $e1..$e2;
+            //~^ ERROR refutable pattern in local binding
             let $e1...$e2;
             //~^ ERROR `...` range patterns are deprecated
             //~| WARN this is accepted in the current edition
+            //~| ERROR refutable pattern in local binding
             let $e1..=$e2;
+            //~^ ERROR refutable pattern in local binding
         }
     }
 
@@ -146,12 +149,18 @@ fn with_macro_expr_var() {
     macro_rules! mac {
         ($e:expr) => {
             let ..$e;
+            //~^ ERROR refutable pattern in local binding
             let ...$e;
             //~^ ERROR range-to patterns with `...` are not allowed
+            //~| ERROR refutable pattern in local binding
             let ..=$e;
+            //~^ ERROR refutable pattern in local binding
             let $e..;
+            //~^ ERROR refutable pattern in local binding
             let $e...; //~ ERROR inclusive range with no end
+            //~^ ERROR refutable pattern in local binding
             let $e..=; //~ ERROR inclusive range with no end
+            //~^ ERROR refutable pattern in local binding
         }
     }
 
diff --git a/tests/ui/parser/recover/recover-range-pats.stderr b/tests/ui/parser/recover/recover-range-pats.stderr
index 5b69ca5cd6d..7c5cc4777b6 100644
--- a/tests/ui/parser/recover/recover-range-pats.stderr
+++ b/tests/ui/parser/recover/recover-range-pats.stderr
@@ -159,7 +159,7 @@ LL |     if let ....3 = 0 {}
    |            ^^^ help: use `..=` instead
 
 error: range-to patterns with `...` are not allowed
-  --> $DIR/recover-range-pats.rs:149:17
+  --> $DIR/recover-range-pats.rs:153:17
    |
 LL |             let ...$e;
    |                 ^^^ help: use `..=` instead
@@ -170,7 +170,7 @@ LL |     mac!(0);
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0586]: inclusive range with no end
-  --> $DIR/recover-range-pats.rs:153:19
+  --> $DIR/recover-range-pats.rs:160:19
    |
 LL |             let $e...;
    |                   ^^^ help: use `..` instead
@@ -182,7 +182,7 @@ LL |     mac!(0);
    = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0586]: inclusive range with no end
-  --> $DIR/recover-range-pats.rs:154:19
+  --> $DIR/recover-range-pats.rs:162:19
    |
 LL |             let $e..=;
    |                   ^^^ help: use `..` instead
@@ -271,7 +271,7 @@ LL |     if let X... .0 = 0 {}
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
 
 error: `...` range patterns are deprecated
-  --> $DIR/recover-range-pats.rs:137:20
+  --> $DIR/recover-range-pats.rs:138:20
    |
 LL |             let $e1...$e2;
    |                    ^^^ help: use `..=` for an inclusive range
@@ -478,7 +478,169 @@ LL |     if let ....3 = 0 {}
    |               |
    |               expected integer, found floating-point number
 
-error: aborting due to 60 previous errors
+error[E0005]: refutable pattern in local binding
+  --> $DIR/recover-range-pats.rs:136:17
+   |
+LL |             let $e1..$e2;
+   |                 ^^^^^^^^ patterns `i32::MIN..=-1_i32` and `1_i32..=i32::MAX` not covered
+...
+LL |     mac2!(0, 1);
+   |     ----------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variants that aren't matched
+   |
+LL |             if let $e1..$e2; { todo!() }
+   |             ++               +++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/recover-range-pats.rs:138:17
+   |
+LL |             let $e1...$e2;
+   |                 ^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `2_i32..=i32::MAX` not covered
+...
+LL |     mac2!(0, 1);
+   |     ----------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variants that aren't matched
+   |
+LL |             if let $e1...$e2; { todo!() }
+   |             ++                +++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/recover-range-pats.rs:142:17
+   |
+LL |             let $e1..=$e2;
+   |                 ^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `2_i32..=i32::MAX` not covered
+...
+LL |     mac2!(0, 1);
+   |     ----------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variants that aren't matched
+   |
+LL |             if let $e1..=$e2; { todo!() }
+   |             ++                +++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/recover-range-pats.rs:151:17
+   |
+LL |             let ..$e;
+   |                 ^^^^ pattern `0_i32..=i32::MAX` not covered
+...
+LL |     mac!(0);
+   |     ------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |             if let ..$e; { todo!() }
+   |             ++           +++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/recover-range-pats.rs:153:17
+   |
+LL |             let ...$e;
+   |                 ^^^^^ pattern `1_i32..=i32::MAX` not covered
+...
+LL |     mac!(0);
+   |     ------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |             if let ...$e; { todo!() }
+   |             ++            +++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/recover-range-pats.rs:156:17
+   |
+LL |             let ..=$e;
+   |                 ^^^^^ pattern `1_i32..=i32::MAX` not covered
+...
+LL |     mac!(0);
+   |     ------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |             if let ..=$e; { todo!() }
+   |             ++            +++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/recover-range-pats.rs:158:17
+   |
+LL |             let $e..;
+   |                 ^^^^ pattern `i32::MIN..=-1_i32` not covered
+...
+LL |     mac!(0);
+   |     ------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |             if let $e..; { todo!() }
+   |             ++           +++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/recover-range-pats.rs:160:17
+   |
+LL |             let $e...;
+   |                 ^^^^^ pattern `i32::MIN..=-1_i32` not covered
+...
+LL |     mac!(0);
+   |     ------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |             if let $e...; { todo!() }
+   |             ++            +++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/recover-range-pats.rs:162:17
+   |
+LL |             let $e..=;
+   |                 ^^^^^ pattern `i32::MIN..=-1_i32` not covered
+...
+LL |     mac!(0);
+   |     ------- in this macro invocation
+   |
+   = 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 `i32`
+   = note: this error originates in the macro `mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: you might want to use `if let` to ignore the variant that isn't matched
+   |
+LL |             if let $e..=; { todo!() }
+   |             ++            +++++++++++
+
+error: aborting due to 69 previous errors
 
-Some errors have detailed explanations: E0029, E0308, E0586.
-For more information about an error, try `rustc --explain E0029`.
+Some errors have detailed explanations: E0005, E0029, E0308, E0586.
+For more information about an error, try `rustc --explain E0005`.
diff --git a/tests/ui/parser/suggest-assoc-const.fixed b/tests/ui/parser/suggest-assoc-const.fixed
index 259f37b23a5..4229135ebb2 100644
--- a/tests/ui/parser/suggest-assoc-const.fixed
+++ b/tests/ui/parser/suggest-assoc-const.fixed
@@ -1,5 +1,6 @@
 // Issue: 101797, Suggest associated const for incorrect use of let in traits
 // run-rustfix
+#![allow(dead_code)]
 trait Trait {
     const _X: i32;
     //~^ ERROR non-item in item list
diff --git a/tests/ui/parser/suggest-assoc-const.rs b/tests/ui/parser/suggest-assoc-const.rs
index c7be712ec07..0cf695bd40a 100644
--- a/tests/ui/parser/suggest-assoc-const.rs
+++ b/tests/ui/parser/suggest-assoc-const.rs
@@ -1,5 +1,6 @@
 // Issue: 101797, Suggest associated const for incorrect use of let in traits
 // run-rustfix
+#![allow(dead_code)]
 trait Trait {
     let _X: i32;
     //~^ ERROR non-item in item list
diff --git a/tests/ui/parser/suggest-assoc-const.stderr b/tests/ui/parser/suggest-assoc-const.stderr
index 7ba1dbdff7e..6e29fad98d4 100644
--- a/tests/ui/parser/suggest-assoc-const.stderr
+++ b/tests/ui/parser/suggest-assoc-const.stderr
@@ -1,5 +1,5 @@
 error: non-item in item list
-  --> $DIR/suggest-assoc-const.rs:4:5
+  --> $DIR/suggest-assoc-const.rs:5:5
    |
 LL |     let _X: i32;
    |     ^^^ help: consider using `const` instead of `let` for associated const: `const`
diff --git a/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed b/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed
index 63704735490..81ee6cdf0a7 100644
--- a/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed
+++ b/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait Foo {
     fn bar() {} //~ ERROR non-item in item list
diff --git a/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs b/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs
index 4650b05e20c..c8f525fc4f0 100644
--- a/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs
+++ b/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait Foo {
     fn bar() {}; //~ ERROR non-item in item list
diff --git a/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr b/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr
index c716d5908ea..396c76ac85f 100644
--- a/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr
+++ b/tests/ui/parser/suggest-removing-semicolon-after-impl-trait-items.stderr
@@ -1,5 +1,5 @@
 error: non-item in item list
-  --> $DIR/suggest-removing-semicolon-after-impl-trait-items.rs:4:16
+  --> $DIR/suggest-removing-semicolon-after-impl-trait-items.rs:5:16
    |
 LL | trait Foo {
    |           - item list starts here
diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs
index b173e23e7a1..a2d2388ff50 100644
--- a/tests/ui/parser/variadic-ffi-semantic-restrictions.rs
+++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.rs
@@ -34,10 +34,12 @@ extern "C" fn f3_3(..., x: isize) {}
 
 const unsafe extern "C" fn f4_1(x: isize, ...) {}
 //~^ ERROR functions cannot be both `const` and C-variadic
+//~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
 
 const extern "C" fn f4_2(x: isize, ...) {}
 //~^ ERROR functions cannot be both `const` and C-variadic
 //~| ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
+//~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
 
 const extern "C" fn f4_3(..., x: isize, ...) {}
 //~^ ERROR functions cannot be both `const` and C-variadic
@@ -48,7 +50,7 @@ extern "C" {
     fn e_f1(...);
     //~^ ERROR C-variadic function must be declared with at least one named argument
     fn e_f2(..., x: isize);
-//~^ ERROR `...` must be the last argument of a C-variadic function
+    //~^ ERROR `...` must be the last argument of a C-variadic function
 }
 
 struct X;
@@ -68,6 +70,7 @@ impl X {
     const fn i_f5(x: isize, ...) {}
     //~^ ERROR only foreign or `unsafe extern "C"` functions may be C-variadic
     //~| ERROR functions cannot be both `const` and C-variadic
+    //~| ERROR destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
 }
 
 trait T {
diff --git a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
index 18526080e4c..6a65ed79d4f 100644
--- a/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
+++ b/tests/ui/parser/variadic-ffi-semantic-restrictions.stderr
@@ -83,25 +83,25 @@ LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
    | ^^^^^ `const` because of this             ^^^ C-variadic because of this
 
 error: functions cannot be both `const` and C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:38:1
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:39:1
    |
 LL | const extern "C" fn f4_2(x: isize, ...) {}
    | ^^^^^ `const` because of this      ^^^ C-variadic because of this
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:38:36
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:39:36
    |
 LL | const extern "C" fn f4_2(x: isize, ...) {}
    |                                    ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:42:26
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:44:26
    |
 LL | const extern "C" fn f4_3(..., x: isize, ...) {}
    |                          ^^^
 
 error: functions cannot be both `const` and C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:42:1
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:44:1
    |
 LL | const extern "C" fn f4_3(..., x: isize, ...) {}
    | ^^^^^                    ^^^            ^^^ C-variadic because of this
@@ -110,67 +110,67 @@ LL | const extern "C" fn f4_3(..., x: isize, ...) {}
    | `const` because of this
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:42:26
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:44:26
    |
 LL | const extern "C" fn f4_3(..., x: isize, ...) {}
    |                          ^^^            ^^^
 
 error: C-variadic function must be declared with at least one named argument
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:48:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
    |
 LL |     fn e_f1(...);
    |             ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:50:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:52:13
    |
 LL |     fn e_f2(..., x: isize);
    |             ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:57:23
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:59:23
    |
 LL |     fn i_f1(x: isize, ...) {}
    |                       ^^^
 
 error: C-variadic function must be declared with at least one named argument
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
    |
 LL |     fn i_f2(...) {}
    |             ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:59:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:61:13
    |
 LL |     fn i_f2(...) {}
    |             ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:62:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13
    |
 LL |     fn i_f3(..., x: isize, ...) {}
    |             ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:62:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:64:13
    |
 LL |     fn i_f3(..., x: isize, ...) {}
    |             ^^^            ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:65:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13
    |
 LL |     fn i_f4(..., x: isize, ...) {}
    |             ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:65:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:67:13
    |
 LL |     fn i_f4(..., x: isize, ...) {}
    |             ^^^            ^^^
 
 error: functions cannot be both `const` and C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:68:5
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:70:5
    |
 LL |     const fn i_f5(x: isize, ...) {}
    |     ^^^^^                   ^^^ C-variadic because of this
@@ -178,70 +178,95 @@ LL |     const fn i_f5(x: isize, ...) {}
    |     `const` because of this
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:68:29
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:70:29
    |
 LL |     const fn i_f5(x: isize, ...) {}
    |                             ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:74:23
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:77:23
    |
 LL |     fn t_f1(x: isize, ...) {}
    |                       ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:76:23
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:79:23
    |
 LL |     fn t_f2(x: isize, ...);
    |                       ^^^
 
 error: C-variadic function must be declared with at least one named argument
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:78:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
    |
 LL |     fn t_f3(...) {}
    |             ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:78:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
    |
 LL |     fn t_f3(...) {}
    |             ^^^
 
 error: C-variadic function must be declared with at least one named argument
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
    |
 LL |     fn t_f4(...);
    |             ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:81:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
    |
 LL |     fn t_f4(...);
    |             ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
    |
 LL |     fn t_f5(..., x: isize) {}
    |             ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:84:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
    |
 LL |     fn t_f5(..., x: isize) {}
    |             ^^^
 
 error: `...` must be the last argument of a C-variadic function
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:90:13
    |
 LL |     fn t_f6(..., x: isize);
    |             ^^^
 
 error: only foreign or `unsafe extern "C"` functions may be C-variadic
-  --> $DIR/variadic-ffi-semantic-restrictions.rs:87:13
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:90:13
    |
 LL |     fn t_f6(..., x: isize);
    |             ^^^
 
-error: aborting due to 40 previous errors
+error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:35:43
+   |
+LL | const unsafe extern "C" fn f4_1(x: isize, ...) {}
+   |                                           ^^^   - value is dropped here
+   |                                           |
+   |                                           the destructor for this type cannot be evaluated in constant functions
+
+error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:39:36
+   |
+LL | const extern "C" fn f4_2(x: isize, ...) {}
+   |                                    ^^^   - value is dropped here
+   |                                    |
+   |                                    the destructor for this type cannot be evaluated in constant functions
+
+error[E0493]: destructor of `VaListImpl<'_>` cannot be evaluated at compile-time
+  --> $DIR/variadic-ffi-semantic-restrictions.rs:70:29
+   |
+LL |     const fn i_f5(x: isize, ...) {}
+   |                             ^^^   - value is dropped here
+   |                             |
+   |                             the destructor for this type cannot be evaluated in constant functions
+
+error: aborting due to 43 previous errors
 
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/pattern/bindings-after-at/bind-by-copy.rs b/tests/ui/pattern/bindings-after-at/bind-by-copy.rs
index 2b349f0ed5f..253b2d88901 100644
--- a/tests/ui/pattern/bindings-after-at/bind-by-copy.rs
+++ b/tests/ui/pattern/bindings-after-at/bind-by-copy.rs
@@ -1,13 +1,30 @@
 // run-pass
+#![allow(unused)]
 
 // Test copy
 
-struct A { a: i32, b: i32 }
-struct B { a: i32, b: C }
-struct D { a: i32, d: C }
-#[derive(Copy,Clone)]
-struct C { c: i32 }
+struct A {
+    a: i32,
+    b: i32,
+}
+struct B {
+    a: i32,
+    b: C,
+}
+struct D {
+    a: i32,
+    d: C,
+}
+#[derive(Copy, Clone)]
+struct C {
+    c: i32,
+}
+enum E {
+    E { a: i32, e: C },
+    NotE,
+}
 
+#[rustfmt::skip]
 pub fn main() {
     match (A {a: 10, b: 20}) {
         x@A {a, b: 20} => { assert!(x.a == 10); assert!(a == 10); }
@@ -23,6 +40,23 @@ pub fn main() {
     y.d.c = 30;
     assert_eq!(d.c, 20);
 
+    match (E::E { a: 10, e: C { c: 20 } }) {
+        x @ E::E{ a, e: C { c } } => {
+            assert!(matches!(x, E::E { a: 10, e: C { c: 20 } }));
+            assert!(a == 10);
+            assert!(c == 20);
+        }
+        _ => panic!(),
+    }
+    match (E::E { a: 10, e: C { c: 20 } }) {
+        mut x @ E::E{ a, e: C { mut c } } => {
+            x = E::NotE;
+            c += 30;
+            assert_eq!(c, 50);
+        }
+        _ => panic!(),
+    }
+
     let some_b = Some(B { a: 10, b: C { c: 20 } });
 
     // in irrefutable pattern
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-move-and-move.rs b/tests/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
index a61d6821524..bfb3c3b20d6 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-move-and-move.rs
@@ -15,8 +15,8 @@ fn main() {
     let a @ (b, c) = (u(), u()); //~ ERROR use of partially moved value
 
     match Ok(U) {
-        a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of moved value
-                                     //~^ ERROR use of moved value
+        a @ Ok(b) | a @ Err(b) => {} //~ ERROR use of partially moved value
+                                     //~^ ERROR use of partially moved value
     }
 
     fn fun(a @ b: U) {} //~ ERROR use of moved value
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr b/tests/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
index 32489715112..ba0622090bb 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
+++ b/tests/ui/pattern/bindings-after-at/borrowck-move-and-move.stderr
@@ -40,35 +40,33 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |     let ref a @ (b, ref c) = (u(), u());
    |         +++         +++
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:18:16
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-move-and-move.rs:18:9
    |
-LL |     match Ok(U) {
-   |           ----- move occurs because value has type `Result<U, U>`, which does not implement the `Copy` trait
 LL |         a @ Ok(b) | a @ Err(b) => {}
-   |         -      ^ value used here after move
+   |         ^      - value partially moved here
    |         |
-   |         value moved here
+   |         value used here after partial move
    |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
    |
-LL |         ref a @ Ok(b) | a @ Err(b) => {}
-   |         +++
+LL |         ref a @ Ok(ref b) | a @ Err(b) => {}
+   |         +++        +++
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-move-and-move.rs:18:29
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-move-and-move.rs:18:21
    |
-LL |     match Ok(U) {
-   |           ----- move occurs because value has type `Result<U, U>`, which does not implement the `Copy` trait
 LL |         a @ Ok(b) | a @ Err(b) => {}
-   |                     -       ^ value used here after move
+   |                     ^       - value partially moved here
    |                     |
-   |                     value moved here
+   |                     value used here after partial move
    |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
    |
-LL |         a @ Ok(b) | ref a @ Err(b) => {}
-   |                     +++
+LL |         a @ Ok(b) | ref a @ Err(ref b) => {}
+   |                     +++         +++
 
 error[E0382]: use of partially moved value
   --> $DIR/borrowck-move-and-move.rs:25:9
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs
index 06dc6e1c4da..ac57838f029 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.rs
@@ -48,19 +48,17 @@ fn main() {
         //~^ ERROR borrow of moved value
         //~| ERROR borrow of moved value
         //~| ERROR borrow of moved value
-        //~| ERROR use of moved value
+        //~| ERROR use of partially moved value
         None => {}
     }
     match Some([U, U]) {
         mut a @ Some([ref b, ref mut c]) => {}
         //~^ ERROR borrow of moved value
-        //~| ERROR borrow of moved value
         None => {}
     }
     match Some(u()) {
         a @ Some(ref b) => {}
         //~^ ERROR borrow of moved value
-        //~| ERROR borrow of moved value
         None => {}
     }
     match Some((u(), u())) {
@@ -68,13 +66,12 @@ fn main() {
         //~^ ERROR borrow of moved value
         //~| ERROR borrow of moved value
         //~| ERROR borrow of moved value
-        //~| ERROR use of moved value
+        //~| ERROR use of partially moved value
         None => {}
     }
     match Some([u(), u()]) {
         mut a @ Some([ref b, ref mut c]) => {}
         //~^ ERROR borrow of moved value
-        //~| ERROR borrow of moved value
         None => {}
     }
 }
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
index 1ed019f0a69..fd7a51388bc 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
@@ -215,7 +215,7 @@ LL |         ref mut a @ Some([ref b, ref mut c]) => {}
    |         +++
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:60:9
    |
 LL |         a @ Some(ref b) => {}
    |         ^        ----- value borrowed here after move
@@ -229,7 +229,7 @@ LL |         ref a @ Some(ref b) => {}
    |         +++
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:65:9
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         ^                 ---------      ----- value borrowed here after move
@@ -244,7 +244,7 @@ LL |         ref a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         +++
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:19
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:65:19
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                   ^^^^^   --------- value borrowed here after move
@@ -258,7 +258,7 @@ LL |         a @ Some((ref mut b @ ref mut c, d @ ref e)) => {}
    |                   +++
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:38
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:65:38
    |
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                                      ^   ----- value borrowed here after move
@@ -272,7 +272,7 @@ LL |         a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
    |                                      +++
 
 error: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:9
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:73:9
    |
 LL |         mut a @ Some([ref b, ref mut c]) => {}
    |         ^^^^^         -----  --------- value borrowed here after move
@@ -314,66 +314,33 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |     let ref a @ (mut b @ ref mut c, ref d @ ref e) = (u(), u());
    |         +++                         +++
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:38
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:47:9
    |
-LL |     match Some((U, U)) {
-   |           ------------ move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
-   |         - value moved here           ^ value used here after move
-   |
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         ref a @ Some((mut b @ ref mut c, d @ ref e)) => {}
-   |         +++
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:55:30
-   |
-LL |     match Some([U, U]) {
-   |           ------------ move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait
-LL |         mut a @ Some([ref b, ref mut c]) => {}
-   |         -----                ^^^^^^^^^ value borrowed here after move
-   |         |
-   |         value moved here
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:61:18
-   |
-LL |     match Some(u()) {
-   |           --------- move occurs because value has type `Option<U>`, which does not implement the `Copy` trait
-LL |         a @ Some(ref b) => {}
-   |         -        ^^^^^ value borrowed here after move
+   |         ^                            - value partially moved here
    |         |
-   |         value moved here
+   |         value used here after partial move
    |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
    |
-LL |         ref a @ Some(ref b) => {}
-   |         +++
+LL |         ref a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
+   |         +++                              +++
 
-error[E0382]: use of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:67:38
+error[E0382]: use of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:65:9
    |
-LL |     match Some((u(), u())) {
-   |           ---------------- move occurs because value has type `Option<(U, U)>`, which does not implement the `Copy` trait
 LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
-   |         - value moved here           ^ value used here after move
+   |         ^                            - value partially moved here
+   |         |
+   |         value used here after partial move
    |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
    |
-LL |         ref a @ Some((mut b @ ref mut c, d @ ref e)) => {}
-   |         +++
-
-error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:75:30
-   |
-LL |     match Some([u(), u()]) {
-   |           ---------------- move occurs because value has type `Option<[U; 2]>`, which does not implement the `Copy` trait
-LL |         mut a @ Some([ref b, ref mut c]) => {}
-   |         -----                ^^^^^^^^^ value borrowed here after move
-   |         |
-   |         value moved here
+LL |         ref a @ Some((mut b @ ref mut c, ref d @ ref e)) => {}
+   |         +++                              +++
 
 error: borrow of moved value
   --> $DIR/borrowck-pat-by-move-and-ref-inverse.rs:11:11
@@ -457,6 +424,6 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |     fn f3(ref a @ [ref mut b, ref c]: [U; 2]) {}
    |           +++
 
-error: aborting due to 33 previous errors
+error: aborting due to 30 previous errors
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs
index 0b0a7801049..095c871e8d2 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.rs
@@ -58,11 +58,13 @@ fn main() {
     match Some([U, U]) {
         ref mut a @ Some([b, mut c]) => {}
         //~^ ERROR cannot move out of value because it is borrowed
+        //~| ERROR borrow of partially moved value
         None => {}
     }
     match Some(u()) {
         ref a @ Some(b) => {}
         //~^ ERROR cannot move out of value because it is borrowed
+        //~| ERROR borrow of partially moved value
         None => {}
     }
     match Some((u(), u())) {
@@ -77,6 +79,7 @@ fn main() {
     match Some([u(), u()]) {
         ref mut a @ Some([b, mut c]) => {}
         //~^ ERROR cannot move out of value because it is borrowed
+        //~| ERROR borrow of partially moved value
         None => {}
     }
 }
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
index c8c4d9b8fdb..45ada8fd516 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref.stderr
@@ -125,7 +125,7 @@ LL |         ref mut a @ Some([b, mut c]) => {}
    |         value is mutably borrowed by `a` here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:64:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:65:9
    |
 LL |         ref a @ Some(b) => {}
    |         ^^^^^        - value is moved into `b` here
@@ -133,7 +133,7 @@ LL |         ref a @ Some(b) => {}
    |         value is borrowed by `a` here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:69:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:71:9
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |         ^^^^^                 -----          - value is moved into `e` here
@@ -142,7 +142,7 @@ LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |         value is borrowed by `a` here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:69:23
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:71:23
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                       ^^^^^   ----- value is moved into `c` here
@@ -150,7 +150,7 @@ LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                       value is borrowed by `b` here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:69:38
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:71:38
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                                      ^^^^^   - value is moved into `e` here
@@ -158,7 +158,7 @@ LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                                      value is borrowed by `d` here
 
 error: cannot move out of value because it is borrowed
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:78:9
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:80:9
    |
 LL |         ref mut a @ Some([b, mut c]) => {}
    |         ^^^^^^^^^         -  ----- value is moved into `c` here
@@ -236,8 +236,36 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |     let ref mut a @ [b, ref mut c] = [u(), u()];
    |                         +++
 
+error[E0382]: borrow of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:59:9
+   |
+LL |         ref mut a @ Some([b, mut c]) => {}
+   |         ^^^^^^^^^            ----- value partially moved here
+   |         |
+   |         value borrowed here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+   |
+LL |         ref mut a @ Some([b, ref mut c]) => {}
+   |                              +++
+
+error[E0382]: borrow of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:65:9
+   |
+LL |         ref a @ Some(b) => {}
+   |         ^^^^^        - value partially moved here
+   |         |
+   |         value borrowed here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+   |
+LL |         ref a @ Some(ref b) => {}
+   |                      +++
+
 error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:69:23
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:71:23
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                       ^^^^^   ----- value moved here
@@ -251,7 +279,7 @@ LL |         ref a @ Some((ref b @ ref mut c, ref d @ e)) => {}
    |                               +++
 
 error[E0382]: borrow of moved value
-  --> $DIR/borrowck-pat-by-move-and-ref.rs:69:38
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:71:38
    |
 LL |         ref a @ Some((ref b @ mut c, ref d @ e)) => {}
    |                                      ^^^^^   - value moved here
@@ -264,6 +292,20 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |         ref a @ Some((ref b @ mut c, ref d @ ref e)) => {}
    |                                              +++
 
+error[E0382]: borrow of partially moved value
+  --> $DIR/borrowck-pat-by-move-and-ref.rs:80:9
+   |
+LL |         ref mut a @ Some([b, mut c]) => {}
+   |         ^^^^^^^^^            ----- value partially moved here
+   |         |
+   |         value borrowed here after partial move
+   |
+   = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+   |
+LL |         ref mut a @ Some([b, ref mut c]) => {}
+   |                              +++
+
 error: cannot move out of value because it is borrowed
   --> $DIR/borrowck-pat-by-move-and-ref.rs:11:11
    |
@@ -345,6 +387,6 @@ LL |     fn f3(ref mut a @ [b, mut c]: [U; 2]) {}
    |
    = note: partial move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error: aborting due to 36 previous errors
+error: aborting due to 39 previous errors
 
 For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
index 6bc0d346c11..98f316dd74b 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.rs
@@ -7,7 +7,7 @@ fn main() {
     match &mut Some(1) {
         ref mut z @ &mut Some(ref a) => {
         //~^ ERROR cannot borrow value as immutable because it is also borrowed as mutable
-        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+        //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
             **z = None;
             println!("{}", *a);
         }
@@ -76,8 +76,8 @@ fn main() {
         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
             //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
             //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
-            //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
-            //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
+            //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+            //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
             *b = U;
             drop(a);
         }
@@ -87,6 +87,8 @@ fn main() {
         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
         //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
         //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
+        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
         //~| ERROR cannot assign to `*b`, as it is immutable for the pattern guard
         _ => {}
     }
@@ -101,6 +103,8 @@ fn main() {
         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
         //~^ ERROR cannot borrow value as mutable because it is also borrowed as immutable
         //~| ERROR cannot borrow value as mutable because it is also borrowed as immutable
+        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
+        //~| ERROR cannot borrow value as immutable because it is also borrowed as mutable
         //~| ERROR cannot move out of `b` in pattern guard
         //~| ERROR cannot move out of `b` in pattern guard
         _ => {}
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
index 0b432487615..9359244c6eb 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-and-ref.stderr
@@ -138,7 +138,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false }
    |                                 value is borrowed by `a` here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:9
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
    |         ^^^^^^^^^      ----- value is borrowed by `b` here
@@ -146,7 +146,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
    |         value is mutably borrowed by `a` here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:33
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:33
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
    |                                 ^^^^^^^^^       ----- value is borrowed by `b` here
@@ -154,7 +154,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); fa
    |                                 value is mutably borrowed by `a` here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
    |         ^^^^^      --------- value is mutably borrowed by `b` here
@@ -162,7 +162,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    |         value is borrowed by `a` here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:33
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:33
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
    |                                 ^^^^^       --------- value is mutably borrowed by `b` here
@@ -170,7 +170,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    |                                 value is borrowed by `a` here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:113:9
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
    |         ^^^^^^^^^      ----- value is borrowed by `b` here
@@ -178,7 +178,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
    |         value is mutably borrowed by `a` here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:33
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:113:33
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
    |                                 ^^^^^^^^^       ----- value is borrowed by `b` here
@@ -186,7 +186,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
    |                                 value is mutably borrowed by `a` here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         ^^^^^    ---------  --------- value is mutably borrowed by `c` here
@@ -195,7 +195,7 @@ LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         value is borrowed by `a` here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         ^^^^^    ---------  --------- value is mutably borrowed by `c` here
@@ -204,7 +204,7 @@ LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         value is borrowed by `a` here
 
 error: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:133:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         ^^^^^    ---------  --------- value is mutably borrowed by `c` here
@@ -213,7 +213,7 @@ LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         value is borrowed by `a` here
 
 error: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:134:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:138:9
    |
 LL |     let ref mut a @ (ref b, ref c) = (U, U);
    |         ^^^^^^^^^    -----  ----- value is borrowed by `c` here
@@ -221,16 +221,16 @@ LL |     let ref mut a @ (ref b, ref c) = (U, U);
    |         |            value is borrowed by `b` here
    |         value is mutably borrowed by `a` here
 
-error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:31
+error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:8:9
    |
 LL |         ref mut z @ &mut Some(ref a) => {
-   |         ---------             ^^^^^ immutable borrow occurs here
+   |         ^^^^^^^^^             ----- immutable borrow occurs here
    |         |
    |         mutable borrow occurs here
 ...
-LL |             **z = None;
-   |             ---------- mutable borrow later used here
+LL |             println!("{}", *a);
+   |                            -- immutable borrow later used here
 
 error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
   --> $DIR/borrowck-pat-ref-mut-and-ref.rs:46:9
@@ -254,27 +254,44 @@ LL |     let ref a @ ref mut b = u();
 LL |     *b = u();
    |     -------- mutable borrow later used here
 
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:20
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:9
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
-   |         -----      ^^^^^^^^^ mutable borrow occurs here
+   |         ^^^^^      --------- mutable borrow occurs here
    |         |
    |         immutable borrow occurs here
 ...
-LL |             drop(a);
-   |                  - immutable borrow later used here
+LL |             *b = U;
+   |             ------ mutable borrow later used here
 
-error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:45
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:76:33
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) => {
-   |                                 -----       ^^^^^^^^^ mutable borrow occurs here
+   |                                 ^^^^^       --------- mutable borrow occurs here
    |                                 |
    |                                 immutable borrow occurs here
 ...
-LL |             drop(a);
-   |                  - immutable borrow later used here
+LL |             *b = U;
+   |             ------ mutable borrow later used here
+
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:9
+   |
+LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
+   |         ^^^^^      --------- mutable borrow occurs here     ------ mutable borrow later used here
+   |         |
+   |         immutable borrow occurs here
+
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:33
+   |
+LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false } => {}
+   |                                 ^^^^^       ---------       ------ mutable borrow later used here
+   |                                 |           |
+   |                                 |           mutable borrow occurs here
+   |                                 immutable borrow occurs here
 
 error[E0594]: cannot assign to `*b`, as it is immutable for the pattern guard
   --> $DIR/borrowck-pat-ref-mut-and-ref.rs:87:61
@@ -285,15 +302,32 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { *b = U; false }
    = note: variables bound in patterns are immutable until the end of the pattern guard
 
 error[E0594]: cannot assign to `*a`, as it is immutable for the pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:94:61
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:96:61
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { *a = Err(U); false } => {}
    |                                                             ^^^^^^^^^^^ cannot assign
    |
    = note: variables bound in patterns are immutable until the end of the pattern guard
 
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:9
+   |
+LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
+   |         ^^^^^      --------- mutable borrow occurs here          - mutable borrow later used here
+   |         |
+   |         immutable borrow occurs here
+
+error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:33
+   |
+LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
+   |                                 ^^^^^       ---------            - mutable borrow later used here
+   |                                 |           |
+   |                                 |           mutable borrow occurs here
+   |                                 immutable borrow occurs here
+
 error[E0507]: cannot move out of `b` in pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
    |                                                                  ^ move occurs because `b` has type `&mut U`, which does not implement the `Copy` trait
@@ -301,7 +335,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error[E0507]: cannot move out of `b` in pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:101:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:103:66
    |
 LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false } => {}
    |                                                                  ^ move occurs because `b` has type `&mut U`, which does not implement the `Copy` trait
@@ -310,7 +344,7 @@ LL |         ref a @ Ok(ref mut b) | ref a @ Err(ref mut b) if { drop(b); false
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0507]: cannot move out of `a` in pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:113:66
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
    |                                                                  ^ move occurs because `a` has type `&mut Result<U, U>`, which does not implement the `Copy` trait
@@ -318,7 +352,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
    = note: variables bound in patterns cannot be moved from until after the end of the pattern guard
 
 error[E0507]: cannot move out of `a` in pattern guard
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:109:66
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:113:66
    |
 LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false } => {}
    |                                                                  ^ move occurs because `a` has type `&mut Result<U, U>`, which does not implement the `Copy` trait
@@ -327,7 +361,7 @@ LL |         ref mut a @ Ok(ref b) | ref mut a @ Err(ref b) if { drop(a); false
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:117:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:121:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         ^^^^^    --------- mutable borrow occurs here
@@ -338,7 +372,7 @@ LL |     *b = U;
    |     ------ mutable borrow later used here
 
 error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:123:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:127:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         ^^^^^    --------- mutable borrow occurs here
@@ -349,7 +383,7 @@ LL |     *b = U;
    |     ------ mutable borrow later used here
 
 error[E0502]: cannot borrow value as immutable because it is also borrowed as mutable
-  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:129:9
+  --> $DIR/borrowck-pat-ref-mut-and-ref.rs:133:9
    |
 LL |     let ref a @ (ref mut b, ref mut c) = (U, U);
    |         ^^^^^    --------- mutable borrow occurs here
@@ -409,7 +443,7 @@ LL |     fn f4_also_moved(ref a @ ref mut b @ c: U) {}
    |                      |       value borrowed here after move
    |                      move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error: aborting due to 47 previous errors
+error: aborting due to 51 previous errors
 
 Some errors have detailed explanations: E0382, E0502, E0507, E0594.
 For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
index 99739c7bce0..5f86a6a0ca9 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.rs
@@ -82,6 +82,8 @@ fn main() {
         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
             //~^ ERROR cannot borrow value as mutable more than once at a time
             //~| ERROR cannot borrow value as mutable more than once at a time
+            //~| ERROR cannot borrow value as mutable more than once at a time
+            //~| ERROR cannot borrow value as mutable more than once at a time
             *b = U;
         }
     }
@@ -89,8 +91,6 @@ fn main() {
         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
             //~^ ERROR cannot borrow value as mutable more than once at a time
             //~| ERROR cannot borrow value as mutable more than once at a time
-            //~| ERROR cannot borrow value as mutable more than once at a time
-            //~| ERROR cannot borrow value as mutable more than once at a time
             *a = Err(U);
 
             // FIXME: The binding name value used above makes for problematic diagnostics.
@@ -101,8 +101,6 @@ fn main() {
         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
             //~^ ERROR cannot borrow value as mutable more than once at a time
             //~| ERROR cannot borrow value as mutable more than once at a time
-            //~| ERROR cannot borrow value as mutable more than once at a time
-            //~| ERROR cannot borrow value as mutable more than once at a time
             drop(a);
         }
     }
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
index c634ea470c5..3446148d2b1 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
@@ -163,7 +163,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     value is mutably borrowed by `a` here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:89:9
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:91:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         ^^^^^^^^^      --------- value is mutably borrowed by `b` here
@@ -171,7 +171,7 @@ LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |         value is mutably borrowed by `a` here
 
 error: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:89:37
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:91:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
    |                                     ^^^^^^^^^       --------- value is mutably borrowed by `b` here
@@ -217,48 +217,26 @@ LL |     *b = U;
    |     ------ first borrow later used here
 
 error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:89:24
-   |
-LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
-   |         ---------      ^^^^^^^^^ second mutable borrow occurs here
-   |         |
-   |         first mutable borrow occurs here
-...
-LL |             *a = Err(U);
-   |             ----------- first borrow later used here
-
-error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:89:53
-   |
-LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
-   |                                     ---------       ^^^^^^^^^ second mutable borrow occurs here
-   |                                     |
-   |                                     first mutable borrow occurs here
-...
-LL |             *a = Err(U);
-   |             ----------- first borrow later used here
-
-error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:101:24
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:82:9
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
-   |         ---------      ^^^^^^^^^ second mutable borrow occurs here
+   |         ^^^^^^^^^      --------- first mutable borrow occurs here
    |         |
-   |         first mutable borrow occurs here
+   |         second mutable borrow occurs here
 ...
-LL |             drop(a);
-   |                  - first borrow later used here
+LL |             *b = U;
+   |             ------ first borrow later used here
 
 error[E0499]: cannot borrow value as mutable more than once at a time
-  --> $DIR/borrowck-pat-ref-mut-twice.rs:101:53
+  --> $DIR/borrowck-pat-ref-mut-twice.rs:82:37
    |
 LL |         ref mut a @ Ok(ref mut b) | ref mut a @ Err(ref mut b) => {
-   |                                     ---------       ^^^^^^^^^ second mutable borrow occurs here
+   |                                     ^^^^^^^^^       --------- first mutable borrow occurs here
    |                                     |
-   |                                     first mutable borrow occurs here
+   |                                     second mutable borrow occurs here
 ...
-LL |             drop(a);
-   |                  - first borrow later used here
+LL |             *b = U;
+   |             ------ first borrow later used here
 
 error: cannot borrow value as mutable more than once at a time
   --> $DIR/borrowck-pat-ref-mut-twice.rs:8:11
@@ -313,7 +291,7 @@ LL |     fn f4_also_moved(ref mut a @ ref mut b @ c: U) {}
    |                      |           value borrowed here after move
    |                      move occurs because value has type `U`, which does not implement the `Copy` trait
 
-error: aborting due to 31 previous errors
+error: aborting due to 29 previous errors
 
 Some errors have detailed explanations: E0382, E0499.
 For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.rs b/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.rs
index f167a3952ee..f0f512bef52 100644
--- a/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.rs
+++ b/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.rs
@@ -10,7 +10,7 @@ fn main() {
     match Ok(0) {
         Ok(a @ b @ a)
         //~^ ERROR identifier `a` is bound more than once in the same pattern
-        | Err(a @ b @ a)
+        | Err(a @ b @ a) //~ ERROR cannot assign twice to immutable variable `a`
         //~^ ERROR identifier `a` is bound more than once in the same pattern
         => {}
     }
@@ -20,7 +20,7 @@ fn main() {
     //~| ERROR identifier `a` is bound more than once in the same pattern
     let ref a @ ref a = ();
     //~^ ERROR identifier `a` is bound more than once in the same pattern
-    let ref mut a @ ref mut a = ();
+    let ref mut a @ ref mut a = (); //~ ERROR cannot borrow value as mutable more than once at a time
     //~^ ERROR identifier `a` is bound more than once in the same pattern
 
     let a @ (Ok(a) | Err(a)) = Ok(());
diff --git a/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr b/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr
index a165549f6b4..e25c30cd492 100644
--- a/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr
+++ b/tests/ui/pattern/bindings-after-at/pat-at-same-name-both.stderr
@@ -58,7 +58,27 @@ error[E0416]: identifier `a` is bound more than once in the same pattern
 LL |     let a @ (Ok(a) | Err(a)) = Ok(());
    |                          ^ used in a pattern more than once
 
-error: aborting due to 10 previous errors
+error: cannot borrow value as mutable more than once at a time
+  --> $DIR/pat-at-same-name-both.rs:23:9
+   |
+LL |     let ref mut a @ ref mut a = ();
+   |         ^^^^^^^^^   --------- value is mutably borrowed by `a` here
+   |         |
+   |         value is mutably borrowed by `a` here
+
+error[E0384]: cannot assign twice to immutable variable `a`
+  --> $DIR/pat-at-same-name-both.rs:13:15
+   |
+LL |         Ok(a @ b @ a)
+   |                    -
+   |                    |
+   |                    first assignment to `a`
+   |                    help: consider making this binding mutable: `mut a`
+LL |
+LL |         | Err(a @ b @ a)
+   |               ^ cannot assign twice to immutable variable
+
+error: aborting due to 12 previous errors
 
-Some errors have detailed explanations: E0415, E0416.
-For more information about an error, try `rustc --explain E0415`.
+Some errors have detailed explanations: E0384, E0415, E0416.
+For more information about an error, try `rustc --explain E0384`.
diff --git a/tests/ui/pattern/issue-22546.rs b/tests/ui/pattern/issue-22546.rs
index c26e457f9e4..8a0f51d0b84 100644
--- a/tests/ui/pattern/issue-22546.rs
+++ b/tests/ui/pattern/issue-22546.rs
@@ -15,7 +15,7 @@ impl<T: ::std::fmt::Display> Foo<T> {
     }
 }
 
-trait Tr {
+trait Tr { //~ WARN trait `Tr` is never used
     type U;
 }
 
diff --git a/tests/ui/pattern/issue-22546.stderr b/tests/ui/pattern/issue-22546.stderr
new file mode 100644
index 00000000000..e067a95e422
--- /dev/null
+++ b/tests/ui/pattern/issue-22546.stderr
@@ -0,0 +1,10 @@
+warning: trait `Tr` is never used
+  --> $DIR/issue-22546.rs:18:7
+   |
+LL | trait Tr {
+   |       ^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-28992-empty.rs b/tests/ui/pattern/issue-28992-empty.rs
index 74cfeb6db8e..74cfeb6db8e 100644
--- a/tests/ui/issues/issue-28992-empty.rs
+++ b/tests/ui/pattern/issue-28992-empty.rs
diff --git a/tests/ui/issues/issue-28992-empty.stderr b/tests/ui/pattern/issue-28992-empty.stderr
index f69773b8c2b..f69773b8c2b 100644
--- a/tests/ui/issues/issue-28992-empty.stderr
+++ b/tests/ui/pattern/issue-28992-empty.stderr
diff --git a/tests/ui/pattern/pattern-binding-disambiguation.rs b/tests/ui/pattern/pattern-binding-disambiguation.rs
index ce1d8c6c047..8be70f65d0e 100644
--- a/tests/ui/pattern/pattern-binding-disambiguation.rs
+++ b/tests/ui/pattern/pattern-binding-disambiguation.rs
@@ -26,7 +26,7 @@ fn main() {
     match doesnt_matter {
         BracedStruct => {} // OK, `BracedStruct` is a fresh binding
     }
-    match UnitVariant {
+    match UnitVariant { //~ ERROR: `E::TupleVariant` and `E::BracedVariant {  }` not covered
         UnitVariant => {} // OK, `UnitVariant` is a unit variant pattern
     }
     match doesnt_matter {
@@ -48,7 +48,7 @@ fn main() {
     let UnitStruct = UnitStruct; // OK, `UnitStruct` is a unit struct pattern
     let TupleStruct = doesnt_matter; //~ ERROR let bindings cannot shadow tuple structs
     let BracedStruct = doesnt_matter; // OK, `BracedStruct` is a fresh binding
-    let UnitVariant = UnitVariant; // OK, `UnitVariant` is a unit variant pattern
+    let UnitVariant = UnitVariant; //~ ERROR: refutable pattern in local binding
     let TupleVariant = doesnt_matter; //~ ERROR let bindings cannot shadow tuple variants
     let BracedVariant = doesnt_matter; // OK, `BracedVariant` is a fresh binding
     let CONST = CONST; // OK, `CONST` is a const pattern
diff --git a/tests/ui/pattern/pattern-binding-disambiguation.stderr b/tests/ui/pattern/pattern-binding-disambiguation.stderr
index d54467b3c0c..61c32b6a17b 100644
--- a/tests/ui/pattern/pattern-binding-disambiguation.stderr
+++ b/tests/ui/pattern/pattern-binding-disambiguation.stderr
@@ -58,6 +58,53 @@ LL | static STATIC: () = ();
 LL |     let STATIC = doesnt_matter;
    |         ^^^^^^ cannot be named the same as a static
 
-error: aborting due to 6 previous errors
+error[E0004]: non-exhaustive patterns: `E::TupleVariant` and `E::BracedVariant {  }` not covered
+  --> $DIR/pattern-binding-disambiguation.rs:29:11
+   |
+LL |     match UnitVariant {
+   |           ^^^^^^^^^^^ patterns `E::TupleVariant` and `E::BracedVariant {  }` not covered
+   |
+note: `E` defined here
+  --> $DIR/pattern-binding-disambiguation.rs:5:6
+   |
+LL | enum E {
+   |      ^
+LL |     UnitVariant,
+LL |     TupleVariant(),
+   |     ------------ not covered
+LL |     BracedVariant{},
+   |     ------------- not covered
+   = note: the matched value is of type `E`
+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 |         UnitVariant => {}, E::TupleVariant | E::BracedVariant {  } => todo!() // OK, `UnitVariant` is a unit variant pattern
+   |                          ++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+error[E0005]: refutable pattern in local binding
+  --> $DIR/pattern-binding-disambiguation.rs:51:9
+   |
+LL |     let UnitVariant = UnitVariant;
+   |         ^^^^^^^^^^^ patterns `E::TupleVariant` and `E::BracedVariant {  }` 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: `E` defined here
+  --> $DIR/pattern-binding-disambiguation.rs:5:6
+   |
+LL | enum E {
+   |      ^
+LL |     UnitVariant,
+LL |     TupleVariant(),
+   |     ------------ not covered
+LL |     BracedVariant{},
+   |     ------------- not covered
+   = note: the matched value is of type `E`
+help: you might want to use `if let` to ignore the variants that aren't matched
+   |
+LL |     if let UnitVariant = UnitVariant { todo!() };
+   |     ++                               +++++++++++
+
+error: aborting due to 8 previous errors
 
-For more information about this error, try `rustc --explain E0530`.
+Some errors have detailed explanations: E0004, E0005, E0530.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs
index a619fcafc86..1eba7aeb4d6 100644
--- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs
+++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.rs
@@ -1,9 +1,23 @@
 fn main() {
     match &[1, 2, 3][..] {
-        [1, rest..] => println!("{rest:?}"),
+        [1, rest..] => println!("{rest}"),
         //~^ ERROR cannot find value `rest` in this scope
         //~| ERROR cannot find value `rest` in this scope
         //~| ERROR `X..` patterns in slices are experimental
         _ => {}
     }
+    match &[4, 5, 6][..] {
+        [] => {}
+        [_, ..tail] => println!("{tail}"),
+        //~^ ERROR cannot find value `tail` in this scope
+        //~| ERROR cannot find value `tail` in this scope
+        //~| ERROR exclusive range pattern syntax is experimental
+    }
+    match &[7, 8, 9][..] {
+        [] => {}
+        [_, ...tail] => println!("{tail}"),
+        //~^ ERROR cannot find value `tail` in this scope
+        //~| ERROR cannot find value `tail` in this scope
+        //~| ERROR range-to patterns with `...` are not allowed
+    }
 }
diff --git a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr
index c3c9131b63e..3a19517c85b 100644
--- a/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr
+++ b/tests/ui/pattern/range-pattern-meant-to-be-slice-rest-pattern.stderr
@@ -1,31 +1,82 @@
+error: range-to patterns with `...` are not allowed
+  --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:18:13
+   |
+LL |         [_, ...tail] => println!("{tail}"),
+   |             ^^^ help: use `..=` instead
+
 error[E0425]: cannot find value `rest` in this scope
   --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:13
    |
-LL |         [1, rest..] => println!("{rest:?}"),
+LL |         [1, rest..] => println!("{rest}"),
    |             ^^^^ not found in this scope
    |
 help: if you meant to collect the rest of the slice in `rest`, use the at operator
    |
-LL |         [1, rest @ ..] => println!("{rest:?}"),
+LL |         [1, rest @ ..] => println!("{rest}"),
    |                  +
 
 error[E0425]: cannot find value `rest` in this scope
   --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:35
    |
-LL |         [1, rest..] => println!("{rest:?}"),
+LL |         [1, rest..] => println!("{rest}"),
+   |                                   ^^^^ not found in this scope
+
+error[E0425]: cannot find value `tail` in this scope
+  --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:15
+   |
+LL |         [_, ..tail] => println!("{tail}"),
+   |               ^^^^ not found in this scope
+   |
+help: if you meant to collect the rest of the slice in `tail`, use the at operator
+   |
+LL |         [_, tail @ ..] => println!("{tail}"),
+   |             ~~~~~~~~~
+
+error[E0425]: cannot find value `tail` in this scope
+  --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:35
+   |
+LL |         [_, ..tail] => println!("{tail}"),
    |                                   ^^^^ not found in this scope
 
+error[E0425]: cannot find value `tail` in this scope
+  --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:18:16
+   |
+LL |         [_, ...tail] => println!("{tail}"),
+   |                ^^^^ not found in this scope
+   |
+help: if you meant to collect the rest of the slice in `tail`, use the at operator
+   |
+LL |         [_, tail @ ..] => println!("{tail}"),
+   |             ~~~~~~~~~
+
+error[E0425]: cannot find value `tail` in this scope
+  --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:18:36
+   |
+LL |         [_, ...tail] => println!("{tail}"),
+   |                                    ^^^^ not found in this scope
+
 error[E0658]: `X..` patterns in slices are experimental
   --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:3:13
    |
-LL |         [1, rest..] => println!("{rest:?}"),
+LL |         [1, rest..] => println!("{rest}"),
    |             ^^^^^^
    |
    = note: see issue #67264 <https://github.com/rust-lang/rust/issues/67264> for more information
    = help: add `#![feature(half_open_range_patterns_in_slices)]` 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: aborting due to 3 previous errors
+error[E0658]: exclusive range pattern syntax is experimental
+  --> $DIR/range-pattern-meant-to-be-slice-rest-pattern.rs:11:13
+   |
+LL |         [_, ..tail] => println!("{tail}"),
+   |             ^^^^^^
+   |
+   = 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 9 previous errors
 
 Some errors have detailed explanations: E0425, E0658.
 For more information about an error, try `rustc --explain E0425`.
diff --git a/tests/ui/pattern/usefulness/always-inhabited-union-ref.stderr b/tests/ui/pattern/usefulness/always-inhabited-union-ref.exhaustive_patterns.stderr
index cd5c283f9fd..553daff2d96 100644
--- a/tests/ui/pattern/usefulness/always-inhabited-union-ref.stderr
+++ b/tests/ui/pattern/usefulness/always-inhabited-union-ref.exhaustive_patterns.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: type `&!` is non-empty
-  --> $DIR/always-inhabited-union-ref.rs:23:11
+  --> $DIR/always-inhabited-union-ref.rs:26:11
    |
 LL |     match uninhab_ref() {
    |           ^^^^^^^^^^^^^
@@ -14,13 +14,13 @@ LL +     }
    |
 
 error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
-  --> $DIR/always-inhabited-union-ref.rs:27:11
+  --> $DIR/always-inhabited-union-ref.rs:30:11
    |
 LL |     match uninhab_union() {
    |           ^^^^^^^^^^^^^^^
    |
 note: `Foo` defined here
-  --> $DIR/always-inhabited-union-ref.rs:10:11
+  --> $DIR/always-inhabited-union-ref.rs:13:11
    |
 LL | pub union Foo {
    |           ^^^
diff --git a/tests/ui/pattern/usefulness/always-inhabited-union-ref.min_exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/always-inhabited-union-ref.min_exhaustive_patterns.stderr
new file mode 100644
index 00000000000..a1d8002c648
--- /dev/null
+++ b/tests/ui/pattern/usefulness/always-inhabited-union-ref.min_exhaustive_patterns.stderr
@@ -0,0 +1,46 @@
+warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/always-inhabited-union-ref.rs:7:46
+   |
+LL | #![cfg_attr(min_exhaustive_patterns, 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[E0004]: non-exhaustive patterns: type `&!` is non-empty
+  --> $DIR/always-inhabited-union-ref.rs:26:11
+   |
+LL |     match uninhab_ref() {
+   |           ^^^^^^^^^^^^^
+   |
+   = 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 uninhab_ref() {
+LL +         _ => todo!(),
+LL +     }
+   |
+
+error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
+  --> $DIR/always-inhabited-union-ref.rs:30:11
+   |
+LL |     match uninhab_union() {
+   |           ^^^^^^^^^^^^^^^
+   |
+note: `Foo` defined here
+  --> $DIR/always-inhabited-union-ref.rs:13:11
+   |
+LL | pub union Foo {
+   |           ^^^
+   = note: the matched value is of type `Foo`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match uninhab_union() {
+LL +         _ => todo!(),
+LL +     }
+   |
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/always-inhabited-union-ref.rs b/tests/ui/pattern/usefulness/always-inhabited-union-ref.rs
index 7d1cac8a442..247b7f21f68 100644
--- a/tests/ui/pattern/usefulness/always-inhabited-union-ref.rs
+++ b/tests/ui/pattern/usefulness/always-inhabited-union-ref.rs
@@ -1,9 +1,12 @@
+// revisions: min_exhaustive_patterns exhaustive_patterns
+
 // The precise semantics of inhabitedness with respect to unions and references is currently
 // undecided. This test file currently checks a conservative choice.
 
-#![feature(exhaustive_patterns)]
+#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
+#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
+//[min_exhaustive_patterns]~^ WARN the feature `min_exhaustive_patterns` is incomplete
 #![feature(never_type)]
-
 #![allow(dead_code)]
 #![allow(unreachable_code)]
 
diff --git a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr
index 0b4d9972758..59b454d3981 100644
--- a/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr
+++ b/tests/ui/pattern/usefulness/const-partial_eq-fallback-ice.stderr
@@ -9,3 +9,21 @@ LL |     if let CONSTANT = &&MyType {
 
 error: aborting due to 1 previous error
 
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `MyType` in a pattern, `MyType` must be annotated with `#[derive(PartialEq)]`
+  --> $DIR/const-partial_eq-fallback-ice.rs:14:12
+   |
+LL |     if let CONSTANT = &&MyType {
+   |            ^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: the traits must be derived, manual `impl`s are not sufficient
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the lint level is defined here
+  --> $DIR/const-partial_eq-fallback-ice.rs:1:10
+   |
+LL | #![allow(warnings)]
+   |          ^^^^^^^^
+   = note: `#[allow(indirect_structural_match)]` implied by `#[allow(warnings)]`
+
diff --git a/tests/ui/pattern/usefulness/consts-opaque.stderr b/tests/ui/pattern/usefulness/consts-opaque.stderr
index 0b1a2e2736e..6a5bd185e39 100644
--- a/tests/ui/pattern/usefulness/consts-opaque.stderr
+++ b/tests/ui/pattern/usefulness/consts-opaque.stderr
@@ -5,7 +5,7 @@ LL |         QUUX => {}
    |         ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: `#[warn(pointer_structural_match)]` on by default
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
@@ -15,7 +15,7 @@ LL |         QUUX => {}
    |         ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/consts-opaque.rs:108:9
@@ -24,7 +24,7 @@ LL |         WRAPQUUX => {}
    |         ^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/consts-opaque.rs:110:9
@@ -33,7 +33,7 @@ LL |         WRAPQUUX => {}
    |         ^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/consts-opaque.rs:117:9
@@ -42,7 +42,7 @@ LL |         WRAPQUUX => {}
    |         ^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/consts-opaque.rs:127:9
@@ -51,7 +51,7 @@ LL |         WRAPQUUX => {}
    |         ^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/consts-opaque.rs:139:9
@@ -60,7 +60,7 @@ LL |         WHOKNOWSQUUX => {}
    |         ^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/consts-opaque.rs:142:9
@@ -69,7 +69,7 @@ LL |         WHOKNOWSQUUX => {}
    |         ^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 error: unreachable pattern
   --> $DIR/consts-opaque.rs:48:9
@@ -166,3 +166,91 @@ LL |         WRAPQUUX => {}, Wrap(_) => todo!()
 error: aborting due to 10 previous errors; 8 warnings emitted
 
 For more information about this error, try `rustc --explain E0004`.
+Future incompatibility report: Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/consts-opaque.rs:96:9
+   |
+LL |         QUUX => {}
+   |         ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/consts-opaque.rs:98:9
+   |
+LL |         QUUX => {}
+   |         ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/consts-opaque.rs:108:9
+   |
+LL |         WRAPQUUX => {}
+   |         ^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/consts-opaque.rs:110:9
+   |
+LL |         WRAPQUUX => {}
+   |         ^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/consts-opaque.rs:117:9
+   |
+LL |         WRAPQUUX => {}
+   |         ^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/consts-opaque.rs:127:9
+   |
+LL |         WRAPQUUX => {}
+   |         ^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/consts-opaque.rs:139:9
+   |
+LL |         WHOKNOWSQUUX => {}
+   |         ^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/consts-opaque.rs:142:9
+   |
+LL |         WHOKNOWSQUUX => {}
+   |         ^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
index 304435cb21e..4c434192431 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.exhaustive_patterns.stderr
@@ -43,18 +43,18 @@ help: you might want to use `if let` to ignore the variant that isn't matched
 LL |     if let None = x { todo!() };
    |     ++              +++++++++++
 
-error[E0004]: non-exhaustive patterns: `_` not covered
+error[E0004]: non-exhaustive patterns: `0_u8..=u8::MAX` not covered
   --> $DIR/empty-match-check-notes.rs:45:11
    |
 LL |     match 0u8 {
-   |           ^^^ pattern `_` not covered
+   |           ^^^ pattern `0_u8..=u8::MAX` not covered
    |
    = note: the matched value is of type `u8`
    = 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!()
+LL +         0_u8..=u8::MAX => todo!()
    |
 
 error: aborting due to 6 previous errors
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
index 40494b726f0..45f715dc7b2 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.normal.stderr
@@ -42,18 +42,18 @@ help: you might want to use `if let` to ignore the variant that isn't matched
 LL |     if let None = x { todo!() };
    |     ++              +++++++++++
 
-error[E0004]: non-exhaustive patterns: `_` not covered
+error[E0004]: non-exhaustive patterns: `0_u8..=u8::MAX` not covered
   --> $DIR/empty-match-check-notes.rs:45:11
    |
 LL |     match 0u8 {
-   |           ^^^ pattern `_` not covered
+   |           ^^^ pattern `0_u8..=u8::MAX` not covered
    |
    = note: the matched value is of type `u8`
    = 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!()
+LL +         0_u8..=u8::MAX => todo!()
    |
 
 error: aborting due to 6 previous errors
diff --git a/tests/ui/pattern/usefulness/empty-match-check-notes.rs b/tests/ui/pattern/usefulness/empty-match-check-notes.rs
index ee9ff3dcf90..c30cdfc2e4f 100644
--- a/tests/ui/pattern/usefulness/empty-match-check-notes.rs
+++ b/tests/ui/pattern/usefulness/empty-match-check-notes.rs
@@ -43,10 +43,10 @@ fn empty_foreign_enum_private(x: Option<empty::SecretlyUninhabitedForeignStruct>
 
 fn main() {
     match 0u8 {
-        //~^ ERROR `_` not covered
+        //~^ ERROR not covered
         //~| NOTE the matched value is of type
         //~| NOTE match arms with guards don't count towards exhaustivity
-        //~| NOTE pattern `_` not covered
+        //~| NOTE not covered
         _ if false => {}
     }
 }
diff --git a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
index 9c3bebd7797..5f895fab0fb 100644
--- a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
@@ -7,9 +7,36 @@ LL |     match_no_arms!(0u8);
    = note: the matched value is of type `u8`
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
-error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty
+error[E0004]: non-exhaustive patterns: type `i8` is non-empty
   --> $DIR/empty-match.rs:47:20
    |
+LL |     match_no_arms!(0i8);
+   |                    ^^^
+   |
+   = note: the matched value is of type `i8`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
+
+error[E0004]: non-exhaustive patterns: type `usize` is non-empty
+  --> $DIR/empty-match.rs:48:20
+   |
+LL |     match_no_arms!(0usize);
+   |                    ^^^^^^
+   |
+   = note: the matched value is of type `usize`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
+
+error[E0004]: non-exhaustive patterns: type `isize` is non-empty
+  --> $DIR/empty-match.rs:49:20
+   |
+LL |     match_no_arms!(0isize);
+   |                    ^^^^^^
+   |
+   = note: the matched value is of type `isize`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
+
+error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty
+  --> $DIR/empty-match.rs:50:20
+   |
 LL |     match_no_arms!(NonEmptyStruct1);
    |                    ^^^^^^^^^^^^^^^
    |
@@ -22,7 +49,7 @@ LL |     struct NonEmptyStruct1;
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyStruct2` is non-empty
-  --> $DIR/empty-match.rs:48:20
+  --> $DIR/empty-match.rs:51:20
    |
 LL |     match_no_arms!(NonEmptyStruct2(true));
    |                    ^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +63,7 @@ LL |     struct NonEmptyStruct2(bool);
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty
-  --> $DIR/empty-match.rs:49:20
+  --> $DIR/empty-match.rs:52:20
    |
 LL |     match_no_arms!((NonEmptyUnion1 { foo: () }));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +77,7 @@ LL |     union NonEmptyUnion1 {
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty
-  --> $DIR/empty-match.rs:50:20
+  --> $DIR/empty-match.rs:53:20
    |
 LL |     match_no_arms!((NonEmptyUnion2 { foo: () }));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +91,7 @@ LL |     union NonEmptyUnion2 {
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
-  --> $DIR/empty-match.rs:51:20
+  --> $DIR/empty-match.rs:54:20
    |
 LL |     match_no_arms!(NonEmptyEnum1::Foo(true));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@@ -80,7 +107,7 @@ LL |         Foo(bool),
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
-  --> $DIR/empty-match.rs:52:20
+  --> $DIR/empty-match.rs:55:20
    |
 LL |     match_no_arms!(NonEmptyEnum2::Foo(true));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@@ -98,7 +125,7 @@ LL |         Bar,
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
-  --> $DIR/empty-match.rs:53:20
+  --> $DIR/empty-match.rs:56:20
    |
 LL |     match_no_arms!(NonEmptyEnum5::V1);
    |                    ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@@ -121,22 +148,64 @@ LL |         V5,
    = note: the matched value is of type `NonEmptyEnum5`
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
 
-error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/empty-match.rs:55:24
+error[E0004]: non-exhaustive patterns: `0_u8..=u8::MAX` not covered
+  --> $DIR/empty-match.rs:58:24
    |
 LL |     match_guarded_arm!(0u8);
-   |                        ^^^ pattern `_` not covered
+   |                        ^^^ pattern `0_u8..=u8::MAX` not covered
    |
    = note: the matched value is of type `u8`
    = 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 +                 0_u8..=u8::MAX => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `i8::MIN..=i8::MAX` not covered
+  --> $DIR/empty-match.rs:59:24
+   |
+LL |     match_guarded_arm!(0i8);
+   |                        ^^^ pattern `i8::MIN..=i8::MAX` not covered
+   |
+   = note: the matched value is of type `i8`
+   = 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 +                 i8::MIN..=i8::MAX => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `0_usize..` not covered
+  --> $DIR/empty-match.rs:60:24
+   |
+LL |     match_guarded_arm!(0usize);
+   |                        ^^^^^^ pattern `0_usize..` not covered
+   |
+   = note: the matched value is of type `usize`
+   = 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 +                 0_usize.. => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/empty-match.rs:61:24
+   |
+LL |     match_guarded_arm!(0isize);
+   |                        ^^^^^^ pattern `_` not covered
+   |
+   = note: the matched value is of type `isize`
+   = 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[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
-  --> $DIR/empty-match.rs:56:24
+  --> $DIR/empty-match.rs:62:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct1);
    |                        ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
@@ -155,7 +224,7 @@ LL +                 NonEmptyStruct1 => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
-  --> $DIR/empty-match.rs:57:24
+  --> $DIR/empty-match.rs:63:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct2(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
@@ -174,7 +243,7 @@ LL +                 NonEmptyStruct2(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
-  --> $DIR/empty-match.rs:58:24
+  --> $DIR/empty-match.rs:64:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion1 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
@@ -193,7 +262,7 @@ LL +                 NonEmptyUnion1 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
-  --> $DIR/empty-match.rs:59:24
+  --> $DIR/empty-match.rs:65:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion2 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
@@ -212,7 +281,7 @@ LL +                 NonEmptyUnion2 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
-  --> $DIR/empty-match.rs:60:24
+  --> $DIR/empty-match.rs:66:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum1::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@@ -233,7 +302,7 @@ LL +                 NonEmptyEnum1::Foo(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
-  --> $DIR/empty-match.rs:61:24
+  --> $DIR/empty-match.rs:67:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum2::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@@ -256,7 +325,7 @@ LL +                 NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
-  --> $DIR/empty-match.rs:62:24
+  --> $DIR/empty-match.rs:68:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum5::V1);
    |                        ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@@ -284,6 +353,6 @@ LL ~                 _ if false => {},
 LL +                 _ => todo!()
    |
 
-error: aborting due to 16 previous errors
+error: aborting due to 22 previous errors
 
 For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/empty-match.normal.stderr b/tests/ui/pattern/usefulness/empty-match.normal.stderr
index 9c3bebd7797..5f895fab0fb 100644
--- a/tests/ui/pattern/usefulness/empty-match.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-match.normal.stderr
@@ -7,9 +7,36 @@ LL |     match_no_arms!(0u8);
    = note: the matched value is of type `u8`
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
-error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty
+error[E0004]: non-exhaustive patterns: type `i8` is non-empty
   --> $DIR/empty-match.rs:47:20
    |
+LL |     match_no_arms!(0i8);
+   |                    ^^^
+   |
+   = note: the matched value is of type `i8`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
+
+error[E0004]: non-exhaustive patterns: type `usize` is non-empty
+  --> $DIR/empty-match.rs:48:20
+   |
+LL |     match_no_arms!(0usize);
+   |                    ^^^^^^
+   |
+   = note: the matched value is of type `usize`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
+
+error[E0004]: non-exhaustive patterns: type `isize` is non-empty
+  --> $DIR/empty-match.rs:49:20
+   |
+LL |     match_no_arms!(0isize);
+   |                    ^^^^^^
+   |
+   = note: the matched value is of type `isize`
+   = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
+
+error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty
+  --> $DIR/empty-match.rs:50:20
+   |
 LL |     match_no_arms!(NonEmptyStruct1);
    |                    ^^^^^^^^^^^^^^^
    |
@@ -22,7 +49,7 @@ LL |     struct NonEmptyStruct1;
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyStruct2` is non-empty
-  --> $DIR/empty-match.rs:48:20
+  --> $DIR/empty-match.rs:51:20
    |
 LL |     match_no_arms!(NonEmptyStruct2(true));
    |                    ^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +63,7 @@ LL |     struct NonEmptyStruct2(bool);
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty
-  --> $DIR/empty-match.rs:49:20
+  --> $DIR/empty-match.rs:52:20
    |
 LL |     match_no_arms!((NonEmptyUnion1 { foo: () }));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +77,7 @@ LL |     union NonEmptyUnion1 {
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty
-  --> $DIR/empty-match.rs:50:20
+  --> $DIR/empty-match.rs:53:20
    |
 LL |     match_no_arms!((NonEmptyUnion2 { foo: () }));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +91,7 @@ LL |     union NonEmptyUnion2 {
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
-  --> $DIR/empty-match.rs:51:20
+  --> $DIR/empty-match.rs:54:20
    |
 LL |     match_no_arms!(NonEmptyEnum1::Foo(true));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@@ -80,7 +107,7 @@ LL |         Foo(bool),
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
-  --> $DIR/empty-match.rs:52:20
+  --> $DIR/empty-match.rs:55:20
    |
 LL |     match_no_arms!(NonEmptyEnum2::Foo(true));
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@@ -98,7 +125,7 @@ LL |         Bar,
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
-  --> $DIR/empty-match.rs:53:20
+  --> $DIR/empty-match.rs:56:20
    |
 LL |     match_no_arms!(NonEmptyEnum5::V1);
    |                    ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@@ -121,22 +148,64 @@ LL |         V5,
    = note: the matched value is of type `NonEmptyEnum5`
    = help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
 
-error[E0004]: non-exhaustive patterns: `_` not covered
-  --> $DIR/empty-match.rs:55:24
+error[E0004]: non-exhaustive patterns: `0_u8..=u8::MAX` not covered
+  --> $DIR/empty-match.rs:58:24
    |
 LL |     match_guarded_arm!(0u8);
-   |                        ^^^ pattern `_` not covered
+   |                        ^^^ pattern `0_u8..=u8::MAX` not covered
    |
    = note: the matched value is of type `u8`
    = 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 +                 0_u8..=u8::MAX => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `i8::MIN..=i8::MAX` not covered
+  --> $DIR/empty-match.rs:59:24
+   |
+LL |     match_guarded_arm!(0i8);
+   |                        ^^^ pattern `i8::MIN..=i8::MAX` not covered
+   |
+   = note: the matched value is of type `i8`
+   = 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 +                 i8::MIN..=i8::MAX => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `0_usize..` not covered
+  --> $DIR/empty-match.rs:60:24
+   |
+LL |     match_guarded_arm!(0usize);
+   |                        ^^^^^^ pattern `0_usize..` not covered
+   |
+   = note: the matched value is of type `usize`
+   = 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 +                 0_usize.. => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/empty-match.rs:61:24
+   |
+LL |     match_guarded_arm!(0isize);
+   |                        ^^^^^^ pattern `_` not covered
+   |
+   = note: the matched value is of type `isize`
+   = 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[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
-  --> $DIR/empty-match.rs:56:24
+  --> $DIR/empty-match.rs:62:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct1);
    |                        ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
@@ -155,7 +224,7 @@ LL +                 NonEmptyStruct1 => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
-  --> $DIR/empty-match.rs:57:24
+  --> $DIR/empty-match.rs:63:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct2(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
@@ -174,7 +243,7 @@ LL +                 NonEmptyStruct2(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
-  --> $DIR/empty-match.rs:58:24
+  --> $DIR/empty-match.rs:64:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion1 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
@@ -193,7 +262,7 @@ LL +                 NonEmptyUnion1 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
-  --> $DIR/empty-match.rs:59:24
+  --> $DIR/empty-match.rs:65:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion2 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
@@ -212,7 +281,7 @@ LL +                 NonEmptyUnion2 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
-  --> $DIR/empty-match.rs:60:24
+  --> $DIR/empty-match.rs:66:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum1::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@@ -233,7 +302,7 @@ LL +                 NonEmptyEnum1::Foo(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
-  --> $DIR/empty-match.rs:61:24
+  --> $DIR/empty-match.rs:67:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum2::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@@ -256,7 +325,7 @@ LL +                 NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
-  --> $DIR/empty-match.rs:62:24
+  --> $DIR/empty-match.rs:68:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum5::V1);
    |                        ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@@ -284,6 +353,6 @@ LL ~                 _ if false => {},
 LL +                 _ => todo!()
    |
 
-error: aborting due to 16 previous errors
+error: aborting due to 22 previous errors
 
 For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/empty-match.rs b/tests/ui/pattern/usefulness/empty-match.rs
index 321f24adc46..20ab702c9c8 100644
--- a/tests/ui/pattern/usefulness/empty-match.rs
+++ b/tests/ui/pattern/usefulness/empty-match.rs
@@ -44,6 +44,9 @@ fn nonempty() {
     }
 
     match_no_arms!(0u8); //~ ERROR type `u8` is non-empty
+    match_no_arms!(0i8); //~ ERROR type `i8` is non-empty
+    match_no_arms!(0usize); //~ ERROR type `usize` is non-empty
+    match_no_arms!(0isize); //~ ERROR type `isize` is non-empty
     match_no_arms!(NonEmptyStruct1); //~ ERROR type `NonEmptyStruct1` is non-empty
     match_no_arms!(NonEmptyStruct2(true)); //~ ERROR type `NonEmptyStruct2` is non-empty
     match_no_arms!((NonEmptyUnion1 { foo: () })); //~ ERROR type `NonEmptyUnion1` is non-empty
@@ -52,7 +55,10 @@ fn nonempty() {
     match_no_arms!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
     match_no_arms!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
 
-    match_guarded_arm!(0u8); //~ ERROR `_` not covered
+    match_guarded_arm!(0u8); //~ ERROR `0_u8..=u8::MAX` not covered
+    match_guarded_arm!(0i8); //~ ERROR `i8::MIN..=i8::MAX` not covered
+    match_guarded_arm!(0usize); //~ ERROR `0_usize..` not covered
+    match_guarded_arm!(0isize); //~ ERROR `_` not covered
     match_guarded_arm!(NonEmptyStruct1); //~ ERROR `NonEmptyStruct1` not covered
     match_guarded_arm!(NonEmptyStruct2(true)); //~ ERROR `NonEmptyStruct2(_)` not covered
     match_guarded_arm!((NonEmptyUnion1 { foo: () })); //~ ERROR `NonEmptyUnion1 { .. }` not covered
diff --git a/tests/ui/pattern/usefulness/match-privately-empty.stderr b/tests/ui/pattern/usefulness/match-privately-empty.exhaustive_patterns.stderr
index d760790dff6..708a1511244 100644
--- a/tests/ui/pattern/usefulness/match-privately-empty.stderr
+++ b/tests/ui/pattern/usefulness/match-privately-empty.exhaustive_patterns.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
-  --> $DIR/match-privately-empty.rs:13:11
+  --> $DIR/match-privately-empty.rs:16:11
    |
 LL |     match private::DATA {
    |           ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
@@ -12,7 +12,7 @@ note: `Option<Private>` defined here
    = note: the matched value is of type `Option<Private>`
 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 ~         Some(private::Private { misc: false, .. }) => {},
 LL +         Some(Private { misc: true, .. }) => todo!()
    |
 
diff --git a/tests/ui/pattern/usefulness/match-privately-empty.min_exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/match-privately-empty.min_exhaustive_patterns.stderr
new file mode 100644
index 00000000000..a6ce02c0c3c
--- /dev/null
+++ b/tests/ui/pattern/usefulness/match-privately-empty.min_exhaustive_patterns.stderr
@@ -0,0 +1,30 @@
+warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/match-privately-empty.rs:3:46
+   |
+LL | #![cfg_attr(min_exhaustive_patterns, 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[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
+  --> $DIR/match-privately-empty.rs:16:11
+   |
+LL |     match private::DATA {
+   |           ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` not covered
+   |
+note: `Option<Private>` 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<Private>`
+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 ~         Some(private::Private { misc: false, .. }) => {},
+LL +         Some(Private { misc: true, .. }) => todo!()
+   |
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/match-privately-empty.rs b/tests/ui/pattern/usefulness/match-privately-empty.rs
index 315eb03d165..67a9aa2e916 100644
--- a/tests/ui/pattern/usefulness/match-privately-empty.rs
+++ b/tests/ui/pattern/usefulness/match-privately-empty.rs
@@ -1,5 +1,8 @@
+// revisions: min_exhaustive_patterns exhaustive_patterns
+#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
+#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
+//[min_exhaustive_patterns]~^ WARN the feature `min_exhaustive_patterns` is incomplete
 #![feature(never_type)]
-#![feature(exhaustive_patterns)]
 
 mod private {
     pub struct Private {
@@ -11,11 +14,8 @@ mod private {
 
 fn main() {
     match private::DATA {
-    //~^ ERROR non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
+        //~^ ERROR non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered
         None => {}
-        Some(private::Private {
-            misc: false,
-            ..
-        }) => {}
+        Some(private::Private { misc: false, .. }) => {}
     }
 }
diff --git a/tests/ui/pattern/usefulness/slice_of_empty.stderr b/tests/ui/pattern/usefulness/slice_of_empty.exhaustive_patterns.stderr
index d56360d4cec..9770f680b2d 100644
--- a/tests/ui/pattern/usefulness/slice_of_empty.stderr
+++ b/tests/ui/pattern/usefulness/slice_of_empty.exhaustive_patterns.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `&[]` not covered
-  --> $DIR/slice_of_empty.rs:18:11
+  --> $DIR/slice_of_empty.rs:22:11
    |
 LL |     match nevers {
    |           ^^^^^^ pattern `&[]` not covered
diff --git a/tests/ui/pattern/usefulness/slice_of_empty.min_exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/slice_of_empty.min_exhaustive_patterns.stderr
new file mode 100644
index 00000000000..3b9e71f50d5
--- /dev/null
+++ b/tests/ui/pattern/usefulness/slice_of_empty.min_exhaustive_patterns.stderr
@@ -0,0 +1,38 @@
+warning: the feature `min_exhaustive_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/slice_of_empty.rs:3:46
+   |
+LL | #![cfg_attr(min_exhaustive_patterns, 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[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
+  --> $DIR/slice_of_empty.rs:11:11
+   |
+LL |     match nevers {
+   |           ^^^^^^ 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/slice_of_empty.rs:22:11
+   |
+LL |     match nevers {
+   |           ^^^^^^ 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: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/pattern/usefulness/slice_of_empty.rs b/tests/ui/pattern/usefulness/slice_of_empty.rs
index 3cbd0eba57f..5f64dd3fecc 100644
--- a/tests/ui/pattern/usefulness/slice_of_empty.rs
+++ b/tests/ui/pattern/usefulness/slice_of_empty.rs
@@ -1,11 +1,15 @@
+// revisions: min_exhaustive_patterns exhaustive_patterns
+#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
+#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
+//[min_exhaustive_patterns]~^ WARN the feature `min_exhaustive_patterns` is incomplete
 #![feature(never_type)]
-#![feature(exhaustive_patterns)]
 #![deny(unreachable_patterns)]
 
 fn main() {}
 
 fn foo(nevers: &[!]) {
     match nevers {
+        //[min_exhaustive_patterns]~^ ERROR non-exhaustive patterns: `&[_, ..]` not covered
         &[] => (),
     };
 
@@ -16,7 +20,8 @@ fn foo(nevers: &[!]) {
     };
 
     match nevers {
-        //~^ ERROR non-exhaustive patterns: `&[]` not covered
+        //[exhaustive_patterns]~^ ERROR non-exhaustive patterns: `&[]` not covered
+        //[min_exhaustive_patterns]~^^ ERROR non-exhaustive patterns: `&[]` and `&[_, _, ..]` not covered
         &[_] => (),
     };
 }
diff --git a/tests/ui/precondition-checks/misaligned-slice.rs b/tests/ui/precondition-checks/misaligned-slice.rs
new file mode 100644
index 00000000000..c961c800352
--- /dev/null
+++ b/tests/ui/precondition-checks/misaligned-slice.rs
@@ -0,0 +1,11 @@
+// run-fail
+// compile-flags: -Copt-level=3 -Cdebug-assertions=yes
+// error-pattern: unsafe precondition(s) violated: slice::from_raw_parts
+// ignore-debug
+// ignore-wasm32-bare no panic messages
+
+fn main() {
+    unsafe {
+        let _s: &[u64] = std::slice::from_raw_parts(1usize as *const u64, 0);
+    }
+}
diff --git a/tests/ui/precondition-checks/null-slice.rs b/tests/ui/precondition-checks/null-slice.rs
new file mode 100644
index 00000000000..1e67e7f5fb1
--- /dev/null
+++ b/tests/ui/precondition-checks/null-slice.rs
@@ -0,0 +1,11 @@
+// run-fail
+// compile-flags: -Copt-level=3 -Cdebug-assertions=yes
+// error-pattern: unsafe precondition(s) violated: slice::from_raw_parts
+// ignore-debug
+// ignore-wasm32-bare no panic messages
+
+fn main() {
+    unsafe {
+        let _s: &[u8] = std::slice::from_raw_parts(std::ptr::null(), 0);
+    }
+}
diff --git a/tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs b/tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs
new file mode 100644
index 00000000000..1366ba28f1c
--- /dev/null
+++ b/tests/ui/precondition-checks/out-of-bounds-get-unchecked.rs
@@ -0,0 +1,12 @@
+// run-fail
+// compile-flags: -Copt-level=3 -Cdebug-assertions=yes
+// error-pattern: unsafe precondition(s) violated: hint::assert_unchecked
+// ignore-debug
+// ignore-wasm32-bare no panic messages
+
+fn main() {
+    unsafe {
+        let sli: &[u8] = &[0];
+        sli.get_unchecked(1);
+    }
+}
diff --git a/tests/ui/print_type_sizes/niche-filling.rs b/tests/ui/print_type_sizes/niche-filling.rs
index 5ee5085ddc8..feb9643850d 100644
--- a/tests/ui/print_type_sizes/niche-filling.rs
+++ b/tests/ui/print_type_sizes/niche-filling.rs
@@ -1,5 +1,5 @@
-// compile-flags: -Z print-type-sizes --crate-type=lib
-// ignore-debug debug assertions will print more types
+// compile-flags: -Z print-type-sizes --crate-type lib
+// ignore-debug: debug assertions will print more types
 // build-pass
 // ignore-pass
 // ^-- needed because `--pass check` does not emit the output needed.
diff --git a/tests/ui/print_type_sizes/niche-filling.stdout b/tests/ui/print_type_sizes/niche-filling.stdout
index b53b8936603..53a58ccc4ee 100644
--- a/tests/ui/print_type_sizes/niche-filling.stdout
+++ b/tests/ui/print_type_sizes/niche-filling.stdout
@@ -70,6 +70,10 @@ 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::NonZero<u32>`: 4 bytes, alignment: 4 bytes
 print-type-size     field `.0`: 4 bytes
+print-type-size type: `std::option::Option<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: `Enum4<(), (), (), MyOption<u8>>`: 2 bytes, alignment: 1 bytes
 print-type-size     variant `Four`: 2 bytes
 print-type-size         field `.0`: 2 bytes
diff --git a/tests/ui/privacy/associated-item-privacy-trait.stderr b/tests/ui/privacy/associated-item-privacy-trait.stderr
index 4e9dfa4a835..f79c4cff72f 100644
--- a/tests/ui/privacy/associated-item-privacy-trait.stderr
+++ b/tests/ui/privacy/associated-item-privacy-trait.stderr
@@ -75,17 +75,6 @@ LL |     priv_trait::mac!();
    |
    = note: this error originates in the macro `priv_trait::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: trait `PrivTr` is private
-  --> $DIR/associated-item-privacy-trait.rs:29:14
-   |
-LL |         impl PrivTr for u8 {}
-   |              ^^^^^^ private trait
-...
-LL |     priv_trait::mac!();
-   |     ------------------ in this macro invocation
-   |
-   = note: this error originates in the macro `priv_trait::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
-
 error: type `priv_signature::Priv` is private
   --> $DIR/associated-item-privacy-trait.rs:46:21
    |
@@ -328,5 +317,16 @@ LL |     priv_parent_substs::mac!();
    |
    = note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
+error: trait `PrivTr` is private
+  --> $DIR/associated-item-privacy-trait.rs:29:14
+   |
+LL |         impl PrivTr for u8 {}
+   |              ^^^^^^ private trait
+...
+LL |     priv_trait::mac!();
+   |     ------------------ in this macro invocation
+   |
+   = note: this error originates in the macro `priv_trait::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
+
 error: aborting due to 30 previous errors
 
diff --git a/tests/ui/privacy/associated-item-privacy-type-binding.stderr b/tests/ui/privacy/associated-item-privacy-type-binding.stderr
index de9893816fa..52bfa3c2ab8 100644
--- a/tests/ui/privacy/associated-item-privacy-type-binding.stderr
+++ b/tests/ui/privacy/associated-item-privacy-type-binding.stderr
@@ -32,10 +32,10 @@ LL |     priv_trait::mac1!();
    = note: this error originates in the macro `priv_trait::mac1` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: trait `PrivTr` is private
-  --> $DIR/associated-item-privacy-type-binding.rs:16:31
+  --> $DIR/associated-item-privacy-type-binding.rs:16:37
    |
 LL |         trait InSignatureTr2: PubTr<AssocTy = u8> {}
-   |                               ^^^^^^^^^^^^^^^^^^^ private trait
+   |                                     ^^^^^^^^^^^^ private trait
 ...
 LL |     priv_trait::mac1!();
    |     ------------------- in this macro invocation
@@ -164,10 +164,10 @@ LL |     priv_parent_substs::mac!();
    = note: this error originates in the macro `priv_parent_substs::mac` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: type `Priv` is private
-  --> $DIR/associated-item-privacy-type-binding.rs:56:31
+  --> $DIR/associated-item-privacy-type-binding.rs:56:37
    |
 LL |         trait InSignatureTr2: PubTr<AssocTy = u8> {}
-   |                               ^^^^^^^^^^^^^^^^^^^ private type
+   |                                     ^^^^^^^^^^^^ private type
 ...
 LL |     priv_parent_substs::mac!();
    |     -------------------------- in this macro invocation
diff --git a/tests/ui/issues/auxiliary/private-trait-xc.rs b/tests/ui/privacy/auxiliary/private-trait-xc.rs
index 481a48a7cd8..481a48a7cd8 100644
--- a/tests/ui/issues/auxiliary/private-trait-xc.rs
+++ b/tests/ui/privacy/auxiliary/private-trait-xc.rs
diff --git a/tests/ui/issues/issue-11593.rs b/tests/ui/privacy/issue-11593.rs
index 8bf034e8203..8bf034e8203 100644
--- a/tests/ui/issues/issue-11593.rs
+++ b/tests/ui/privacy/issue-11593.rs
diff --git a/tests/ui/issues/issue-11593.stderr b/tests/ui/privacy/issue-11593.stderr
index 8262bc9321a..8262bc9321a 100644
--- a/tests/ui/issues/issue-11593.stderr
+++ b/tests/ui/privacy/issue-11593.stderr
diff --git a/tests/ui/privacy/private-type-in-interface.stderr b/tests/ui/privacy/private-type-in-interface.stderr
index a5e80d6962d..091cae42dea 100644
--- a/tests/ui/privacy/private-type-in-interface.stderr
+++ b/tests/ui/privacy/private-type-in-interface.stderr
@@ -47,10 +47,10 @@ LL | fn g() -> impl Tr2<m::Alias> { 0 }
    |           ^^^^^^^^^^^^^^^^^^ private type
 
 error: type `Priv` is private
-  --> $DIR/private-type-in-interface.rs:28:16
+  --> $DIR/private-type-in-interface.rs:28:11
    |
 LL | fn g() -> impl Tr2<m::Alias> { 0 }
-   |                ^^^^^^^^^^^^^ private type
+   |           ^^^^^^^^^^^^^^^^^^ private type
 
 error: type `ext::Priv` is private
   --> $DIR/private-type-in-interface.rs:30:15
@@ -59,10 +59,10 @@ LL | fn g_ext() -> impl Tr2<ext::Alias> { 0 }
    |               ^^^^^^^^^^^^^^^^^^^^ private type
 
 error: type `ext::Priv` is private
-  --> $DIR/private-type-in-interface.rs:30:20
+  --> $DIR/private-type-in-interface.rs:30:15
    |
 LL | fn g_ext() -> impl Tr2<ext::Alias> { 0 }
-   |                    ^^^^^^^^^^^^^^^ private type
+   |               ^^^^^^^^^^^^^^^^^^^^ private type
 
 error: aborting due to 11 previous errors
 
diff --git a/tests/ui/privacy/projections.rs b/tests/ui/privacy/projections.rs
new file mode 100644
index 00000000000..0e6590de4f5
--- /dev/null
+++ b/tests/ui/privacy/projections.rs
@@ -0,0 +1,60 @@
+mod m {
+    struct Priv;
+    pub type Leak = Priv; //~ WARN: `Priv` is more private than the item `Leak`
+}
+
+trait Trait {
+    type A<T>;
+}
+
+impl Trait for u8 {
+    type A<T> = u8;
+}
+
+fn check() -> <u8 as Trait>::A<m::Leak> {
+    //~^ ERROR: `Priv` is private
+    0
+}
+
+trait Trait2 {
+    type A<T>;
+}
+
+impl Trait2 for u8 {
+    type A<T> = m::Leak;
+    //~^ ERROR: `Priv` is private
+    //~| ERROR: private type `Priv` in public interface
+}
+
+fn check2() -> <u8 as Trait2>::A<u32> {
+    //~^ ERROR: `Priv` is private
+    todo!()
+}
+
+trait Trait3 {
+    type A<T: Trait>;
+}
+
+impl Trait3 for u8 {
+    type A<T: Trait> = T::A<m::Leak>;
+    //~^ ERROR: `Priv` is private
+    //~| ERROR: private type `Priv` in public interface
+}
+
+fn check3() -> <u8 as Trait3>::A<u8> {
+    todo!()
+}
+
+trait Trait4 {
+    type A<T: Trait3>;
+}
+
+impl Trait4 for u8 {
+    type A<T: Trait3> = T::A<u8>;
+}
+
+fn check4() -> <u8 as Trait4>::A<u8> {
+    todo!()
+}
+
+fn main() {}
diff --git a/tests/ui/privacy/projections.stderr b/tests/ui/privacy/projections.stderr
new file mode 100644
index 00000000000..010d77998e3
--- /dev/null
+++ b/tests/ui/privacy/projections.stderr
@@ -0,0 +1,62 @@
+warning: type `Priv` is more private than the item `Leak`
+  --> $DIR/projections.rs:3:5
+   |
+LL |     pub type Leak = Priv;
+   |     ^^^^^^^^^^^^^ type alias `Leak` is reachable at visibility `pub(crate)`
+   |
+note: but type `Priv` is only usable at visibility `pub(self)`
+  --> $DIR/projections.rs:2:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
+
+error[E0446]: private type `Priv` in public interface
+  --> $DIR/projections.rs:24:5
+   |
+LL |     struct Priv;
+   |     ----------- `Priv` declared as private
+...
+LL |     type A<T> = m::Leak;
+   |     ^^^^^^^^^ can't leak private type
+
+error[E0446]: private type `Priv` in public interface
+  --> $DIR/projections.rs:39:5
+   |
+LL |     struct Priv;
+   |     ----------- `Priv` declared as private
+...
+LL |     type A<T: Trait> = T::A<m::Leak>;
+   |     ^^^^^^^^^^^^^^^^ can't leak private type
+
+error: type `Priv` is private
+  --> $DIR/projections.rs:14:15
+   |
+LL | fn check() -> <u8 as Trait>::A<m::Leak> {
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^ private type
+
+error: type `Priv` is private
+  --> $DIR/projections.rs:29:39
+   |
+LL |   fn check2() -> <u8 as Trait2>::A<u32> {
+   |  _______________________________________^
+LL | |
+LL | |     todo!()
+LL | | }
+   | |_^ private type
+
+error: type `Priv` is private
+  --> $DIR/projections.rs:24:17
+   |
+LL |     type A<T> = m::Leak;
+   |                 ^^^^^^^ private type
+
+error: type `Priv` is private
+  --> $DIR/projections.rs:39:24
+   |
+LL |     type A<T: Trait> = T::A<m::Leak>;
+   |                        ^^^^^^^^^^^^^ private type
+
+error: aborting due to 6 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/privacy/projections2.rs b/tests/ui/privacy/projections2.rs
new file mode 100644
index 00000000000..1afbf6d196e
--- /dev/null
+++ b/tests/ui/privacy/projections2.rs
@@ -0,0 +1,38 @@
+mod m {
+    use super::*;
+    struct Priv;
+    pub type Leak = Priv; //~ WARN: `Priv` is more private than the item `Leak`
+
+    trait Trait3 {
+        type A<T: Trait>;
+    }
+
+    impl Trait3 for u8 {
+        type A<T: Trait> = T::A<Leak>;
+    }
+
+    pub trait Trait4 {
+        type A<T: Trait>;
+    }
+
+    impl Trait4 for u8 {
+        type A<T: Trait> = <u8 as Trait3>::A<T>;
+        //~^ ERROR: private associated type `Trait3::A` in public interface
+        //~| ERROR: private trait `Trait3` in public interface
+    }
+}
+
+pub trait Trait {
+    type A<T>;
+}
+
+impl Trait for u8 {
+    type A<T> = u8;
+}
+use m::*;
+
+fn check4() -> <u8 as Trait4>::A<u8> {
+    todo!()
+}
+
+fn main() {}
diff --git a/tests/ui/privacy/projections2.stderr b/tests/ui/privacy/projections2.stderr
new file mode 100644
index 00000000000..6eae9643c5a
--- /dev/null
+++ b/tests/ui/privacy/projections2.stderr
@@ -0,0 +1,34 @@
+warning: type `Priv` is more private than the item `Leak`
+  --> $DIR/projections2.rs:4:5
+   |
+LL |     pub type Leak = Priv;
+   |     ^^^^^^^^^^^^^ type alias `Leak` is reachable at visibility `pub(crate)`
+   |
+note: but type `Priv` is only usable at visibility `pub(self)`
+  --> $DIR/projections2.rs:3:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
+
+error[E0446]: private associated type `Trait3::A` in public interface
+  --> $DIR/projections2.rs:19:9
+   |
+LL |         type A<T: Trait>;
+   |         ---------------- `Trait3::A` declared as private
+...
+LL |         type A<T: Trait> = <u8 as Trait3>::A<T>;
+   |         ^^^^^^^^^^^^^^^^ can't leak private associated type
+
+error[E0446]: private trait `Trait3` in public interface
+  --> $DIR/projections2.rs:19:9
+   |
+LL |     trait Trait3 {
+   |     ------------ `Trait3` declared as private
+...
+LL |         type A<T: Trait> = <u8 as Trait3>::A<T>;
+   |         ^^^^^^^^^^^^^^^^ can't leak private trait
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0446`.
diff --git a/tests/ui/privacy/sealed-traits/re-exported-trait.fixed b/tests/ui/privacy/sealed-traits/re-exported-trait.fixed
index 79b6a6516ab..6de7b865a99 100644
--- a/tests/ui/privacy/sealed-traits/re-exported-trait.fixed
+++ b/tests/ui/privacy/sealed-traits/re-exported-trait.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 pub mod a {
     pub use self::b::Trait;
diff --git a/tests/ui/privacy/sealed-traits/re-exported-trait.rs b/tests/ui/privacy/sealed-traits/re-exported-trait.rs
index 5f96dfdcbd6..bf07d666dff 100644
--- a/tests/ui/privacy/sealed-traits/re-exported-trait.rs
+++ b/tests/ui/privacy/sealed-traits/re-exported-trait.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 pub mod a {
     pub use self::b::Trait;
diff --git a/tests/ui/privacy/sealed-traits/re-exported-trait.stderr b/tests/ui/privacy/sealed-traits/re-exported-trait.stderr
index 9f2291e6825..6e2f36e3f38 100644
--- a/tests/ui/privacy/sealed-traits/re-exported-trait.stderr
+++ b/tests/ui/privacy/sealed-traits/re-exported-trait.stderr
@@ -1,11 +1,11 @@
 error[E0603]: module `b` is private
-  --> $DIR/re-exported-trait.rs:11:9
+  --> $DIR/re-exported-trait.rs:12:9
    |
 LL | impl a::b::Trait for S {}
    |         ^ private module
    |
 note: the module `b` is defined here
-  --> $DIR/re-exported-trait.rs:5:5
+  --> $DIR/re-exported-trait.rs:6:5
    |
 LL |     mod b {
    |     ^^^^^
diff --git a/tests/ui/privacy/struct-field-type.rs b/tests/ui/privacy/struct-field-type.rs
new file mode 100644
index 00000000000..6a4a19297e1
--- /dev/null
+++ b/tests/ui/privacy/struct-field-type.rs
@@ -0,0 +1,10 @@
+mod m {
+    struct Priv;
+    pub type Leak = Priv; //~ WARN: `Priv` is more private than the item `Leak`
+}
+
+struct S {
+    field: m::Leak, //~ ERROR: `Priv` is private
+}
+
+fn main() {}
diff --git a/tests/ui/privacy/struct-field-type.stderr b/tests/ui/privacy/struct-field-type.stderr
new file mode 100644
index 00000000000..854ff6a98a4
--- /dev/null
+++ b/tests/ui/privacy/struct-field-type.stderr
@@ -0,0 +1,21 @@
+warning: type `Priv` is more private than the item `Leak`
+  --> $DIR/struct-field-type.rs:3:5
+   |
+LL |     pub type Leak = Priv;
+   |     ^^^^^^^^^^^^^ type alias `Leak` is reachable at visibility `pub(crate)`
+   |
+note: but type `Priv` is only usable at visibility `pub(self)`
+  --> $DIR/struct-field-type.rs:2:5
+   |
+LL |     struct Priv;
+   |     ^^^^^^^^^^^
+   = note: `#[warn(private_interfaces)]` on by default
+
+error: type `Priv` is private
+  --> $DIR/struct-field-type.rs:7:5
+   |
+LL |     field: m::Leak,
+   |     ^^^^^ private type
+
+error: aborting due to 1 previous error; 1 warning emitted
+
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
index ae5f9f86726..a61c868ed0a 100644
--- 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
@@ -1,6 +1,7 @@
 // run-rustfix
 
 #[derive(Debug)] //~ ERROR `derive` attribute cannot be used at crate level
+#[allow(dead_code)]
 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
index 639c64f8827..403f4470de7 100644
--- 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
@@ -1,6 +1,7 @@
 // run-rustfix
 
 #![derive(Debug)] //~ ERROR `derive` attribute cannot be used at crate level
+#[allow(dead_code)]
 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
index f62cdd14b87..09908160542 100644
--- 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
@@ -3,6 +3,7 @@ error: `derive` attribute cannot be used at crate level
    |
 LL | #![derive(Debug)]
    | ^^^^^^^^^^^^^^^^^
+LL | #[allow(dead_code)]
 LL | struct Test {}
    |        ---- the inner attribute doesn't annotate this struct
    |
diff --git a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs
index d364c467714..2aa390bfd39 100644
--- a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs
+++ b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs
@@ -5,13 +5,13 @@ fn a<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) where 'b: 'a {
 
 fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
     // Illegal now because there is no `'b:'a` declaration.
-    *x = *y;
+    *x = *y; //~ ERROR: lifetime may not live long enough
 }
 
 fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
     // Here we try to call `foo` but do not know that `'a` and `'b` are
     // related as required.
-    a(x, y);
+    a(x, y); //~ ERROR: lifetime may not live long enough
 }
 
 fn d() {
diff --git a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
index d8269514bef..5a02d01b4e1 100644
--- a/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
+++ b/tests/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr
@@ -9,6 +9,35 @@ LL |     let _: fn(&mut &isize, &mut &isize) = a;
    = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b _, &'c mut &'d _)`
                  found fn item `for<'a, 'b> fn(&'a mut &_, &'b mut &_) {a::<'_, '_>}`
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:8:5
+   |
+LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
+   |      --  -- lifetime `'b` defined here
+   |      |
+   |      lifetime `'a` defined here
+LL |     // Illegal now because there is no `'b:'a` declaration.
+LL |     *x = *y;
+   |     ^^^^^^^ assignment requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:14:5
+   |
+LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
+   |      -- -- lifetime `'b` defined here
+   |      |
+   |      lifetime `'a` defined here
+...
+LL |     a(x, y);
+   |     ^^^^^^^ argument requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+   = note: requirement occurs because of a mutable reference to `&isize`
+   = note: mutable references are invariant over their type parameter
+   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs
index 60dafdd528c..baf1693b0cc 100644
--- a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs
+++ b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs
@@ -6,14 +6,14 @@ fn a<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) where
 
 fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
     // Illegal now because there is no `'b:'a` declaration.
-    *x = *y;
+    *x = *y; //~ ERROR: lifetime may not live long enough
     *z = *y;
 }
 
 fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
     // Here we try to call `foo` but do not know that `'a` and `'b` are
     // related as required.
-    a(x, y, z);
+    a(x, y, z); //~ ERROR: lifetime may not live long enough
 }
 
 fn d() {
diff --git a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
index e383f352b9e..063ff46bb6c 100644
--- a/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
+++ b/tests/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr
@@ -9,6 +9,35 @@ LL |     let _: fn(&mut &isize, &mut &isize, &mut &isize) = a;
    = note: expected fn pointer `for<'a, 'b, 'c, 'd, 'e, 'f> fn(&'a mut &'b _, &'c mut &'d _, &'e mut &'f _)`
                  found fn item `for<'a, 'b, 'c> fn(&'a mut &_, &'b mut &_, &'c mut &_) {a::<'_, '_, '_>}`
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:9:5
+   |
+LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
+   |      --  -- lifetime `'b` defined here
+   |      |
+   |      lifetime `'a` defined here
+LL |     // Illegal now because there is no `'b:'a` declaration.
+LL |     *x = *y;
+   |     ^^^^^^^ assignment requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:5
+   |
+LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
+   |      -- -- lifetime `'b` defined here
+   |      |
+   |      lifetime `'a` defined here
+...
+LL |     a(x, y, z);
+   |     ^^^^^^^^^^ argument requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+   = note: requirement occurs because of a mutable reference to `&isize`
+   = note: mutable references are invariant over their type parameter
+   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/regions/regions-lifetime-bounds-on-fns.rs b/tests/ui/regions/regions-lifetime-bounds-on-fns.rs
index 177f52fa72d..c7b7b52d50d 100644
--- a/tests/ui/regions/regions-lifetime-bounds-on-fns.rs
+++ b/tests/ui/regions/regions-lifetime-bounds-on-fns.rs
@@ -5,13 +5,13 @@ fn a<'a, 'b:'a>(x: &mut &'a isize, y: &mut &'b isize) {
 
 fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
     // Illegal now because there is no `'b:'a` declaration.
-    *x = *y;
+    *x = *y; //~ ERROR: lifetime may not live long enough
 }
 
 fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
     // Here we try to call `foo` but do not know that `'a` and `'b` are
     // related as required.
-    a(x, y);
+    a(x, y); //~ ERROR: lifetime may not live long enough
 }
 
 fn d() {
diff --git a/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr b/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr
index 989e91c702b..830a61a21f9 100644
--- a/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr
+++ b/tests/ui/regions/regions-lifetime-bounds-on-fns.stderr
@@ -9,6 +9,35 @@ LL |     let _: fn(&mut &isize, &mut &isize) = a;
    = note: expected fn pointer `for<'a, 'b, 'c, 'd> fn(&'a mut &'b _, &'c mut &'d _)`
                  found fn item `for<'a, 'b> fn(&'a mut &_, &'b mut &_) {a::<'_, '_>}`
 
-error: aborting due to 1 previous error
+error: lifetime may not live long enough
+  --> $DIR/regions-lifetime-bounds-on-fns.rs:8:5
+   |
+LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
+   |      --  -- lifetime `'b` defined here
+   |      |
+   |      lifetime `'a` defined here
+LL |     // Illegal now because there is no `'b:'a` declaration.
+LL |     *x = *y;
+   |     ^^^^^^^ assignment requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+
+error: lifetime may not live long enough
+  --> $DIR/regions-lifetime-bounds-on-fns.rs:14:5
+   |
+LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
+   |      -- -- lifetime `'b` defined here
+   |      |
+   |      lifetime `'a` defined here
+...
+LL |     a(x, y);
+   |     ^^^^^^^ argument requires that `'b` must outlive `'a`
+   |
+   = help: consider adding the following bound: `'b: 'a`
+   = note: requirement occurs because of a mutable reference to `&isize`
+   = note: mutable references are invariant over their type parameter
+   = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
+
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/regions/regions-no-variance-from-fn-generics.rs b/tests/ui/regions/regions-no-variance-from-fn-generics.rs
index 76706a82781..a455d4efd71 100644
--- a/tests/ui/regions/regions-no-variance-from-fn-generics.rs
+++ b/tests/ui/regions/regions-no-variance-from-fn-generics.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 #![allow(unused_variables)]
 // Issue #12856: a lifetime formal binding introduced by a generic fn
 // should not upset the variance inference for actual occurrences of
diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr
index 4f853829279..fbb9ede8aa1 100644
--- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr
+++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.default.stderr
@@ -5,6 +5,8 @@ LL | fn outer<T: Tr>() { // outer function
    |          - type parameter from outer item
 LL |     const K: u32 = T::C;
    |                    ^^^^ use of generic parameter from outer item
+   |
+   = note: a `const` is a separate item from the item that contains it
 
 error[E0401]: can't use generic parameters from outer item
   --> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24
@@ -14,6 +16,8 @@ LL | impl<T> Tr for T { // outer impl block
 LL |     const C: u32 = {
 LL |         const I: u32 = T::C;
    |                        ^^^^ use of generic parameter from outer item
+   |
+   = note: a `const` is a separate item from the item that contains it
 
 error[E0401]: can't use generic parameters from outer item
   --> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20
@@ -22,6 +26,8 @@ LL | struct S<T: Tr>(U32<{ // outer struct
    |          - type parameter from outer item
 LL |     const _: u32 = T::C;
    |                    ^^^^ use of generic parameter from outer item
+   |
+   = note: a `const` is a separate item from the item that contains it
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr
index 1cb55842bc6..60aa94038c3 100644
--- a/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr
+++ b/tests/ui/resolve/generic-params-from-outer-item-in-const-item.generic_const_items.stderr
@@ -7,6 +7,8 @@ LL |     const K: u32 = T::C;
    |            -       ^^^^ use of generic parameter from outer item
    |            |
    |            help: try introducing a local generic parameter here: `<T>`
+   |
+   = note: a `const` is a separate item from the item that contains it
 
 error[E0401]: can't use generic parameters from outer item
   --> $DIR/generic-params-from-outer-item-in-const-item.rs:19:24
@@ -18,6 +20,8 @@ LL |         const I: u32 = T::C;
    |                -       ^^^^ use of generic parameter from outer item
    |                |
    |                help: try introducing a local generic parameter here: `<T>`
+   |
+   = note: a `const` is a separate item from the item that contains it
 
 error[E0401]: can't use generic parameters from outer item
   --> $DIR/generic-params-from-outer-item-in-const-item.rs:27:20
@@ -28,6 +32,8 @@ LL |     const _: u32 = T::C;
    |            -       ^^^^ use of generic parameter from outer item
    |            |
    |            help: try introducing a local generic parameter here: `<T>`
+   |
+   = note: a `const` is a separate item from the item that contains it
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed
index e730f94660b..a7ab88fe993 100644
--- a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed
+++ b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 
+#![allow(dead_code)]
 #![deny(unused_qualifications)]
 #![feature(unsized_fn_params)]
 
diff --git a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs
index 641c892e3de..05936b191ff 100644
--- a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs
+++ b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 
+#![allow(dead_code)]
 #![deny(unused_qualifications)]
 #![feature(unsized_fn_params)]
 
diff --git a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr
index d9c7fd21871..bcda7210712 100644
--- a/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr
+++ b/tests/ui/resolve/issue-113808-invalid-unused-qualifications-suggestion.stderr
@@ -1,11 +1,11 @@
 error: unnecessary qualification
-  --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:12:6
+  --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:13:6
    |
 LL | impl ops::Index<str> for A {
    |      ^^^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:3:9
+  --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:4:9
    |
 LL | #![deny(unused_qualifications)]
    |         ^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL + impl Index<str> for A {
    |
 
 error: unnecessary qualification
-  --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:28:6
+  --> $DIR/issue-113808-invalid-unused-qualifications-suggestion.rs:29:6
    |
 LL | impl inner::Trait<u8> for () {}
    |      ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/resolve/issue-12796.rs b/tests/ui/resolve/issue-12796.rs
index de3e73437f0..e5dcf964345 100644
--- a/tests/ui/resolve/issue-12796.rs
+++ b/tests/ui/resolve/issue-12796.rs
@@ -1,7 +1,7 @@
 trait Trait {
     fn outer(&self) {
         fn inner(_: &Self) {
-            //~^ ERROR can't use generic parameters from outer item
+            //~^ ERROR can't use `Self` from outer item
         }
     }
 }
diff --git a/tests/ui/resolve/issue-12796.stderr b/tests/ui/resolve/issue-12796.stderr
index 6809fd50f74..2305971303a 100644
--- a/tests/ui/resolve/issue-12796.stderr
+++ b/tests/ui/resolve/issue-12796.stderr
@@ -1,10 +1,10 @@
-error[E0401]: can't use generic parameters from outer item
+error[E0401]: can't use `Self` from outer item
   --> $DIR/issue-12796.rs:3:22
    |
 LL |         fn inner(_: &Self) {
    |                      ^^^^
    |                      |
-   |                      use of generic parameter from outer item
+   |                      use of `Self` from outer item
    |                      can't use `Self` here
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr
index 363bb556478..ca32147d197 100644
--- a/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr
+++ b/tests/ui/resolve/issue-65025-extern-static-parent-generics.stderr
@@ -6,6 +6,8 @@ LL | unsafe fn foo<A>() {
 LL |     extern "C" {
 LL |         static baz: *const A;
    |                            ^ use of generic parameter from outer item
+   |
+   = note: a `static` is a separate item from the item that contains it
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr
index f1fe1a6002c..98ffb4567f1 100644
--- a/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr
+++ b/tests/ui/resolve/issue-65035-static-with-parent-generics.stderr
@@ -6,6 +6,8 @@ LL | fn f<T>() {
 LL |     extern "C" {
 LL |         static a: *const T;
    |                          ^ use of generic parameter from outer item
+   |
+   = note: a `static` is a separate item from the item that contains it
 
 error[E0401]: can't use generic parameters from outer item
   --> $DIR/issue-65035-static-with-parent-generics.rs:9:22
@@ -14,6 +16,8 @@ LL | fn g<T: Default>() {
    |      - type parameter from outer item
 LL |     static a: *const T = Default::default();
    |                      ^ use of generic parameter from outer item
+   |
+   = note: a `static` is a separate item from the item that contains it
 
 error[E0401]: can't use generic parameters from outer item
   --> $DIR/issue-65035-static-with-parent-generics.rs:15:24
@@ -23,6 +27,8 @@ LL | fn h<const N: usize>() {
 LL |     extern "C" {
 LL |         static a: [u8; N];
    |                        ^ use of generic parameter from outer item
+   |
+   = note: a `static` is a separate item from the item that contains it
 
 error[E0401]: can't use generic parameters from outer item
   --> $DIR/issue-65035-static-with-parent-generics.rs:21:20
@@ -31,6 +37,8 @@ LL | fn i<const N: usize>() {
    |            - const parameter from outer item
 LL |     static a: [u8; N] = [0; N];
    |                    ^ use of generic parameter from outer item
+   |
+   = note: a `static` is a separate item from the item that contains it
 
 error[E0401]: can't use generic parameters from outer item
   --> $DIR/issue-65035-static-with-parent-generics.rs:21:29
@@ -39,6 +47,8 @@ LL | fn i<const N: usize>() {
    |            - const parameter from outer item
 LL |     static a: [u8; N] = [0; N];
    |                             ^ use of generic parameter from outer item
+   |
+   = note: a `static` is a separate item from the item that contains it
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/resolve/use-self-in-inner-fn.rs b/tests/ui/resolve/use-self-in-inner-fn.rs
index f4dfa4c40ab..62f9dc5664f 100644
--- a/tests/ui/resolve/use-self-in-inner-fn.rs
+++ b/tests/ui/resolve/use-self-in-inner-fn.rs
@@ -4,8 +4,8 @@ impl A {
 //~^ NOTE `Self` type implicitly declared here, by this `impl`
     fn banana(&mut self) {
         fn peach(this: &Self) {
-        //~^ ERROR can't use generic parameters from outer item
-        //~| NOTE use of generic parameter from outer item
+        //~^ ERROR can't use `Self` from outer item
+        //~| NOTE use of `Self` from outer item
         //~| NOTE refer to the type directly here instead
         }
     }
diff --git a/tests/ui/resolve/use-self-in-inner-fn.stderr b/tests/ui/resolve/use-self-in-inner-fn.stderr
index 165e100bf2f..9c388df8bc2 100644
--- a/tests/ui/resolve/use-self-in-inner-fn.stderr
+++ b/tests/ui/resolve/use-self-in-inner-fn.stderr
@@ -1,4 +1,4 @@
-error[E0401]: can't use generic parameters from outer item
+error[E0401]: can't use `Self` from outer item
   --> $DIR/use-self-in-inner-fn.rs:6:25
    |
 LL | impl A {
@@ -7,7 +7,7 @@ LL | impl A {
 LL |         fn peach(this: &Self) {
    |                         ^^^^
    |                         |
-   |                         use of generic parameter from outer item
+   |                         use of `Self` from outer item
    |                         refer to the type directly here instead
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.rs b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.rs
index 2490909b6a5..715f5874b2c 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.rs
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.rs
@@ -3,8 +3,9 @@ fn main() {}
 fn attr_in_guard() {
     match None::<u32> {
         Some(!) //~ ERROR `!` patterns are experimental
+        //~^ ERROR: mismatched types
             if #[deny(unused_mut)] //~ ERROR attributes on expressions are experimental
             false //~ ERROR a guard on a never pattern will never be run
     }
-    match false {}
+    match false {} //~ ERROR: `bool` is non-empty
 }
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.stderr
index a456b686e56..f16f5e5be87 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.stderr
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/ICE-119271-never-arm-attr-in-guard.stderr
@@ -1,5 +1,5 @@
 error[E0658]: attributes on expressions are experimental
-  --> $DIR/ICE-119271-never-arm-attr-in-guard.rs:6:16
+  --> $DIR/ICE-119271-never-arm-attr-in-guard.rs:7:16
    |
 LL |             if #[deny(unused_mut)]
    |                ^^^^^^^^^^^^^^^^^^^
@@ -19,11 +19,34 @@ LL |         Some(!)
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error: a guard on a never pattern will never be run
-  --> $DIR/ICE-119271-never-arm-attr-in-guard.rs:7:13
+  --> $DIR/ICE-119271-never-arm-attr-in-guard.rs:8:13
    |
 LL |             false
    |             ^^^^^ help: remove this guard
 
-error: aborting due to 3 previous errors
+error: mismatched types
+  --> $DIR/ICE-119271-never-arm-attr-in-guard.rs:5:14
+   |
+LL |         Some(!)
+   |              ^ a never pattern must be used on an uninhabited type
+   |
+   = note: the matched value is of type `u32`
+
+error[E0004]: non-exhaustive patterns: type `bool` is non-empty
+  --> $DIR/ICE-119271-never-arm-attr-in-guard.rs:10:11
+   |
+LL |     match false {}
+   |           ^^^^^
+   |
+   = note: the matched value is of type `bool`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     match false {
+LL +         _ => todo!(),
+LL ~     }
+   |
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0658`.
+Some errors have detailed explanations: E0004, E0658.
+For more information about an error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/bindings.rs b/tests/ui/rfcs/rfc-0000-never_patterns/bindings.rs
index f2e238ecb13..11489ccaacd 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/bindings.rs
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/bindings.rs
@@ -1,6 +1,7 @@
 #![feature(never_patterns)]
 #![allow(incomplete_features)]
 
+#[derive(Copy, Clone)]
 enum Void {}
 
 fn main() {
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/bindings.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/bindings.stderr
index b69ba80af88..d9c0f67335c 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/bindings.stderr
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/bindings.stderr
@@ -1,47 +1,47 @@
 error: never patterns cannot contain variable bindings
-  --> $DIR/bindings.rs:16:15
+  --> $DIR/bindings.rs:17:15
    |
 LL |         Err(&(_a, _b, !)),
    |               ^^ help: use a wildcard `_` instead
 
 error: never patterns cannot contain variable bindings
-  --> $DIR/bindings.rs:16:19
+  --> $DIR/bindings.rs:17:19
    |
 LL |         Err(&(_a, _b, !)),
    |                   ^^ help: use a wildcard `_` instead
 
 error: never patterns cannot contain variable bindings
-  --> $DIR/bindings.rs:21:25
+  --> $DIR/bindings.rs:22:25
    |
 LL |         Ok(_ok) | Err(&(_a, _b, !)) => {}
    |                         ^^ help: use a wildcard `_` instead
 
 error: never patterns cannot contain variable bindings
-  --> $DIR/bindings.rs:21:29
+  --> $DIR/bindings.rs:22:29
    |
 LL |         Ok(_ok) | Err(&(_a, _b, !)) => {}
    |                             ^^ help: use a wildcard `_` instead
 
 error: never patterns cannot contain variable bindings
-  --> $DIR/bindings.rs:34:10
+  --> $DIR/bindings.rs:35:10
    |
 LL |     let (_a, (! | !)) = (true, void);
    |          ^^ help: use a wildcard `_` instead
 
 error: never patterns cannot contain variable bindings
-  --> $DIR/bindings.rs:38:9
+  --> $DIR/bindings.rs:39:9
    |
 LL |     let _a @ ! = void;
    |         ^^ help: use a wildcard `_` instead
 
 error: never patterns cannot contain variable bindings
-  --> $DIR/bindings.rs:41:10
+  --> $DIR/bindings.rs:42:10
    |
 LL |     let (_a @ (), !) = ((), void);
    |          ^^ help: use a wildcard `_` instead
 
 error: never patterns cannot contain variable bindings
-  --> $DIR/bindings.rs:44:14
+  --> $DIR/bindings.rs:45:14
    |
 LL |             (_b @ (_, !))) = (true, void);
    |              ^^ help: use a wildcard `_` instead
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/check.rs b/tests/ui/rfcs/rfc-0000-never_patterns/check.rs
index e298112244a..b6da0c20e07 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/check.rs
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/check.rs
@@ -15,18 +15,18 @@ fn no_arms_or_guards(x: Void) {
         //~^ ERROR a never pattern is always unreachable
         None => {}
     }
-    match None::<Void> {
+    match None::<Void> { //~ ERROR: `Some(_)` not covered
         Some(!) if true,
         //~^ ERROR guard on a never pattern
         None => {}
     }
-    match None::<Void> {
+    match None::<Void> { //~ ERROR: `Some(_)` not covered
         Some(!) if true => {}
         //~^ ERROR a never pattern is always unreachable
         None => {}
     }
     match None::<Void> {
-        Some(never!()) => {},
+        Some(never!()) => {}
         //~^ ERROR a never pattern is always unreachable
         None => {}
     }
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/check.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/check.stderr
index bfbc7a1b534..5497252890f 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/check.stderr
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/check.stderr
@@ -25,11 +25,48 @@ LL |         Some(!) if true => {}
 error: a never pattern is always unreachable
   --> $DIR/check.rs:29:27
    |
-LL |         Some(never!()) => {},
+LL |         Some(never!()) => {}
    |                           ^^
    |                           |
    |                           this will never be executed
    |                           help: remove this expression
 
-error: aborting due to 4 previous errors
+error[E0004]: non-exhaustive patterns: `Some(_)` not covered
+  --> $DIR/check.rs:18:11
+   |
+LL |     match None::<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[E0004]: non-exhaustive patterns: `Some(_)` not covered
+  --> $DIR/check.rs:23:11
+   |
+LL |     match None::<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: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs b/tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs
index 31a23fa002c..72ee4d24bb6 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/typeck.rs
@@ -2,7 +2,7 @@
 //[pass] check-pass
 //[fail] check-fail
 #![feature(never_patterns)]
-#![feature(exhaustive_patterns)]
+#![feature(min_exhaustive_patterns)]
 #![allow(incomplete_features)]
 
 #[derive(Copy, Clone)]
@@ -107,7 +107,7 @@ fn never_pattern_typeck_pass(void: Void) {
     }
     match (&[] as &[Void]) {
         [] => {}
-        [!],
+        [!, ..],
     }
     // Accept on a composite empty type.
     match None::<&(u32, Void)> {
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs
index df8e22abf62..0374cbdbc1f 100644
--- a/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/unreachable.rs
@@ -2,7 +2,7 @@
 //[normal] check-pass
 #![feature(never_patterns)]
 #![allow(incomplete_features)]
-#![cfg_attr(exh_pats, feature(exhaustive_patterns))]
+#![cfg_attr(exh_pats, feature(min_exhaustive_patterns))]
 #![allow(dead_code, unreachable_code)]
 #![deny(unreachable_patterns)]
 
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
index 910d491baaf..9945041113d 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-embedded.stderr
@@ -5,7 +5,7 @@ LL |         WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLIN
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 note: the lint level is defined here
@@ -16,3 +16,20 @@ LL | #![warn(indirect_structural_match)]
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+  --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:24:9
+   |
+LL |         WRAP_DOUBLY_INDIRECT_INLINE => { panic!("WRAP_DOUBLY_INDIRECT_INLINE matched itself"); }
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: the traits must be derived, manual `impl`s are not sufficient
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the lint level is defined here
+  --> $DIR/cant-hide-behind-doubly-indirect-embedded.rs:7:9
+   |
+LL | #![warn(indirect_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
index cadd9be023c..6ac261ae814 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-doubly-indirect-param.stderr
@@ -5,7 +5,7 @@ LL |         WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 note: the lint level is defined here
@@ -16,3 +16,20 @@ LL | #![warn(indirect_structural_match)]
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+  --> $DIR/cant-hide-behind-doubly-indirect-param.rs:24:9
+   |
+LL |         WRAP_DOUBLY_INDIRECT_PARAM => { panic!("WRAP_DOUBLY_INDIRECT_PARAM matched itself"); }
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: the traits must be derived, manual `impl`s are not sufficient
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the lint level is defined here
+  --> $DIR/cant-hide-behind-doubly-indirect-param.rs:7:9
+   |
+LL | #![warn(indirect_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
index e4321cc6a4c..41616fb90fe 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-embedded.stderr
@@ -5,7 +5,7 @@ LL |         WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itse
    |         ^^^^^^^^^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 note: the lint level is defined here
@@ -16,3 +16,20 @@ LL | #![warn(indirect_structural_match)]
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+  --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:24:9
+   |
+LL |         WRAP_INDIRECT_INLINE => { panic!("WRAP_INDIRECT_INLINE matched itself"); }
+   |         ^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: the traits must be derived, manual `impl`s are not sufficient
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the lint level is defined here
+  --> $DIR/cant-hide-behind-indirect-struct-embedded.rs:7:9
+   |
+LL | #![warn(indirect_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
index decc29ad67c..99dea5171d1 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/cant-hide-behind-indirect-struct-param.stderr
@@ -5,7 +5,7 @@ LL |         WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself
    |         ^^^^^^^^^^^^^^^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 note: the lint level is defined here
@@ -16,3 +16,20 @@ LL | #![warn(indirect_structural_match)]
 
 warning: 1 warning emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `NoDerive` in a pattern, `NoDerive` must be annotated with `#[derive(PartialEq)]`
+  --> $DIR/cant-hide-behind-indirect-struct-param.rs:24:9
+   |
+LL |         WRAP_INDIRECT_PARAM => { panic!("WRAP_INDIRECT_PARAM matched itself"); }
+   |         ^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: the traits must be derived, manual `impl`s are not sufficient
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the lint level is defined here
+  --> $DIR/cant-hide-behind-indirect-struct-param.rs:7:9
+   |
+LL | #![warn(indirect_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr
index 080bf5885ba..11163ba70ec 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/fn-ptr-is-structurally-matchable.stderr
@@ -5,7 +5,7 @@ LL |         Wrap(CFN1) => count += 1,
    |              ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: `#[warn(pointer_structural_match)]` on by default
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
@@ -15,7 +15,7 @@ LL |         Wrap(CFN2) => count += 1,
    |              ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/fn-ptr-is-structurally-matchable.rs:61:14
@@ -24,7 +24,7 @@ LL |         Wrap(CFN3) => count += 1,
    |              ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/fn-ptr-is-structurally-matchable.rs:70:14
@@ -33,7 +33,7 @@ LL |         Wrap(CFN4) => count += 1,
    |              ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/fn-ptr-is-structurally-matchable.rs:79:14
@@ -42,7 +42,7 @@ LL |         Wrap(CFN5) => count += 1,
    |              ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/fn-ptr-is-structurally-matchable.rs:88:14
@@ -51,7 +51,7 @@ LL |         Wrap(CFN6) => count += 1,
    |              ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/fn-ptr-is-structurally-matchable.rs:97:14
@@ -60,7 +60,7 @@ LL |         Wrap(CFN7) => count += 1,
    |              ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/fn-ptr-is-structurally-matchable.rs:106:14
@@ -69,7 +69,7 @@ LL |         Wrap(CFN8) => count += 1,
    |              ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/fn-ptr-is-structurally-matchable.rs:115:14
@@ -78,7 +78,7 @@ LL |         Wrap(CFN9) => count += 1,
    |              ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
   --> $DIR/fn-ptr-is-structurally-matchable.rs:138:9
@@ -87,7 +87,117 @@ LL |         CFOO => count += 1,
    |         ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: 10 warnings emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:43:14
+   |
+LL |         Wrap(CFN1) => count += 1,
+   |              ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:52:14
+   |
+LL |         Wrap(CFN2) => count += 1,
+   |              ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:61:14
+   |
+LL |         Wrap(CFN3) => count += 1,
+   |              ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:70:14
+   |
+LL |         Wrap(CFN4) => count += 1,
+   |              ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:79:14
+   |
+LL |         Wrap(CFN5) => count += 1,
+   |              ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:88:14
+   |
+LL |         Wrap(CFN6) => count += 1,
+   |              ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:97:14
+   |
+LL |         Wrap(CFN7) => count += 1,
+   |              ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:106:14
+   |
+LL |         Wrap(CFN8) => count += 1,
+   |              ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:115:14
+   |
+LL |         Wrap(CFN9) => count += 1,
+   |              ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/fn-ptr-is-structurally-matchable.rs:138:9
+   |
+LL |         CFOO => count += 1,
+   |         ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: `#[warn(pointer_structural_match)]` on by default
+
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs
index fdb67bcf2d8..374e5d5acd0 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.rs
@@ -10,7 +10,7 @@
 
 // Issue 62307 pointed out a case where the structural-match checking
 // was too shallow.
-#![warn(indirect_structural_match, nontrivial_structural_match)]
+#![warn(indirect_structural_match)]
 // run-pass
 
 #[derive(Debug)]
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
index d0f2b820afa..d4ab1ce3ba2 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-62307-match-ref-ref-forbidden-without-eq.stderr
@@ -5,13 +5,13 @@ LL |         RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0);
    |         ^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 note: the lint level is defined here
   --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9
    |
-LL | #![warn(indirect_structural_match, nontrivial_structural_match)]
+LL | #![warn(indirect_structural_match)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]`
@@ -21,9 +21,43 @@ LL |         RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1);
    |         ^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/62411>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
    = note: the traits must be derived, manual `impl`s are not sufficient
    = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
 
 warning: 2 warnings emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]`
+  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:31:9
+   |
+LL |         RR_B1 => { println!("CLAIM RR0: {:?} matches {:?}", RR_B1, RR_B0); }
+   |         ^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: the traits must be derived, manual `impl`s are not sufficient
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the lint level is defined here
+  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9
+   |
+LL | #![warn(indirect_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+warning: to use a constant of type `B` in a pattern, `B` must be annotated with `#[derive(PartialEq)]`
+  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:38:9
+   |
+LL |         RR_B1 => { println!("CLAIM RR1: {:?} matches {:?}", RR_B1, RR_B1); }
+   |         ^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+   = note: the traits must be derived, manual `impl`s are not sufficient
+   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
+note: the lint level is defined here
+  --> $DIR/issue-62307-match-ref-ref-forbidden-without-eq.rs:13:9
+   |
+LL | #![warn(indirect_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr
index 4fdfce60bb8..0edcf44c4d7 100644
--- a/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr
+++ b/tests/ui/rfcs/rfc-1445-restrict-constants-in-patterns/issue-63479-match-fnptr.stderr
@@ -5,7 +5,7 @@ LL |     B(TEST) => println!("matched"),
    |       ^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 note: the lint level is defined here
   --> $DIR/issue-63479-match-fnptr.rs:8:9
    |
@@ -19,7 +19,37 @@ LL |     TEST2 => println!("matched"),
    |     ^^^^^
    |
    = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #62411 <https://github.com/rust-lang/rust/issues/70861>
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
 
 warning: 2 warnings emitted
 
+Future incompatibility report: Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/issue-63479-match-fnptr.rs:36:7
+   |
+LL |     B(TEST) => println!("matched"),
+   |       ^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+note: the lint level is defined here
+  --> $DIR/issue-63479-match-fnptr.rs:8:9
+   |
+LL | #![warn(pointer_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+Future breakage diagnostic:
+warning: function pointers and raw pointers not derived from integers in patterns behave unpredictably and should not be relied upon. See https://github.com/rust-lang/rust/issues/70861 for details.
+  --> $DIR/issue-63479-match-fnptr.rs:42:5
+   |
+LL |     TEST2 => println!("matched"),
+   |     ^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #120362 <https://github.com/rust-lang/rust/issues/120362>
+note: the lint level is defined here
+  --> $DIR/issue-63479-match-fnptr.rs:8:9
+   |
+LL | #![warn(pointer_structural_match)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr
new file mode 100644
index 00000000000..4a219ff8b55
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.current.stderr
@@ -0,0 +1,15 @@
+warning: methods `good_virt` and `good_indirect` are never used
+  --> $DIR/manual-self-impl-for-unsafe-obj.rs:22:8
+   |
+LL | trait Good {
+   |       ---- methods in this trait
+LL |     fn good_virt(&self) -> char {
+   |        ^^^^^^^^^
+...
+LL |     fn good_indirect(&self) -> char {
+   |        ^^^^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr
new file mode 100644
index 00000000000..4a219ff8b55
--- /dev/null
+++ b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.next.stderr
@@ -0,0 +1,15 @@
+warning: methods `good_virt` and `good_indirect` are never used
+  --> $DIR/manual-self-impl-for-unsafe-obj.rs:22:8
+   |
+LL | trait Good {
+   |       ---- methods in this trait
+LL |     fn good_virt(&self) -> char {
+   |        ^^^^^^^^^
+...
+LL |     fn good_indirect(&self) -> char {
+   |        ^^^^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
index c7665affb99..c8eee9835fe 100644
--- a/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
+++ b/tests/ui/rfcs/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
@@ -19,7 +19,7 @@ trait Bad {
 }
 
 trait Good {
-    fn good_virt(&self) -> char {
+    fn good_virt(&self) -> char { //~ WARN methods `good_virt` and `good_indirect` are never used
         panic!()
     }
     fn good_indirect(&self) -> char {
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
index 43e33cbb120..351438a5470 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
+++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.rs
@@ -7,7 +7,9 @@ use std::arch::asm;
 //~^ ERROR `#[track_caller]` requires Rust ABI
 #[naked]
 extern "C" fn f() {
-    asm!("", options(noreturn));
+    unsafe {
+        asm!("", options(noreturn));
+    }
 }
 
 struct S;
@@ -17,7 +19,9 @@ impl S {
     //~^ ERROR `#[track_caller]` requires Rust ABI
     #[naked]
     extern "C" fn g() {
-        asm!("", options(noreturn));
+        unsafe {
+            asm!("", options(noreturn));
+        }
     }
 }
 
diff --git a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr
index 3f7d0df42a0..04c5c649d7f 100644
--- a/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr
+++ b/tests/ui/rfcs/rfc-2091-track-caller/error-with-naked.stderr
@@ -5,7 +5,7 @@ LL | #[track_caller]
    | ^^^^^^^^^^^^^^^
 
 error[E0736]: cannot use `#[track_caller]` with `#[naked]`
-  --> $DIR/error-with-naked.rs:16:5
+  --> $DIR/error-with-naked.rs:18:5
    |
 LL |     #[track_caller]
    |     ^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL | #[track_caller]
    | ^^^^^^^^^^^^^^^
 
 error[E0737]: `#[track_caller]` requires Rust ABI
-  --> $DIR/error-with-naked.rs:16:5
+  --> $DIR/error-with-naked.rs:18:5
    |
 LL |     #[track_caller]
    |     ^^^^^^^^^^^^^^^
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs
index 1374ad935a3..a032a2ca052 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.rs
@@ -12,7 +12,7 @@ fn call(f: impl Fn()) {
     f()
 }
 
-fn call_mut(f: impl FnMut()) {
+fn call_mut(mut f: impl FnMut()) {
     f()
 }
 
diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
index 100f2048269..67bfaa4c98c 100644
--- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
+++ b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-traits.stderr
@@ -27,10 +27,10 @@ LL |     call_mut(foo);
    = note: wrap the `fn() {foo}` in a closure with no arguments: `|| { /* code */ }`
    = note: `#[target_feature]` functions do not implement the `Fn` traits
 note: required by a bound in `call_mut`
-  --> $DIR/fn-traits.rs:15:21
+  --> $DIR/fn-traits.rs:15:25
    |
-LL | fn call_mut(f: impl FnMut()) {
-   |                     ^^^^^^^ required by this bound in `call_mut`
+LL | fn call_mut(mut f: impl FnMut()) {
+   |                         ^^^^^^^ required by this bound in `call_mut`
 
 error[E0277]: expected a `FnOnce()` closure, found `fn() {foo}`
   --> $DIR/fn-traits.rs:26:15
@@ -80,10 +80,10 @@ LL |     call_mut(foo_unsafe);
    = note: wrap the `unsafe fn() {foo_unsafe}` in a closure with no arguments: `|| { /* code */ }`
    = note: `#[target_feature]` functions do not implement the `Fn` traits
 note: required by a bound in `call_mut`
-  --> $DIR/fn-traits.rs:15:21
+  --> $DIR/fn-traits.rs:15:25
    |
-LL | fn call_mut(f: impl FnMut()) {
-   |                     ^^^^^^^ required by this bound in `call_mut`
+LL | fn call_mut(mut f: impl FnMut()) {
+   |                         ^^^^^^^ required by this bound in `call_mut`
 
 error[E0277]: expected a `FnOnce()` closure, found `unsafe fn() {foo_unsafe}`
   --> $DIR/fn-traits.rs:32:15
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr
index d70b0d66177..14c41f3e01d 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method-fail.stderr
@@ -4,5 +4,19 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
    |                                       ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closure-trait-method-fail.rs:15:5
+   |
+LL |     x(())
+   |     ^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32 + ~const std::ops::FnOnce<((),)>>(x: T) -> i32 {
+   |                                                         ++++++++++++++++++++++++++++++++
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr
index 1642de78692..8fe11fffbf9 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closure-trait-method.stderr
@@ -4,5 +4,19 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
    |                                       ^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closure-trait-method.rs:15:5
+   |
+LL |     x(())
+   |     ^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32 + ~const std::ops::FnOnce<((),)>>(x: T) -> i32 {
+   |                                                         ++++++++++++++++++++++++++++++++
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr
index 2e448c64d7a..b66b27ad2bd 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/const-closures.stderr
@@ -22,5 +22,45 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | const fn answer<F: ~const Fn() -> u8>(f: &F) -> u8 {
    |                           ^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closures.rs:12:5
+   |
+LL |     f() * 7
+   |     ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL |         F: ~const FnOnce() -> u8 + ~const std::ops::Fn<()>,
+   |                                  +++++++++++++++++++++++++
+
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closures.rs:24:5
+   |
+LL |     f() + f()
+   |     ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL | const fn answer<F: ~const Fn() -> u8 + ~const std::ops::Fn<()>>(f: &F) -> u8 {
+   |                                      +++++++++++++++++++++++++
+
+error[E0015]: cannot call non-const closure in constant functions
+  --> $DIR/const-closures.rs:24:11
+   |
+LL |     f() + f()
+   |           ^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+help: consider further restricting this bound
+   |
+LL | const fn answer<F: ~const Fn() -> u8 + ~const std::ops::Fn<()>>(f: &F) -> u8 {
+   |                                      +++++++++++++++++++++++++
+
+error: aborting due to 7 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
index b3977e6cede..2468d51cfdd 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.rs
@@ -30,8 +30,7 @@ fn non_const_context() {
 #[unstable(feature = "none", issue = "none")]
 const fn const_context() {
     Unstable::func();
-    // ^ This is okay regardless of whether the `unstable` feature is enabled, as this function is
-    // not const-stable.
+    //[stable]~^ ERROR not yet stable as a const fn
     Foo::func();
     //[unstable]~^ ERROR not yet stable as a const fn
     // ^ fails, because the `foo` feature is not active
@@ -42,8 +41,7 @@ const fn const_context() {
 pub const fn const_context_not_const_stable() {
     //[stable]~^ ERROR function has missing const stability attribute
     Unstable::func();
-    // ^ This is okay regardless of whether the `unstable` feature is enabled, as this function is
-    // not const-stable.
+    //[stable]~^ ERROR not yet stable as a const fn
     Foo::func();
     //[unstable]~^ ERROR not yet stable as a const fn
     // ^ fails, because the `foo` feature is not active
@@ -53,7 +51,7 @@ pub const fn const_context_not_const_stable() {
 #[rustc_const_stable(feature = "cheese", since = "1.0.0")]
 const fn stable_const_context() {
     Unstable::func();
-    //[unstable]~^ ERROR not yet stable as a const fn
+    //~^ ERROR not yet stable as a const fn
     Foo::func();
     //[unstable]~^ ERROR not yet stable as a const fn
     const_context_not_const_stable()
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr
index a1aca762ef4..95129539770 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.stable.stderr
@@ -10,16 +10,40 @@ LL | | }
    = note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
 
 error: function has missing const stability attribute
-  --> $DIR/staged-api.rs:42:1
+  --> $DIR/staged-api.rs:41:1
    |
 LL | / pub const fn const_context_not_const_stable() {
 LL | |
 LL | |     Unstable::func();
-LL | |     // ^ This is okay regardless of whether the `unstable` feature is enabled, as this function is
+LL | |
 ...  |
 LL | |     // ^ fails, because the `foo` feature is not active
 LL | | }
    | |_^
 
-error: aborting due to 2 previous errors
+error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:32:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+
+error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:43:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(unstable)]` to the crate attributes to enable
+
+error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
+  --> $DIR/staged-api.rs:53:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: const-stable functions can only call other const-stable functions
+
+error: aborting due to 5 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr
index c38d1a81ae7..c9ca15d5b56 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/staged-api.unstable.stderr
@@ -1,5 +1,5 @@
 error: `<Foo as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:35:5
+  --> $DIR/staged-api.rs:34:5
    |
 LL |     Foo::func();
    |     ^^^^^^^^^^^
@@ -7,7 +7,7 @@ LL |     Foo::func();
    = help: add `#![feature(foo)]` to the crate attributes to enable
 
 error: `<Foo as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:47:5
+  --> $DIR/staged-api.rs:45:5
    |
 LL |     Foo::func();
    |     ^^^^^^^^^^^
@@ -15,7 +15,7 @@ LL |     Foo::func();
    = help: add `#![feature(foo)]` to the crate attributes to enable
 
 error: `<staged_api::Unstable as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:55:5
+  --> $DIR/staged-api.rs:53:5
    |
 LL |     Unstable::func();
    |     ^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL |     Unstable::func();
    = help: const-stable functions can only call other const-stable functions
 
 error: `<Foo as staged_api::MyTrait>::func` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:57:5
+  --> $DIR/staged-api.rs:55:5
    |
 LL |     Foo::func();
    |     ^^^^^^^^^^^
@@ -31,7 +31,7 @@ LL |     Foo::func();
    = help: const-stable functions can only call other const-stable functions
 
 error: `const_context_not_const_stable` is not yet stable as a const fn
-  --> $DIR/staged-api.rs:59:5
+  --> $DIR/staged-api.rs:57:5
    |
 LL |     const_context_not_const_stable()
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr
index bf53b995bb6..e51ff148339 100644
--- a/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr
+++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/std-impl-gate.gated.stderr
@@ -4,6 +4,16 @@ error[E0635]: unknown feature `const_default_impls`
 LL | #![cfg_attr(gated, feature(const_trait_impl, const_default_impls))]
    |                                              ^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0015]: cannot call non-const fn `<Vec<usize> as Default>::default` in constant functions
+  --> $DIR/std-impl-gate.rs:13:5
+   |
+LL |     Default::default()
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0635`.
+Some errors have detailed explanations: E0015, E0635.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/rust-2018/issue-51008-1.rs b/tests/ui/rust-2018/issue-51008-1.rs
index da7b8ef65c5..67dfbf64601 100644
--- a/tests/ui/rust-2018/issue-51008-1.rs
+++ b/tests/ui/rust-2018/issue-51008-1.rs
@@ -2,7 +2,7 @@
 // being incorrectly considered part of the "elided lifetimes" from
 // the impl.
 //
-// run-pass
+// check-pass
 
 trait A {
 
diff --git a/tests/ui/rust-2018/issue-51008.rs b/tests/ui/rust-2018/issue-51008.rs
index 56517b9adee..f9e4bc14ec8 100644
--- a/tests/ui/rust-2018/issue-51008.rs
+++ b/tests/ui/rust-2018/issue-51008.rs
@@ -2,7 +2,7 @@
 // being incorrectly considered part of the "elided lifetimes" from
 // the impl.
 //
-// run-pass
+// check-pass
 
 trait A {
 
diff --git a/tests/ui/sized/coinductive-2.rs b/tests/ui/sized/coinductive-2.rs
index 212274d2e4b..43a5a28f710 100644
--- a/tests/ui/sized/coinductive-2.rs
+++ b/tests/ui/sized/coinductive-2.rs
@@ -11,7 +11,7 @@ impl<T> CollectionFactory<T> for Vec<()> {
     type Collection = Vec<T>;
 }
 
-trait Collection<T>: Sized {
+trait Collection<T>: Sized { //~ WARN trait `Collection` is never used
     fn push(&mut self, v: T);
 }
 
diff --git a/tests/ui/sized/coinductive-2.stderr b/tests/ui/sized/coinductive-2.stderr
new file mode 100644
index 00000000000..1390b1f8d7b
--- /dev/null
+++ b/tests/ui/sized/coinductive-2.stderr
@@ -0,0 +1,10 @@
+warning: trait `Collection` is never used
+  --> $DIR/coinductive-2.rs:14:7
+   |
+LL | trait Collection<T>: Sized {
+   |       ^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/span/issue-23827.rs b/tests/ui/span/issue-23827.rs
index 6b065bf6cbf..81037771389 100644
--- a/tests/ui/span/issue-23827.rs
+++ b/tests/ui/span/issue-23827.rs
@@ -2,6 +2,7 @@
 
 #![feature(fn_traits, unboxed_closures)]
 
+#[derive(Copy, Clone)]
 pub struct Prototype {
     pub target: u32
 }
diff --git a/tests/ui/span/issue-23827.stderr b/tests/ui/span/issue-23827.stderr
index fe7c7794c9c..56f449ab08b 100644
--- a/tests/ui/span/issue-23827.stderr
+++ b/tests/ui/span/issue-23827.stderr
@@ -1,5 +1,5 @@
 error[E0046]: not all trait items implemented, missing: `Output`
-  --> $DIR/issue-23827.rs:26:1
+  --> $DIR/issue-23827.rs:27:1
    |
 LL | impl<C: Component> FnOnce<(C,)> for Prototype {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `Output` in implementation
diff --git a/tests/ui/span/issue-39698.rs b/tests/ui/span/issue-39698.rs
index 1079bae2c06..9799e67e521 100644
--- a/tests/ui/span/issue-39698.rs
+++ b/tests/ui/span/issue-39698.rs
@@ -12,5 +12,6 @@ fn main() {
         //~| ERROR is not bound in all patterns
         //~| ERROR is not bound in all patterns
         //~| ERROR is not bound in all patterns
+        //~| ERROR `a` is possibly-uninitialized
     }
 }
diff --git a/tests/ui/span/issue-39698.stderr b/tests/ui/span/issue-39698.stderr
index 50008083211..73fcc5c8477 100644
--- a/tests/ui/span/issue-39698.stderr
+++ b/tests/ui/span/issue-39698.stderr
@@ -38,6 +38,19 @@ LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}
    |                  |          variable not in all patterns
    |                  variable not in all patterns
 
-error: aborting due to 4 previous errors
+error[E0381]: used binding `a` is possibly-uninitialized
+  --> $DIR/issue-39698.rs:10:79
+   |
+LL |         T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); }
+   |               -                                      -                        ^ `a` used here but it is possibly-uninitialized
+   |               |                                      |
+   |               |                                      binding initialized here in some conditions
+   |               binding initialized here in some conditions
+   |               binding declared here but left uninitialized
+   |
+   = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0408`.
+Some errors have detailed explanations: E0381, E0408.
+For more information about an error, try `rustc --explain E0381`.
diff --git a/tests/ui/specialization/assoc-ty-graph-cycle.rs b/tests/ui/specialization/assoc-ty-graph-cycle.rs
index fc39b553a61..bec8cc187b4 100644
--- a/tests/ui/specialization/assoc-ty-graph-cycle.rs
+++ b/tests/ui/specialization/assoc-ty-graph-cycle.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 // Make sure we don't crash with a cycle error during coherence.
 
diff --git a/tests/ui/specialization/const_trait_impl.stderr b/tests/ui/specialization/const_trait_impl.stderr
index 913d51875cd..187049e623c 100644
--- a/tests/ui/specialization/const_trait_impl.stderr
+++ b/tests/ui/specialization/const_trait_impl.stderr
@@ -16,5 +16,33 @@ error: `~const` can only be applied to `#[const_trait]` traits
 LL | impl<T: ~const Default + ~const Sub> const A for T {
    |                ^^^^^^^
 
-error: aborting due to 3 previous errors
+error[E0015]: cannot call non-const fn `<() as A>::a` in constants
+  --> $DIR/const_trait_impl.rs:52:23
+   |
+LL | const _: () = assert!(<()>::a() == 42);
+   |                       ^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error[E0015]: cannot call non-const fn `<u8 as A>::a` in constants
+  --> $DIR/const_trait_impl.rs:53:23
+   |
+LL | const _: () = assert!(<u8>::a() == 3);
+   |                       ^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error[E0015]: cannot call non-const fn `<u16 as A>::a` in constants
+  --> $DIR/const_trait_impl.rs:54:23
+   |
+LL | const _: () = assert!(<u16>::a() == 2);
+   |                       ^^^^^^^^^^
+   |
+   = note: calls in constants are limited to constant functions, tuple structs and tuple variants
+   = help: add `#![feature(effects)]` to the crate attributes to enable
+
+error: aborting due to 6 previous errors
 
+For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/specialization/defaultimpl/out-of-order.rs b/tests/ui/specialization/defaultimpl/out-of-order.rs
index 13258ac8c9f..94b3905178f 100644
--- a/tests/ui/specialization/defaultimpl/out-of-order.rs
+++ b/tests/ui/specialization/defaultimpl/out-of-order.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 // Test that you can list the more specific impl before the more general one.
 
diff --git a/tests/ui/specialization/defaultimpl/overlap-projection.rs b/tests/ui/specialization/defaultimpl/overlap-projection.rs
index 0add4d5516c..46f54c466a8 100644
--- a/tests/ui/specialization/defaultimpl/overlap-projection.rs
+++ b/tests/ui/specialization/defaultimpl/overlap-projection.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 // Test that impls on projected self types can resolve overlap, even when the
 // projections involve specialization, so long as the associated type is
diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr
index e9498a00317..78d77a78e0e 100644
--- a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr
+++ b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr
@@ -7,6 +7,13 @@ LL | impl Overlap for u32 {
 LL | impl Overlap for <u32 as Default>::Id {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
 
-error: aborting due to 1 previous error
+error[E0282]: type annotations needed
+  --> $DIR/specialization-default-items-drop-coherence.rs:18:23
+   |
+LL |     default type Id = T;
+   |                       ^ cannot infer type for associated type `<T as Default>::Id`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0119, E0282.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.rs b/tests/ui/specialization/specialization-default-items-drop-coherence.rs
index 37903c21071..87eb5d90def 100644
--- a/tests/ui/specialization/specialization-default-items-drop-coherence.rs
+++ b/tests/ui/specialization/specialization-default-items-drop-coherence.rs
@@ -11,25 +11,25 @@
 #![allow(incomplete_features)]
 
 trait Default {
-   type Id;
+    type Id;
 }
 
 impl<T> Default for T {
-   default type Id = T;
+    default type Id = T; //[next]~ ERROR type annotations needed
 }
 
 trait Overlap {
-   type Assoc;
+    type Assoc;
 }
 
 impl Overlap for u32 {
-   type Assoc = usize;
+    type Assoc = usize;
 }
 
 impl Overlap for <u32 as Default>::Id {
-   //[coherence]~^ ERROR conflicting implementations of trait `Overlap` for type `u32`
-   //[next]~^^ ERROR conflicting implementations of trait `Overlap` for type `u32`
-   type Assoc = Box<usize>;
+    //[coherence]~^ ERROR conflicting implementations of trait `Overlap` for type `u32`
+    //[next]~^^ ERROR conflicting implementations of trait `Overlap` for type `u32`
+    type Assoc = Box<usize>;
 }
 
 fn main() {}
diff --git a/tests/ui/specialization/specialization-out-of-order.rs b/tests/ui/specialization/specialization-out-of-order.rs
index cb7563e2760..66e6c3c9eab 100644
--- a/tests/ui/specialization/specialization-out-of-order.rs
+++ b/tests/ui/specialization/specialization-out-of-order.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 // Test that you can list the more specific impl before the more general one.
 
diff --git a/tests/ui/specialization/specialization-overlap-projection.rs b/tests/ui/specialization/specialization-overlap-projection.rs
index b07efb2a5c1..cd21eab24c0 100644
--- a/tests/ui/specialization/specialization-overlap-projection.rs
+++ b/tests/ui/specialization/specialization-overlap-projection.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 // Test that impls on projected self types can resolve overlap, even when the
 // projections involve specialization, so long as the associated type is
diff --git a/tests/ui/specialization/specialization-supertraits.rs b/tests/ui/specialization/specialization-supertraits.rs
index fb85d801921..d0c9dbb1d40 100644
--- a/tests/ui/specialization/specialization-supertraits.rs
+++ b/tests/ui/specialization/specialization-supertraits.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(specialization)] //~ WARN the feature `specialization` is incomplete
 
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs
index 6d6d793c62b..4089ec72885 100644
--- a/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.rs
@@ -14,3 +14,4 @@ pub const fn foobar() -> u32 {
 }
 
 const VAR: u32 = foobar();
+//~^ ERROR: `foobar` is not yet stable as a const fn
diff --git a/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr
index 232de41c769..918d6ebf992 100644
--- a/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr
+++ b/tests/ui/stability-attribute/const-stability-attribute-implies-missing.stderr
@@ -4,5 +4,13 @@ error: feature `const_bar` implying `const_foobar` does not exist
 LL | #[rustc_const_unstable(feature = "const_foobar", issue = "1", implied_by = "const_bar")]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: `foobar` is not yet stable as a const fn
+  --> $DIR/const-stability-attribute-implies-missing.rs:16:18
+   |
+LL | const VAR: u32 = foobar();
+   |                  ^^^^^^^^
+   |
+   = help: add `#![feature(const_foobar)]` to the crate attributes to enable
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/static/static-drop-scope.rs b/tests/ui/static/static-drop-scope.rs
index 34afa9873a3..74b224c9be0 100644
--- a/tests/ui/static/static-drop-scope.rs
+++ b/tests/ui/static/static-drop-scope.rs
@@ -6,11 +6,9 @@ impl Drop for WithDtor {
 
 static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
 //~^ ERROR destructor of
-//~| ERROR temporary value dropped while borrowed
 
 const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
 //~^ ERROR destructor of
-//~| ERROR temporary value dropped while borrowed
 
 static EARLY_DROP_S: i32 = (WithDtor, 0).1;
 //~^ ERROR destructor of
diff --git a/tests/ui/static/static-drop-scope.stderr b/tests/ui/static/static-drop-scope.stderr
index cedcb736794..2c55161628f 100644
--- a/tests/ui/static/static-drop-scope.stderr
+++ b/tests/ui/static/static-drop-scope.stderr
@@ -6,36 +6,16 @@ LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
    |                                                            |
    |                                                            the destructor for this type cannot be evaluated in statics
 
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/static-drop-scope.rs:7:60
-   |
-LL | static PROMOTION_FAIL_S: Option<&'static WithDtor> = Some(&WithDtor);
-   |                                                      ------^^^^^^^^-
-   |                                                      |     |       |
-   |                                                      |     |       temporary value is freed at the end of this statement
-   |                                                      |     creates a temporary value which is freed while still in use
-   |                                                      using this value as a static requires that borrow lasts for `'static`
-
 error[E0493]: destructor of `WithDtor` cannot be evaluated at compile-time
-  --> $DIR/static-drop-scope.rs:11:59
+  --> $DIR/static-drop-scope.rs:10:59
    |
 LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
    |                                                           ^^^^^^^^- value is dropped here
    |                                                           |
    |                                                           the destructor for this type cannot be evaluated in constants
 
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/static-drop-scope.rs:11:59
-   |
-LL | const PROMOTION_FAIL_C: Option<&'static WithDtor> = Some(&WithDtor);
-   |                                                     ------^^^^^^^^-
-   |                                                     |     |       |
-   |                                                     |     |       temporary value is freed at the end of this statement
-   |                                                     |     creates a temporary value which is freed while still in use
-   |                                                     using this value as a constant requires that borrow lasts for `'static`
-
 error[E0493]: destructor of `(WithDtor, i32)` cannot be evaluated at compile-time
-  --> $DIR/static-drop-scope.rs:15:28
+  --> $DIR/static-drop-scope.rs:13:28
    |
 LL | static EARLY_DROP_S: i32 = (WithDtor, 0).1;
    |                            ^^^^^^^^^^^^^ - value is dropped here
@@ -43,7 +23,7 @@ LL | static EARLY_DROP_S: i32 = (WithDtor, 0).1;
    |                            the destructor for this type cannot be evaluated in statics
 
 error[E0493]: destructor of `(WithDtor, i32)` cannot be evaluated at compile-time
-  --> $DIR/static-drop-scope.rs:18:27
+  --> $DIR/static-drop-scope.rs:16:27
    |
 LL | const EARLY_DROP_C: i32 = (WithDtor, 0).1;
    |                           ^^^^^^^^^^^^^ - value is dropped here
@@ -51,7 +31,7 @@ LL | const EARLY_DROP_C: i32 = (WithDtor, 0).1;
    |                           the destructor for this type cannot be evaluated in constants
 
 error[E0493]: destructor of `T` cannot be evaluated at compile-time
-  --> $DIR/static-drop-scope.rs:21:24
+  --> $DIR/static-drop-scope.rs:19:24
    |
 LL | const fn const_drop<T>(_: T) {}
    |                        ^      - value is dropped here
@@ -59,7 +39,7 @@ LL | const fn const_drop<T>(_: T) {}
    |                        the destructor for this type cannot be evaluated in constant functions
 
 error[E0493]: destructor of `(T, ())` cannot be evaluated at compile-time
-  --> $DIR/static-drop-scope.rs:25:5
+  --> $DIR/static-drop-scope.rs:23:5
    |
 LL |     (x, ()).1
    |     ^^^^^^^ the destructor for this type cannot be evaluated in constant functions
@@ -68,7 +48,7 @@ LL | }
    | - value is dropped here
 
 error[E0493]: destructor of `(Option<WithDtor>, i32)` cannot be evaluated at compile-time
-  --> $DIR/static-drop-scope.rs:29:34
+  --> $DIR/static-drop-scope.rs:27:34
    |
 LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
    |                                  ^^^^^^^^^^^^^^^^^^^ - value is dropped here
@@ -76,14 +56,13 @@ LL | const EARLY_DROP_C_OPTION: i32 = (Some(WithDtor), 0).1;
    |                                  the destructor for this type cannot be evaluated in constants
 
 error[E0493]: destructor of `(Option<WithDtor>, i32)` cannot be evaluated at compile-time
-  --> $DIR/static-drop-scope.rs:34:43
+  --> $DIR/static-drop-scope.rs:32:43
    |
 LL | const EARLY_DROP_C_OPTION_CONSTANT: i32 = (HELPER, 0).1;
    |                                           ^^^^^^^^^^^ - value is dropped here
    |                                           |
    |                                           the destructor for this type cannot be evaluated in constants
 
-error: aborting due to 10 previous errors
+error: aborting due to 8 previous errors
 
-Some errors have detailed explanations: E0493, E0716.
-For more information about an error, try `rustc --explain E0493`.
+For more information about this error, try `rustc --explain E0493`.
diff --git a/tests/ui/statics/static-impl.rs b/tests/ui/statics/static-impl.rs
index e7bdb38ee62..9e2db7e0caf 100644
--- a/tests/ui/statics/static-impl.rs
+++ b/tests/ui/statics/static-impl.rs
@@ -35,7 +35,7 @@ impl uint_utils for usize {
 
 trait vec_utils<T> {
     fn length_(&self, ) -> usize;
-    fn iter_<F>(&self, f: F) where F: FnMut(&T);
+    fn iter_<F>(&self, f: F) where F: FnMut(&T); //~ WARN method `iter_` is never used
     fn map_<U, F>(&self, f: F) -> Vec<U> where F: FnMut(&T) -> U;
 }
 
diff --git a/tests/ui/statics/static-impl.stderr b/tests/ui/statics/static-impl.stderr
new file mode 100644
index 00000000000..83c3ffbefe1
--- /dev/null
+++ b/tests/ui/statics/static-impl.stderr
@@ -0,0 +1,13 @@
+warning: method `iter_` is never used
+  --> $DIR/static-impl.rs:38:8
+   |
+LL | trait vec_utils<T> {
+   |       --------- method in this trait
+LL |     fn length_(&self, ) -> usize;
+LL |     fn iter_<F>(&self, f: F) where F: FnMut(&T);
+   |        ^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/stdlib-unit-tests/raw-fat-ptr.rs b/tests/ui/stdlib-unit-tests/raw-fat-ptr.rs
index 0f535523dcc..4a8289cb242 100644
--- a/tests/ui/stdlib-unit-tests/raw-fat-ptr.rs
+++ b/tests/ui/stdlib-unit-tests/raw-fat-ptr.rs
@@ -32,7 +32,7 @@ fn assert_inorder<T: PartialEq + PartialOrd>(a: &[T]) {
     }
 }
 
-trait Foo { fn foo(&self) -> usize; }
+trait Foo { fn foo(&self) -> usize; } //~ WARN method `foo` is never used
 impl<T> Foo for T {
     fn foo(&self) -> usize {
         mem::size_of::<T>()
diff --git a/tests/ui/stdlib-unit-tests/raw-fat-ptr.stderr b/tests/ui/stdlib-unit-tests/raw-fat-ptr.stderr
new file mode 100644
index 00000000000..670fa5bb922
--- /dev/null
+++ b/tests/ui/stdlib-unit-tests/raw-fat-ptr.stderr
@@ -0,0 +1,12 @@
+warning: method `foo` is never used
+  --> $DIR/raw-fat-ptr.rs:35:16
+   |
+LL | trait Foo { fn foo(&self) -> usize; }
+   |       ---      ^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/structs-enums/enum-null-pointer-opt.rs b/tests/ui/structs-enums/enum-null-pointer-opt.rs
index 356f8a6dd36..21564eeec29 100644
--- a/tests/ui/structs-enums/enum-null-pointer-opt.rs
+++ b/tests/ui/structs-enums/enum-null-pointer-opt.rs
@@ -7,7 +7,7 @@ use std::ptr::NonNull;
 use std::rc::Rc;
 use std::sync::Arc;
 
-trait Trait { fn dummy(&self) { } }
+trait Trait { fn dummy(&self) { } } //~ WARN method `dummy` is never used
 trait Mirror { type Image; }
 impl<T> Mirror for T { type Image = T; }
 struct ParamTypeStruct<T>(#[allow(dead_code)] T);
diff --git a/tests/ui/structs-enums/enum-null-pointer-opt.stderr b/tests/ui/structs-enums/enum-null-pointer-opt.stderr
new file mode 100644
index 00000000000..64e93ffaffd
--- /dev/null
+++ b/tests/ui/structs-enums/enum-null-pointer-opt.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/enum-null-pointer-opt.rs:10:18
+   |
+LL | trait Trait { fn dummy(&self) { } }
+   |       -----      ^^^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/structs-enums/enum-rec/issue-17431-6.rs b/tests/ui/structs-enums/enum-rec/issue-17431-6.rs
index b7e49873da8..20231dc83db 100644
--- a/tests/ui/structs-enums/enum-rec/issue-17431-6.rs
+++ b/tests/ui/structs-enums/enum-rec/issue-17431-6.rs
@@ -1,7 +1,10 @@
+// ignore-macos: cycle error does not appear on apple
+
 use std::sync::Mutex;
 
 enum Foo { X(Mutex<Option<Foo>>) }
 //~^ ERROR recursive type `Foo` has infinite size
+//~| ERROR cycle detected
 
 impl Foo { fn bar(self) {} }
 
diff --git a/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr b/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr
index e34eb04bc04..22f8519d0ef 100644
--- a/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr
+++ b/tests/ui/structs-enums/enum-rec/issue-17431-6.stderr
@@ -1,5 +1,5 @@
 error[E0072]: recursive type `Foo` has infinite size
-  --> $DIR/issue-17431-6.rs:3:1
+  --> $DIR/issue-17431-6.rs:5:1
    |
 LL | enum Foo { X(Mutex<Option<Foo>>) }
    | ^^^^^^^^                  --- recursive without indirection
@@ -9,6 +9,17 @@ help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle
 LL | enum Foo { X(Mutex<Option<Box<Foo>>>) }
    |                           ++++   +
 
-error: aborting due to 1 previous error
+error[E0391]: cycle detected when computing when `Foo` needs drop
+  --> $DIR/issue-17431-6.rs:5:1
+   |
+LL | enum Foo { X(Mutex<Option<Foo>>) }
+   | ^^^^^^^^
+   |
+   = note: ...which immediately requires computing when `Foo` needs drop again
+   = note: cycle used when computing whether `Foo` needs drop
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0072`.
+Some errors have detailed explanations: E0072, E0391.
+For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/suggestions/bound-suggestions.fixed b/tests/ui/suggestions/bound-suggestions.fixed
index 17a019c6984..ef61fb9ad32 100644
--- a/tests/ui/suggestions/bound-suggestions.fixed
+++ b/tests/ui/suggestions/bound-suggestions.fixed
@@ -40,26 +40,31 @@ fn test_many_bounds_where<X>(x: X) where X: Sized + std::fmt::Debug, X: Sized {
     //~^ ERROR doesn't implement
 }
 
+#[allow(dead_code)]
 trait Foo<T>: Sized {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
 }
 
+#[allow(dead_code)]
 trait Bar: std::fmt::Display + Sized {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
 }
 
+#[allow(dead_code)]
 trait Baz: Sized where Self: std::fmt::Display {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
 }
 
+#[allow(dead_code)]
 trait Qux<T>: Sized where Self: std::fmt::Display {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
 }
 
+#[allow(dead_code)]
 trait Bat<T>: std::fmt::Display + Sized {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
diff --git a/tests/ui/suggestions/bound-suggestions.rs b/tests/ui/suggestions/bound-suggestions.rs
index 86f708d42f5..6d17fae6a08 100644
--- a/tests/ui/suggestions/bound-suggestions.rs
+++ b/tests/ui/suggestions/bound-suggestions.rs
@@ -40,26 +40,31 @@ fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized {
     //~^ ERROR doesn't implement
 }
 
+#[allow(dead_code)]
 trait Foo<T> {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
 }
 
+#[allow(dead_code)]
 trait Bar: std::fmt::Display {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
 }
 
+#[allow(dead_code)]
 trait Baz where Self: std::fmt::Display {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
 }
 
+#[allow(dead_code)]
 trait Qux<T> where Self: std::fmt::Display {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
 }
 
+#[allow(dead_code)]
 trait Bat<T>: std::fmt::Display {
     const SIZE: usize = core::mem::size_of::<Self>();
     //~^ ERROR the size for values of type `Self` cannot be known at compilation time
diff --git a/tests/ui/suggestions/bound-suggestions.stderr b/tests/ui/suggestions/bound-suggestions.stderr
index 7e58ccd461d..4965e7439f8 100644
--- a/tests/ui/suggestions/bound-suggestions.stderr
+++ b/tests/ui/suggestions/bound-suggestions.stderr
@@ -71,7 +71,7 @@ LL | fn test_many_bounds_where<X>(x: X) where X: Sized + std::fmt::Debug, X: Siz
    |                                                   +++++++++++++++++
 
 error[E0277]: the size for values of type `Self` cannot be known at compilation time
-  --> $DIR/bound-suggestions.rs:44:46
+  --> $DIR/bound-suggestions.rs:45:46
    |
 LL |     const SIZE: usize = core::mem::size_of::<Self>();
    |                                              ^^^^ doesn't have a size known at compile-time
@@ -84,7 +84,7 @@ LL | trait Foo<T>: Sized {
    |             +++++++
 
 error[E0277]: the size for values of type `Self` cannot be known at compilation time
-  --> $DIR/bound-suggestions.rs:49:46
+  --> $DIR/bound-suggestions.rs:51:46
    |
 LL |     const SIZE: usize = core::mem::size_of::<Self>();
    |                                              ^^^^ doesn't have a size known at compile-time
@@ -97,7 +97,7 @@ LL | trait Bar: std::fmt::Display + Sized {
    |                              +++++++
 
 error[E0277]: the size for values of type `Self` cannot be known at compilation time
-  --> $DIR/bound-suggestions.rs:54:46
+  --> $DIR/bound-suggestions.rs:57:46
    |
 LL |     const SIZE: usize = core::mem::size_of::<Self>();
    |                                              ^^^^ doesn't have a size known at compile-time
@@ -110,7 +110,7 @@ LL | trait Baz: Sized where Self: std::fmt::Display {
    |          +++++++
 
 error[E0277]: the size for values of type `Self` cannot be known at compilation time
-  --> $DIR/bound-suggestions.rs:59:46
+  --> $DIR/bound-suggestions.rs:63:46
    |
 LL |     const SIZE: usize = core::mem::size_of::<Self>();
    |                                              ^^^^ doesn't have a size known at compile-time
@@ -123,7 +123,7 @@ LL | trait Qux<T>: Sized where Self: std::fmt::Display {
    |             +++++++
 
 error[E0277]: the size for values of type `Self` cannot be known at compilation time
-  --> $DIR/bound-suggestions.rs:64:46
+  --> $DIR/bound-suggestions.rs:69:46
    |
 LL |     const SIZE: usize = core::mem::size_of::<Self>();
    |                                              ^^^^ doesn't have a size known at compile-time
diff --git a/tests/ui/suggestions/constrain-trait.fixed b/tests/ui/suggestions/constrain-trait.fixed
index f292f27f0f3..f7360efe4c5 100644
--- a/tests/ui/suggestions/constrain-trait.fixed
+++ b/tests/ui/suggestions/constrain-trait.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 // check-only
+#![allow(dead_code)]
 
 #[derive(Debug)]
 struct Demo {
diff --git a/tests/ui/suggestions/constrain-trait.rs b/tests/ui/suggestions/constrain-trait.rs
index 99ccf7a7f3b..799100669b6 100644
--- a/tests/ui/suggestions/constrain-trait.rs
+++ b/tests/ui/suggestions/constrain-trait.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 // check-only
+#![allow(dead_code)]
 
 #[derive(Debug)]
 struct Demo {
diff --git a/tests/ui/suggestions/constrain-trait.stderr b/tests/ui/suggestions/constrain-trait.stderr
index a26f86917bc..b28972ecde0 100644
--- a/tests/ui/suggestions/constrain-trait.stderr
+++ b/tests/ui/suggestions/constrain-trait.stderr
@@ -1,5 +1,5 @@
 error[E0599]: no method named `get_a` found for reference `&Self` in the current scope
-  --> $DIR/constrain-trait.rs:15:31
+  --> $DIR/constrain-trait.rs:16:31
    |
 LL |         println!("{:?}", self.get_a());
    |                               ^^^^^ method not found in `&Self`
@@ -11,7 +11,7 @@ LL | trait UseString: std::fmt::Debug + GetString {
    |                                  +++++++++++
 
 error[E0599]: no method named `get_a` found for reference `&Self` in the current scope
-  --> $DIR/constrain-trait.rs:21:31
+  --> $DIR/constrain-trait.rs:22:31
    |
 LL |         println!("{:?}", self.get_a());
    |                               ^^^^^ method not found in `&Self`
diff --git a/tests/ui/suggestions/derive-trait-for-method-call.rs b/tests/ui/suggestions/derive-trait-for-method-call.rs
index 25043da52aa..b5ce0078c9b 100644
--- a/tests/ui/suggestions/derive-trait-for-method-call.rs
+++ b/tests/ui/suggestions/derive-trait-for-method-call.rs
@@ -19,7 +19,7 @@ struct CloneStruct {
 struct Foo<X, Y> (X, Y);
 impl<X: Clone + Default + , Y: Clone + Default> Foo<X, Y> {
     fn test(&self) -> (X, Y) {
-        (self.0, self.1)
+        (self.0.clone(), self.1.clone())
     }
 }
 
diff --git a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs
index 255cab06070..c24672816ac 100644
--- a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs
+++ b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs
@@ -64,6 +64,8 @@ mod bay {
 
     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32> + 'a>) -> &'a () {
         val.use_self()
+        //~^ ERROR: cannot return value referencing function parameter `val`
+        //~| ERROR: borrowed data escapes outside of function
     }
 }
 
@@ -86,6 +88,7 @@ mod bax {
 
     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32> + 'a>) -> &'a () {
         val.use_self()
+        //~^ ERROR: cannot return value referencing function parameter `val`
     }
 }
 
diff --git a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr
index a7e03f491b9..505765d2b41 100644
--- a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr
+++ b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.stderr
@@ -17,7 +17,7 @@ LL |         val.use_self()
    |         `val` is borrowed here
 
 error[E0515]: cannot return value referencing function parameter `val`
-  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:109:9
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:112:9
    |
 LL |         val.use_self()
    |         ---^^^^^^^^^^^
@@ -25,6 +25,50 @@ LL |         val.use_self()
    |         returns a value referencing data owned by the current function
    |         `val` is borrowed here
 
-error: aborting due to 3 previous errors
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:66:9
+   |
+LL |     fn use_it<'a>(val: Box<dyn ObjectTrait<Assoc = i32> + 'a>) -> &'a () {
+   |               --  --- `val` is a reference that is only valid in the function body
+   |               |
+   |               lifetime `'a` defined here
+LL |         val.use_self()
+   |         ^^^^^^^^^^^^^^
+   |         |
+   |         `val` escapes the function body here
+   |         argument requires that `'a` must outlive `'static`
+   |
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:60:30
+   |
+LL |     impl MyTrait for Box<dyn ObjectTrait<Assoc = i32>> {
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+LL |         fn use_self(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s `'static` requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl MyTrait for Box<dyn ObjectTrait<Assoc = i32> + '_> {
+   |                                                       ++++
+
+error[E0515]: cannot return value referencing function parameter `val`
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:66:9
+   |
+LL |         val.use_self()
+   |         ---^^^^^^^^^^^
+   |         |
+   |         returns a value referencing data owned by the current function
+   |         `val` is borrowed here
+
+error[E0515]: cannot return value referencing function parameter `val`
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound-needing-more-suggestions.rs:90:9
+   |
+LL |         val.use_self()
+   |         ---^^^^^^^^^^^
+   |         |
+   |         returns a value referencing data owned by the current function
+   |         `val` is borrowed here
+
+error: aborting due to 6 previous errors
 
-For more information about this error, try `rustc --explain E0515`.
+Some errors have detailed explanations: E0515, E0521.
+For more information about an error, try `rustc --explain E0515`.
diff --git a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs
index ae3cd315c83..574aea9cc6e 100644
--- a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs
+++ b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.rs
@@ -36,6 +36,7 @@ mod bar {
 
     fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
         val.use_self()
+        //~^ ERROR: borrowed data escapes
     }
 }
 
@@ -53,6 +54,7 @@ mod baz {
 
     fn use_it<'a>(val: &'a Box<dyn ObjectTrait + 'a>) -> &'a () {
         val.use_self()
+        //~^ ERROR: borrowed data escapes
     }
 }
 
diff --git a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr
index da72c8ebf19..6effaf61099 100644
--- a/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr
+++ b/tests/ui/suggestions/impl-on-dyn-trait-with-implicit-static-bound.stderr
@@ -24,7 +24,7 @@ LL |     impl<T> MyTrait<T> for dyn ObjectTrait<T> + '_ {
    |                                               ++++
 
 error[E0521]: borrowed data escapes outside of function
-  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:70:9
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:72:9
    |
 LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
    |               --  --- `val` is a reference that is only valid in the function body
@@ -37,7 +37,7 @@ LL |         val.use_self()
    |         argument requires that `'a` must outlive `'static`
    |
 note: the used `impl` has a `'static` requirement
-  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:65:14
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:67:14
    |
 LL |     impl dyn ObjectTrait {
    |              ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
@@ -49,7 +49,7 @@ LL |     impl dyn ObjectTrait + '_ {
    |                          ++++
 
 error[E0521]: borrowed data escapes outside of function
-  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:90:9
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:92:9
    |
 LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> {
    |               --  --- `val` is a reference that is only valid in the function body
@@ -62,7 +62,7 @@ LL |         val.use_self()
    |         argument requires that `'a` must outlive `'static`
    |
 note: the used `impl` has a `'static` requirement
-  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:87:26
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:89:26
    |
 LL |         fn use_self(&self) -> &() { panic!() }
    |            -------- calling this method introduces the `impl`'s `'static` requirement
@@ -75,7 +75,7 @@ LL |     impl MyTrait for dyn ObjectTrait + '_ {}
    |                                      ++++
 
 error[E0521]: borrowed data escapes outside of function
-  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:110:9
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:112:9
    |
 LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> impl OtherTrait<'a> + 'a {
    |               --  --- `val` is a reference that is only valid in the function body
@@ -88,7 +88,7 @@ LL |         MyTrait::use_self(val)
    |         argument requires that `'a` must outlive `'static`
    |
 note: the used `impl` has a `'static` requirement
-  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:106:26
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:108:26
    |
 LL |         fn use_self(&self) -> &() { panic!() }
    |            -------- calling this method introduces the `impl`'s `'static` requirement
@@ -100,6 +100,56 @@ help: consider relaxing the implicit `'static` requirement
 LL |     impl MyTrait for dyn ObjectTrait + '_ {}
    |                                      ++++
 
-error: aborting due to 4 previous errors
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:38:9
+   |
+LL |     fn use_it<'a>(val: &'a dyn ObjectTrait) -> &'a () {
+   |               --  --- `val` is a reference that is only valid in the function body
+   |               |
+   |               lifetime `'a` defined here
+LL |         val.use_self()
+   |         ^^^^^^^^^^^^^^
+   |         |
+   |         `val` escapes the function body here
+   |         argument requires that `'a` must outlive `'static`
+   |
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:32:26
+   |
+LL |     impl MyTrait for dyn ObjectTrait {
+   |                          ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+LL |         fn use_self(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s `'static` requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl MyTrait for dyn ObjectTrait + '_ {
+   |                                      ++++
+
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:56:9
+   |
+LL |     fn use_it<'a>(val: &'a Box<dyn ObjectTrait + 'a>) -> &'a () {
+   |               --  --- `val` is a reference that is only valid in the function body
+   |               |
+   |               lifetime `'a` defined here
+LL |         val.use_self()
+   |         ^^^^^^^^^^^^^^
+   |         |
+   |         `val` escapes the function body here
+   |         argument requires that `'a` must outlive `'static`
+   |
+note: the used `impl` has a `'static` requirement
+  --> $DIR/impl-on-dyn-trait-with-implicit-static-bound.rs:50:30
+   |
+LL |     impl MyTrait for Box<dyn ObjectTrait> {
+   |                              ^^^^^^^^^^^ this has an implicit `'static` lifetime requirement
+LL |         fn use_self(&self) -> &() { panic!() }
+   |            -------- calling this method introduces the `impl`'s `'static` requirement
+help: consider relaxing the implicit `'static` requirement
+   |
+LL |     impl MyTrait for Box<dyn ObjectTrait + '_> {
+   |                                          ++++
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0521`.
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime.rs b/tests/ui/suggestions/impl-trait-missing-lifetime.rs
index 6f7c912d707..b03d6161493 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime.rs
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime.rs
@@ -8,6 +8,7 @@ fn f(_: impl Iterator<Item = &'_ ()>) {}
 // But that lifetime does not participate in resolution.
 fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
 //~^ ERROR missing lifetime specifier
+//~| ERROR lifetime may not live long enough
 
 // This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
 async fn h(_: impl Iterator<Item = &'_ ()>) {}
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr
index c1dbaae0649..70998b67c04 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr
@@ -20,7 +20,7 @@ LL + fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
    |
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/impl-trait-missing-lifetime.rs:16:60
+  --> $DIR/impl-trait-missing-lifetime.rs:17:60
    |
 LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
    |                                                            ^^ expected named lifetime parameter
@@ -41,13 +41,19 @@ LL + async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
    |
 
 error: lifetime may not live long enough
-  --> $DIR/impl-trait-missing-lifetime.rs:16:69
+  --> $DIR/impl-trait-missing-lifetime.rs:17:69
    |
 LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
    | -----------------------------------------------------------------   ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
    | |
    | return type `impl Future<Output = Option<&'static ()>>` contains a lifetime `'1`
 
-error: aborting due to 3 previous errors
+error: lifetime may not live long enough
+  --> $DIR/impl-trait-missing-lifetime.rs:9:63
+   |
+LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
+   |      ----- has type `x`                                       ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/suggestions/invalid-bin-op.stderr b/tests/ui/suggestions/invalid-bin-op.stderr
index 2bd745c645a..018250c8c1b 100644
--- a/tests/ui/suggestions/invalid-bin-op.stderr
+++ b/tests/ui/suggestions/invalid-bin-op.stderr
@@ -16,6 +16,10 @@ help: consider annotating `S<T>` with `#[derive(PartialEq)]`
 LL + #[derive(PartialEq)]
 LL | struct S<T>(T);
    |
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | pub fn foo<T>(s: S<T>, t: S<T>) where S<T>: PartialEq {
+   |                                 +++++++++++++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/suggestions/issue-102892.rs b/tests/ui/suggestions/issue-102892.rs
index c1a791d8d85..ac7f16f8c65 100644
--- a/tests/ui/suggestions/issue-102892.rs
+++ b/tests/ui/suggestions/issue-102892.rs
@@ -9,6 +9,7 @@ struct B;
 
 fn process_without_annot(arc: &Arc<(A, B)>) {
     let (a, b) = **arc; // suggests putting `&**arc` here; with that, fixed!
+    //~^ ERROR: cannot move out of an `Arc`
 }
 
 fn process_with_annot(arc: &Arc<(A, B)>) {
diff --git a/tests/ui/suggestions/issue-102892.stderr b/tests/ui/suggestions/issue-102892.stderr
index e64a89ffe33..38f19b33218 100644
--- a/tests/ui/suggestions/issue-102892.stderr
+++ b/tests/ui/suggestions/issue-102892.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-102892.rs:15:26
+  --> $DIR/issue-102892.rs:16:26
    |
 LL |     let (a, b): (A, B) = &**arc; // suggests putting `&**arc` here too
    |                 ------   ^^^^^^ expected `(A, B)`, found `&(A, B)`
@@ -19,7 +19,7 @@ LL |     let (a, b): &(A, B) = &**arc; // suggests putting `&**arc` here too
    |                 +
 
 error[E0308]: mismatched types
-  --> $DIR/issue-102892.rs:20:32
+  --> $DIR/issue-102892.rs:21:32
    |
 LL |     let (a, b): ((A, B), A) = (&mut *mutation, &(**arc).0); // suggests putting `&**arc` here too
    |                                ^^^^^^^^^^^^^^ expected `(A, B)`, found `&mut (A, B)`
@@ -37,7 +37,7 @@ LL |     let (a, b): (&mut (A, B), A) = (&mut *mutation, &(**arc).0); // suggest
    |                  ++++
 
 error[E0308]: mismatched types
-  --> $DIR/issue-102892.rs:20:48
+  --> $DIR/issue-102892.rs:21:48
    |
 LL |     let (a, b): ((A, B), A) = (&mut *mutation, &(**arc).0); // suggests putting `&**arc` here too
    |                                                ^^^^^^^^^^ expected `A`, found `&A`
@@ -52,6 +52,23 @@ help: alternatively, consider changing the type annotation
 LL |     let (a, b): ((A, B), &A) = (&mut *mutation, &(**arc).0); // suggests putting `&**arc` here too
    |                          +
 
-error: aborting due to 3 previous errors
+error[E0507]: cannot move out of an `Arc`
+  --> $DIR/issue-102892.rs:11:18
+   |
+LL |     let (a, b) = **arc; // suggests putting `&**arc` here; with that, fixed!
+   |          -  -    ^^^^^
+   |          |  |
+   |          |  ...and here
+   |          data moved here
+   |
+   = note: move occurs because these variables have types that don't implement the `Copy` trait
+help: consider removing the dereference here
+   |
+LL -     let (a, b) = **arc; // suggests putting `&**arc` here; with that, fixed!
+LL +     let (a, b) = *arc; // suggests putting `&**arc` here; with that, fixed!
+   |
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0308, E0507.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/suggestions/issue-109195.rs b/tests/ui/suggestions/issue-109195.rs
new file mode 100644
index 00000000000..cc499b0d776
--- /dev/null
+++ b/tests/ui/suggestions/issue-109195.rs
@@ -0,0 +1,20 @@
+fn main() {
+    String::from::utf8;
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `from_utf8`
+    String::from::utf8();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `from_utf8`
+    String::from::utf16();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP there is an associated function with a similar name: `from_utf16`
+    String::from::method_that_doesnt_exist();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP if there were a trait named `Example` with associated type `from`
+    str::from::utf8();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP if there were a trait named `Example` with associated type `from`
+    str::from::utf8_mut();
+    //~^ ERROR ambiguous associated type [E0223]
+    //~| HELP if there were a trait named `Example` with associated type `from`
+}
diff --git a/tests/ui/suggestions/issue-109195.stderr b/tests/ui/suggestions/issue-109195.stderr
new file mode 100644
index 00000000000..10cf9cfd28c
--- /dev/null
+++ b/tests/ui/suggestions/issue-109195.stderr
@@ -0,0 +1,69 @@
+error[E0223]: ambiguous associated type
+  --> $DIR/issue-109195.rs:2:5
+   |
+LL |     String::from::utf8;
+   |     ^^^^^^^^^^^^
+   |
+help: there is an associated function with a similar name: `from_utf8`
+   |
+LL |     String::from_utf8;
+   |             ~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/issue-109195.rs:5:5
+   |
+LL |     String::from::utf8();
+   |     ^^^^^^^^^^^^
+   |
+help: there is an associated function with a similar name: `from_utf8`
+   |
+LL |     String::from_utf8();
+   |             ~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/issue-109195.rs:8:5
+   |
+LL |     String::from::utf16();
+   |     ^^^^^^^^^^^^
+   |
+help: there is an associated function with a similar name: `from_utf16`
+   |
+LL |     String::from_utf16();
+   |             ~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/issue-109195.rs:11:5
+   |
+LL |     String::from::method_that_doesnt_exist();
+   |     ^^^^^^^^^^^^
+   |
+help: if there were a trait named `Example` with associated type `from` implemented for `String`, you could use the fully-qualified path
+   |
+LL |     <String as Example>::from::method_that_doesnt_exist();
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/issue-109195.rs:14:5
+   |
+LL |     str::from::utf8();
+   |     ^^^^^^^^^
+   |
+help: if there were a trait named `Example` with associated type `from` implemented for `str`, you could use the fully-qualified path
+   |
+LL |     <str as Example>::from::utf8();
+   |     ~~~~~~~~~~~~~~~~~~~~~~
+
+error[E0223]: ambiguous associated type
+  --> $DIR/issue-109195.rs:17:5
+   |
+LL |     str::from::utf8_mut();
+   |     ^^^^^^^^^
+   |
+help: if there were a trait named `Example` with associated type `from` implemented for `str`, you could use the fully-qualified path
+   |
+LL |     <str as Example>::from::utf8_mut();
+   |     ~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 6 previous errors
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/suggestions/issue-61963.rs b/tests/ui/suggestions/issue-61963.rs
index a27c3845253..d31ed01b191 100644
--- a/tests/ui/suggestions/issue-61963.rs
+++ b/tests/ui/suggestions/issue-61963.rs
@@ -18,20 +18,10 @@ pub struct Qux<T>(T);
 pub struct Foo {
     //~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
     //~| WARN this is accepted in the current edition
-    //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this is accepted in the current edition
-    //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this is accepted in the current edition
-    //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this is accepted in the current edition
     qux: Qux<Qux<Baz>>,
     bar: Box<Bar>,
     //~^ ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
     //~| WARN this is accepted in the current edition
-    //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this is accepted in the current edition
-    //~| ERROR trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
-    //~| WARN this is accepted in the current edition
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/issue-61963.stderr b/tests/ui/suggestions/issue-61963.stderr
index ec62153b0a7..754d02b1c02 100644
--- a/tests/ui/suggestions/issue-61963.stderr
+++ b/tests/ui/suggestions/issue-61963.stderr
@@ -1,5 +1,5 @@
 error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/issue-61963.rs:28:14
+  --> $DIR/issue-61963.rs:22:14
    |
 LL |     bar: Box<Bar>,
    |              ^^^
@@ -29,75 +29,5 @@ help: use `dyn`
 LL | dyn pub struct Foo {
    | +++
 
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/issue-61963.rs:28:14
-   |
-LL |     bar: Box<Bar>,
-   |              ^^^
-   |
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL |     bar: Box<dyn Bar>,
-   |              +++
-
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/issue-61963.rs:28:14
-   |
-LL |     bar: Box<Bar>,
-   |              ^^^
-   |
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL |     bar: Box<dyn Bar>,
-   |              +++
-
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/issue-61963.rs:18:1
-   |
-LL | pub struct Foo {
-   | ^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | dyn pub struct Foo {
-   | +++
-
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/issue-61963.rs:18:1
-   |
-LL | pub struct Foo {
-   | ^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | dyn pub struct Foo {
-   | +++
-
-error: trait objects without an explicit `dyn` are deprecated
-  --> $DIR/issue-61963.rs:18:1
-   |
-LL | pub struct Foo {
-   | ^^^
-   |
-   = 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: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
-   |
-LL | dyn pub struct Foo {
-   | +++
-
-error: aborting due to 7 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/suggestions/issue-86667.rs b/tests/ui/suggestions/issue-86667.rs
index 366787df1b4..b1a7e6e9665 100644
--- a/tests/ui/suggestions/issue-86667.rs
+++ b/tests/ui/suggestions/issue-86667.rs
@@ -4,14 +4,15 @@
 // compile-flags: --edition 2018
 
 async fn a(s1: &str, s2: &str) -> &str {
-//~^ ERROR: missing lifetime specifier [E0106]
+    //~^ ERROR: missing lifetime specifier [E0106]
     s1
-//~^ ERROR: lifetime may not live long enough
+    //~^ ERROR: lifetime may not live long enough
 }
 
 fn b(s1: &str, s2: &str) -> &str {
-//~^ ERROR: missing lifetime specifier [E0106]
+    //~^ ERROR: missing lifetime specifier [E0106]
     s1
+    //~^ ERROR lifetime may not live long enough
 }
 
 fn main() {}
diff --git a/tests/ui/suggestions/issue-86667.stderr b/tests/ui/suggestions/issue-86667.stderr
index 8d611641626..e3d673ff233 100644
--- a/tests/ui/suggestions/issue-86667.stderr
+++ b/tests/ui/suggestions/issue-86667.stderr
@@ -31,6 +31,15 @@ LL |
 LL |     s1
    |     ^^ returning this value requires that `'1` must outlive `'static`
 
-error: aborting due to 3 previous errors
+error: lifetime may not live long enough
+  --> $DIR/issue-86667.rs:14:5
+   |
+LL | fn b(s1: &str, s2: &str) -> &str {
+   |          - let's call the lifetime of this reference `'1`
+LL |
+LL |     s1
+   |     ^^ returning this value requires that `'1` must outlive `'static`
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/suggestions/lifetimes/type-param-bound-scope.fixed b/tests/ui/suggestions/lifetimes/type-param-bound-scope.fixed
index 3257ea04c69..d4a8381fcb1 100644
--- a/tests/ui/suggestions/lifetimes/type-param-bound-scope.fixed
+++ b/tests/ui/suggestions/lifetimes/type-param-bound-scope.fixed
@@ -1,6 +1,7 @@
 // Make sure we suggest the bound `T: 'a` in the correct scope:
 // trait, impl or associated fn.
 // run-rustfix
+#![allow(dead_code)]
 
 struct Inv<'a>(#[allow(dead_code)] Option<*mut &'a u8>);
 
diff --git a/tests/ui/suggestions/lifetimes/type-param-bound-scope.rs b/tests/ui/suggestions/lifetimes/type-param-bound-scope.rs
index fcc13aad996..dc43e2df6dd 100644
--- a/tests/ui/suggestions/lifetimes/type-param-bound-scope.rs
+++ b/tests/ui/suggestions/lifetimes/type-param-bound-scope.rs
@@ -1,6 +1,7 @@
 // Make sure we suggest the bound `T: 'a` in the correct scope:
 // trait, impl or associated fn.
 // run-rustfix
+#![allow(dead_code)]
 
 struct Inv<'a>(#[allow(dead_code)] Option<*mut &'a u8>);
 
diff --git a/tests/ui/suggestions/lifetimes/type-param-bound-scope.stderr b/tests/ui/suggestions/lifetimes/type-param-bound-scope.stderr
index d3ca2cc1162..91054472c04 100644
--- a/tests/ui/suggestions/lifetimes/type-param-bound-scope.stderr
+++ b/tests/ui/suggestions/lifetimes/type-param-bound-scope.stderr
@@ -1,5 +1,5 @@
 error[E0309]: the parameter type `Self` may not live long enough
-  --> $DIR/type-param-bound-scope.rs:11:9
+  --> $DIR/type-param-bound-scope.rs:12:9
    |
 LL | trait Trait1<'a>: Sized {
    |              -- the parameter type `Self` must be valid for the lifetime `'a` as defined here...
@@ -13,7 +13,7 @@ LL | trait Trait1<'a>: Sized where Self: 'a {
    |                         ++++++++++++++
 
 error[E0309]: the parameter type `Self` may not live long enough
-  --> $DIR/type-param-bound-scope.rs:18:9
+  --> $DIR/type-param-bound-scope.rs:19:9
    |
 LL |     fn foo<'a>(self, lt: Inv<'a>) {
    |            -- the parameter type `Self` must be valid for the lifetime `'a` as defined here...
@@ -26,7 +26,7 @@ LL |     fn foo<'a>(self, lt: Inv<'a>) where Self: 'a {
    |                                   ++++++++++++++
 
 error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/type-param-bound-scope.rs:25:9
+  --> $DIR/type-param-bound-scope.rs:26:9
    |
 LL |     fn foo<'a>(arg: T, lt: Inv<'a>) {
    |            -- the parameter type `T` must be valid for the lifetime `'a` as defined here...
@@ -39,7 +39,7 @@ LL |     fn foo<'a>(arg: T, lt: Inv<'a>) where T: 'a {
    |                                     +++++++++++
 
 error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/type-param-bound-scope.rs:32:9
+  --> $DIR/type-param-bound-scope.rs:33:9
    |
 LL | trait Trait4<'a> {
    |              -- the parameter type `T` must be valid for the lifetime `'a` as defined here...
@@ -53,7 +53,7 @@ LL |     fn foo<T: 'a>(arg: T, lt: Inv<'a>) {
    |             ++++
 
 error[E0309]: the parameter type `T` may not live long enough
-  --> $DIR/type-param-bound-scope.rs:42:9
+  --> $DIR/type-param-bound-scope.rs:43:9
    |
 LL | impl<'a, T> Trait5<'a> for T {
    |      -- the parameter type `T` must be valid for the lifetime `'a` as defined here...
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed
index 47b35b412c0..53476ee8c59 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.fixed
@@ -8,8 +8,8 @@ pub struct Vector2<T: Debug + Copy + Clone>{
 }
 
 #[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type
-pub struct AABB<K: Copy + Debug>{
-    pub loc: Vector2<K>,
+pub struct AABB<K: Copy + Debug + std::fmt::Debug>{
+    pub loc: Vector2<K>, //~ ERROR `K` doesn't implement `Debug`
     pub size: Vector2<K>
 }
 
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs
index 771e9105c62..08c4f344e4e 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.rs
@@ -9,7 +9,7 @@ pub struct Vector2<T: Debug + Copy + Clone>{
 
 #[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type
 pub struct AABB<K: Copy>{
-    pub loc: Vector2<K>,
+    pub loc: Vector2<K>, //~ ERROR `K` doesn't implement `Debug`
     pub size: Vector2<K>
 }
 
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr
index ed1bde5f83e..bfb96b4076b 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-3.stderr
@@ -18,6 +18,23 @@ help: consider further restricting this bound
 LL | pub struct AABB<K: Copy + Debug>{
    |                         +++++++
 
-error: aborting due to 1 previous error
+error[E0277]: `K` doesn't implement `Debug`
+  --> $DIR/missing-bound-in-derive-copy-impl-3.rs:12:14
+   |
+LL |     pub loc: Vector2<K>,
+   |              ^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+note: required by a bound in `Vector2`
+  --> $DIR/missing-bound-in-derive-copy-impl-3.rs:5:23
+   |
+LL | pub struct Vector2<T: Debug + Copy + Clone>{
+   |                       ^^^^^ required by this bound in `Vector2`
+help: consider further restricting this bound
+   |
+LL | pub struct AABB<K: Copy + std::fmt::Debug>{
+   |                         +++++++++++++++++
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0204`.
+Some errors have detailed explanations: E0204, E0277.
+For more information about an error, try `rustc --explain E0204`.
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs
index 9c7b7ba099c..2f1ebc1f133 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.rs
@@ -9,6 +9,8 @@ pub struct Vector2<T: Debug + Copy + Clone>{
 #[derive(Debug, Copy, Clone)] //~ ERROR the trait `Copy` cannot be implemented for this type
 pub struct AABB<K>{
     pub loc: Vector2<K>,
+    //~^ ERROR doesn't implement `Debug`
+    //~| ERROR `K: Copy` is not satisfied
     pub size: Vector2<K>
 }
 
diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr
index 03db737fa87..f3213e1a4c8 100644
--- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr
+++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr
@@ -18,6 +18,39 @@ help: consider restricting type parameter `K`
 LL | pub struct AABB<K: Debug>{
    |                  +++++++
 
-error: aborting due to 1 previous error
+error[E0277]: `K` doesn't implement `Debug`
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:11:14
+   |
+LL |     pub loc: Vector2<K>,
+   |              ^^^^^^^^^^ `K` cannot be formatted using `{:?}` because it doesn't implement `Debug`
+   |
+note: required by a bound in `Vector2`
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:4:23
+   |
+LL | pub struct Vector2<T: Debug + Copy + Clone>{
+   |                       ^^^^^ required by this bound in `Vector2`
+help: consider restricting type parameter `K`
+   |
+LL | pub struct AABB<K: std::fmt::Debug>{
+   |                  +++++++++++++++++
+
+error[E0277]: the trait bound `K: Copy` is not satisfied
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:11:14
+   |
+LL |     pub loc: Vector2<K>,
+   |              ^^^^^^^^^^ the trait `Copy` is not implemented for `K`
+   |
+note: required by a bound in `Vector2`
+  --> $DIR/missing-bound-in-derive-copy-impl.rs:4:31
+   |
+LL | pub struct Vector2<T: Debug + Copy + Clone>{
+   |                               ^^^^ required by this bound in `Vector2`
+help: consider restricting type parameter `K`
+   |
+LL | pub struct AABB<K: std::marker::Copy>{
+   |                  +++++++++++++++++++
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0204`.
+Some errors have detailed explanations: E0204, E0277.
+For more information about an error, try `rustc --explain E0204`.
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed
index f32c61a99bb..90bc10d34c6 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 #[derive(Clone)]
 struct Wrapper<T>(T);
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs
index d7725f4a374..34673852a9b 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 #[derive(Clone)]
 struct Wrapper<T>(T);
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr
index 6dc512223d1..23a75154f20 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl-2.stderr
@@ -1,5 +1,5 @@
 error[E0204]: the trait `Copy` cannot be implemented for this type
-  --> $DIR/missing-bound-in-manual-copy-impl-2.rs:16:18
+  --> $DIR/missing-bound-in-manual-copy-impl-2.rs:17:18
    |
 LL | struct Wrapper<T>(T);
    |                   - this field does not implement `Copy`
@@ -8,7 +8,7 @@ LL | impl<S> Copy for Wrapper<OnlyCopyIfDisplay<S>> {}
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: the `Copy` impl for `OnlyCopyIfDisplay<S>` requires that `S: std::fmt::Display`
-  --> $DIR/missing-bound-in-manual-copy-impl-2.rs:4:19
+  --> $DIR/missing-bound-in-manual-copy-impl-2.rs:5:19
    |
 LL | struct Wrapper<T>(T);
    |                   ^
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed
index 1139b315313..ff84e42c947 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 #[derive(Clone)]
 struct Wrapper<T>(T);
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs
index 19549248efc..35d0a9dda79 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 #[derive(Clone)]
 struct Wrapper<T>(T);
diff --git a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr
index fd38d4c64b4..c9f277fb350 100644
--- a/tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr
+++ b/tests/ui/suggestions/missing-bound-in-manual-copy-impl.stderr
@@ -1,5 +1,5 @@
 error[E0204]: the trait `Copy` cannot be implemented for this type
-  --> $DIR/missing-bound-in-manual-copy-impl.rs:6:18
+  --> $DIR/missing-bound-in-manual-copy-impl.rs:7:18
    |
 LL | struct Wrapper<T>(T);
    |                   - this field does not implement `Copy`
diff --git a/tests/ui/suggestions/missing-lifetime-specifier.rs b/tests/ui/suggestions/missing-lifetime-specifier.rs
index 01dcc94f747..85dd6a5635a 100644
--- a/tests/ui/suggestions/missing-lifetime-specifier.rs
+++ b/tests/ui/suggestions/missing-lifetime-specifier.rs
@@ -1,4 +1,6 @@
 // different number of duplicated diagnostics on different targets
+// only-x86_64
+// only-linux
 // compile-flags: -Zdeduplicate-diagnostics=yes
 
 #![allow(bare_trait_objects)]
@@ -18,21 +20,31 @@ pub union Qux<'t, 'k, I> {
 trait Tar<'t, 'k, I> {}
 
 thread_local! {
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
     static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
       //~^ ERROR missing lifetime specifiers
       //~| ERROR missing lifetime specifiers
 }
 thread_local! {
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
       //~^ ERROR missing lifetime specifiers
       //~| ERROR missing lifetime specifiers
 }
 thread_local! {
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
     //~^ ERROR missing lifetime specifiers
     //~| ERROR missing lifetime specifiers
 }
 thread_local! {
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
+    //~| ERROR lifetime may not live long enough
     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
     //~^ ERROR missing lifetime specifiers
     //~| ERROR missing lifetime specifiers
diff --git a/tests/ui/suggestions/missing-lifetime-specifier.stderr b/tests/ui/suggestions/missing-lifetime-specifier.stderr
index 7a7ef47c35b..62eca162148 100644
--- a/tests/ui/suggestions/missing-lifetime-specifier.stderr
+++ b/tests/ui/suggestions/missing-lifetime-specifier.stderr
@@ -1,5 +1,5 @@
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:21:44
+  --> $DIR/missing-lifetime-specifier.rs:25:44
    |
 LL |     static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
    |                                            ^^^ expected 2 lifetime parameters
@@ -11,9 +11,11 @@ LL |     static a: RefCell<HashMap<i32, Vec<Vec<Foo<'static, 'static>>>>> = RefC
    |                                               ++++++++++++++++++
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:21:44
+  --> $DIR/missing-lifetime-specifier.rs:25:44
    |
 LL | / thread_local! {
+LL | |
+LL | |
 LL | |     static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
    | |                                            ^^^ expected 2 lifetime parameters
 LL | |
@@ -24,7 +26,7 @@ LL | | }
    = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:26:44
+  --> $DIR/missing-lifetime-specifier.rs:33:44
    |
 LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
    |                                            ^^^^ expected 2 lifetime parameters
@@ -38,9 +40,12 @@ LL |     static b: RefCell<HashMap<i32, Vec<Vec<&'static Bar<'static, 'static>>>
    |                                             +++++++    ++++++++++++++++++
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:26:44
+  --> $DIR/missing-lifetime-specifier.rs:33:44
    |
 LL | / thread_local! {
+LL | |
+LL | |
+LL | |
 LL | |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
    | |                                            ^^^^ expected 2 lifetime parameters
    | |                                            |
@@ -53,7 +58,7 @@ LL | | }
    = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 4 lifetimes it is borrowed from
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:31:47
+  --> $DIR/missing-lifetime-specifier.rs:40:47
    |
 LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
    |                                               ^ expected 2 lifetime parameters
@@ -65,9 +70,11 @@ LL |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
    |                                                +++++++++++++++++
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:31:47
+  --> $DIR/missing-lifetime-specifier.rs:40:47
    |
 LL | / thread_local! {
+LL | |
+LL | |
 LL | |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
    | |                                               ^ expected 2 lifetime parameters
 LL | |
@@ -78,7 +85,7 @@ LL | | }
    = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:36:44
+  --> $DIR/missing-lifetime-specifier.rs:48:44
    |
 LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^   ^ expected 2 lifetime parameters
@@ -92,9 +99,12 @@ LL |     static d: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, 'static, i
    |                                             +++++++     +++++++++++++++++
 
 error[E0106]: missing lifetime specifiers
-  --> $DIR/missing-lifetime-specifier.rs:36:44
+  --> $DIR/missing-lifetime-specifier.rs:48:44
    |
 LL | / thread_local! {
+LL | |
+LL | |
+LL | |
 LL | |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
    | |                                            ^   ^ expected 2 lifetime parameters
    | |                                            |
@@ -107,7 +117,7 @@ LL | | }
    = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 4 lifetimes it is borrowed from
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-specifier.rs:46:44
+  --> $DIR/missing-lifetime-specifier.rs:58:44
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^ expected named lifetime parameter
@@ -119,7 +129,7 @@ LL |     static f: RefCell<HashMap<i32, Vec<Vec<&'static Tar<'static, i32>>>>> =
    |                                             +++++++
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/missing-lifetime-specifier.rs:46:44
+  --> $DIR/missing-lifetime-specifier.rs:58:44
    |
 LL | / thread_local! {
 LL | |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
@@ -133,7 +143,7 @@ LL | | }
    = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from
 
 error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied
-  --> $DIR/missing-lifetime-specifier.rs:42:44
+  --> $DIR/missing-lifetime-specifier.rs:54:44
    |
 LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                            ^^^ ------- supplied 1 lifetime argument
@@ -141,7 +151,7 @@ LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, i32>>>>> = RefCell:
    |                                            expected 2 lifetime arguments
    |
 note: union defined here, with 2 lifetime parameters: `'t`, `'k`
-  --> $DIR/missing-lifetime-specifier.rs:14:11
+  --> $DIR/missing-lifetime-specifier.rs:16:11
    |
 LL | pub union Qux<'t, 'k, I> {
    |           ^^^ --  --
@@ -151,7 +161,7 @@ LL |     static e: RefCell<HashMap<i32, Vec<Vec<Qux<'static, 'static, i32>>>>> =
    |                                                       +++++++++
 
 error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied
-  --> $DIR/missing-lifetime-specifier.rs:46:45
+  --> $DIR/missing-lifetime-specifier.rs:58:45
    |
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                             ^^^ ------- supplied 1 lifetime argument
@@ -159,7 +169,7 @@ LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, i32>>>>> = RefCell
    |                                             expected 2 lifetime arguments
    |
 note: trait defined here, with 2 lifetime parameters: `'t`, `'k`
-  --> $DIR/missing-lifetime-specifier.rs:18:7
+  --> $DIR/missing-lifetime-specifier.rs:20:7
    |
 LL | trait Tar<'t, 'k, I> {}
    |       ^^^ --  --
@@ -168,7 +178,199 @@ help: add missing lifetime argument
 LL |     static f: RefCell<HashMap<i32, Vec<Vec<&Tar<'static, 'static, i32>>>>> = RefCell::new(HashMap::new());
    |                                                        +++++++++
 
-error: aborting due to 12 previous errors
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:22:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |     static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
+LL | |
+LL | |
+LL | | }
+   | | ^
+   | | |
+   | |_has type `Option<&mut Option<RefCell<HashMap<i32, Vec<Vec<Foo<'1, '_>>>>>>>`
+   |   returning this value requires that `'1` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:22:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |     static a: RefCell<HashMap<i32, Vec<Vec<Foo>>>> = RefCell::new(HashMap::new());
+LL | |
+LL | |
+LL | | }
+   | | ^
+   | | |
+   | |_has type `Option<&mut Option<RefCell<HashMap<i32, Vec<Vec<Foo<'_, '2>>>>>>>`
+   |   returning this value requires that `'2` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:29:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |
+LL | |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar>>>> = RefCell::new(HashMap::new());
+   | |                                            - let's call the lifetime of this reference `'1`
+LL | |
+LL | |
+LL | | }
+   | |_^ returning this value requires that `'1` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar + '_>>>> = RefCell::new(HashMap::new());
+   |                                                 ++++
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:29:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | | ^
+   | | |
+   | |_has type `Option<&mut Option<RefCell<HashMap<i32, Vec<Vec<&dyn Bar<'2, '_>>>>>>>`
+   |   returning this value requires that `'2` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar + '_>>>> = RefCell::new(HashMap::new());
+   |                                                 ++++
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:29:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | | ^
+   | | |
+   | |_has type `Option<&mut Option<RefCell<HashMap<i32, Vec<Vec<&dyn Bar<'_, '3>>>>>>>`
+   |   returning this value requires that `'3` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound
+   |
+LL |     static b: RefCell<HashMap<i32, Vec<Vec<&Bar + '_>>>> = RefCell::new(HashMap::new());
+   |                                                 ++++
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:37:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
+LL | |
+LL | |
+LL | | }
+   | | ^
+   | | |
+   | |_has type `Option<&mut Option<RefCell<HashMap<i32, Vec<Vec<Qux<'1, '_, i32>>>>>>>`
+   |   returning this value requires that `'1` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:37:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |     static c: RefCell<HashMap<i32, Vec<Vec<Qux<i32>>>>> = RefCell::new(HashMap::new());
+LL | |
+LL | |
+LL | | }
+   | | ^
+   | | |
+   | |_has type `Option<&mut Option<RefCell<HashMap<i32, Vec<Vec<Qux<'_, '2, i32>>>>>>>`
+   |   returning this value requires that `'2` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:44:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |
+LL | |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32>>>>> = RefCell::new(HashMap::new());
+   | |                                            - let's call the lifetime of this reference `'1`
+LL | |
+LL | |
+LL | | }
+   | |_^ returning this value requires that `'1` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32> + '_>>>> = RefCell::new(HashMap::new());
+   |                                                      ++++
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:44:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | | ^
+   | | |
+   | |_has type `Option<&mut Option<RefCell<HashMap<i32, Vec<Vec<&dyn Tar<'2, '_, i32>>>>>>>`
+   |   returning this value requires that `'2` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32> + '_>>>> = RefCell::new(HashMap::new());
+   |                                                      ++++
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lifetime-specifier.rs:44:1
+   |
+LL | / thread_local! {
+LL | |
+LL | |
+LL | |
+...  |
+LL | |
+LL | | }
+   | | ^
+   | | |
+   | |_has type `Option<&mut Option<RefCell<HashMap<i32, Vec<Vec<&dyn Tar<'_, '3, i32>>>>>>>`
+   |   returning this value requires that `'3` must outlive `'static`
+   |
+   = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound
+   |
+LL |     static d: RefCell<HashMap<i32, Vec<Vec<&Tar<i32> + '_>>>> = RefCell::new(HashMap::new());
+   |                                                      ++++
+
+error: aborting due to 22 previous errors
 
 Some errors have detailed explanations: E0106, E0107.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/suggestions/missing-lt-for-hrtb.rs b/tests/ui/suggestions/missing-lt-for-hrtb.rs
index 04ea3d831c9..a48c5665d67 100644
--- a/tests/ui/suggestions/missing-lt-for-hrtb.rs
+++ b/tests/ui/suggestions/missing-lt-for-hrtb.rs
@@ -8,6 +8,8 @@ fn main() {
     let x = S(&|x| {
         println!("hi");
         x
+        //~^ ERROR lifetime may not live long enough
+        //~| ERROR lifetime may not live long enough
     });
     x.0(&X(&()));
 }
diff --git a/tests/ui/suggestions/missing-lt-for-hrtb.stderr b/tests/ui/suggestions/missing-lt-for-hrtb.stderr
index fa515644431..e8c536ac47d 100644
--- a/tests/ui/suggestions/missing-lt-for-hrtb.stderr
+++ b/tests/ui/suggestions/missing-lt-for-hrtb.stderr
@@ -31,6 +31,28 @@ help: consider using one of the available lifetimes here
 LL | struct V<'a>(&'a dyn for<'b> Fn(&X) -> &'lifetime X<'lifetime>);
    |                                         +++++++++  +++++++++++
 
-error: aborting due to 2 previous errors
+error: lifetime may not live long enough
+  --> $DIR/missing-lt-for-hrtb.rs:10:9
+   |
+LL |     let x = S(&|x| {
+   |                 -- return type of closure is &'2 X<'_>
+   |                 |
+   |                 has type `&'1 X<'_>`
+LL |         println!("hi");
+LL |         x
+   |         ^ returning this value requires that `'1` must outlive `'2`
+
+error: lifetime may not live long enough
+  --> $DIR/missing-lt-for-hrtb.rs:10:9
+   |
+LL |     let x = S(&|x| {
+   |                 -- return type of closure is &X<'4>
+   |                 |
+   |                 has type `&X<'3>`
+LL |         println!("hi");
+LL |         x
+   |         ^ returning this value requires that `'3` must outlive `'4`
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/suggestions/missing-trait-item.fixed b/tests/ui/suggestions/missing-trait-item.fixed
index a1cf359ec91..ded4ec19760 100644
--- a/tests/ui/suggestions/missing-trait-item.fixed
+++ b/tests/ui/suggestions/missing-trait-item.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait T {
     unsafe fn foo(a: &usize, b: &usize) -> usize;
diff --git a/tests/ui/suggestions/missing-trait-item.rs b/tests/ui/suggestions/missing-trait-item.rs
index b4fca25ba2f..de8974037ac 100644
--- a/tests/ui/suggestions/missing-trait-item.rs
+++ b/tests/ui/suggestions/missing-trait-item.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait T {
     unsafe fn foo(a: &usize, b: &usize) -> usize;
diff --git a/tests/ui/suggestions/missing-trait-item.stderr b/tests/ui/suggestions/missing-trait-item.stderr
index 4a9d7b472c9..298d0d16438 100644
--- a/tests/ui/suggestions/missing-trait-item.stderr
+++ b/tests/ui/suggestions/missing-trait-item.stderr
@@ -1,5 +1,5 @@
 error[E0046]: not all trait items implemented, missing: `foo`, `bar`
-  --> $DIR/missing-trait-item.rs:10:5
+  --> $DIR/missing-trait-item.rs:11:5
    |
 LL |     unsafe fn foo(a: &usize, b: &usize) -> usize;
    |     --------------------------------------------- `foo` from trait
@@ -10,7 +10,7 @@ LL |     impl T for () {}
    |     ^^^^^^^^^^^^^ missing `foo`, `bar` in implementation
 
 error[E0046]: not all trait items implemented, missing: `foo`, `bar`
-  --> $DIR/missing-trait-item.rs:12:5
+  --> $DIR/missing-trait-item.rs:13:5
    |
 LL |     unsafe fn foo(a: &usize, b: &usize) -> usize;
    |     --------------------------------------------- `foo` from trait
diff --git a/tests/ui/tag-variant-cast-non-nullary.stderr b/tests/ui/tag-variant-cast-non-nullary.stderr
index 560dd7e8164..2e1dde27d0f 100644
--- a/tests/ui/tag-variant-cast-non-nullary.stderr
+++ b/tests/ui/tag-variant-cast-non-nullary.stderr
@@ -4,7 +4,8 @@ error[E0605]: non-primitive cast: `NonNullary` as `isize`
 LL |     let val = v as isize;
    |               ^^^^^^^^^^ help: consider using the `From` trait instead: `isize::from(v)`
    |
-   = note: an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+   = note: an `as` expression can be used to convert enum types to numeric types only if the enum type is unit-only or field-less
+   = note: see https://doc.rust-lang.org/reference/items/enumerations.html#casting for more information
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/threads-sendsync/sync-send-atomics.rs b/tests/ui/threads-sendsync/sync-send-atomics.rs
index 0466f4f0e9d..6b260311a50 100644
--- a/tests/ui/threads-sendsync/sync-send-atomics.rs
+++ b/tests/ui/threads-sendsync/sync-send-atomics.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 // pretty-expanded FIXME #23616
 
diff --git a/tests/ui/traits/alias/bounds.rs b/tests/ui/traits/alias/bounds.rs
index b97eb38c5af..7b1920bc8f2 100644
--- a/tests/ui/traits/alias/bounds.rs
+++ b/tests/ui/traits/alias/bounds.rs
@@ -4,7 +4,7 @@
 
 use std::marker::PhantomData;
 
-trait Empty {}
+trait Empty {} //~ WARN trait `Empty` is never used
 trait EmptyAlias = Empty;
 trait CloneDefault = Clone + Default;
 trait SendSyncAlias = Send + Sync;
diff --git a/tests/ui/traits/alias/bounds.stderr b/tests/ui/traits/alias/bounds.stderr
new file mode 100644
index 00000000000..7fb8e918da3
--- /dev/null
+++ b/tests/ui/traits/alias/bounds.stderr
@@ -0,0 +1,10 @@
+warning: trait `Empty` is never used
+  --> $DIR/bounds.rs:7:7
+   |
+LL | trait Empty {}
+   |       ^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/alias/syntax.rs b/tests/ui/traits/alias/syntax.rs
index 17557a51aa7..50c77d33c6b 100644
--- a/tests/ui/traits/alias/syntax.rs
+++ b/tests/ui/traits/alias/syntax.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(trait_alias)]
 
diff --git a/tests/ui/traits/bound/impl-comparison-duplicates.rs b/tests/ui/traits/bound/impl-comparison-duplicates.rs
index de6c2afa2bb..a59662c2797 100644
--- a/tests/ui/traits/bound/impl-comparison-duplicates.rs
+++ b/tests/ui/traits/bound/impl-comparison-duplicates.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // Tests that type parameter bounds on an implementation need not match the
 // trait exactly, as long as the implementation doesn't demand *more* bounds
 // than the trait.
diff --git a/tests/ui/traits/bound/recursion.rs b/tests/ui/traits/bound/recursion.rs
index 0023ff654e8..767040dff3f 100644
--- a/tests/ui/traits/bound/recursion.rs
+++ b/tests/ui/traits/bound/recursion.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait I { fn i(&self) -> Self; }
diff --git a/tests/ui/traits/composition-trivial.rs b/tests/ui/traits/composition-trivial.rs
index 90e5dcd68e8..41e6a556074 100644
--- a/tests/ui/traits/composition-trivial.rs
+++ b/tests/ui/traits/composition-trivial.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Foo {
diff --git a/tests/ui/traits/cycle-generic-bound.rs b/tests/ui/traits/cycle-generic-bound.rs
index 9241f3789d7..77685c26da2 100644
--- a/tests/ui/traits/cycle-generic-bound.rs
+++ b/tests/ui/traits/cycle-generic-bound.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // Regression test for #15477. This test just needs to compile.
 
 // pretty-expanded FIXME #23616
diff --git a/tests/ui/traits/default-method/bound-subst4.rs b/tests/ui/traits/default-method/bound-subst4.rs
index ef133064582..6bc4cf0ef80 100644
--- a/tests/ui/traits/default-method/bound-subst4.rs
+++ b/tests/ui/traits/default-method/bound-subst4.rs
@@ -4,7 +4,7 @@
 
 trait A<T> {
     fn g(&self, x: usize) -> usize { x }
-    fn h(&self, x: T) { }
+    fn h(&self, x: T) { } //~ WARN method `h` is never used
 }
 
 impl<T> A<T> for isize { }
diff --git a/tests/ui/traits/default-method/bound-subst4.stderr b/tests/ui/traits/default-method/bound-subst4.stderr
new file mode 100644
index 00000000000..548c46f1233
--- /dev/null
+++ b/tests/ui/traits/default-method/bound-subst4.stderr
@@ -0,0 +1,13 @@
+warning: method `h` is never used
+  --> $DIR/bound-subst4.rs:7:8
+   |
+LL | trait A<T> {
+   |       - method in this trait
+LL |     fn g(&self, x: usize) -> usize { x }
+LL |     fn h(&self, x: T) { }
+   |        ^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/default-method/mut.rs b/tests/ui/traits/default-method/mut.rs
index 5f8e983b09c..3294b96561f 100644
--- a/tests/ui/traits/default-method/mut.rs
+++ b/tests/ui/traits/default-method/mut.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 #![allow(unused_assignments)]
 // pretty-expanded FIXME #23616
 
diff --git a/tests/ui/traits/impl-inherent-prefer-over-trait.rs b/tests/ui/traits/impl-inherent-prefer-over-trait.rs
index 82760788897..f03e730d091 100644
--- a/tests/ui/traits/impl-inherent-prefer-over-trait.rs
+++ b/tests/ui/traits/impl-inherent-prefer-over-trait.rs
@@ -3,7 +3,7 @@
 struct Foo;
 
 trait Trait {
-    fn bar(&self);
+    fn bar(&self); //~ WARN method `bar` is never used
 }
 
 // Inherent impls should be preferred over trait ones.
diff --git a/tests/ui/traits/impl-inherent-prefer-over-trait.stderr b/tests/ui/traits/impl-inherent-prefer-over-trait.stderr
new file mode 100644
index 00000000000..f0bb21402d8
--- /dev/null
+++ b/tests/ui/traits/impl-inherent-prefer-over-trait.stderr
@@ -0,0 +1,12 @@
+warning: method `bar` is never used
+  --> $DIR/impl-inherent-prefer-over-trait.rs:6:8
+   |
+LL | trait Trait {
+   |       ----- method in this trait
+LL |     fn bar(&self);
+   |        ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/impl-object-overlap-issue-23853.rs b/tests/ui/traits/impl-object-overlap-issue-23853.rs
index e490967b690..c0d3af11443 100644
--- a/tests/ui/traits/impl-object-overlap-issue-23853.rs
+++ b/tests/ui/traits/impl-object-overlap-issue-23853.rs
@@ -5,7 +5,7 @@
 // including `Bar`, but the object type `Bar` also implicitly supplies
 // this context.
 
-trait Foo { fn dummy(&self) { } }
+trait Foo { fn dummy(&self) { } } //~ WARN method `dummy` is never used
 
 trait Bar: Foo { }
 
diff --git a/tests/ui/traits/impl-object-overlap-issue-23853.stderr b/tests/ui/traits/impl-object-overlap-issue-23853.stderr
new file mode 100644
index 00000000000..9fa7a36816e
--- /dev/null
+++ b/tests/ui/traits/impl-object-overlap-issue-23853.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/impl-object-overlap-issue-23853.rs:8:16
+   |
+LL | trait Foo { fn dummy(&self) { } }
+   |       ---      ^^^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/impl.rs b/tests/ui/traits/impl.rs
index f512d91ebeb..7bec1b6c9ff 100644
--- a/tests/ui/traits/impl.rs
+++ b/tests/ui/traits/impl.rs
@@ -9,7 +9,7 @@ use traitimpl::Bar;
 static mut COUNT: usize = 1;
 
 trait T {
-    fn t(&self) {}
+    fn t(&self) {} //~ WARN method `t` is never used
 }
 
 impl<'a> dyn T+'a {
diff --git a/tests/ui/traits/impl.stderr b/tests/ui/traits/impl.stderr
new file mode 100644
index 00000000000..98b6fb03d83
--- /dev/null
+++ b/tests/ui/traits/impl.stderr
@@ -0,0 +1,12 @@
+warning: method `t` is never used
+  --> $DIR/impl.rs:12:8
+   |
+LL | trait T {
+   |       - method in this trait
+LL |     fn t(&self) {}
+   |        ^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-33096.rs b/tests/ui/traits/issue-33096.rs
index f0b472e2fe8..f0b472e2fe8 100644
--- a/tests/ui/issues/issue-33096.rs
+++ b/tests/ui/traits/issue-33096.rs
diff --git a/tests/ui/traits/issue-38033.rs b/tests/ui/traits/issue-38033.rs
index 16b867ec88f..4d76df1e8d5 100644
--- a/tests/ui/traits/issue-38033.rs
+++ b/tests/ui/traits/issue-38033.rs
@@ -19,7 +19,7 @@ trait IntoFuture {
     type Item;
     type Error;
 
-    fn into_future(self) -> Self::Future;
+    fn into_future(self) -> Self::Future; //~ WARN method `into_future` is never used
 }
 
 impl<F: Future> IntoFuture for F {
diff --git a/tests/ui/traits/issue-38033.stderr b/tests/ui/traits/issue-38033.stderr
new file mode 100644
index 00000000000..05385e8cf4d
--- /dev/null
+++ b/tests/ui/traits/issue-38033.stderr
@@ -0,0 +1,13 @@
+warning: method `into_future` is never used
+  --> $DIR/issue-38033.rs:22:8
+   |
+LL | trait IntoFuture {
+   |       ---------- method in this trait
+...
+LL |     fn into_future(self) -> Self::Future;
+   |        ^^^^^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-40085.rs b/tests/ui/traits/issue-40085.rs
index 132044cfd6d..132044cfd6d 100644
--- a/tests/ui/issues/issue-40085.rs
+++ b/tests/ui/traits/issue-40085.rs
diff --git a/tests/ui/traits/issue-50480.rs b/tests/ui/traits/issue-50480.rs
index 683a85a32c1..cc7ea32eb3a 100644
--- a/tests/ui/traits/issue-50480.rs
+++ b/tests/ui/traits/issue-50480.rs
@@ -5,11 +5,13 @@ struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
 //~| ERROR cannot find type `NotDefined` in this scope
 //~| ERROR cannot find type `N` in this scope
 //~| ERROR cannot find type `N` in this scope
+//~| ERROR `i32` is not an iterator
 
 #[derive(Clone, Copy)]
 //~^ ERROR the trait `Copy` cannot be implemented for this type
 struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
 //~^ ERROR cannot find type `NotDefined` in this scope
 //~| ERROR cannot find type `N` in this scope
+//~| ERROR `i32` is not an iterator
 
 fn main() {}
diff --git a/tests/ui/traits/issue-50480.stderr b/tests/ui/traits/issue-50480.stderr
index 4f72db60a16..68d3d5c80d0 100644
--- a/tests/ui/traits/issue-50480.stderr
+++ b/tests/ui/traits/issue-50480.stderr
@@ -38,7 +38,7 @@ LL | struct Foo<NotDefined>(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, St
    |           ++++++++++++
 
 error[E0412]: cannot find type `N` in this scope
-  --> $DIR/issue-50480.rs:11:18
+  --> $DIR/issue-50480.rs:12:18
    |
 LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |            -     ^
@@ -55,7 +55,7 @@ LL | struct Bar<T, N>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, Strin
    |             +++
 
 error[E0412]: cannot find type `NotDefined` in this scope
-  --> $DIR/issue-50480.rs:11:21
+  --> $DIR/issue-50480.rs:12:21
    |
 LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |                     ^^^^^^^^^^ not found in this scope
@@ -74,7 +74,7 @@ LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0204]: the trait `Copy` cannot be implemented for this type
-  --> $DIR/issue-50480.rs:9:17
+  --> $DIR/issue-50480.rs:10:17
    |
 LL | #[derive(Clone, Copy)]
    |                 ^^^^
@@ -86,7 +86,25 @@ LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
    |
    = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 8 previous errors
+error[E0277]: `i32` is not an iterator
+  --> $DIR/issue-50480.rs:3:27
+   |
+LL | struct Foo(N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `i32`
+   = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
+
+error[E0277]: `i32` is not an iterator
+  --> $DIR/issue-50480.rs:12:33
+   |
+LL | struct Bar<T>(T, N, NotDefined, <i32 as Iterator>::Item, Vec<i32>, String);
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ `i32` is not an iterator
+   |
+   = help: the trait `Iterator` is not implemented for `i32`
+   = note: if you want to iterate between `start` until a value `end`, use the exclusive range syntax `start..end` or the inclusive range syntax `start..=end`
+
+error: aborting due to 10 previous errors
 
-Some errors have detailed explanations: E0204, E0412.
+Some errors have detailed explanations: E0204, E0277, E0412.
 For more information about an error, try `rustc --explain E0204`.
diff --git a/tests/ui/traits/issue-56488.rs b/tests/ui/traits/issue-56488.rs
index e2f3996927b..8b68f314c04 100644
--- a/tests/ui/traits/issue-56488.rs
+++ b/tests/ui/traits/issue-56488.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(trait_alias)]
 
diff --git a/tests/ui/issues/issue-58344.rs b/tests/ui/traits/issue-58344.rs
index 0cb04dcb22a..0cb04dcb22a 100644
--- a/tests/ui/issues/issue-58344.rs
+++ b/tests/ui/traits/issue-58344.rs
diff --git a/tests/ui/traits/issue-59029-2.rs b/tests/ui/traits/issue-59029-2.rs
index 2bdb128d8c4..fca9f1f13c9 100644
--- a/tests/ui/traits/issue-59029-2.rs
+++ b/tests/ui/traits/issue-59029-2.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 #![feature(trait_alias)]
 
 trait Svc<Req> { type Res; }
diff --git a/tests/ui/traits/issue-6128.rs b/tests/ui/traits/issue-6128.rs
index 07d92f8f8a0..f5fa0de809a 100644
--- a/tests/ui/traits/issue-6128.rs
+++ b/tests/ui/traits/issue-6128.rs
@@ -3,7 +3,7 @@
 use std::collections::HashMap;
 
 trait Graph<Node, Edge> {
-    fn f(&self, _: Edge);
+    fn f(&self, _: Edge); //~ WARN methods `f` and `g` are never used
     fn g(&self, _: Node);
 }
 
diff --git a/tests/ui/traits/issue-6128.stderr b/tests/ui/traits/issue-6128.stderr
new file mode 100644
index 00000000000..c9518ea41ea
--- /dev/null
+++ b/tests/ui/traits/issue-6128.stderr
@@ -0,0 +1,14 @@
+warning: methods `f` and `g` are never used
+  --> $DIR/issue-6128.rs:6:8
+   |
+LL | trait Graph<Node, Edge> {
+   |       ----- methods in this trait
+LL |     fn f(&self, _: Edge);
+   |        ^
+LL |     fn g(&self, _: Node);
+   |        ^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/issue-78372.rs b/tests/ui/traits/issue-78372.rs
index 92f9f4b467a..143325c097c 100644
--- a/tests/ui/traits/issue-78372.rs
+++ b/tests/ui/traits/issue-78372.rs
@@ -6,8 +6,9 @@ impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {} //~ ERROR cannot find type `U`
 //~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures
 trait Foo: X<u32> {}
 trait X<T> {
-    fn foo(self: Smaht<Self, T>);
+    fn foo(self: Smaht<Self, T>); //~ ERROR: invalid `self`
 }
 trait Marker {}
 impl Marker for dyn Foo {}
+//~^ ERROR cannot be made into an object
 fn main() {}
diff --git a/tests/ui/traits/issue-78372.stderr b/tests/ui/traits/issue-78372.stderr
index 44a62988daf..edb07957c44 100644
--- a/tests/ui/traits/issue-78372.stderr
+++ b/tests/ui/traits/issue-78372.stderr
@@ -61,7 +61,34 @@ error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion
 LL | impl<T> DispatchFromDyn<Smaht<U, MISC>> for T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/issue-78372.rs:12:17
+   |
+LL |     fn foo(self: Smaht<Self, T>);
+   |                  -------------- help: consider changing method `foo`'s `self` parameter to be `&self`: `&Self`
+...
+LL | impl Marker for dyn Foo {}
+   |                 ^^^^^^^ `Foo` 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/issue-78372.rs:9:18
+   |
+LL | trait Foo: X<u32> {}
+   |       --- this trait cannot be made into an object...
+LL | trait X<T> {
+LL |     fn foo(self: Smaht<Self, T>);
+   |                  ^^^^^^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on
 
-Some errors have detailed explanations: E0378, E0412, E0658.
-For more information about an error, try `rustc --explain E0378`.
+error[E0307]: invalid `self` parameter type: Smaht<Self, T>
+  --> $DIR/issue-78372.rs:9:18
+   |
+LL |     fn foo(self: Smaht<Self, T>);
+   |                  ^^^^^^^^^^^^^^
+   |
+   = note: type of `self` must be `Self` or a type that dereferences to it
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error: aborting due to 8 previous errors
+
+Some errors have detailed explanations: E0038, E0307, E0378, E0412, E0658.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/traits/method-on-unbounded-type-param.rs b/tests/ui/traits/method-on-unbounded-type-param.rs
new file mode 100644
index 00000000000..8505eb41e98
--- /dev/null
+++ b/tests/ui/traits/method-on-unbounded-type-param.rs
@@ -0,0 +1,15 @@
+fn f<T>(a: T, b: T) -> std::cmp::Ordering {
+    a.cmp(&b) //~ ERROR E0599
+}
+fn g<T>(a: T, b: T) -> std::cmp::Ordering {
+    (&a).cmp(&b) //~ ERROR E0599
+}
+fn h<T>(a: &T, b: T) -> std::cmp::Ordering {
+    a.cmp(&b) //~ ERROR E0599
+}
+trait T {}
+impl<X: std::cmp::Ord> T for X {}
+fn main() {
+    let x: Box<dyn T> = Box::new(0);
+    x.cmp(&x); //~ ERROR E0599
+}
diff --git a/tests/ui/traits/method-on-unbounded-type-param.stderr b/tests/ui/traits/method-on-unbounded-type-param.stderr
new file mode 100644
index 00000000000..0d8bd8ee964
--- /dev/null
+++ b/tests/ui/traits/method-on-unbounded-type-param.stderr
@@ -0,0 +1,84 @@
+error[E0599]: no method named `cmp` found for type parameter `T` in the current scope
+  --> $DIR/method-on-unbounded-type-param.rs:2:7
+   |
+LL | fn f<T>(a: T, b: T) -> std::cmp::Ordering {
+   |      - method `cmp` not found for this type parameter
+LL |     a.cmp(&b)
+   |       ^^^ method cannot be called on `T` due to unsatisfied trait bounds
+   |
+   = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following traits define an item `cmp`, perhaps you need to restrict type parameter `T` with one of them:
+   |
+LL | fn f<T: Ord>(a: T, b: T) -> std::cmp::Ordering {
+   |       +++++
+LL | fn f<T: Iterator>(a: T, b: T) -> std::cmp::Ordering {
+   |       ++++++++++
+
+error[E0599]: the method `cmp` exists for reference `&T`, but its trait bounds were not satisfied
+  --> $DIR/method-on-unbounded-type-param.rs:5:10
+   |
+LL |     (&a).cmp(&b)
+   |          ^^^ method cannot be called on `&T` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `T: Ord`
+           which is required by `&T: Ord`
+           `&T: Iterator`
+           which is required by `&mut &T: Iterator`
+           `T: Iterator`
+           which is required by `&mut T: Iterator`
+   = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following traits define an item `cmp`, perhaps you need to restrict type parameter `T` with one of them:
+   |
+LL | fn g<T: Ord>(a: T, b: T) -> std::cmp::Ordering {
+   |       +++++
+LL | fn g<T: Iterator>(a: T, b: T) -> std::cmp::Ordering {
+   |       ++++++++++
+
+error[E0599]: the method `cmp` exists for reference `&T`, but its trait bounds were not satisfied
+  --> $DIR/method-on-unbounded-type-param.rs:8:7
+   |
+LL |     a.cmp(&b)
+   |       ^^^ method cannot be called on `&T` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `T: Ord`
+           which is required by `&T: Ord`
+           `&T: Iterator`
+           which is required by `&mut &T: Iterator`
+           `T: Iterator`
+           which is required by `&mut T: Iterator`
+   = help: items from traits can only be used if the type parameter is bounded by the trait
+help: the following traits define an item `cmp`, perhaps you need to restrict type parameter `T` with one of them:
+   |
+LL | fn h<T: Ord>(a: &T, b: T) -> std::cmp::Ordering {
+   |       +++++
+LL | fn h<T: Iterator>(a: &T, b: T) -> std::cmp::Ordering {
+   |       ++++++++++
+
+error[E0599]: the method `cmp` exists for struct `Box<dyn T>`, but its trait bounds were not satisfied
+  --> $DIR/method-on-unbounded-type-param.rs:14:7
+   |
+LL | trait T {}
+   | ------- doesn't satisfy `dyn T: Iterator` or `dyn T: Ord`
+...
+LL |     x.cmp(&x);
+   |       ^^^ method cannot be called on `Box<dyn T>` due to unsatisfied trait bounds
+   |
+   = note: the following trait bounds were not satisfied:
+           `dyn T: Iterator`
+           which is required by `Box<dyn T>: Iterator`
+           `dyn T: Ord`
+           which is required by `Box<dyn T>: Ord`
+           `Box<dyn T>: Iterator`
+           which is required by `&mut Box<dyn T>: Iterator`
+           `dyn T: Iterator`
+           which is required by `&mut dyn T: Iterator`
+   = help: items from traits can only be used if the trait is implemented and in scope
+   = note: the following traits define an item `cmp`, perhaps you need to implement one of them:
+           candidate #1: `Ord`
+           candidate #2: `Iterator`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/traits/multidispatch-conditional-impl-not-considered.rs b/tests/ui/traits/multidispatch-conditional-impl-not-considered.rs
index f845e198aa5..e9ae8ab012a 100644
--- a/tests/ui/traits/multidispatch-conditional-impl-not-considered.rs
+++ b/tests/ui/traits/multidispatch-conditional-impl-not-considered.rs
@@ -6,7 +6,7 @@
 
 use std::cell::RefCell;
 
-trait Foo {
+trait Foo { //~ WARN trait `Foo` is never used
     fn foo(&self) {}
 }
 
diff --git a/tests/ui/traits/multidispatch-conditional-impl-not-considered.stderr b/tests/ui/traits/multidispatch-conditional-impl-not-considered.stderr
new file mode 100644
index 00000000000..25313a477f7
--- /dev/null
+++ b/tests/ui/traits/multidispatch-conditional-impl-not-considered.stderr
@@ -0,0 +1,10 @@
+warning: trait `Foo` is never used
+  --> $DIR/multidispatch-conditional-impl-not-considered.rs:9:7
+   |
+LL | trait Foo {
+   |       ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/multidispatch-infer-convert-target.rs b/tests/ui/traits/multidispatch-infer-convert-target.rs
index 626e1ae71bc..a3653dea2cb 100644
--- a/tests/ui/traits/multidispatch-infer-convert-target.rs
+++ b/tests/ui/traits/multidispatch-infer-convert-target.rs
@@ -5,7 +5,7 @@
 use std::mem;
 
 trait Convert<Target> {
-    fn convert(&self) -> Target;
+    fn convert(&self) -> Target; //~ WARN method `convert` is never used
 }
 
 impl Convert<u32> for i16 {
diff --git a/tests/ui/traits/multidispatch-infer-convert-target.stderr b/tests/ui/traits/multidispatch-infer-convert-target.stderr
new file mode 100644
index 00000000000..c8c1b642719
--- /dev/null
+++ b/tests/ui/traits/multidispatch-infer-convert-target.stderr
@@ -0,0 +1,12 @@
+warning: method `convert` is never used
+  --> $DIR/multidispatch-infer-convert-target.rs:8:8
+   |
+LL | trait Convert<Target> {
+   |       ------- method in this trait
+LL |     fn convert(&self) -> Target;
+   |        ^^^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/traits/negative-impls/negative-specializes-negative.rs b/tests/ui/traits/negative-impls/negative-specializes-negative.rs
index 35297ab124e..01829e41301 100644
--- a/tests/ui/traits/negative-impls/negative-specializes-negative.rs
+++ b/tests/ui/traits/negative-impls/negative-specializes-negative.rs
@@ -3,7 +3,7 @@
 
 // Test a negative impl that "specializes" another negative impl.
 //
-// run-pass
+// check-pass
 
 trait MyTrait {}
 
diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
index af471b5e193..d7a2c8e7a92 100644
--- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
@@ -8,6 +8,7 @@ trait Overflow {
 }
 impl<T> Overflow for T {
     type Assoc = <T as Overflow>::Assoc;
+    //~^ ERROR: overflow
 }
 
 
diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
index e3c0dabf549..583945723d5 100644
--- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Trait` for type `<LocalTy as Overflow>::Assoc`
-  --> $DIR/trait_ref_is_knowable-norm-overflow.rs:17:1
+  --> $DIR/trait_ref_is_knowable-norm-overflow.rs:18:1
    |
 LL | impl<T: Copy> Trait for T {}
    | ------------------------- first implementation here
@@ -7,6 +7,24 @@ LL | struct LocalTy;
 LL | impl Trait for <LocalTy as Overflow>::Assoc {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<LocalTy as Overflow>::Assoc`
 
-error: aborting due to 1 previous error
+error[E0275]: overflow evaluating the requirement `<T as Overflow>::Assoc: Sized`
+  --> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18
+   |
+LL |     type Assoc = <T as Overflow>::Assoc;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`trait_ref_is_knowable_norm_overflow`)
+note: required by a bound in `Overflow::Assoc`
+  --> $DIR/trait_ref_is_knowable-norm-overflow.rs:7:5
+   |
+LL |     type Assoc;
+   |     ^^^^^^^^^^^ required by this bound in `Overflow::Assoc`
+help: consider relaxing the implicit `Sized` restriction
+   |
+LL |     type Assoc: ?Sized;
+   |               ++++++++
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0119, E0275.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
index c7e2e2d5e04..f6c75317a34 100644
--- a/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
+++ b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
@@ -24,6 +24,18 @@ where
 {
 }
 
+// HACK: This impls is necessary so that the impl above is well-formed.
+//
+// When checking that the impl above is well-formed we check `B<T>: Trait<'a, 'b>`
+// with the where clauses `A<T>: Trait<'a, 'b>` and `A<T> NotImplemented`. Trying to
+// use the impl itself to prove that adds region constraints as we uniquified the
+// regions in the `A<T>: Trait<'a, 'b>` where-bound. As both the impl above
+// and the impl below now apply with some constraints, we failed with ambiguity.
+impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B<T>
+where
+    A<T>: NotImplemented,
+{}
+
 // This impl directly requires 'b to be equal to 'static.
 //
 // Because of the coinductive cycle through `C<T>` it also requires
diff --git a/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr
index 7b3075f4ff3..0cbd9654044 100644
--- a/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr
+++ b/tests/ui/traits/next-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr
@@ -1,5 +1,5 @@
 error: lifetime may not live long enough
-  --> $DIR/fixpoint-rerun-all-cycle-heads.rs:47:5
+  --> $DIR/fixpoint-rerun-all-cycle-heads.rs:59:5
    |
 LL | fn check<'a, T: ?Sized>() {
    |          -- lifetime `'a` defined here
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs b/tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs
new file mode 100644
index 00000000000..37730d38c7a
--- /dev/null
+++ b/tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs
@@ -0,0 +1,40 @@
+// compile-flags: -Znext-solver
+// check-pass
+
+// If a trait goal is proven using the environment, we discard
+// impl candidates when normalizing. However, in this example
+// the env candidates start as ambiguous and end up not applying,
+// so normalization should succeed later on.
+
+trait Trait<T>: Sized {
+    type Assoc: From<Self>;
+}
+
+impl<T, U> Trait<U> for T {
+    type Assoc = T;
+}
+
+fn mk_assoc<T: Trait<U>, U>(t: T, _: U) -> <T as Trait<U>>::Assoc {
+    t.into()
+}
+
+fn generic<T>(t: T) -> T
+where
+    T: Trait<u32>,
+    T: Trait<i16>,
+{
+    let u = Default::default();
+
+    // at this point we have 2 ambig env candidates
+    let ret: T = mk_assoc(t, u);
+
+    // now both env candidates don't apply, so we're now able to
+    // normalize using this impl candidates. For this to work
+    // the normalizes-to must have remained ambiguous above.
+    let _: u8 = u;
+    ret
+}
+
+fn main() {
+    assert_eq!(generic(1), 1);
+}
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-1.rs b/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-1.rs
new file mode 100644
index 00000000000..63742d0d1a1
--- /dev/null
+++ b/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-1.rs
@@ -0,0 +1,30 @@
+// compile-flags: -Znext-solver
+// check-pass
+
+// Normalizing `<T as Trait>::TraitAssoc` in the elaborated environment
+// `[T: Trait, T: Super, <T as Super>::SuperAssoc = <T as Trait>::TraitAssoc]`
+// has a single impl candidate, which uses the environment to
+// normalize `<T as Trait>::TraitAssoc` to itself. We avoid this overflow
+// by discarding impl candidates the trait bound is proven by a where-clause.
+
+// https://github.com/rust-lang/trait-system-refactor-initiative/issues/76
+trait Super {
+    type SuperAssoc;
+}
+
+trait Trait: Super<SuperAssoc = Self::TraitAssoc> {
+    type TraitAssoc;
+}
+
+impl<T, U> Trait for T
+where
+    T: Super<SuperAssoc = U>,
+{
+    type TraitAssoc = U;
+}
+
+fn overflow<T: Trait>() {
+    let x: <T as Trait>::TraitAssoc;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-2.rs b/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-2.rs
new file mode 100644
index 00000000000..b0ef0d44baf
--- /dev/null
+++ b/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-2.rs
@@ -0,0 +1,29 @@
+// revisions: next current
+//[next] compile-flags: -Znext-solver
+// check-pass
+
+#![allow(warnings)]
+trait Trait<U> {
+    type Assoc;
+}
+
+impl<T> Trait<u64> for T {
+    type Assoc = T;
+}
+
+fn lazy_init<T: Trait<U>, U>() -> (T, <T as Trait<U>>::Assoc) {
+    todo!()
+}
+
+fn foo<T: Trait<u32, Assoc = T>>(x: T) {
+    // When considering impl candidates to be equally valid as env candidates
+    // this ends up being ambiguous as `U` can be both `u32´ and `u64` here.
+    //
+    // This is acceptable breakage but we should still note that it's
+    // theoretically breaking.
+    let (delayed, mut proj) = lazy_init::<_, _>();
+    proj = x;
+    let _: T = delayed;
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-3.rs b/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-3.rs
new file mode 100644
index 00000000000..807e19a4a58
--- /dev/null
+++ b/tests/ui/traits/next-solver/env-shadows-impls/discard-impls-shadowed-by-env-3.rs
@@ -0,0 +1,18 @@
+// compile-flags: -Znext-solver
+// check-pass
+
+// If we normalize using the impl here the constraints from normalization and
+// trait goals can differ. This is especially bad if normalization results
+// in stronger constraints.
+trait Trait<'a> {
+    type Assoc;
+}
+
+impl<T> Trait<'static> for T {
+    type Assoc = ();
+}
+
+// normalizing requires `'a == 'static`, the trait bound does not.
+fn foo<'a, T: Trait<'a>>(_: T::Assoc) {}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.rs b/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.rs
new file mode 100644
index 00000000000..af2c44ea233
--- /dev/null
+++ b/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.rs
@@ -0,0 +1,29 @@
+// compile-flags: -Znext-solver
+
+// Checks whether the new solver is smart enough to infer `?0 = U` when solving:
+// `normalizes-to(<Vec<?0> as Trait>::Assoc, u8)`
+// with `normalizes-to(<Vec<U> as Trait>::Assoc, u8)` in the paramenv even when
+// there is a separate `Vec<T>: Trait` bound  in the paramenv.
+//
+// We currently intentionally do not guide inference this way.
+
+trait Trait {
+    type Assoc;
+}
+
+fn foo<T: Trait<Assoc = u8>>(x: T) {}
+
+fn unconstrained<T>() -> Vec<T> {
+    todo!()
+}
+
+fn bar<T, U>()
+where
+    Vec<T>: Trait,
+    Vec<U>: Trait<Assoc = u8>,
+{
+    foo(unconstrained())
+    //~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr b/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.stderr
index c1a8b74df08..36d281e11dd 100644
--- a/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.self_infer.stderr
+++ b/tests/ui/traits/next-solver/env-shadows-impls/normalizes_to_ignores_unnormalizable_candidate.stderr
@@ -1,21 +1,21 @@
 error[E0283]: type annotations needed
-  --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:36:5
+  --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:25:5
    |
 LL |     foo(unconstrained())
    |     ^^^ --------------- type must be known at this point
    |     |
    |     cannot infer type of the type parameter `T` declared on the function `foo`
    |
-   = note: cannot satisfy `_: Trait`
+   = note: cannot satisfy `Vec<_>: Trait`
 note: required by a bound in `foo`
-  --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:19:11
+  --> $DIR/normalizes_to_ignores_unnormalizable_candidate.rs:14:11
    |
 LL | fn foo<T: Trait<Assoc = u8>>(x: T) {}
    |           ^^^^^^^^^^^^^^^^^ required by this bound in `foo`
 help: consider specifying the generic argument
    |
-LL |     foo::<T>(unconstrained())
-   |        +++++
+LL |     foo::<Vec<T>>(unconstrained())
+   |        ++++++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs
new file mode 100644
index 00000000000..5989e605bd9
--- /dev/null
+++ b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.rs
@@ -0,0 +1,31 @@
+// compile-flags: -Znext-solver
+
+trait Foo {
+    type Assoc;
+}
+
+trait Bar {}
+
+impl<T> Foo for T {
+    type Assoc = i32;
+}
+
+impl<T> Bar for T where T: Foo<Assoc = i32> {}
+
+fn require_bar<T: Bar>() {}
+
+fn foo<T: Foo>() {
+    // Unlike the classic solver, the new solver previously projected
+    // `<T as Foo>::Assoc = _` down to `i32` even though there's a param-env
+    // candidate here, since we don't assemble any param-env projection
+    // candidates for `T: Foo` alone.
+    //
+    // However, allowing impl candidates shadowed by env candidates results
+    // in multiple issues, so we explicitly hide them, e.g.
+    //
+    //     https://github.com/rust-lang/trait-system-refactor-initiative/issues/76
+    require_bar::<T>();
+    //~^ ERROR the trait bound `T: Bar` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr
new file mode 100644
index 00000000000..2785357e792
--- /dev/null
+++ b/tests/ui/traits/next-solver/env-shadows-impls/param-candidate-shadows-project.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `T: Bar` is not satisfied
+  --> $DIR/param-candidate-shadows-project.rs:27:19
+   |
+LL |     require_bar::<T>();
+   |                   ^ the trait `Bar` is not implemented for `T`
+   |
+note: required by a bound in `require_bar`
+  --> $DIR/param-candidate-shadows-project.rs:15:19
+   |
+LL | fn require_bar<T: Bar>() {}
+   |                   ^^^ required by this bound in `require_bar`
+help: consider further restricting this bound
+   |
+LL | fn foo<T: Foo + Bar>() {
+   |               +++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr
index ad8b24a39c7..aaadf604a80 100644
--- a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr
+++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr
@@ -1,11 +1,9 @@
-error[E0275]: overflow evaluating the requirement `<<T as Id<_>>::Id as Unnormalizable>::Assoc == _`
+error[E0284]: type annotations needed: cannot satisfy `<<T as Id<_>>::Id as Unnormalizable>::Assoc == _`
   --> $DIR/occurs-check-nested-alias.rs:36:9
    |
 LL |     x = y;
-   |         ^
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`occurs_check_nested_alias`)
+   |         ^ cannot satisfy `<<T as Id<_>>::Id as Unnormalizable>::Assoc == _`
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0275`.
+For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.rs b/tests/ui/traits/next-solver/issue-118950-root-region.rs
index 10fb7d525b7..c50276c78b4 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.rs
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.rs
@@ -12,6 +12,7 @@ trait ToUnit<'a> {
 trait Overlap<T> {}
 
 type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
+//~^ ERROR: not well-formed
 
 impl<T> Overlap<T> for T {}
 
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
index c16a48d5f15..f4638348358 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -1,5 +1,5 @@
 error[E0412]: cannot find type `Missing` in this scope
-  --> $DIR/issue-118950-root-region.rs:18:55
+  --> $DIR/issue-118950-root-region.rs:19:55
    |
 LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
    |                                                       ^^^^^^^ not found in this scope
@@ -22,7 +22,7 @@ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type:
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Weak, AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) })
 error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
-  --> $DIR/issue-118950-root-region.rs:18:1
+  --> $DIR/issue-118950-root-region.rs:19:1
    |
 LL | impl<T> Overlap<T> for T {}
    | ------------------------ first implementation here
@@ -30,7 +30,13 @@ LL |
 LL | impl<T> Overlap<for<'a> fn(Assoc<'a, T>)> for T where Missing: Overlap<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `fn(_)`
 
-error: aborting due to 2 previous errors; 1 warning emitted
+error: the type `<*const T as ToUnit<'a>>::Unit` is not well-formed
+  --> $DIR/issue-118950-root-region.rs:14:21
+   |
+LL | type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit;
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 3 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0119, E0412.
 For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/traits/next-solver/normalize-param-env-2.rs b/tests/ui/traits/next-solver/normalize-param-env-2.rs
index ce084651bfb..9da1f8dbec1 100644
--- a/tests/ui/traits/next-solver/normalize-param-env-2.rs
+++ b/tests/ui/traits/next-solver/normalize-param-env-2.rs
@@ -1,24 +1,29 @@
-// check-pass
 // compile-flags: -Znext-solver
-// Issue 92505
+// known-bug: #92505
 
+// When checking that the impl method where-bounds are implied by the trait,
+// we prove  `<() as A<T>>::Assoc: A<T>` in the environment `<() as A<T>>::Assoc: A<T>`.
+//
+// Normalizing `<() as A<T>>::Assoc` is ambiguous in that environment. The
+// where-bound `<() as A<T>>::Assoc: A<T>` may apply, resulting in overflow.
 trait A<T> {
-    type I;
+    type Assoc;
 
     fn f()
     where
-        Self::I: A<T>,
+        Self::Assoc: A<T>,
     {
     }
 }
 
 impl<T> A<T> for () {
-    type I = ();
+    type Assoc = ();
 
     fn f()
     where
-        Self::I: A<T>,
+        Self::Assoc: A<T>,
     {
+
         <() as A<T>>::f();
     }
 }
diff --git a/tests/ui/traits/next-solver/normalize-param-env-2.stderr b/tests/ui/traits/next-solver/normalize-param-env-2.stderr
new file mode 100644
index 00000000000..a52022e539e
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize-param-env-2.stderr
@@ -0,0 +1,35 @@
+error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
+  --> $DIR/normalize-param-env-2.rs:24:22
+   |
+LL |         Self::Assoc: A<T>,
+   |                      ^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
+note: the requirement `<() as A<T>>::Assoc: A<T>` appears on the `impl`'s method `f` but not on the corresponding trait's method
+  --> $DIR/normalize-param-env-2.rs:12:8
+   |
+LL | trait A<T> {
+   |       - in this trait
+...
+LL |     fn f()
+   |        ^ this trait's method doesn't have the requirement `<() as A<T>>::Assoc: A<T>`
+
+error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc: A<T>`
+  --> $DIR/normalize-param-env-2.rs:24:22
+   |
+LL |         Self::Assoc: A<T>,
+   |                      ^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
+
+error[E0275]: overflow evaluating the requirement `<() as A<T>>::Assoc well-formed`
+  --> $DIR/normalize-param-env-2.rs:24:22
+   |
+LL |         Self::Assoc: A<T>,
+   |                      ^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_2`)
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr b/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr
new file mode 100644
index 00000000000..dec820c61b0
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize-param-env-4.next.stderr
@@ -0,0 +1,19 @@
+error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc: Trait`
+  --> $DIR/normalize-param-env-4.rs:18:26
+   |
+LL |     <T as Trait>::Assoc: Trait,
+   |                          ^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
+
+error[E0275]: overflow evaluating the requirement `<T as Trait>::Assoc well-formed`
+  --> $DIR/normalize-param-env-4.rs:18:26
+   |
+LL |     <T as Trait>::Assoc: Trait,
+   |                          ^^^^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`normalize_param_env_4`)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/next-solver/normalize-param-env-4.rs b/tests/ui/traits/next-solver/normalize-param-env-4.rs
new file mode 100644
index 00000000000..d49f7492297
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize-param-env-4.rs
@@ -0,0 +1,34 @@
+// revisions: current next
+//[next] compile-flags: -Znext-solver
+//[next] known-bug: #92505
+//[current] check-pass
+
+trait Trait {
+    type Assoc;
+}
+
+impl<T> Trait for T {
+    type Assoc = T;
+}
+
+fn impls_trait<T: Trait>() {}
+
+fn foo<T>()
+where
+    <T as Trait>::Assoc: Trait,
+{
+    // Trying to use `<T as Trait>::Assoc: Trait` to prove `T: Trait`
+    // requires normalizing `<T as Trait>::Assoc`. We do not normalize
+    // using impl candidates if there's a where-bound for that trait.
+    //
+    // We therefore check whether `T: Trait` is proven by the environment.
+    // For that we try to apply the `<T as Trait>::Assoc: Trait` candidate,
+    // trying to normalize its self type results in overflow.
+    //
+    // In the old solver we eagerly normalize the environment, ignoring the
+    // unnormalized `<T as Trait>::Assoc: Trait` where-bound when normalizing
+    // `<T as Trait>::Asosc`
+    impls_trait::<T>();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/normalize-region-obligations.rs b/tests/ui/traits/next-solver/normalize-region-obligations.rs
index 13c86b630f6..d189e4893a3 100644
--- a/tests/ui/traits/next-solver/normalize-region-obligations.rs
+++ b/tests/ui/traits/next-solver/normalize-region-obligations.rs
@@ -1,4 +1,4 @@
-// revisions: normalize_param_env normalize_obligation
+// revisions: normalize_param_env normalize_obligation hrtb
 // check-pass
 // compile-flags: -Znext-solver
 
@@ -7,16 +7,23 @@ trait Foo {
     type Gat<'a> where <Self as Mirror>::Assoc: 'a;
     #[cfg(normalize_obligation)]
     type Gat<'a> where Self: 'a;
+    #[cfg(hrtb)]
+    type Gat<'b> where for<'a> <Self as MirrorRegion<'a>>::Assoc: 'b;
 }
 
 trait Mirror { type Assoc: ?Sized; }
 impl<T: ?Sized> Mirror for T { type Assoc = T; }
 
+trait MirrorRegion<'a> { type Assoc: ?Sized; }
+impl<'a, T> MirrorRegion<'a> 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;
+    #[cfg(hrtb)]
+    type Gat<'b> = i32 where Self: 'b;
 }
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/normalize-type-outlives-in-param-env.rs b/tests/ui/traits/next-solver/normalize-type-outlives-in-param-env.rs
new file mode 100644
index 00000000000..7477c56cd54
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize-type-outlives-in-param-env.rs
@@ -0,0 +1,18 @@
+// check-pass
+// compile-flags: -Znext-solver
+
+trait Mirror {
+    type Assoc;
+}
+
+impl<T> Mirror for T {
+    type Assoc = T;
+}
+
+fn is_static<T: 'static>() {}
+
+fn test<T>() where <T as Mirror>::Assoc: 'static {
+    is_static::<T>();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/normalize-type-outlives.rs b/tests/ui/traits/next-solver/normalize-type-outlives.rs
new file mode 100644
index 00000000000..f50eb6326e2
--- /dev/null
+++ b/tests/ui/traits/next-solver/normalize-type-outlives.rs
@@ -0,0 +1,13 @@
+// check-pass
+
+trait Tr<'a> {
+    type Assoc;
+}
+
+fn outlives<'o, T: 'o>() {}
+
+fn foo<'a, 'b, T: Tr<'a, Assoc = ()>>() {
+    outlives::<'b, T::Assoc>();
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.rs b/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.rs
deleted file mode 100644
index 7dc87daccd9..00000000000
--- a/tests/ui/traits/next-solver/normalizes_to_ignores_unnormalizable_candidate.rs
+++ /dev/null
@@ -1,40 +0,0 @@
-// [no_self_infer] check-pass
-// compile-flags: -Znext-solver
-// revisions: self_infer no_self_infer
-
-// checks that the new solver is smart enough to infer `?0 = U` when solving:
-// `normalizes-to(<Vec<?0> as Trait>::Assoc, u8)`
-// with `normalizes-to(<Vec<U> as Trait>::Assoc, u8)` in the paramenv even when
-// there is a separate `Vec<T>: Trait` bound  in the paramenv.
-//
-// FIXME(-Znext-solver)
-// This could also compile for `normalizes-to(<?0 as Trait>::Assoc, u8)` but
-// we currently immediately consider a goal ambiguous if the self type is an
-// inference variable.
-
-trait Trait {
-    type Assoc;
-}
-
-fn foo<T: Trait<Assoc = u8>>(x: T) {}
-
-#[cfg(self_infer)]
-fn unconstrained<T>() -> T {
-    todo!()
-}
-
-#[cfg(no_self_infer)]
-fn unconstrained<T>() -> Vec<T> {
-    todo!()
-}
-
-fn bar<T, U>()
-where
-    Vec<T>: Trait,
-    Vec<U>: Trait<Assoc = u8>,
-{
-    foo(unconstrained())
-    //[self_infer]~^ ERROR type annotations needed
-}
-
-fn main() {}
diff --git a/tests/ui/traits/next-solver/param-candidate-doesnt-shadow-project.rs b/tests/ui/traits/next-solver/param-candidate-doesnt-shadow-project.rs
deleted file mode 100644
index f67b073c53c..00000000000
--- a/tests/ui/traits/next-solver/param-candidate-doesnt-shadow-project.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// compile-flags: -Znext-solver
-// check-pass
-
-trait Foo {
-    type Assoc;
-}
-
-trait Bar {}
-
-impl<T> Foo for T {
-    type Assoc = i32;
-}
-
-impl<T> Bar for T where T: Foo<Assoc = i32> {}
-
-fn require_bar<T: Bar>() {}
-
-fn foo<T: Foo>() {
-    // Unlike the classic solver, `<T as Foo>::Assoc = _` will still project
-    // down to `i32` even though there's a param-env candidate here, since we
-    // don't assemble any param-env projection candidates for `T: Foo` alone.
-    require_bar::<T>();
-}
-
-fn main() {}
diff --git a/tests/ui/traits/next-solver/specialization-transmute.rs b/tests/ui/traits/next-solver/specialization-transmute.rs
index 6f93a1d3f40..d96936f60f7 100644
--- a/tests/ui/traits/next-solver/specialization-transmute.rs
+++ b/tests/ui/traits/next-solver/specialization-transmute.rs
@@ -1,5 +1,5 @@
 // compile-flags: -Znext-solver
-//~^ ERROR cannot normalize `<T as Default>::Id`
+//~^ 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 946a7cbaa80..ea1ae387f56 100644
--- a/tests/ui/traits/next-solver/specialization-transmute.stderr
+++ b/tests/ui/traits/next-solver/specialization-transmute.stderr
@@ -8,7 +8,7 @@ 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: cannot normalize `<T as Default>::Id: '_`
 
 error[E0284]: type annotations needed: cannot satisfy `<T as Default>::Id == _`
   --> $DIR/specialization-transmute.rs:16:23
diff --git a/tests/ui/traits/object/pretty.rs b/tests/ui/traits/object/pretty.rs
new file mode 100644
index 00000000000..8958871ed5d
--- /dev/null
+++ b/tests/ui/traits/object/pretty.rs
@@ -0,0 +1,37 @@
+// Test for pretty-printing trait object types.
+
+trait Super {
+    type Assoc;
+}
+trait Any: Super {}
+trait Fixed: Super<Assoc = u8> {}
+trait FixedSub: Fixed {}
+trait FixedStatic: Super<Assoc = &'static u8> {}
+
+trait SuperGeneric<'a> {
+    type Assoc2;
+}
+trait AnyGeneric<'a>: SuperGeneric<'a> {}
+trait FixedGeneric1<'a>: SuperGeneric<'a, Assoc2 = &'a u8> {}
+trait FixedGeneric2<'a>: Super<Assoc = &'a u8> {}
+trait FixedHrtb: for<'a> SuperGeneric<'a, Assoc2 = &'a u8> {}
+trait AnyDifferentBinders: for<'a> SuperGeneric<'a, Assoc2 = &'a u8> + Super {}
+trait FixedDifferentBinders: for<'a> SuperGeneric<'a, Assoc2 = &'a u8> + Super<Assoc = u8> {}
+
+fn dyn_super(x: &dyn Super<Assoc = u8>) { x } //~ERROR mismatched types
+fn dyn_any(x: &dyn Any<Assoc = u8>) { x } //~ERROR mismatched types
+fn dyn_fixed(x: &dyn Fixed) { x } //~ERROR mismatched types
+fn dyn_fixed_multi(x: &dyn Fixed<Assoc = u16>) { x } //~ERROR mismatched types
+fn dyn_fixed_sub(x: &dyn FixedSub) { x } //~ERROR mismatched types
+fn dyn_fixed_static(x: &dyn FixedStatic) { x } //~ERROR mismatched types
+
+fn dyn_super_generic(x: &dyn for<'a> SuperGeneric<'a, Assoc2 = &'a u8>) { x } //~ERROR mismatched types
+fn dyn_any_generic(x: &dyn for<'a> AnyGeneric<'a, Assoc2 = &'a u8>) { x } //~ERROR mismatched types
+fn dyn_fixed_generic1(x: &dyn for<'a> FixedGeneric1<'a>) { x } //~ERROR mismatched types
+fn dyn_fixed_generic2(x: &dyn for<'a> FixedGeneric2<'a>) { x } //~ERROR mismatched types
+fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>) { x } //~ERROR mismatched types
+fn dyn_fixed_hrtb(x: &dyn FixedHrtb) { x } //~ERROR mismatched types
+fn dyn_any_different_binders(x: &dyn AnyDifferentBinders<Assoc = u8>) { x } //~ERROR mismatched types
+fn dyn_fixed_different_binders(x: &dyn FixedDifferentBinders) { x } //~ERROR mismatched types
+
+fn main() {}
diff --git a/tests/ui/traits/object/pretty.stderr b/tests/ui/traits/object/pretty.stderr
new file mode 100644
index 00000000000..bc645e5f967
--- /dev/null
+++ b/tests/ui/traits/object/pretty.stderr
@@ -0,0 +1,157 @@
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:21:43
+   |
+LL | fn dyn_super(x: &dyn Super<Assoc = u8>) { x }
+   |                                        -  ^ expected `()`, found `&dyn Super<Assoc = u8>`
+   |                                        |
+   |                                        help: try adding a return type: `-> &dyn Super<Assoc = u8>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn Super<Assoc = u8>`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:22:39
+   |
+LL | fn dyn_any(x: &dyn Any<Assoc = u8>) { x }
+   |                                    -  ^ expected `()`, found `&dyn Any<Assoc = u8>`
+   |                                    |
+   |                                    help: try adding a return type: `-> &dyn Any<Assoc = u8>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn Any<Assoc = u8>`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:23:31
+   |
+LL | fn dyn_fixed(x: &dyn Fixed) { x }
+   |                            -  ^ expected `()`, found `&dyn Fixed`
+   |                            |
+   |                            help: try adding a return type: `-> &dyn Fixed`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn Fixed`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:24:50
+   |
+LL | fn dyn_fixed_multi(x: &dyn Fixed<Assoc = u16>) { x }
+   |                                               -  ^ expected `()`, found `&dyn Fixed<Assoc = u16>`
+   |                                               |
+   |                                               help: try adding a return type: `-> &dyn Fixed<Assoc = u16>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn Fixed<Assoc = u16>`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:25:38
+   |
+LL | fn dyn_fixed_sub(x: &dyn FixedSub) { x }
+   |                                   -  ^ expected `()`, found `&dyn FixedSub`
+   |                                   |
+   |                                   help: try adding a return type: `-> &dyn FixedSub`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn FixedSub`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:26:44
+   |
+LL | fn dyn_fixed_static(x: &dyn FixedStatic) { x }
+   |                                         -  ^ expected `()`, found `&dyn FixedStatic`
+   |                                         |
+   |                                         help: try adding a return type: `-> &dyn FixedStatic`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn FixedStatic`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:28:75
+   |
+LL | fn dyn_super_generic(x: &dyn for<'a> SuperGeneric<'a, Assoc2 = &'a u8>) { x }
+   |                                                                        -  ^ expected `()`, found `&dyn SuperGeneric<'a, Assoc2 = &u8>`
+   |                                                                        |
+   |                                                                        help: try adding a return type: `-> &dyn for<'a> SuperGeneric<'a, Assoc2 = &'a u8>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn for<'a> SuperGeneric<'a, Assoc2 = &'a u8>`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:29:71
+   |
+LL | fn dyn_any_generic(x: &dyn for<'a> AnyGeneric<'a, Assoc2 = &'a u8>) { x }
+   |                                                                    -  ^ expected `()`, found `&dyn AnyGeneric<'a, Assoc2 = &u8>`
+   |                                                                    |
+   |                                                                    help: try adding a return type: `-> &dyn for<'a> AnyGeneric<'a, Assoc2 = &'a u8>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn for<'a> AnyGeneric<'a, Assoc2 = &'a u8>`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:30:60
+   |
+LL | fn dyn_fixed_generic1(x: &dyn for<'a> FixedGeneric1<'a>) { x }
+   |                                                         -  ^ expected `()`, found `&dyn FixedGeneric1<'a>`
+   |                                                         |
+   |                                                         help: try adding a return type: `-> &dyn for<'a> FixedGeneric1<'a>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn for<'a> FixedGeneric1<'a>`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:31:60
+   |
+LL | fn dyn_fixed_generic2(x: &dyn for<'a> FixedGeneric2<'a>) { x }
+   |                                                         -  ^ expected `()`, found `&dyn FixedGeneric2<'a>`
+   |                                                         |
+   |                                                         help: try adding a return type: `-> &dyn for<'a> FixedGeneric2<'a>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn for<'a> FixedGeneric2<'a>`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:32:79
+   |
+LL | fn dyn_fixed_generic_multi(x: &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>) { x }
+   |                                                                            -  ^ expected `()`, found `&dyn FixedGeneric1<'a, Assoc2 = ...>`
+   |                                                                            |
+   |                                                                            help: try adding a return type: `-> &dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn for<'a> FixedGeneric1<'a, Assoc2 = &u8>`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:33:40
+   |
+LL | fn dyn_fixed_hrtb(x: &dyn FixedHrtb) { x }
+   |                                     -  ^ expected `()`, found `&dyn FixedHrtb`
+   |                                     |
+   |                                     help: try adding a return type: `-> &dyn FixedHrtb`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn FixedHrtb`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:34:73
+   |
+LL | fn dyn_any_different_binders(x: &dyn AnyDifferentBinders<Assoc = u8>) { x }
+   |                                                                      -  ^ expected `()`, found `&dyn AnyDifferentBinders<Assoc = ...>`
+   |                                                                      |
+   |                                                                      help: try adding a return type: `-> &dyn AnyDifferentBinders<Assoc = u8>`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn AnyDifferentBinders<Assoc = u8>`
+
+error[E0308]: mismatched types
+  --> $DIR/pretty.rs:35:65
+   |
+LL | fn dyn_fixed_different_binders(x: &dyn FixedDifferentBinders) { x }
+   |                                                              -  ^ expected `()`, found `&dyn FixedDifferentBinders`
+   |                                                              |
+   |                                                              help: try adding a return type: `-> &dyn FixedDifferentBinders`
+   |
+   = note: expected unit type `()`
+              found reference `&dyn FixedDifferentBinders`
+
+error: aborting due to 14 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/pointee-normalize-equate.rs b/tests/ui/traits/pointee-normalize-equate.rs
new file mode 100644
index 00000000000..2e75933aca0
--- /dev/null
+++ b/tests/ui/traits/pointee-normalize-equate.rs
@@ -0,0 +1,56 @@
+// check-pass
+// revisions: old next
+//[next] compile-flags: -Znext-solver
+
+#![feature(ptr_metadata)]
+
+use std::ptr::{self, Pointee};
+
+fn cast_same_meta<T: ?Sized, U: ?Sized>(ptr: *const T) -> *const U
+where
+    T: Pointee<Metadata = <U as Pointee>::Metadata>,
+{
+    let (thin, meta) = ptr.to_raw_parts();
+    ptr::from_raw_parts(thin, meta)
+}
+
+struct Wrapper<T: ?Sized>(T);
+
+// normalize `Wrapper<T>::Metadata` -> `T::Metadata`
+fn wrapper_to_tail<T: ?Sized>(ptr: *const T) -> *const Wrapper<T> {
+    cast_same_meta(ptr)
+}
+
+// normalize `Wrapper<T>::Metadata` -> `T::Metadata` -> `()`
+fn wrapper_to_unit<T>(ptr: *const ()) -> *const Wrapper<T> {
+    cast_same_meta(ptr)
+}
+
+trait Project {
+    type Assoc: ?Sized;
+}
+
+struct WrapperProject<T: ?Sized + Project>(T::Assoc);
+
+// normalize `WrapperProject<T>::Metadata` -> `T::Assoc::Metadata`
+fn wrapper_project_tail<T: ?Sized + Project>(ptr: *const T::Assoc) -> *const WrapperProject<T> {
+    cast_same_meta(ptr)
+}
+
+// normalize `WrapperProject<T>::Metadata` -> `T::Assoc::Metadata` -> `()`
+fn wrapper_project_unit<T: ?Sized + Project>(ptr: *const ()) -> *const WrapperProject<T>
+where
+    T::Assoc: Sized,
+{
+    cast_same_meta(ptr)
+}
+
+// normalize `<[T] as Pointee>::Metadata` -> `usize`, even if `[T]: Sized`
+fn sized_slice<T>(ptr: *const [T]) -> *const str
+where
+    [T]: Sized,
+{
+    cast_same_meta(ptr)
+}
+
+fn main() {}
diff --git a/tests/ui/traits/self-without-lifetime-constraint.rs b/tests/ui/traits/self-without-lifetime-constraint.rs
index 99013d32ab8..50901173b76 100644
--- a/tests/ui/traits/self-without-lifetime-constraint.rs
+++ b/tests/ui/traits/self-without-lifetime-constraint.rs
@@ -15,6 +15,7 @@ impl<'a> ValueRef<'a> {
         match *self {
             ValueRef::Text(t) => {
                 std::str::from_utf8(t).map_err(|_| FromSqlError::InvalidType).map(|x| (x, &x))
+                //~^ ERROR: cannot return value referencing function parameter `x`
             }
             _ => Err(FromSqlError::InvalidType),
         }
diff --git a/tests/ui/traits/self-without-lifetime-constraint.stderr b/tests/ui/traits/self-without-lifetime-constraint.stderr
index 0a5ae8a027e..8997d2a98b3 100644
--- a/tests/ui/traits/self-without-lifetime-constraint.stderr
+++ b/tests/ui/traits/self-without-lifetime-constraint.stderr
@@ -1,5 +1,5 @@
 error: `impl` item signature doesn't match `trait` item signature
-  --> $DIR/self-without-lifetime-constraint.rs:45:5
+  --> $DIR/self-without-lifetime-constraint.rs:46:5
    |
 LL |     fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self, &Self>;
    |     -------------------------------------------------------------------- expected `fn(ValueRef<'1>) -> Result<(&'2 str, &'1 &'2 str), FromSqlError>`
@@ -10,10 +10,20 @@ LL |     fn column_result(value: ValueRef<'_>) -> FromSqlResult<&str, &&str> {
    = note: expected signature `fn(ValueRef<'1>) -> Result<(&'2 str, &'1 &'2 str), FromSqlError>`
               found signature `fn(ValueRef<'1>) -> Result<(&'1 str, &'1 &'1 str), FromSqlError>`
 help: the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
-  --> $DIR/self-without-lifetime-constraint.rs:41:60
+  --> $DIR/self-without-lifetime-constraint.rs:42:60
    |
 LL |     fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self, &Self>;
    |                                                            ^^^^ consider borrowing this type parameter in the trait
 
-error: aborting due to 1 previous error
+error[E0515]: cannot return value referencing function parameter `x`
+  --> $DIR/self-without-lifetime-constraint.rs:17:87
+   |
+LL |                 std::str::from_utf8(t).map_err(|_| FromSqlError::InvalidType).map(|x| (x, &x))
+   |                                                                                       ^^^^--^
+   |                                                                                       |   |
+   |                                                                                       |   `x` is borrowed here
+   |                                                                                       returns a value referencing data owned by the current function
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0515`.
diff --git a/tests/ui/traits/trait-upcasting/lifetime.rs b/tests/ui/traits/trait-upcasting/lifetime.rs
index 9825158c2dd..6486ec3891c 100644
--- a/tests/ui/traits/trait-upcasting/lifetime.rs
+++ b/tests/ui/traits/trait-upcasting/lifetime.rs
@@ -7,7 +7,7 @@ trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
         10
     }
 
-    fn z(&self) -> i32 {
+    fn z(&self) -> i32 { //~ WARN methods `z` and `y` are never used
         11
     }
 
@@ -21,7 +21,7 @@ trait Bar: Foo {
         20
     }
 
-    fn w(&self) -> i32 {
+    fn w(&self) -> i32 { //~ WARN method `w` is never used
         21
     }
 }
diff --git a/tests/ui/traits/trait-upcasting/lifetime.stderr b/tests/ui/traits/trait-upcasting/lifetime.stderr
new file mode 100644
index 00000000000..ca8f9cf63f3
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/lifetime.stderr
@@ -0,0 +1,25 @@
+warning: methods `z` and `y` are never used
+  --> $DIR/lifetime.rs:10:8
+   |
+LL | trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
+   |       --- methods in this trait
+...
+LL |     fn z(&self) -> i32 {
+   |        ^
+...
+LL |     fn y(&self) -> i32 {
+   |        ^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: method `w` is never used
+  --> $DIR/lifetime.rs:24:8
+   |
+LL | trait Bar: Foo {
+   |       --- method in this trait
+...
+LL |     fn w(&self) -> i32 {
+   |        ^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/traits/trait-upcasting/replace-vptr.rs b/tests/ui/traits/trait-upcasting/replace-vptr.rs
index 9ccfc9306ac..5ef65786bb7 100644
--- a/tests/ui/traits/trait-upcasting/replace-vptr.rs
+++ b/tests/ui/traits/trait-upcasting/replace-vptr.rs
@@ -3,7 +3,7 @@
 #![feature(trait_upcasting)]
 
 trait A {
-    fn foo_a(&self);
+    fn foo_a(&self); //~ WARN method `foo_a` is never used
 }
 
 trait B {
@@ -11,7 +11,7 @@ trait B {
 }
 
 trait C: A + B {
-    fn foo_c(&self);
+    fn foo_c(&self); //~ WARN method `foo_c` is never used
 }
 
 struct S(i32);
diff --git a/tests/ui/traits/trait-upcasting/replace-vptr.stderr b/tests/ui/traits/trait-upcasting/replace-vptr.stderr
new file mode 100644
index 00000000000..823094761b3
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/replace-vptr.stderr
@@ -0,0 +1,20 @@
+warning: method `foo_a` is never used
+  --> $DIR/replace-vptr.rs:6:8
+   |
+LL | trait A {
+   |       - method in this trait
+LL |     fn foo_a(&self);
+   |        ^^^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: method `foo_c` is never used
+  --> $DIR/replace-vptr.rs:14:8
+   |
+LL | trait C: A + B {
+   |       - method in this trait
+LL |     fn foo_c(&self);
+   |        ^^^^^
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/traits/use-before-def.rs b/tests/ui/traits/use-before-def.rs
index 1ee2b941909..e52dc53fbab 100644
--- a/tests/ui/traits/use-before-def.rs
+++ b/tests/ui/traits/use-before-def.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 #![allow(non_camel_case_types)]
 
 // Issue #1761
diff --git a/tests/ui/traits/wf-object/reverse-order.rs b/tests/ui/traits/wf-object/reverse-order.rs
index 74b2ef48533..e90c8763d65 100644
--- a/tests/ui/traits/wf-object/reverse-order.rs
+++ b/tests/ui/traits/wf-object/reverse-order.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 // Ensure that `dyn $($AutoTrait)+ ObjSafe` is well-formed.
 
diff --git a/tests/ui/trivial_casts-rpass.rs b/tests/ui/trivial_casts-rpass.rs
index 8e49468bf0c..4653a8df802 100644
--- a/tests/ui/trivial_casts-rpass.rs
+++ b/tests/ui/trivial_casts-rpass.rs
@@ -4,7 +4,7 @@
 #![allow(trivial_casts, trivial_numeric_casts)]
 
 trait Foo {
-    fn foo(&self) {}
+    fn foo(&self) {} //~ WARN method `foo` is never used
 }
 
 pub struct Bar;
diff --git a/tests/ui/trivial_casts-rpass.stderr b/tests/ui/trivial_casts-rpass.stderr
new file mode 100644
index 00000000000..74698b61ab4
--- /dev/null
+++ b/tests/ui/trivial_casts-rpass.stderr
@@ -0,0 +1,12 @@
+warning: method `foo` is never used
+  --> $DIR/trivial_casts-rpass.rs:7:8
+   |
+LL | trait Foo {
+   |       --- method in this trait
+LL |     fn foo(&self) {}
+   |        ^^^
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs b/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs
index acbf15dcb6c..5f3b711b31a 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs
+++ b/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.rs
@@ -31,10 +31,7 @@ impl Tr for E {
     type V = u8;
     fn f() -> Self::V { 0 }
     //~^ ERROR ambiguous associated item
-    //~| ERROR ambiguous associated item
     //~| WARN this was previously accepted
-    //~| WARN this was previously accepted
-    //~| HELP use fully-qualified syntax
     //~| HELP use fully-qualified syntax
 }
 
diff --git a/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr b/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
index 359bd09ecd0..0f42fcbe04d 100644
--- a/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
+++ b/tests/ui/type-alias-enum-variants/enum-variant-priority-lint-ambiguous_associated_items.stderr
@@ -18,25 +18,5 @@ LL |     type V;
    |     ^^^^^^
    = note: `#[deny(ambiguous_associated_items)]` on by default
 
-error: ambiguous associated item
-  --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:32:15
-   |
-LL |     fn f() -> Self::V { 0 }
-   |               ^^^^^^^ help: use fully-qualified syntax: `<E as Tr>::V`
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #57644 <https://github.com/rust-lang/rust/issues/57644>
-note: `V` could refer to the variant defined here
-  --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:22:5
-   |
-LL |     V
-   |     ^
-note: `V` could also refer to the associated type defined here
-  --> $DIR/enum-variant-priority-lint-ambiguous_associated_items.rs:26:5
-   |
-LL |     type V;
-   |     ^^^^^^
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs
index ac32dbde04b..1a5daa13458 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.rs
@@ -6,6 +6,7 @@ mod test_type_param_static {
     fn defining<A: 'static>(s: A) -> Ty<A> { s }
     fn assert_static<A: 'static>() {}
     fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
+    //~^ ERROR: the parameter type `A` may not live long enough
 }
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
index ff11aee4026..d1c06330c15 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
@@ -12,6 +12,20 @@ help: consider adding an explicit lifetime bound
 LL |     type Ty<A: 'static> = impl Sized + 'static;
    |              +++++++++
 
-error: aborting due to 1 previous error
+error[E0310]: the parameter type `A` may not live long enough
+  --> $DIR/implied_lifetime_wf_check4_static.rs:8:41
+   |
+LL |     fn test<A>() where Ty<A>: 'static { assert_static::<A>() }
+   |                                         ^^^^^^^^^^^^^^^^^^
+   |                                         |
+   |                                         the parameter type `A` must be valid for the static lifetime...
+   |                                         ...so that the type `A` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     fn test<A: 'static>() where Ty<A>: 'static { assert_static::<A>() }
+   |              +++++++++
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/type-alias-impl-trait/issue-58887.rs b/tests/ui/type-alias-impl-trait/issue-58887.rs
index 9675867656a..68d85ed6b0f 100644
--- a/tests/ui/type-alias-impl-trait/issue-58887.rs
+++ b/tests/ui/type-alias-impl-trait/issue-58887.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 
 #![feature(impl_trait_in_assoc_type)]
 
diff --git a/tests/ui/type-alias-impl-trait/issue-77179.rs b/tests/ui/type-alias-impl-trait/issue-77179.rs
index 3d6c826d6ac..2d9345a3e5e 100644
--- a/tests/ui/type-alias-impl-trait/issue-77179.rs
+++ b/tests/ui/type-alias-impl-trait/issue-77179.rs
@@ -7,6 +7,7 @@ type Pointer<T> = impl std::ops::Deref<Target = T>;
 fn test() -> Pointer<_> {
     //~^ ERROR: the placeholder `_` is not allowed within types
     Box::new(1)
+    //~^ ERROR: expected generic type parameter, found `i32`
 }
 
 fn main() {
diff --git a/tests/ui/type-alias-impl-trait/issue-77179.stderr b/tests/ui/type-alias-impl-trait/issue-77179.stderr
index c5cacfd3cd3..ebd78e5b7a5 100644
--- a/tests/ui/type-alias-impl-trait/issue-77179.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-77179.stderr
@@ -8,7 +8,7 @@ LL | fn test() -> Pointer<_> {
    |              help: replace with the correct return type: `Pointer<i32>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions
-  --> $DIR/issue-77179.rs:17:25
+  --> $DIR/issue-77179.rs:18:25
    |
 LL |     fn bar() -> Pointer<_>;
    |                         ^
@@ -16,6 +16,16 @@ LL |     fn bar() -> Pointer<_>;
    |                         not allowed in type signatures
    |                         help: use type parameters instead: `T`
 
-error: aborting due to 2 previous errors
+error[E0792]: expected generic type parameter, found `i32`
+  --> $DIR/issue-77179.rs:9:5
+   |
+LL | type Pointer<T> = impl std::ops::Deref<Target = T>;
+   |              - this generic parameter must be used with a generic type parameter
+...
+LL |     Box::new(1)
+   |     ^^^^^^^^^^^
+
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0121`.
+Some errors have detailed explanations: E0121, E0792.
+For more information about an error, try `rustc --explain E0121`.
diff --git a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
index 0f0a02e97d8..6431cf37df7 100644
--- a/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
+++ b/tests/ui/type-alias-impl-trait/no_inferrable_concrete_type.rs
@@ -14,5 +14,7 @@ mod foo {
 }
 
 fn main() {
-    let _: foo::Foo = std::mem::transmute(0u8);
+    unsafe {
+        let _: foo::Foo = std::mem::transmute(0u8);
+    }
 }
diff --git a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
index d92bafce142..fd76526644b 100644
--- a/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
+++ b/tests/ui/type-alias-impl-trait/rpit_tait_equality_in_canonical_query.current.stderr
@@ -1,4 +1,4 @@
-note: no errors encountered even though `span_delayed_bug` issued
+note: no errors encountered even though delayed bugs were created
 
 note: those delayed bugs will now be shown as internal compiler errors
 
diff --git a/tests/ui/issues/issue-16338.rs b/tests/ui/typeck/issue-16338.rs
index 321b3576cd6..321b3576cd6 100644
--- a/tests/ui/issues/issue-16338.rs
+++ b/tests/ui/typeck/issue-16338.rs
diff --git a/tests/ui/issues/issue-16338.stderr b/tests/ui/typeck/issue-16338.stderr
index e24b9bfa3c0..e24b9bfa3c0 100644
--- a/tests/ui/issues/issue-16338.stderr
+++ b/tests/ui/typeck/issue-16338.stderr
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.rs b/tests/ui/typeck/typeck_type_placeholder_item.rs
index 4eba14f5a93..591a7278ddc 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.rs
+++ b/tests/ui/typeck/typeck_type_placeholder_item.rs
@@ -198,6 +198,7 @@ trait Qux {
     //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
 }
 impl Qux for Struct {
+    //~^ ERROR not all trait items implemented, missing: `F`
     type A = _;
     //~^ ERROR the placeholder `_` is not allowed within types on item signatures for associated types
     type B = _;
diff --git a/tests/ui/typeck/typeck_type_placeholder_item.stderr b/tests/ui/typeck/typeck_type_placeholder_item.stderr
index a4325b01f02..bfcc76c1dae 100644
--- a/tests/ui/typeck/typeck_type_placeholder_item.stderr
+++ b/tests/ui/typeck/typeck_type_placeholder_item.stderr
@@ -29,7 +29,7 @@ LL | struct BadStruct2<_, T>(_, T);
    |                   ^ expected identifier, found reserved identifier
 
 error: associated constant in `impl` without body
-  --> $DIR/typeck_type_placeholder_item.rs:205:5
+  --> $DIR/typeck_type_placeholder_item.rs:206:5
    |
 LL |     const C: _;
    |     ^^^^^^^^^^-
@@ -411,7 +411,7 @@ LL | type Y = impl Trait<_>;
    |                     ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
-  --> $DIR/typeck_type_placeholder_item.rs:216:31
+  --> $DIR/typeck_type_placeholder_item.rs:217:31
    |
 LL | fn value() -> Option<&'static _> {
    |               ----------------^-
@@ -420,7 +420,7 @@ LL | fn value() -> Option<&'static _> {
    |               help: replace with the correct return type: `Option<&'static u8>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
-  --> $DIR/typeck_type_placeholder_item.rs:221:10
+  --> $DIR/typeck_type_placeholder_item.rs:222:10
    |
 LL | const _: Option<_> = map(value);
    |          ^^^^^^^^^
@@ -429,7 +429,7 @@ LL | const _: Option<_> = map(value);
    |          help: replace with the correct type: `Option<u8>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
-  --> $DIR/typeck_type_placeholder_item.rs:224:31
+  --> $DIR/typeck_type_placeholder_item.rs:225:31
    |
 LL | fn evens_squared(n: usize) -> _ {
    |                               ^
@@ -438,13 +438,13 @@ LL | fn evens_squared(n: usize) -> _ {
    |                               help: replace with an appropriate return type: `impl Iterator<Item = usize>`
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants
-  --> $DIR/typeck_type_placeholder_item.rs:229:10
+  --> $DIR/typeck_type_placeholder_item.rs:230:10
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |          ^ not allowed in type signatures
    |
-note: however, the inferred type `Map<Filter<Range<i32>, {closure@typeck_type_placeholder_item.rs:229:29}>, {closure@typeck_type_placeholder_item.rs:229:49}>` cannot be named
-  --> $DIR/typeck_type_placeholder_item.rs:229:14
+note: however, the inferred type `Map<Filter<Range<i32>, {closure@typeck_type_placeholder_item.rs:230:29}>, {closure@typeck_type_placeholder_item.rs:230:49}>` cannot be named
+  --> $DIR/typeck_type_placeholder_item.rs:230:14
    |
 LL | const _: _ = (1..10).filter(|x| x % 2 == 0).map(|x| x * x);
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -631,25 +631,25 @@ LL |         fn clone_from(&mut self, other: &FnTest9) { *self = FnTest9; }
    |                                         ~~~~~~~~
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
-  --> $DIR/typeck_type_placeholder_item.rs:201:14
+  --> $DIR/typeck_type_placeholder_item.rs:202:14
    |
 LL |     type A = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types
-  --> $DIR/typeck_type_placeholder_item.rs:203:14
+  --> $DIR/typeck_type_placeholder_item.rs:204:14
    |
 LL |     type B = _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:205:14
+  --> $DIR/typeck_type_placeholder_item.rs:206:14
    |
 LL |     const C: _;
    |              ^ not allowed in type signatures
 
 error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated constants
-  --> $DIR/typeck_type_placeholder_item.rs:208:14
+  --> $DIR/typeck_type_placeholder_item.rs:209:14
    |
 LL |     const D: _ = 42;
    |              ^
@@ -657,7 +657,16 @@ LL |     const D: _ = 42;
    |              not allowed in type signatures
    |              help: replace with the correct type: `i32`
 
-error: aborting due to 71 previous errors
+error[E0046]: not all trait items implemented, missing: `F`
+  --> $DIR/typeck_type_placeholder_item.rs:200:1
+   |
+LL |     type F: std::ops::Fn(_);
+   |     ----------------------- `F` from trait
+...
+LL | impl Qux for Struct {
+   | ^^^^^^^^^^^^^^^^^^^ missing `F` in implementation
+
+error: aborting due to 72 previous errors
 
-Some errors have detailed explanations: E0121, E0282, E0403.
-For more information about an error, try `rustc --explain E0121`.
+Some errors have detailed explanations: E0046, E0121, E0282, E0403.
+For more information about an error, try `rustc --explain E0046`.
diff --git a/tests/ui/typeof/issue-100183.stderr b/tests/ui/typeof/issue-100183.stderr
index 7be923d9383..57317d449cf 100644
--- a/tests/ui/typeof/issue-100183.stderr
+++ b/tests/ui/typeof/issue-100183.stderr
@@ -6,8 +6,8 @@ LL |     y: (typeof("hey"),),
    |
 help: consider replacing `typeof(...)` with an actual type
    |
-LL |     y: (&'static str,),
-   |         ~~~~~~~~~~~~
+LL |     y: (&str,),
+   |         ~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
index e90784a54ae..c1281ce6a42 100644
--- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
+++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
@@ -11,6 +11,19 @@ LL |     <i32 as Add<u32>>::add(1, 2);
              <&'a i32 as Add<i32>>
              <&i32 as Add<&i32>>
 
+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`
+   |
+   = help: the trait `Add<u32>` is not implemented for `i32`
+   = help: the following other types implement trait `Add<Rhs>`:
+             <i32 as Add>
+             <i32 as Add<&i32>>
+             <&'a i32 as Add<i32>>
+             <&i32 as Add<&i32>>
+
 error[E0308]: mismatched types
   --> $DIR/ufcs-qpath-self-mismatch.rs:7:28
    |
@@ -55,19 +68,6 @@ help: change the type of the numeric literal from `u32` to `i32`
 LL |     <i32 as Add<i32>>::add(1, 2i32);
    |                                ~~~
 
-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`
-   |
-   = help: the trait `Add<u32>` is not implemented for `i32`
-   = help: the following other types implement trait `Add<Rhs>`:
-             <i32 as Add>
-             <i32 as Add<&i32>>
-             <&'a i32 as Add<i32>>
-             <&i32 as Add<&i32>>
-
 error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs
index ea73b8b3c4a..8537eb71774 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs
@@ -33,6 +33,7 @@ fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) {
     //~^ ERROR trait takes 1 lifetime argument but 0 lifetime arguments were supplied
     // Here, the omitted lifetimes are expanded to distinct things.
     same_type(x, y)
+    //~^ ERROR borrowed data escapes outside of function
 }
 
 fn main() { }
diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
index d73aef851fd..6e6c649ca3d 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr
@@ -34,6 +34,22 @@ note: trait defined here, with 1 lifetime parameter: `'a`
 LL | trait Foo<'a,T> {
    |       ^^^ --
 
-error: aborting due to 3 previous errors
+error[E0521]: borrowed data escapes outside of function
+  --> $DIR/unboxed-closure-sugar-region.rs:35:5
+   |
+LL | fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) {
+   |          -                                - `y` declared here, outside of the function body
+   |          |
+   |          `x` is a reference that is only valid in the function body
+   |          has type `&dyn Foo<'1, (isize,), Output = ()>`
+...
+LL |     same_type(x, y)
+   |     ^^^^^^^^^^^^^^^
+   |     |
+   |     `x` escapes the function body here
+   |     argument requires that `'1` must outlive `'static`
+
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0107`.
+Some errors have detailed explanations: E0107, E0521.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/underscore-lifetime/underscore-lifetime-binders.rs b/tests/ui/underscore-lifetime/underscore-lifetime-binders.rs
index 3d049cc5639..ebc38798544 100644
--- a/tests/ui/underscore-lifetime/underscore-lifetime-binders.rs
+++ b/tests/ui/underscore-lifetime/underscore-lifetime-binders.rs
@@ -14,6 +14,7 @@ fn meh() -> Box<dyn for<'_> Meh<'_>> //~ ERROR cannot be used here
 }
 
 fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } //~ ERROR missing lifetime specifier
+//~^ ERROR lifetime may not live long enough
 
 fn main() {
     let x = 5;
diff --git a/tests/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/tests/ui/underscore-lifetime/underscore-lifetime-binders.stderr
index cd74d27dcb5..5d2954d1d71 100644
--- a/tests/ui/underscore-lifetime/underscore-lifetime-binders.stderr
+++ b/tests/ui/underscore-lifetime/underscore-lifetime-binders.stderr
@@ -45,7 +45,15 @@ help: consider introducing a named lifetime parameter
 LL | fn foo2<'a>(_: &'a u8, y: &'a u8) -> &'a u8 { y }
    |        ++++     ~~         ~~         ~~
 
-error: aborting due to 5 previous errors
+error: lifetime may not live long enough
+  --> $DIR/underscore-lifetime-binders.rs:16:43
+   |
+LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y }
+   |                       -                   ^ returning this value requires that `'1` must outlive `'static`
+   |                       |
+   |                       let's call the lifetime of this reference `'1`
+
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0106, E0637.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.fixed b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.fixed
index 5be6ff8e7e1..700e4f25423 100644
--- a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.fixed
+++ b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait WithType<T> {}
 trait WithRegion<'a> { }
diff --git a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.rs b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.rs
index d7072aa1181..66ba9b24dac 100644
--- a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.rs
+++ b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait WithType<T> {}
 trait WithRegion<'a> { }
diff --git a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.stderr b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.stderr
index 54e62f34fba..f012120e550 100644
--- a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.stderr
+++ b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2015.stderr
@@ -1,5 +1,5 @@
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/where-clause-inherent-impl-ampersand-rust2015.rs:13:17
+  --> $DIR/where-clause-inherent-impl-ampersand-rust2015.rs:14:17
    |
 LL |     T: WithType<&u32>
    |                 ^ explicit lifetime name needed here
diff --git a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.fixed b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.fixed
index 0f1be586589..56682db3b0b 100644
--- a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.fixed
+++ b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.fixed
@@ -1,5 +1,6 @@
 // edition:2018
 // run-rustfix
+#![allow(dead_code)]
 
 trait WithType<T> {}
 trait WithRegion<'a> { }
diff --git a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.rs b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.rs
index 59f7e472e2d..5302b2f1576 100644
--- a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.rs
+++ b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.rs
@@ -1,5 +1,6 @@
 // edition:2018
 // run-rustfix
+#![allow(dead_code)]
 
 trait WithType<T> {}
 trait WithRegion<'a> { }
diff --git a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.stderr b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.stderr
index 36f3e9ef145..7d675dd41e9 100644
--- a/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.stderr
+++ b/tests/ui/underscore-lifetime/where-clause-inherent-impl-ampersand-rust2018.stderr
@@ -1,5 +1,5 @@
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/where-clause-inherent-impl-ampersand-rust2018.rs:14:17
+  --> $DIR/where-clause-inherent-impl-ampersand-rust2018.rs:15:17
    |
 LL |     T: WithType<&u32>
    |                 ^ explicit lifetime name needed here
diff --git a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.fixed b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.fixed
index 55c7470960e..f3adc7e7fad 100644
--- a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.fixed
+++ b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.fixed
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait WithType<T> {}
 trait WithRegion<'a> { }
diff --git a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.rs b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.rs
index 42a35b02161..1e084e9ad41 100644
--- a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.rs
+++ b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.rs
@@ -1,4 +1,5 @@
 // run-rustfix
+#![allow(dead_code)]
 
 trait WithType<T> {}
 trait WithRegion<'a> { }
diff --git a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.stderr b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.stderr
index 92b7a9c2af8..8aa0e52c688 100644
--- a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.stderr
+++ b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2015.stderr
@@ -1,5 +1,5 @@
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/where-clause-trait-impl-region-2015.rs:10:17
+  --> $DIR/where-clause-trait-impl-region-2015.rs:11:17
    |
 LL |     T: WithType<&u32>
    |                 ^ explicit lifetime name needed here
diff --git a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.fixed b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.fixed
index 09b96fe5ea4..dd8074abed7 100644
--- a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.fixed
+++ b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.fixed
@@ -1,6 +1,8 @@
 // run-rustfix
 // edition:2018
 
+#![allow(dead_code)]
+
 trait WithType<T> {}
 trait WithRegion<'a> { }
 
diff --git a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.rs b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.rs
index 445f38cbee1..4fc9c71b179 100644
--- a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.rs
+++ b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.rs
@@ -1,6 +1,8 @@
 // run-rustfix
 // edition:2018
 
+#![allow(dead_code)]
+
 trait WithType<T> {}
 trait WithRegion<'a> { }
 
diff --git a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.stderr b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.stderr
index 63d8b99ed18..22940d0b0b1 100644
--- a/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.stderr
+++ b/tests/ui/underscore-lifetime/where-clause-trait-impl-region-2018.stderr
@@ -1,5 +1,5 @@
 error[E0637]: `&` without an explicit lifetime name cannot be used here
-  --> $DIR/where-clause-trait-impl-region-2018.rs:11:17
+  --> $DIR/where-clause-trait-impl-region-2018.rs:13:17
    |
 LL |     T: WithType<&u32>
    |                 ^ explicit lifetime name needed here
diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr
index 304e738ed25..c9131a8372a 100644
--- a/tests/ui/uninhabited/uninhabited-irrefutable.stderr
+++ b/tests/ui/uninhabited/uninhabited-irrefutable.exhaustive_patterns.stderr
@@ -1,5 +1,5 @@
 error[E0005]: refutable pattern in local binding
-  --> $DIR/uninhabited-irrefutable.rs:29:9
+  --> $DIR/uninhabited-irrefutable.rs:32:9
    |
 LL |     let Foo::D(_y, _z) = x;
    |         ^^^^^^^^^^^^^^ pattern `Foo::A(_)` not covered
@@ -7,7 +7,7 @@ LL |     let Foo::D(_y, _z) = x;
    = 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: `Foo` defined here
-  --> $DIR/uninhabited-irrefutable.rs:18:6
+  --> $DIR/uninhabited-irrefutable.rs:21:6
    |
 LL | enum Foo {
    |      ^^^
diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr b/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr
new file mode 100644
index 00000000000..c9131a8372a
--- /dev/null
+++ b/tests/ui/uninhabited/uninhabited-irrefutable.min_exhaustive_patterns.stderr
@@ -0,0 +1,26 @@
+error[E0005]: refutable pattern in local binding
+  --> $DIR/uninhabited-irrefutable.rs:32:9
+   |
+LL |     let Foo::D(_y, _z) = x;
+   |         ^^^^^^^^^^^^^^ pattern `Foo::A(_)` 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: `Foo` defined here
+  --> $DIR/uninhabited-irrefutable.rs:21:6
+   |
+LL | enum Foo {
+   |      ^^^
+LL |
+LL |     A(foo::SecretlyEmpty),
+   |     - not covered
+   = note: pattern `Foo::A(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
+   = note: the matched value is of type `Foo`
+help: you might want to use `let else` to handle the variant that isn't matched
+   |
+LL |     let Foo::D(_y, _z) = x else { todo!() };
+   |                            ++++++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0005`.
diff --git a/tests/ui/uninhabited/uninhabited-irrefutable.rs b/tests/ui/uninhabited/uninhabited-irrefutable.rs
index cfd60a8d903..2ef3b668cb0 100644
--- a/tests/ui/uninhabited/uninhabited-irrefutable.rs
+++ b/tests/ui/uninhabited/uninhabited-irrefutable.rs
@@ -1,5 +1,8 @@
+// revisions: min_exhaustive_patterns exhaustive_patterns
+#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
+#![cfg_attr(min_exhaustive_patterns, feature(min_exhaustive_patterns))]
+#![cfg_attr(min_exhaustive_patterns, allow(incomplete_features))]
 #![feature(never_type)]
-#![feature(exhaustive_patterns)]
 
 mod foo {
     pub struct SecretlyEmpty {
diff --git a/tests/ui/wf/hir-wf-canonicalized.rs b/tests/ui/wf/hir-wf-canonicalized.rs
index bdb84409d00..eac238f0fca 100644
--- a/tests/ui/wf/hir-wf-canonicalized.rs
+++ b/tests/ui/wf/hir-wf-canonicalized.rs
@@ -9,8 +9,8 @@ trait Callback<T: Foo>: Fn(&Bar<'_, T>, &T::V) {}
 struct Bar<'a, T> {
     callback: Box<dyn Callback<dyn Callback<Bar<'a, T>>>>,
     //~^ ERROR the trait bound `Bar<'a, T>: Foo` is not satisfied
-    //~| ERROR the trait bound `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static): Foo` is not satisfied
-    //~| ERROR the size for values of type `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static)` cannot be known at compilation time
+    //~| ERROR the trait bound `(dyn Callback<Bar<'a, T>, Output = ()> + 'static): Foo` is not satisfied
+    //~| ERROR the size for values of type `(dyn Callback<Bar<'a, T>, Output = ()> + 'static)` cannot be known at compilation time
 }
 
 impl<T: Foo> Bar<'_, Bar<'_, T>> {}
diff --git a/tests/ui/wf/hir-wf-canonicalized.stderr b/tests/ui/wf/hir-wf-canonicalized.stderr
index 4dca1f65232..8938801ce3d 100644
--- a/tests/ui/wf/hir-wf-canonicalized.stderr
+++ b/tests/ui/wf/hir-wf-canonicalized.stderr
@@ -10,11 +10,11 @@ help: this trait has no implementations, consider adding one
 LL | trait Foo {
    | ^^^^^^^^^
 
-error[E0277]: the trait bound `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static): Foo` is not satisfied
+error[E0277]: the trait bound `(dyn Callback<Bar<'a, T>, Output = ()> + 'static): Foo` is not satisfied
   --> $DIR/hir-wf-canonicalized.rs:10:15
    |
 LL |     callback: Box<dyn Callback<dyn Callback<Bar<'a, T>>>>,
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static)`
+   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(dyn Callback<Bar<'a, T>, Output = ()> + 'static)`
    |
 help: this trait has no implementations, consider adding one
   --> $DIR/hir-wf-canonicalized.rs:3:1
@@ -22,13 +22,13 @@ help: this trait has no implementations, consider adding one
 LL | trait Foo {
    | ^^^^^^^^^
 
-error[E0277]: the size for values of type `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static)` cannot be known at compilation time
+error[E0277]: the size for values of type `(dyn Callback<Bar<'a, T>, Output = ()> + 'static)` cannot be known at compilation time
   --> $DIR/hir-wf-canonicalized.rs:10:15
    |
 LL |     callback: Box<dyn Callback<dyn Callback<Bar<'a, T>>>>,
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
-   = help: the trait `Sized` is not implemented for `(dyn Callback<Bar<'a, T>, for<'b, 'c, 'd> Output = ()> + 'static)`
+   = help: the trait `Sized` is not implemented for `(dyn Callback<Bar<'a, T>, Output = ()> + 'static)`
 note: required by an implicit `Sized` bound in `Bar`
   --> $DIR/hir-wf-canonicalized.rs:9:16
    |
diff --git a/tests/ui/where-clauses/issue-50825-1.rs b/tests/ui/where-clauses/issue-50825-1.rs
index ee4316029a8..2ee34ad714e 100644
--- a/tests/ui/where-clauses/issue-50825-1.rs
+++ b/tests/ui/where-clauses/issue-50825-1.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // regression test for issue #50825
 // Make sure that the `impl` bound (): X<T = ()> is preferred over
 // the (): X bound in the where clause.
diff --git a/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs b/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs
index ea60fa70876..65fd2f3096c 100644
--- a/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs
+++ b/tests/ui/where-clauses/where-clause-bounds-inconsistency.rs
@@ -1,4 +1,4 @@
-// run-pass
+// check-pass
 // pretty-expanded FIXME #23616
 
 trait Bound {
diff --git a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs
index 6fc570b9b5b..a7ce0590fcd 100644
--- a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs
+++ b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.rs
@@ -3,7 +3,7 @@
 
 // pretty-expanded FIXME #23616
 
-trait TheTrait { fn dummy(&self) { } }
+trait TheTrait { fn dummy(&self) { } } //~ WARN method `dummy` is never used
 
 impl TheTrait for &'static isize { }
 
diff --git a/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr
new file mode 100644
index 00000000000..a9fe11ea6b3
--- /dev/null
+++ b/tests/ui/where-clauses/where-clause-early-bound-lifetimes.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/where-clause-early-bound-lifetimes.rs:6:21
+   |
+LL | trait TheTrait { fn dummy(&self) { } }
+   |       --------      ^^^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs b/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs
index daa3c8dd8e3..8f9c6fbff3d 100644
--- a/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs
+++ b/tests/ui/where-clauses/where-clause-method-substituion-rpass.rs
@@ -2,7 +2,7 @@
 #![allow(unused_variables)]
 // pretty-expanded FIXME #23616
 
-trait Foo<T> { fn dummy(&self, arg: T) { } }
+trait Foo<T> { fn dummy(&self, arg: T) { } } //~ WARN method `dummy` is never used
 
 trait Bar<A> {
     fn method<B>(&self) where A: Foo<B>;
diff --git a/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr b/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr
new file mode 100644
index 00000000000..0d09cb9de3f
--- /dev/null
+++ b/tests/ui/where-clauses/where-clause-method-substituion-rpass.stderr
@@ -0,0 +1,12 @@
+warning: method `dummy` is never used
+  --> $DIR/where-clause-method-substituion-rpass.rs:5:19
+   |
+LL | trait Foo<T> { fn dummy(&self, arg: T) { } }
+   |       ---         ^^^^^
+   |       |
+   |       method in this trait
+   |
+   = note: `#[warn(dead_code)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed
index 2f47c0d91fa..4e1aa59aac0 100644
--- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed
+++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.fixed
@@ -1,6 +1,8 @@
 // check-pass
 // run-rustfix
 
+#![allow(dead_code)]
+
 trait Trait {
     // Fine.
     type Assoc where u32: Copy;
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs
index b20aa9398b5..05b2f8c82a4 100644
--- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs
+++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.rs
@@ -1,6 +1,8 @@
 // check-pass
 // run-rustfix
 
+#![allow(dead_code)]
+
 trait Trait {
     // Fine.
     type Assoc where u32: Copy;
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr
index b4de051845f..6ff9d2dd73b 100644
--- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr
+++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-impl.stderr
@@ -1,5 +1,5 @@
 warning: where clause not allowed here
-  --> $DIR/where-clause-placement-assoc-type-in-impl.rs:13:16
+  --> $DIR/where-clause-placement-assoc-type-in-impl.rs:15:16
    |
 LL |     type Assoc where u32: Copy = ();
    |                ^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL +     type Assoc  = () where u32: Copy;
    |
 
 warning: where clause not allowed here
-  --> $DIR/where-clause-placement-assoc-type-in-impl.rs:16:17
+  --> $DIR/where-clause-placement-assoc-type-in-impl.rs:18:17
    |
 LL |     type Assoc2 where u32: Copy = () where i32: Copy;
    |                 ^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL +     type Assoc2  = () where i32: Copy, u32: Copy;
    |
 
 warning: where clause not allowed here
-  --> $DIR/where-clause-placement-assoc-type-in-impl.rs:24:17
+  --> $DIR/where-clause-placement-assoc-type-in-impl.rs:26:17
    |
 LL |     type Assoc2 where u32: Copy, i32: Copy = ();
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed
index d171eba50b7..940e2cc8e97 100644
--- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed
+++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.fixed
@@ -1,6 +1,7 @@
 // check-pass
 // run-rustfix
 
+#![allow(dead_code)]
 #![feature(associated_type_defaults)]
 
 trait Trait {
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.rs b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.rs
index 59afee65794..7001a9245a5 100644
--- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.rs
+++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.rs
@@ -1,6 +1,7 @@
 // check-pass
 // run-rustfix
 
+#![allow(dead_code)]
 #![feature(associated_type_defaults)]
 
 trait Trait {
diff --git a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr
index a81cb8c8cd6..9e9967ef739 100644
--- a/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr
+++ b/tests/ui/where-clauses/where-clause-placement-assoc-type-in-trait.stderr
@@ -1,5 +1,5 @@
 warning: where clause not allowed here
-  --> $DIR/where-clause-placement-assoc-type-in-trait.rs:8:16
+  --> $DIR/where-clause-placement-assoc-type-in-trait.rs:9:16
    |
 LL |     type Assoc where u32: Copy = ();
    |                ^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL +     type Assoc  = () where u32: Copy;
    |
 
 warning: where clause not allowed here
-  --> $DIR/where-clause-placement-assoc-type-in-trait.rs:11:17
+  --> $DIR/where-clause-placement-assoc-type-in-trait.rs:12:17
    |
 LL |     type Assoc2 where u32: Copy = () where i32: Copy;
    |                 ^^^^^^^^^^^^^^^
diff --git a/triagebot.toml b/triagebot.toml
index 68c863bb919..ef3f3693e61 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -658,7 +658,6 @@ compiler-team = [
 ]
 compiler-team-contributors = [
     "@TaKO8Ki",
-    "@b-naber",
     "@nnethercote",
     "@fmease",
 ]
@@ -670,7 +669,6 @@ libs = [
     "@cuviper",
     "@joshtriplett",
     "@Mark-Simulacrum",
-    "@m-ou-se",
 ]
 bootstrap = [
     "@Mark-Simulacrum",