about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Conjob Bot <miri@cron.bot>2024-02-10 05:02:28 +0000
committerThe Miri Conjob Bot <miri@cron.bot>2024-02-10 05:02:28 +0000
commit3e97b415c3df72d39f99f07f8f5c82ed34a7afaa (patch)
tree0ea8b63cd62bbfdb0925579bf6e08673cfdee317
parentd4b8ed007376f869f69c389c900d5fb3a9c4b5ac (diff)
parent29fd82b24e8990ab133cb07d7c670202a197743e (diff)
downloadrust-3e97b415c3df72d39f99f07f8f5c82ed34a7afaa.tar.gz
rust-3e97b415c3df72d39f99f07f8f5c82ed34a7afaa.zip
Merge from rustc
-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.rs87
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs85
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs6
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs16
-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/mod.rs4
-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/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs5
-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_ssa/Cargo.toml2
-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/interpret/step.rs20
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs7
-rw-r--r--compiler/rustc_const_eval/src/lib.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs5
-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.rs2
-rw-r--r--compiler/rustc_error_codes/src/lib.rs2
-rw-r--r--compiler/rustc_error_messages/src/lib.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs7
-rw-r--r--compiler/rustc_errors/src/diagnostic_impls.rs4
-rw-r--r--compiler/rustc_errors/src/lib.rs50
-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/lib.rs2
-rw-r--r--compiler/rustc_feature/src/removed.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs8
-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/generics.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/lint.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs32
-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/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/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.rs5
-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.rs6
-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/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs68
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs3
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs5
-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/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_lexer/src/lib.rs3
-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.rs4
-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/lib.rs2
-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.rs10
-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/lib.rs6
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs1
-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/print/pretty.rs60
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs50
-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.rs3
-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/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/promote_consts.rs1
-rw-r--r--compiler/rustc_monomorphize/src/lib.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/src/check_attr.rs13
-rw-r--r--compiler/rustc_passes/src/errors.rs3
-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.rs7
-rw-r--r--compiler/rustc_pattern_analysis/src/lib.rs3
-rw-r--r--compiler/rustc_pattern_analysis/src/lints.rs2
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs8
-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/src/late.rs30
-rw-r--r--compiler/rustc_resolve/src/lib.rs3
-rw-r--r--compiler/rustc_serialize/src/lib.rs2
-rw-r--r--compiler/rustc_session/src/lib.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs1
-rw-r--r--compiler/rustc_span/src/lib.rs2
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs2
-rw-r--r--compiler/rustc_target/src/lib.rs2
-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/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/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.rs139
-rw-r--r--library/core/src/intrinsics/mir.rs2
-rw-r--r--library/core/src/lib.rs2
-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/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.rs8
-rw-r--r--library/core/src/ptr/mod.rs45
-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.rs4
-rw-r--r--library/panic_unwind/src/seh.rs4
-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/thread/local.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs2
-rw-r--r--src/bootstrap/src/core/builder.rs4
-rw-r--r--src/bootstrap/src/core/download.rs6
-rw-r--r--src/bootstrap/src/lib.rs4
-rwxr-xr-xsrc/ci/docker/run.sh7
-rw-r--r--src/librustdoc/clean/inline.rs27
-rw-r--r--src/librustdoc/clean/mod.rs2
-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.rs2
-rw-r--r--src/librustdoc/passes/lint/redundant_explicit_links.rs49
-rw-r--r--src/stage0.json824
-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/coverage-dump/src/covfun.rs2
-rw-r--r--src/tools/miri/src/bin/miri.rs4
-rw-r--r--src/tools/miri/src/lib.rs6
-rw-r--r--src/tools/tidy/src/ui_tests.rs4
-rw-r--r--tests/assembly/is_aligned.rs4
-rw-r--r--tests/codegen/async-closure-debug.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/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/gvn_copy_moves.fn0.GVN.diff27
-rw-r--r--tests/mir-opt/gvn_copy_moves.rs46
-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/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/separate_const_switch.identity.SeparateConstSwitch.diff6
-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/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/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/higher-ranked.rs17
-rw-r--r--tests/ui/associated-type-bounds/nested-bounds-dont-eliminate-alias-bounds.rs37
-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/hr-associated-type-bound-object.stderr4
-rw-r--r--tests/ui/async-await/async-closures/async-fn-mut-for-async-fn.rs3
-rw-r--r--tests/ui/async-await/async-closures/async-fn-once-for-async-fn.rs3
-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/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/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/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/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/cast/enum-to-numeric-cast.rs46
-rw-r--r--tests/ui/cast/enum-to-numeric-cast.stderr35
-rw-r--r--tests/ui/cast/issue-88621.stderr4
-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/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-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-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/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-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/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/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/unstable-const-fn-in-libcore.stderr35
-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/did_you_mean/bad-assoc-ty.stderr2
-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.stderr66
-rw-r--r--tests/ui/dyn-keyword/dyn-angle-brackets.stderr2
-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/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/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/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-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/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/generics/generic-extern.rs2
-rw-r--r--tests/ui/generics/generic-extern.stderr13
-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/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/fresh-lifetime-from-bare-trait-obj-114664.rs4
-rw-r--r--tests/ui/impl-trait/fresh-lifetime-from-bare-trait-obj-114664.stderr32
-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/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/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-28344.stderr4
-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-3878.rs9
-rw-r--r--tests/ui/issues/issue-58734.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-86756.stderr2
-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/bare-trait-objects-path.stderr8
-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.stderr32
-rw-r--r--tests/ui/lint/force-warn/cap-lints-allow.rs4
-rw-r--r--tests/ui/lint/force-warn/cap-lints-allow.stderr32
-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.stderr32
-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.stderr32
-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.stderr32
-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-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/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/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/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_sized_unnecessary.rs2
-rw-r--r--tests/ui/object-safety/assoc_type_bounds_sized_unnecessary.stderr20
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr4
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr12
-rw-r--r--tests/ui/object-safety/avoid-ice-on-warning.old.stderr2
-rw-r--r--tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr2
-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/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/recover/recover-range-pats.rs9
-rw-r--r--tests/ui/parser/recover/recover-range-pats.stderr176
-rw-r--r--tests/ui/parser/trait-object-trait-parens.stderr6
-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-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/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/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/struct-field-type.rs10
-rw-r--r--tests/ui/privacy/struct-field-type.stderr21
-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/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-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/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/const_trait_impl.stderr30
-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/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/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/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/issue-102892.rs1
-rw-r--r--tests/ui/suggestions/issue-102892.stderr27
-rw-r--r--tests/ui/suggestions/issue-116434-2015.rs23
-rw-r--r--tests/ui/suggestions/issue-116434-2015.stderr81
-rw-r--r--tests/ui/suggestions/issue-116434-2021.rs17
-rw-r--r--tests/ui/suggestions/issue-116434-2021.stderr26
-rw-r--r--tests/ui/suggestions/issue-61963.rs10
-rw-r--r--tests/ui/suggestions/issue-61963.stderr78
-rw-r--r--tests/ui/suggestions/issue-86667.rs7
-rw-r--r--tests/ui/suggestions/issue-86667.stderr11
-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-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/suggest-swapping-self-ty-and-trait.stderr2
-rw-r--r--tests/ui/tag-variant-cast-non-nullary.stderr3
-rw-r--r--tests/ui/traits/bound/not-on-bare-trait.stderr2
-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-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-58344.rs (renamed from tests/ui/issues/issue-58344.rs)0
-rw-r--r--tests/ui/traits/issue-78372.rs3
-rw-r--r--tests/ui/traits/issue-78372.stderr33
-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/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/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/unspecified-self-in-trait-ref.stderr10
-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-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/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/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/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--triagebot.toml1
951 files changed, 14499 insertions, 6847 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 7b81ed4875c..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))
     }
 
@@ -569,7 +569,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     });
                 }
 
-                let path = if trees.is_empty() && !prefix.segments.is_empty() {
+                // 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);
@@ -633,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(
@@ -650,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,
@@ -722,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);
@@ -755,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)
@@ -803,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,
                         )
@@ -882,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)
@@ -916,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(
@@ -929,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)
                         }
@@ -1323,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) })
@@ -1401,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());
@@ -1607,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.
@@ -1681,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,
@@ -1695,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,
                 })
@@ -1703,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 063b6627050..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;
@@ -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 };
 
@@ -1006,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
@@ -1085,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)
@@ -1163,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)));
@@ -1210,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)),
@@ -1289,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))
     }
 
@@ -1299,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
@@ -1341,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 => {
@@ -1460,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 },
@@ -1513,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)
@@ -1523,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)
                     }
@@ -1581,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
@@ -1848,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 {
@@ -1876,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)),
             },
@@ -1977,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 {
@@ -1985,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, &[])),
         };
@@ -2025,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(
@@ -2164,7 +2161,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     .map(|def| {
                         self.lower_ty(
                             def,
-                            &ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
+                            ImplTraitContext::Disallowed(ImplTraitPosition::GenericDefault),
                         )
                     });
 
@@ -2174,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).
@@ -2204,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,
@@ -2224,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 =
@@ -2233,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 }
     }
 
@@ -2241,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))
     }
@@ -2249,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))
     }
@@ -2285,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 76c7e530a6b..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> {
@@ -205,7 +205,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     segment,
                     param_mode,
                     ParenthesizedGenericArgs::Err,
-                    &ImplTraitContext::Disallowed(ImplTraitPosition::Path),
+                    ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                     None,
                     None,
                 )
@@ -220,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
@@ -374,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(_))
@@ -405,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
@@ -415,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.:
@@ -429,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,
                         ),
@@ -437,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/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index fd20d352203..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;
@@ -213,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,
@@ -1984,6 +1981,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     ConstraintCategory::SizedBound,
                 );
             }
+            &Rvalue::NullaryOp(NullOp::DebugAssertions, _) => {}
 
             Rvalue::ShallowInitBox(operand, ty) => {
                 self.check_operand(operand, location);
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/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/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/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_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/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/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/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 5ff81615552..ee3f349c6b8 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -544,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/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 519bde98820..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;
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 d212e18b4cd..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]
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 1763c355069..03717a4d654 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -77,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"]
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/lib.rs b/compiler/rustc_errors/src/lib.rs
index ec5029e505f..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.
@@ -598,6 +606,7 @@ 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,
@@ -654,6 +663,7 @@ 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;
@@ -675,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;
             }
         }
 
@@ -694,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))
@@ -845,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()
     }
@@ -922,13 +929,22 @@ 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`.
@@ -937,8 +953,8 @@ impl DiagCtxt {
         })
     }
 
-    /// 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;
@@ -949,8 +965,8 @@ impl DiagCtxt {
         })
     }
 
-    /// 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 =
@@ -1224,10 +1240,8 @@ impl DiagCtxtInner {
         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
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/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 040892df4c3..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),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 1fb91ff8bbc..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 = "..."))`.
@@ -514,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.
@@ -550,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/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/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs
index a6ac8ecd950..cee7c84adb2 100644
--- a/compiler/rustc_hir_analysis/src/astconv/lint.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs
@@ -243,7 +243,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                 tcx.node_span_lint(BARE_TRAIT_OBJECTS, self_ty.hir_id, self_ty.span, msg, |lint| {
                     if self_ty.span.can_be_used_for_suggestions() {
                         lint.multipart_suggestion_verbose(
-                            "use `dyn`",
+                            "if this is an object-safe trait, use `dyn`",
                             sugg,
                             Applicability::MachineApplicable,
                         );
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index cfd38fb48f4..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).
         }
@@ -2493,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
@@ -2503,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),
                 }
@@ -2539,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
@@ -2573,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/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/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index fbe6f454dbc..1cd4b4cc4fc 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 54664f38b19..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:
@@ -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 007df203f71..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()
@@ -2017,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)
         {
@@ -3251,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/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 59bed38ec2a..dd9ed80ca72 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2182,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/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 2d8b47a9cc0..78ef70398e5 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -306,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.
@@ -711,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,
@@ -863,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);
@@ -895,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
@@ -909,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
     }
 
@@ -1032,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(
@@ -1043,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.
@@ -1261,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
@@ -1455,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,
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/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index 13c17ee1cd2..7edfbf02a68 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -221,11 +221,11 @@ 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)), _) => {
@@ -298,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 } => {
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/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 eabc1b953af..ed551658d91 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_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/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 1c03de410ee..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]
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/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/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 85631bd8edb..79aa9a547f7 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -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/lib.rs b/compiler/rustc_middle/src/lib.rs
index 9f1609a5595..2aaece1060a 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -49,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)]
@@ -58,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/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/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/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_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 1156e8be13e..692f4511bb8 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -665,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_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/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/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_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/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index e652c79d851..ec704dec352 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -827,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() });
@@ -853,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 {
@@ -2221,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/errors.rs b/compiler/rustc_passes/src/errors.rs
index 61c953bcb59..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};
@@ -1753,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,
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 bdb6cf19eac..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;
@@ -62,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 1a151e72488..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;
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/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index 576005b2c7f..80a807b4f27 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -1520,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 = place.is_scrutinee && !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()`.
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/src/late.rs b/compiler/rustc_resolve/src/late.rs
index f0b5311f1e1..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};
@@ -1645,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;
                 }
@@ -1737,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);
 
@@ -1758,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<'_>,
@@ -1891,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,
@@ -3941,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
@@ -4547,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/lib.rs b/compiler/rustc_resolve/src/lib.rs
index 16dce7e431d..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]
@@ -1629,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_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 bcf04a71ae2..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)]
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_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/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 d02578c4846..8dec04e2c4f 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/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 955c81eee6b..95f833372fb 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]),
@@ -2313,7 +2326,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,
@@ -2322,16 +2335,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 2258e796103..27dbe0351da 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
@@ -728,64 +770,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 c9d06b0f675..42074f4a079 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 6ea80c8d42f..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.
@@ -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)
     }
@@ -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 09d589f7cd8..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)]
@@ -181,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/async_function.rs b/library/core/src/ops/async_function.rs
index efbe9d164c3..c5a8303a75c 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 1d5d683fa16..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
             )
         };
 
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index bc05b5b07de..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
     }
@@ -1207,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)
     }
@@ -1411,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)
     }
@@ -1581,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)
     }
@@ -1656,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/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 15298e1c816..6deebc0d263 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -59,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)]
@@ -112,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/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/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/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 73f29d6bb6f..27b1d311864 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -173,6 +173,8 @@ impl Step for Std {
         {
             builder.info("WARNING: Using a potentially old libstd. This may not behave well.");
 
+            builder.ensure(StartupObjects { compiler, target });
+
             self.copy_extra_objects(builder, &compiler, target);
 
             builder.ensure(StdLink::from_std(self, compiler));
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index 4bb8ed2fa67..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,
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..836684ca20a 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.
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/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/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 097bbeb6d28..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]
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/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/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/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 c78444fa94f..aaa2a2e2705 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/lib.rs b/src/tools/miri/src/lib.rs
index 6fbf28a7520..adc547aa6cd 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/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 4a44c40debd..03f8a701627 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -14,8 +14,8 @@ use std::path::{Path, PathBuf};
 // #73494.
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
-const ISSUES_ENTRY_LIMIT: usize = 1819;
-const ROOT_ENTRY_LIMIT: usize = 871;
+const ISSUES_ENTRY_LIMIT: usize = 1794;
+const ROOT_ENTRY_LIMIT: usize = 870;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
     "rs",     // test source files
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/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/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/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/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/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/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/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/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/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/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/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-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/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/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 f73b43dd152..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,9 +2,6 @@
 // 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)]
 
 extern crate block_on;
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 0ba323a71cd..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,9 +2,6 @@
 // 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)]
 
 extern crate block_on;
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/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/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/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/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/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/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/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/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/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-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/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-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/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/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/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/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/did_you_mean/bad-assoc-ty.stderr b/tests/ui/did_you_mean/bad-assoc-ty.stderr
index eed01267224..d5754bdc664 100644
--- a/tests/ui/did_you_mean/bad-assoc-ty.stderr
+++ b/tests/ui/did_you_mean/bad-assoc-ty.stderr
@@ -182,7 +182,7 @@ LL | type H = Fn(u8) -> (u8)::Output;
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | type H = <dyn Fn(u8) -> (u8)>::Output;
    |          ++++               +
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..711bfa188ec 100644
--- a/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
+++ b/tests/ui/dyn-keyword/dyn-2018-edition-lint.stderr
@@ -11,7 +11,7 @@ note: the lint level is defined here
    |
 LL | #[deny(bare_trait_objects)]
    |        ^^^^^^^^^^^^^^^^^^
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn function(x: &dyn SomeTrait, y: Box<SomeTrait>) {
    |                 +++
@@ -24,79 +24,23 @@ 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>
-help: use `dyn`
+help: if this is an object-safe trait, 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:17:14
+  --> $DIR/dyn-2018-edition-lint.rs:9:14
    |
 LL |     let _x: &SomeTrait = todo!();
    |              ^^^^^^^^^
    |
    = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, 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/dyn-keyword/dyn-angle-brackets.stderr b/tests/ui/dyn-keyword/dyn-angle-brackets.stderr
index 0b194cb8364..41298cc73c8 100644
--- a/tests/ui/dyn-keyword/dyn-angle-brackets.stderr
+++ b/tests/ui/dyn-keyword/dyn-angle-brackets.stderr
@@ -11,7 +11,7 @@ note: the lint level is defined here
    |
 LL | #![deny(bare_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |         <dyn fmt::Debug>::fmt(self, f)
    |          +++
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/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/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/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-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/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/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/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/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/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..3cb3af89bfc 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
@@ -7,38 +7,10 @@ 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: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, 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/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/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/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-28344.stderr b/tests/ui/issues/issue-28344.stderr
index 71d642109ac..8b427b692a7 100644
--- a/tests/ui/issues/issue-28344.stderr
+++ b/tests/ui/issues/issue-28344.stderr
@@ -7,7 +7,7 @@ LL |     let x: u8 = BitXor::bitor(0 as u8, 0 as u8);
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let x: u8 = <dyn BitXor>::bitor(0 as u8, 0 as u8);
    |                 ++++       +
@@ -35,7 +35,7 @@ LL |     let g = BitXor::bitor;
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let g = <dyn BitXor>::bitor;
    |             ++++       +
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-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-58734.stderr b/tests/ui/issues/issue-58734.stderr
index 5ae1ec7cac8..71581e96844 100644
--- a/tests/ui/issues/issue-58734.stderr
+++ b/tests/ui/issues/issue-58734.stderr
@@ -7,7 +7,7 @@ LL |     Trait::nonexistent(());
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     <dyn Trait>::nonexistent(());
    |     ++++      +
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-86756.stderr b/tests/ui/issues/issue-86756.stderr
index bfa7459ab4a..d0906a6fa74 100644
--- a/tests/ui/issues/issue-86756.stderr
+++ b/tests/ui/issues/issue-86756.stderr
@@ -21,7 +21,7 @@ LL |     eq::<dyn, 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: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     eq::<dyn, dyn Foo>
    |               +++
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/bare-trait-objects-path.stderr b/tests/ui/lint/bare-trait-objects-path.stderr
index c5d72707f80..da1d9f248a0 100644
--- a/tests/ui/lint/bare-trait-objects-path.stderr
+++ b/tests/ui/lint/bare-trait-objects-path.stderr
@@ -7,7 +7,7 @@ LL |     let _: Dyn::Ty;
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let _: <dyn Dyn>::Ty;
    |            ++++    +
@@ -26,7 +26,7 @@ LL |     Dyn::func();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     <dyn Dyn>::func();
    |     ++++    +
@@ -39,7 +39,7 @@ LL |     ::Dyn::func();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     <dyn (::Dyn)>::func();
    |     ++++++     ++
@@ -52,7 +52,7 @@ LL |     Dyn::CONST;
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     <dyn Dyn>::CONST;
    |     ++++    +
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..388dc6160cb 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
@@ -7,38 +7,10 @@ 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: requested on the command line with `--force-warn bare-trait-objects`
-help: use `dyn`
+help: if this is an object-safe trait, 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..a037fb671af 100644
--- a/tests/ui/lint/force-warn/cap-lints-allow.stderr
+++ b/tests/ui/lint/force-warn/cap-lints-allow.stderr
@@ -7,38 +7,10 @@ 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: requested on the command line with `--force-warn bare-trait-objects`
-help: use `dyn`
+help: if this is an object-safe trait, 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..a74cda2239f 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
@@ -8,38 +8,10 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
-help: use `dyn`
+help: if this is an object-safe trait, 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..c9472a3b9b9 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
@@ -8,38 +8,10 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
-help: use `dyn`
+help: if this is an object-safe trait, 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..558d5cbb531 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
@@ -8,38 +8,10 @@ LL | pub fn function(_x: Box<SomeTrait>) {}
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `--force-warn bare-trait-objects` implied by `--force-warn rust-2018-idioms`
    = help: to override `--force-warn rust-2018-idioms` add `#[allow(bare_trait_objects)]`
-help: use `dyn`
+help: if this is an object-safe trait, 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/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/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/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/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/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_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/object-safety/avoid-ice-on-warning-2.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr
index 41c09b7df62..70e7ea53528 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning-2.old.stderr
@@ -7,7 +7,7 @@ LL | fn id<F>(f: Copy) -> usize {
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn id<F>(f: dyn Copy) -> usize {
    |             +++
@@ -21,7 +21,7 @@ LL | fn id<F>(f: Copy) -> usize {
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn id<F>(f: dyn Copy) -> usize {
    |             +++
diff --git a/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr
index a36e2519c80..f499e2d946f 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning-3.old.stderr
@@ -7,7 +7,7 @@ LL | trait B { fn f(a: A) -> A; }
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait B { fn f(a: dyn A) -> A; }
    |                   +++
@@ -20,7 +20,7 @@ LL | trait B { fn f(a: A) -> A; }
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait B { fn f(a: A) -> dyn A; }
    |                         +++
@@ -33,7 +33,7 @@ LL | trait A { fn g(b: B) -> B; }
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait A { fn g(b: dyn B) -> B; }
    |                   +++
@@ -46,7 +46,7 @@ LL | trait A { fn g(b: B) -> B; }
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait A { fn g(b: B) -> dyn B; }
    |                         +++
@@ -60,7 +60,7 @@ LL | trait B { fn f(a: A) -> A; }
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait B { fn f(a: dyn A) -> A; }
    |                   +++
@@ -96,7 +96,7 @@ LL | trait A { fn g(b: B) -> B; }
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | trait A { fn g(b: dyn B) -> B; }
    |                   +++
diff --git a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr
index 7c7af968280..3939c06eabe 100644
--- a/tests/ui/object-safety/avoid-ice-on-warning.old.stderr
+++ b/tests/ui/object-safety/avoid-ice-on-warning.old.stderr
@@ -19,7 +19,7 @@ LL | fn call_this<F>(f: F) : Fn(&str) + call_that {}
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn call_this<F>(f: F) : dyn Fn(&str) + call_that {}
    |                         +++
diff --git a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr
index 274d5a639a4..f795e910d21 100644
--- a/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr
+++ b/tests/ui/object-safety/bare-trait-dont-suggest-dyn.old.stderr
@@ -11,7 +11,7 @@ note: the lint level is defined here
    |
 LL | #![deny(bare_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn ord_prefer_dot(s: String) -> dyn Ord {
    |                                 +++
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/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/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/trait-object-trait-parens.stderr b/tests/ui/parser/trait-object-trait-parens.stderr
index 5e07a3fe6c7..3134746b930 100644
--- a/tests/ui/parser/trait-object-trait-parens.stderr
+++ b/tests/ui/parser/trait-object-trait-parens.stderr
@@ -25,7 +25,7 @@ LL |     let _: Box<(Obj) + (?Sized) + (for<'a> Trait<'a>)>;
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let _: Box<dyn (Obj) + (?Sized) + (for<'a> Trait<'a>)>;
    |                +++
@@ -49,7 +49,7 @@ LL |     let _: Box<?Sized + (for<'a> Trait<'a>) + (Obj)>;
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let _: Box<dyn ?Sized + (for<'a> Trait<'a>) + (Obj)>;
    |                +++
@@ -73,7 +73,7 @@ LL |     let _: Box<for<'a> Trait<'a> + (Obj) + (?Sized)>;
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let _: Box<dyn for<'a> Trait<'a> + (Obj) + (?Sized)>;
    |                +++
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/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/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/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/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/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/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-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/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/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/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/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/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/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/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-116434-2015.rs b/tests/ui/suggestions/issue-116434-2015.rs
new file mode 100644
index 00000000000..614fc27b771
--- /dev/null
+++ b/tests/ui/suggestions/issue-116434-2015.rs
@@ -0,0 +1,23 @@
+trait Foo {
+    type Clone;
+    fn foo() -> Clone;
+    //~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+    //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+    //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| ERROR the trait `Clone` cannot be made into an object [E0038]
+}
+
+trait DbHandle: Sized {}
+
+trait DbInterface {
+    type DbHandle;
+    fn handle() -> DbHandle;
+    //~^ WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+    //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| WARNING trait objects without an explicit `dyn` are deprecated [bare_trait_objects]
+    //~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+    //~| ERROR the trait `DbHandle` cannot be made into an object [E0038]
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/issue-116434-2015.stderr b/tests/ui/suggestions/issue-116434-2015.stderr
new file mode 100644
index 00000000000..2d87029b6eb
--- /dev/null
+++ b/tests/ui/suggestions/issue-116434-2015.stderr
@@ -0,0 +1,81 @@
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/issue-116434-2015.rs:3:17
+   |
+LL |     fn foo() -> Clone;
+   |                 ^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(bare_trait_objects)]` on by default
+help: if this is an object-safe trait, use `dyn`
+   |
+LL |     fn foo() -> dyn Clone;
+   |                 +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/issue-116434-2015.rs:15:20
+   |
+LL |     fn handle() -> DbHandle;
+   |                    ^^^^^^^^
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+help: if this is an object-safe trait, use `dyn`
+   |
+LL |     fn handle() -> dyn DbHandle;
+   |                    +++
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/issue-116434-2015.rs:3:17
+   |
+LL |     fn foo() -> Clone;
+   |                 ^^^^^
+   |
+   = 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: if this is an object-safe trait, use `dyn`
+   |
+LL |     fn foo() -> dyn Clone;
+   |                 +++
+
+error[E0038]: the trait `Clone` cannot be made into an object
+  --> $DIR/issue-116434-2015.rs:3:17
+   |
+LL |     fn foo() -> Clone;
+   |                 ^^^^^ `Clone` cannot be made into an object
+   |
+   = note: the trait cannot be made into an object because it requires `Self: Sized`
+   = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+
+warning: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/issue-116434-2015.rs:15:20
+   |
+LL |     fn handle() -> DbHandle;
+   |                    ^^^^^^^^
+   |
+   = 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: if this is an object-safe trait, use `dyn`
+   |
+LL |     fn handle() -> dyn DbHandle;
+   |                    +++
+
+error[E0038]: the trait `DbHandle` cannot be made into an object
+  --> $DIR/issue-116434-2015.rs:15:20
+   |
+LL |     fn handle() -> DbHandle;
+   |                    ^^^^^^^^ `DbHandle` 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-116434-2015.rs:11:17
+   |
+LL | trait DbHandle: Sized {}
+   |       --------  ^^^^^ ...because it requires `Self: Sized`
+   |       |
+   |       this trait cannot be made into an object...
+
+error: aborting due to 2 previous errors; 4 warnings emitted
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/suggestions/issue-116434-2021.rs b/tests/ui/suggestions/issue-116434-2021.rs
new file mode 100644
index 00000000000..74c30e0cc1f
--- /dev/null
+++ b/tests/ui/suggestions/issue-116434-2021.rs
@@ -0,0 +1,17 @@
+// edition:2021
+
+trait Foo {
+    type Clone;
+    fn foo() -> Clone;
+    //~^ ERROR the trait `Clone` cannot be made into an object [E0038]
+}
+
+trait DbHandle: Sized {}
+
+trait DbInterface {
+    type DbHandle;
+    fn handle() -> DbHandle;
+    //~^ ERROR the trait `DbHandle` cannot be made into an object [E0038]
+}
+
+fn main() {}
diff --git a/tests/ui/suggestions/issue-116434-2021.stderr b/tests/ui/suggestions/issue-116434-2021.stderr
new file mode 100644
index 00000000000..43ad82d484a
--- /dev/null
+++ b/tests/ui/suggestions/issue-116434-2021.stderr
@@ -0,0 +1,26 @@
+error[E0038]: the trait `Clone` cannot be made into an object
+  --> $DIR/issue-116434-2021.rs:5:17
+   |
+LL |     fn foo() -> Clone;
+   |                 ^^^^^ `Clone` cannot be made into an object
+   |
+   = note: the trait cannot be made into an object because it requires `Self: Sized`
+   = note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+
+error[E0038]: the trait `DbHandle` cannot be made into an object
+  --> $DIR/issue-116434-2021.rs:13:20
+   |
+LL |     fn handle() -> DbHandle;
+   |                    ^^^^^^^^ `DbHandle` 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-116434-2021.rs:9:17
+   |
+LL | trait DbHandle: Sized {}
+   |       --------  ^^^^^ ...because it requires `Self: Sized`
+   |       |
+   |       this trait cannot be made into an object...
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
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..084b0cbeef2 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>,
    |              ^^^
@@ -11,7 +11,7 @@ note: the lint level is defined here
    |
 LL | #![deny(bare_trait_objects)]
    |         ^^^^^^^^^^^^^^^^^^
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     bar: Box<dyn Bar>,
    |              +++
@@ -24,80 +24,10 @@ 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>
-help: use `dyn`
+help: if this is an object-safe trait, 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/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-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/suggest-swapping-self-ty-and-trait.stderr b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
index ffd505fffb4..0098814f81e 100644
--- a/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
+++ b/tests/ui/suggestions/suggest-swapping-self-ty-and-trait.stderr
@@ -40,7 +40,7 @@ LL | impl<'a, T> Struct<T> for Trait<'a, T> {}
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | impl<'a, T> Struct<T> for dyn Trait<'a, T> {}
    |                           +++
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/traits/bound/not-on-bare-trait.stderr b/tests/ui/traits/bound/not-on-bare-trait.stderr
index 6d56851bf34..f1e7a28654a 100644
--- a/tests/ui/traits/bound/not-on-bare-trait.stderr
+++ b/tests/ui/traits/bound/not-on-bare-trait.stderr
@@ -7,7 +7,7 @@ LL | fn foo(_x: Foo + Send) {
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL | fn foo(_x: dyn Foo + Send) {
    |            +++
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/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/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-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/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/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/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/unspecified-self-in-trait-ref.stderr b/tests/ui/traits/unspecified-self-in-trait-ref.stderr
index b5e8e88676c..3614348ceed 100644
--- a/tests/ui/traits/unspecified-self-in-trait-ref.stderr
+++ b/tests/ui/traits/unspecified-self-in-trait-ref.stderr
@@ -7,7 +7,7 @@ LL |     let a = Foo::lol();
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
    = note: `#[warn(bare_trait_objects)]` on by default
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let a = <dyn Foo>::lol();
    |             ++++    +
@@ -26,7 +26,7 @@ LL |     let b = Foo::<_>::lol();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let b = <dyn Foo::<_>>::lol();
    |             ++++         +
@@ -45,7 +45,7 @@ LL |     let c = Bar::lol();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let c = <dyn Bar>::lol();
    |             ++++    +
@@ -64,7 +64,7 @@ LL |     let d = Bar::<usize, _>::lol();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let d = <dyn Bar::<usize, _>>::lol();
    |             ++++                +
@@ -83,7 +83,7 @@ LL |     let e = Bar::<usize>::lol();
    |
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-help: use `dyn`
+help: if this is an object-safe trait, use `dyn`
    |
 LL |     let e = <dyn Bar::<usize>>::lol();
    |             ++++             +
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-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/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/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/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/triagebot.toml b/triagebot.toml
index eba8e283815..ef3f3693e61 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -669,7 +669,6 @@ libs = [
     "@cuviper",
     "@joshtriplett",
     "@Mark-Simulacrum",
-    "@m-ou-se",
 ]
 bootstrap = [
     "@Mark-Simulacrum",