about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock8
-rw-r--r--compiler/rustc_ast/src/ast.rs22
-rw-r--r--compiler/rustc_ast/src/util/literal.rs74
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs44
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs30
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs27
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs23
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs4
-rw-r--r--compiler/rustc_data_structures/src/sorted_map.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs5
-rw-r--r--compiler/rustc_errors/src/emitter.rs5
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs13
-rw-r--r--compiler/rustc_hir/src/intravisit.rs4
-rw-r--r--compiler/rustc_hir/src/target.rs36
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/lint.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs147
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs202
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check_unused.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs30
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/prelude2021.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/suggest.rs26
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs15
-rw-r--r--compiler/rustc_infer/src/infer/outlives/verify.rs7
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs (renamed from compiler/rustc_infer/src/infer/combine.rs)8
-rw-r--r--compiler/rustc_infer/src/infer/relate/equate.rs (renamed from compiler/rustc_infer/src/infer/equate.rs)8
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs (renamed from compiler/rustc_infer/src/infer/generalize.rs)12
-rw-r--r--compiler/rustc_infer/src/infer/relate/glb.rs (renamed from compiler/rustc_infer/src/infer/glb.rs)11
-rw-r--r--compiler/rustc_infer/src/infer/relate/higher_ranked.rs (renamed from compiler/rustc_infer/src/infer/higher_ranked/mod.rs)2
-rw-r--r--compiler/rustc_infer/src/infer/relate/lattice.rs (renamed from compiler/rustc_infer/src/infer/lattice.rs)6
-rw-r--r--compiler/rustc_infer/src/infer/relate/lub.rs (renamed from compiler/rustc_infer/src/infer/lub.rs)7
-rw-r--r--compiler/rustc_infer/src/infer/relate/mod.rs12
-rw-r--r--compiler/rustc_infer/src/infer/relate/nll.rs (renamed from compiler/rustc_infer/src/infer/nll_relate/mod.rs)4
-rw-r--r--compiler/rustc_infer/src/infer/relate/sub.rs (renamed from compiler/rustc_infer/src/infer/sub.rs)4
-rw-r--r--compiler/rustc_lexer/src/unescape.rs21
-rw-r--r--compiler/rustc_lint/src/builtin.rs2
-rw-r--r--compiler/rustc_lint/src/context.rs39
-rw-r--r--compiler/rustc_lint/src/early.rs8
-rw-r--r--compiler/rustc_lint/src/levels.rs11
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint/src/lints.rs56
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs3
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs42
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp8
-rw-r--r--compiler/rustc_macros/src/diagnostics/diagnostic.rs4
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs4
-rw-r--r--compiler/rustc_middle/src/lint.rs36
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs18
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs6
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs20
-rw-r--r--compiler/rustc_parse/src/lexer/unescape_error_reporting.rs75
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs2
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs2
-rw-r--r--compiler/rustc_passes/src/lang_items.rs378
-rw-r--r--compiler/rustc_passes/src/weak_lang_items.rs30
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs2
-rw-r--r--compiler/rustc_resolve/src/rustdoc.rs3
-rw-r--r--compiler/rustc_session/src/config.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/context.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs5
-rw-r--r--library/alloc/src/ffi/c_str.rs6
-rw-r--r--library/core/src/any.rs39
-rw-r--r--library/core/src/ffi/c_str.rs4
-rw-r--r--library/core/src/net/ip_addr.rs2
-rw-r--r--library/core/src/ptr/mod.rs7
-rw-r--r--library/core/src/slice/ascii.rs3
-rw-r--r--library/core/src/str/mod.rs79
-rw-r--r--library/proc_macro/src/bridge/mod.rs1
-rw-r--r--library/proc_macro/src/lib.rs3
-rw-r--r--library/std/Cargo.toml5
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/panicking.rs4
-rw-r--r--library/std/src/process.rs2
-rw-r--r--library/std/src/rt.rs2
-rw-r--r--library/std/src/sys/personality/mod.rs2
-rw-r--r--src/bootstrap/bootstrap.py16
-rw-r--r--src/bootstrap/src/bin/rustc.rs52
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs16
-rw-r--r--src/bootstrap/src/core/builder.rs140
-rw-r--r--src/bootstrap/src/core/download.rs35
-rw-r--r--src/bootstrap/src/utils/dylib.rs13
-rw-r--r--src/bootstrap/src/utils/helpers.rs10
-rw-r--r--src/ci/docker/host-x86_64/mingw-check/Dockerfile6
-rw-r--r--src/librustdoc/clean/mod.rs18
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/librustdoc/html/markdown.rs12
-rw-r--r--src/librustdoc/html/render/write_shared.rs4
-rw-r--r--src/librustdoc/html/static/js/src-script.js15
-rw-r--r--src/librustdoc/lint.rs4
-rw-r--r--src/librustdoc/passes/check_custom_code_classes.rs2
-rw-r--r--src/librustdoc/passes/check_doc_test_visibility.rs4
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs2
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs2
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs2
-rw-r--r--src/librustdoc/passes/lint/html_tags.rs4
-rw-r--r--src/librustdoc/passes/lint/redundant_explicit_links.rs4
-rw-r--r--src/librustdoc/passes/lint/unescaped_backticks.rs2
-rw-r--r--src/librustdoc/visit_ast.rs9
-rw-r--r--src/stage0.json48
-rw-r--r--src/tools/bump-stage0/src/main.rs2
-rw-r--r--src/tools/clippy/.github/workflows/clippy_bors.yml2
-rw-r--r--src/tools/clippy/CHANGELOG.md5
-rw-r--r--src/tools/clippy/clippy_dev/src/lint.rs10
-rw-r--r--src/tools/clippy/clippy_dev/src/serve.rs4
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_lints/src/as_conversions.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs137
-rw-r--r--src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs139
-rw-r--r--src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/markdown.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/ineffective_open_options.rs95
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs125
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mod.rs47
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_float_methods.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_string_new.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs31
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_if.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs25
-rw-r--r--src/tools/clippy/clippy_lints/src/renamed_lints.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs114
-rw-r--r--src/tools/clippy/clippy_lints/src/same_name_method.rs46
-rw-r--r--src/tools/clippy/clippy_lints/src/single_call_fn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/uninhabited_references.rs84
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/vec.rs157
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs17
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs80
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs55
-rw-r--r--src/tools/clippy/lintcheck/src/main.rs6
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/src/main.rs2
-rw-r--r--src/tools/clippy/tests/headers.rs7
-rw-r--r--src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr2
-rw-r--r--src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr2
-rw-r--r--src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr2
-rw-r--r--src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs2
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed2
-rw-r--r--src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs2
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.fixed (renamed from src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed)26
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.rs (renamed from src/tools/clippy/tests/ui/blocks_in_if_conditions.rs)26
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.stderr (renamed from src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr)33
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions_closure.rs (renamed from src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs)21
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions_closure.stderr (renamed from src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr)21
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed3
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs3
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.stderr24
-rw-r--r--src/tools/clippy/tests/ui/doc_unsafe.rs2
-rw-r--r--src/tools/clippy/tests/ui/ineffective_open_options.fixed41
-rw-r--r--src/tools/clippy/tests/ui/ineffective_open_options.rs41
-rw-r--r--src/tools/clippy/tests/ui/ineffective_open_options.stderr17
-rw-r--r--src/tools/clippy/tests/ui/infallible_destructuring_match.fixed2
-rw-r--r--src/tools/clippy/tests/ui/infallible_destructuring_match.rs2
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.rs366
-rw-r--r--src/tools/clippy/tests/ui/infinite_loops.stderr259
-rw-r--r--src/tools/clippy/tests/ui/manual_filter.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_filter.rs2
-rw-r--r--src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed15
-rw-r--r--src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs15
-rw-r--r--src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr54
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed15
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs15
-rw-r--r--src/tools/clippy/tests/ui/needless_if.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_if.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.fixed2
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs13
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr62
-rw-r--r--src/tools/clippy/tests/ui/no_effect.rs31
-rw-r--r--src/tools/clippy/tests/ui/no_effect.stderr58
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.fixed115
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.rs115
-rw-r--r--src/tools/clippy/tests/ui/ptr_as_ptr.stderr146
-rw-r--r--src/tools/clippy/tests/ui/regex.rs4
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed7
-rw-r--r--src/tools/clippy/tests/ui/rename.rs3
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr122
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed38
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs38
-rw-r--r--src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr40
-rw-r--r--src/tools/clippy/tests/ui/uninhabited_references.rs22
-rw-r--r--src/tools/clippy/tests/ui/uninhabited_references.stderr39
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.fixed19
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.rs19
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_operation.stderr38
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed23
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs23
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.stderr176
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs2
-rw-r--r--src/tools/clippy/tests/ui/vec.fixed34
-rw-r--r--src/tools/clippy/tests/ui/vec.rs34
-rw-r--r--src/tools/clippy/tests/ui/vec.stderr8
-rw-r--r--src/tools/clippy/triagebot.toml1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs4
-rw-r--r--tests/codegen/debug-accessibility/crate-enum.rs26
-rw-r--r--tests/codegen/debug-accessibility/crate-struct.rs23
-rw-r--r--tests/codegen/debug-accessibility/private-enum.rs21
-rw-r--r--tests/codegen/debug-accessibility/private-struct.rs17
-rw-r--r--tests/codegen/debug-accessibility/public-enum.rs21
-rw-r--r--tests/codegen/debug-accessibility/public-struct.rs17
-rw-r--r--tests/codegen/debug-accessibility/struct-fields.rs30
-rw-r--r--tests/codegen/debug-accessibility/super-enum.rs27
-rw-r--r--tests/codegen/debug-accessibility/super-struct.rs23
-rw-r--r--tests/codegen/debug-accessibility/tuple-fields.rs24
-rw-r--r--tests/coverage/assert_not.cov-map16
-rw-r--r--tests/coverage/assert_not.coverage12
-rw-r--r--tests/coverage/assert_not.rs11
-rw-r--r--tests/rustdoc-gui/globals.goml24
-rw-r--r--tests/ui/coherence/occurs-check/associated-type.next.stderr16
-rw-r--r--tests/ui/coherence/occurs-check/associated-type.old.stderr16
-rw-r--r--tests/ui/duplicate_entry_error.stderr7
-rw-r--r--tests/ui/error-codes/E0152.stderr2
-rw-r--r--tests/ui/error-codes/E0264.stderr2
-rw-r--r--tests/ui/hygiene/cross-crate-define-and-use.rs1
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs5
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr43
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs5
-rw-r--r--tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr45
-rw-r--r--tests/ui/lang-items/lang-item-generic-requirements.rs3
-rw-r--r--tests/ui/lang-items/lang-item-generic-requirements.stderr37
-rw-r--r--tests/ui/lint/ptr_null_checks.rs2
-rw-r--r--tests/ui/lint/ptr_null_checks.stderr54
-rw-r--r--tests/ui/lint/reference_casting.rs2
-rw-r--r--tests/ui/lint/reference_casting.stderr84
-rw-r--r--tests/ui/panic-handler/panic-handler-duplicate.stderr12
-rw-r--r--tests/ui/panic-handler/panic-handler-std.stderr6
-rw-r--r--tests/ui/proc-macro/auxiliary/env.rs28
-rw-r--r--tests/ui/proc-macro/env.rs17
-rw-r--r--tests/ui/regions/resolve-re-error-ice.rs6
-rw-r--r--tests/ui/regions/resolve-re-error-ice.stderr42
-rw-r--r--tests/ui/structs-enums/type-sizes.rs1
-rw-r--r--tests/ui/traits/issue-102989.rs1
-rw-r--r--tests/ui/traits/issue-102989.stderr22
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.stderr16
-rw-r--r--triagebot.toml14
279 files changed, 4777 insertions, 2012 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 98c030b3996..dbe5b2ec6b7 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -598,7 +598,7 @@ dependencies = [
  "itertools",
  "quine-mc_cluskey",
  "regex",
- "regex-syntax 0.7.2",
+ "regex-syntax 0.8.2",
  "rustc-semver",
  "semver",
  "serde",
@@ -3196,6 +3196,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78"
 
 [[package]]
+name = "regex-syntax"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+
+[[package]]
 name = "remote-test-client"
 version = "0.1.0"
 
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 5755ae8a8bc..9d543563c0f 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2845,6 +2845,28 @@ impl Item {
     pub fn span_with_attributes(&self) -> Span {
         self.attrs.iter().fold(self.span, |acc, attr| acc.to(attr.span))
     }
+
+    pub fn opt_generics(&self) -> Option<&Generics> {
+        match &self.kind {
+            ItemKind::ExternCrate(_)
+            | ItemKind::Use(_)
+            | ItemKind::Mod(_, _)
+            | ItemKind::ForeignMod(_)
+            | ItemKind::GlobalAsm(_)
+            | ItemKind::MacCall(_)
+            | ItemKind::MacroDef(_) => None,
+            ItemKind::Static(_) => None,
+            ItemKind::Const(i) => Some(&i.generics),
+            ItemKind::Fn(i) => Some(&i.generics),
+            ItemKind::TyAlias(i) => Some(&i.generics),
+            ItemKind::TraitAlias(generics, _)
+            | ItemKind::Enum(_, generics)
+            | ItemKind::Struct(_, generics)
+            | ItemKind::Union(_, generics) => Some(&generics),
+            ItemKind::Trait(i) => Some(&i.generics),
+            ItemKind::Impl(i) => Some(&i.generics),
+        }
+    }
 }
 
 /// `extern` qualifier on a function item or function type.
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index 50eb92125b9..92b9adf1db7 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -77,6 +77,8 @@ impl LitKind {
                 // new symbol because the string in the LitKind is different to the
                 // string in the token.
                 let s = symbol.as_str();
+                // Vanilla strings are so common we optimize for the common case where no chars
+                // requiring special behaviour are present.
                 let symbol = if s.contains(['\\', '\r']) {
                     let mut buf = String::with_capacity(s.len());
                     let mut error = Ok(());
@@ -104,27 +106,20 @@ impl LitKind {
                 LitKind::Str(symbol, ast::StrStyle::Cooked)
             }
             token::StrRaw(n) => {
-                // Ditto.
-                let s = symbol.as_str();
-                let symbol =
-                    if s.contains('\r') {
-                        let mut buf = String::with_capacity(s.len());
-                        let mut error = Ok(());
-                        unescape_literal(s, Mode::RawStr, &mut |_, unescaped_char| {
-                            match unescaped_char {
-                                Ok(c) => buf.push(c),
-                                Err(err) => {
-                                    if err.is_fatal() {
-                                        error = Err(LitError::LexerError);
-                                    }
-                                }
+                // Raw strings have no escapes, so we only need to check for invalid chars, and we
+                // can reuse the symbol on success.
+                let mut error = Ok(());
+                unescape_literal(symbol.as_str(), Mode::RawStr, &mut |_, unescaped_char| {
+                    match unescaped_char {
+                        Ok(_) => {}
+                        Err(err) => {
+                            if err.is_fatal() {
+                                error = Err(LitError::LexerError);
                             }
-                        });
-                        error?;
-                        Symbol::intern(&buf)
-                    } else {
-                        symbol
-                    };
+                        }
+                    }
+                });
+                error?;
                 LitKind::Str(symbol, ast::StrStyle::Raw(n))
             }
             token::ByteStr => {
@@ -143,25 +138,19 @@ impl LitKind {
                 LitKind::ByteStr(buf.into(), StrStyle::Cooked)
             }
             token::ByteStrRaw(n) => {
+                // Raw strings have no escapes, so we only need to check for invalid chars, and we
+                // can convert the symbol directly to a `Lrc<u8>` on success.
                 let s = symbol.as_str();
-                let bytes = if s.contains('\r') {
-                    let mut buf = Vec::with_capacity(s.len());
-                    let mut error = Ok(());
-                    unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c {
-                        Ok(c) => buf.push(byte_from_char(c)),
-                        Err(err) => {
-                            if err.is_fatal() {
-                                error = Err(LitError::LexerError);
-                            }
+                let mut error = Ok(());
+                unescape_literal(s, Mode::RawByteStr, &mut |_, c| match c {
+                    Ok(_) => {}
+                    Err(err) => {
+                        if err.is_fatal() {
+                            error = Err(LitError::LexerError);
                         }
-                    });
-                    error?;
-                    buf
-                } else {
-                    symbol.to_string().into_bytes()
-                };
-
-                LitKind::ByteStr(bytes.into(), StrStyle::Raw(n))
+                    }
+                });
+                LitKind::ByteStr(s.to_owned().into_bytes().into(), StrStyle::Raw(n))
             }
             token::CStr => {
                 let s = symbol.as_str();
@@ -172,7 +161,6 @@ impl LitKind {
                         error = Err(LitError::NulInCStr(span));
                     }
                     Ok(CStrUnit::Byte(b)) => buf.push(b),
-                    Ok(CStrUnit::Char(c)) if c.len_utf8() == 1 => buf.push(c as u8),
                     Ok(CStrUnit::Char(c)) => {
                         buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes())
                     }
@@ -187,18 +175,15 @@ impl LitKind {
                 LitKind::CStr(buf.into(), StrStyle::Cooked)
             }
             token::CStrRaw(n) => {
+                // Raw strings have no escapes, so we only need to check for invalid chars, and we
+                // can convert the symbol directly to a `Lrc<u8>` on success.
                 let s = symbol.as_str();
-                let mut buf = Vec::with_capacity(s.len());
                 let mut error = Ok(());
                 unescape_c_string(s, Mode::RawCStr, &mut |span, c| match c {
                     Ok(CStrUnit::Byte(0) | CStrUnit::Char('\0')) => {
                         error = Err(LitError::NulInCStr(span));
                     }
-                    Ok(CStrUnit::Byte(b)) => buf.push(b),
-                    Ok(CStrUnit::Char(c)) if c.len_utf8() == 1 => buf.push(c as u8),
-                    Ok(CStrUnit::Char(c)) => {
-                        buf.extend_from_slice(c.encode_utf8(&mut [0; 4]).as_bytes())
-                    }
+                    Ok(_) => {}
                     Err(err) => {
                         if err.is_fatal() {
                             error = Err(LitError::LexerError);
@@ -206,6 +191,7 @@ impl LitKind {
                     }
                 });
                 error?;
+                let mut buf = s.to_owned().into_bytes();
                 buf.push(0);
                 LitKind::CStr(buf.into(), StrStyle::Raw(n))
             }
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 0bbdcb7f09e..11b5131b8d7 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1260,9 +1260,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
         );
 
         // `a = lhs1; b = lhs2;`.
-        let stmts = self
-            .arena
-            .alloc_from_iter(std::iter::once(destructure_let).chain(assignments.into_iter()));
+        let stmts = self.arena.alloc_from_iter(std::iter::once(destructure_let).chain(assignments));
 
         // Wrap everything in a block.
         hir::ExprKind::Block(self.block_all(whole_span, stmts, None), None)
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index d9663d50c59..5c9e43f1e06 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -453,6 +453,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
     tcx.ensure_with_value().output_filenames(());
     tcx.ensure_with_value().early_lint_checks(());
     tcx.ensure_with_value().debugger_visualizers(LOCAL_CRATE);
+    tcx.ensure_with_value().get_lang_items(());
     let (mut resolver, krate) = tcx.resolver_for_lowering(()).steal();
 
     let ast_index = index_crate(&resolver.node_id_to_def_id, &krate);
@@ -765,6 +766,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.resolver.get_import_res(id).present_items()
     }
 
+    fn make_lang_item_path(
+        &mut self,
+        lang_item: hir::LangItem,
+        span: Span,
+        args: Option<&'hir hir::GenericArgs<'hir>>,
+    ) -> &'hir hir::Path<'hir> {
+        let def_id = self.tcx.require_lang_item(lang_item, Some(span));
+        let def_kind = self.tcx.def_kind(def_id);
+        let res = Res::Def(def_kind, def_id);
+        self.arena.alloc(hir::Path {
+            span,
+            res,
+            segments: self.arena.alloc_from_iter([hir::PathSegment {
+                ident: Ident::new(lang_item.name(), span),
+                hir_id: self.next_id(),
+                res,
+                args,
+                infer_args: false,
+            }]),
+        })
+    }
+
     /// Reuses the span but adds information like the kind of the desugaring and features that are
     /// allowed inside this span.
     fn mark_span_with_reason(
@@ -1976,18 +1999,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
         };
 
-        let future_args = self.arena.alloc(hir::GenericArgs {
+        let bound_args = self.arena.alloc(hir::GenericArgs {
             args: &[],
             bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
             parenthesized: hir::GenericArgsParentheses::No,
             span_ext: DUMMY_SP,
         });
 
-        hir::GenericBound::LangItemTrait(
-            trait_lang_item,
-            opaque_ty_span,
-            self.next_id(),
-            future_args,
+        hir::GenericBound::Trait(
+            hir::PolyTraitRef {
+                bound_generic_params: &[],
+                trait_ref: hir::TraitRef {
+                    path: self.make_lang_item_path(
+                        trait_lang_item,
+                        opaque_ty_span,
+                        Some(bound_args),
+                    ),
+                    hir_ref_id: self.next_id(),
+                },
+                span: opaque_ty_span,
+            },
+            hir::TraitBoundModifier::None,
         )
     }
 
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 4c3cef2e763..8441dfaa7df 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -788,28 +788,18 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
         };
         let opaque_ty = hir.item(id);
         if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
-            bounds:
-                [
-                    hir::GenericBound::LangItemTrait(
-                        hir::LangItem::Future,
-                        _,
-                        _,
-                        hir::GenericArgs {
-                            bindings:
-                                [
-                                    hir::TypeBinding {
-                                        ident: Ident { name: sym::Output, .. },
-                                        kind:
-                                            hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
-                                        ..
-                                    },
-                                ],
-                            ..
-                        },
-                    ),
-                ],
+            bounds: [hir::GenericBound::Trait(trait_ref, _)],
             ..
         }) = opaque_ty.kind
+            && let Some(segment) = trait_ref.trait_ref.path.segments.last()
+            && let Some(args) = segment.args
+            && let [
+                hir::TypeBinding {
+                    ident: Ident { name: sym::Output, .. },
+                    kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
+                    ..
+                },
+            ] = args.bindings
         {
             ty
         } else {
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index f4b9296dbbd..8f60175a603 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -353,7 +353,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         let new_kind = match ty.kind() {
             Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)),
             Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)),
-            t @ (Uint(_) | Int(_)) => t.clone(),
+            t @ (Uint(_) | Int(_)) => *t,
             _ => panic!("tried to get overflow intrinsic for op applied to non-int type"),
         };
 
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 7968f238b40..883f82caa80 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -607,7 +607,7 @@ pub fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFile) ->
 
                     if let Ok(rel_path) = abs_path.strip_prefix(working_directory) {
                         (
-                            working_directory.to_string_lossy().into(),
+                            working_directory.to_string_lossy(),
                             rel_path.to_string_lossy().into_owned(),
                         )
                     } else {
@@ -977,6 +977,27 @@ fn build_field_di_node<'ll, 'tcx>(
     }
 }
 
+/// Returns the `DIFlags` corresponding to the visibility of the item identified by `did`.
+///
+/// `DIFlags::Flag{Public,Protected,Private}` correspond to `DW_AT_accessibility`
+/// (public/protected/private) aren't exactly right for Rust, but neither is `DW_AT_visibility`
+/// (local/exported/qualified), and there's no way to set `DW_AT_visibility` in LLVM's API.
+fn visibility_di_flags<'ll, 'tcx>(
+    cx: &CodegenCx<'ll, 'tcx>,
+    did: DefId,
+    type_did: DefId,
+) -> DIFlags {
+    let parent_did = cx.tcx.parent(type_did);
+    let visibility = cx.tcx.visibility(did);
+    match visibility {
+        Visibility::Public => DIFlags::FlagPublic,
+        // Private fields have a restricted visibility of the module containing the type.
+        Visibility::Restricted(did) if did == parent_did => DIFlags::FlagPrivate,
+        // `pub(crate)`/`pub(super)` visibilities are any other restricted visibility.
+        Visibility::Restricted(..) => DIFlags::FlagProtected,
+    }
+}
+
 /// Creates the debuginfo node for a Rust struct type. Maybe be a regular struct or a tuple-struct.
 fn build_struct_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
@@ -1000,7 +1021,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
             &compute_debuginfo_type_name(cx.tcx, struct_type, false),
             size_and_align_of(struct_type_and_layout),
             Some(containing_scope),
-            DIFlags::FlagZero,
+            visibility_di_flags(cx, adt_def.did(), adt_def.did()),
         ),
         // Fields:
         |cx, owner| {
@@ -1023,7 +1044,7 @@ fn build_struct_type_di_node<'ll, 'tcx>(
                         &field_name[..],
                         (field_layout.size, field_layout.align.abi),
                         struct_type_and_layout.fields.offset(i),
-                        DIFlags::FlagZero,
+                        visibility_di_flags(cx, f.did, adt_def.did()),
                         type_di_node(cx, field_layout.ty),
                     )
                 })
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
index 7ef185250a3..4a2861af44c 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
@@ -26,8 +26,8 @@ use crate::{
             enums::{tag_base_type, DiscrResult},
             file_metadata, size_and_align_of, type_di_node,
             type_map::{self, Stub, UniqueTypeId},
-            unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS, NO_SCOPE_METADATA,
-            UNKNOWN_LINE_NUMBER,
+            unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec,
+            NO_GENERICS, NO_SCOPE_METADATA, UNKNOWN_LINE_NUMBER,
         },
         utils::DIB,
     },
@@ -215,7 +215,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
             &enum_type_name,
             cx.size_and_align_of(enum_type),
             NO_SCOPE_METADATA,
-            DIFlags::FlagZero,
+            visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did()),
         ),
         |cx, enum_type_di_node| {
             match enum_type_and_layout.variants {
@@ -320,6 +320,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
     variant_index: VariantIdx,
 ) -> SmallVec<&'ll DIType> {
     let variant_layout = enum_type_and_layout.for_variant(cx, variant_index);
+    let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
     let variant_struct_type_di_node = super::build_enum_variant_struct_type_di_node(
         cx,
         enum_type_and_layout,
@@ -327,6 +328,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
         variant_index,
         enum_adt_def.variant(variant_index),
         variant_layout,
+        visibility_flags,
     );
 
     let tag_base_type = cx.tcx.types.u32;
@@ -364,7 +366,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
             //       since the later is sometimes smaller (if it has fewer fields).
             size_and_align_of(enum_type_and_layout),
             Size::ZERO,
-            DIFlags::FlagZero,
+            visibility_flags,
             variant_struct_type_wrapper_di_node,
         ),
         unsafe {
@@ -376,7 +378,7 @@ fn build_single_variant_union_fields<'ll, 'tcx>(
                 unknown_file_metadata(cx),
                 UNKNOWN_LINE_NUMBER,
                 variant_names_type_di_node,
-                DIFlags::FlagZero,
+                visibility_flags,
                 Some(cx.const_u64(SINGLE_VARIANT_VIRTUAL_DISR)),
                 tag_base_type_align.bits() as u32,
             )
@@ -403,6 +405,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
             (variant_index, variant_name)
         }),
     );
+    let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
 
     let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_indices
         .map(|variant_index| {
@@ -417,6 +420,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
                 variant_index,
                 variant_def,
                 variant_layout,
+                visibility_flags,
             );
 
             VariantFieldInfo {
@@ -437,6 +441,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
         tag_base_type,
         tag_field,
         untagged_variant_index,
+        visibility_flags,
     )
 }
 
@@ -744,6 +749,7 @@ fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
         tag_base_type,
         tag_field,
         None,
+        DIFlags::FlagZero,
     )
 }
 
@@ -758,6 +764,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
     tag_base_type: Ty<'tcx>,
     tag_field: usize,
     untagged_variant_index: Option<VariantIdx>,
+    di_flags: DIFlags,
 ) -> SmallVec<&'ll DIType> {
     let tag_base_type_di_node = type_di_node(cx, tag_base_type);
     let mut unions_fields = SmallVec::with_capacity(variant_field_infos.len() + 1);
@@ -801,7 +808,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
                 align.bits() as u32,
                 // Union fields are always at offset zero
                 Size::ZERO.bits(),
-                DIFlags::FlagZero,
+                di_flags,
                 variant_struct_type_wrapper,
             )
         }
@@ -835,7 +842,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
             TAG_FIELD_NAME_128_LO,
             size_and_align,
             lo_offset,
-            DIFlags::FlagZero,
+            di_flags,
             type_di_node,
         ));
 
@@ -855,7 +862,7 @@ fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
             TAG_FIELD_NAME,
             cx.size_and_align_of(enum_type_and_layout.field(cx, tag_field).ty),
             enum_type_and_layout.fields.offset(tag_field),
-            DIFlags::FlagZero,
+            di_flags,
             tag_base_type_di_node,
         ));
     }
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
index df1df6d197e..eef8dbb33b4 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/mod.rs
@@ -250,6 +250,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
     variant_index: VariantIdx,
     variant_def: &VariantDef,
     variant_layout: TyAndLayout<'tcx>,
+    di_flags: DIFlags,
 ) -> &'ll DIType {
     debug_assert_eq!(variant_layout.ty, enum_type_and_layout.ty);
 
@@ -267,7 +268,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
             // NOTE: We use size and align of enum_type, not from variant_layout:
             size_and_align_of(enum_type_and_layout),
             Some(enum_type_di_node),
-            DIFlags::FlagZero,
+            di_flags,
         ),
         |cx, struct_type_di_node| {
             (0..variant_layout.fields.count())
@@ -289,7 +290,7 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
                         &field_name,
                         (field_layout.size, field_layout.align.abi),
                         variant_layout.fields.offset(field_index),
-                        DIFlags::FlagZero,
+                        di_flags,
                         type_di_node(cx, field_layout.ty),
                     )
                 })
@@ -395,7 +396,7 @@ pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
                 })
                 .collect();
 
-            state_specific_fields.into_iter().chain(common_fields.into_iter()).collect()
+            state_specific_fields.into_iter().chain(common_fields).collect()
         },
         |cx| build_generic_type_param_di_nodes(cx, coroutine_type_and_layout.ty),
     )
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
index 130ca2727e4..cba4e3811d5 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
@@ -7,8 +7,8 @@ use crate::{
             enums::tag_base_type,
             file_metadata, size_and_align_of, type_di_node,
             type_map::{self, Stub, StubInfo, UniqueTypeId},
-            unknown_file_metadata, DINodeCreationResult, SmallVec, NO_GENERICS,
-            UNKNOWN_LINE_NUMBER,
+            unknown_file_metadata, visibility_di_flags, DINodeCreationResult, SmallVec,
+            NO_GENERICS, UNKNOWN_LINE_NUMBER,
         },
         utils::{create_DIArray, get_namespace_for_item, DIB},
     },
@@ -63,6 +63,8 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
     let enum_type_and_layout = cx.layout_of(enum_type);
     let enum_type_name = compute_debuginfo_type_name(cx.tcx, enum_type, false);
 
+    let visibility_flags = visibility_di_flags(cx, enum_adt_def.did(), enum_adt_def.did());
+
     debug_assert!(!wants_c_like_enum_debuginfo(enum_type_and_layout));
 
     type_map::build_type_with_children(
@@ -74,7 +76,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
             &enum_type_name,
             size_and_align_of(enum_type_and_layout),
             Some(containing_scope),
-            DIFlags::FlagZero,
+            visibility_flags,
         ),
         |cx, enum_type_di_node| {
             // Build the struct type for each variant. These will be referenced by the
@@ -92,6 +94,7 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
                         variant_index,
                         enum_adt_def.variant(variant_index),
                         enum_type_and_layout.for_variant(cx, variant_index),
+                        visibility_flags,
                     ),
                     source_info: None,
                 })
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 40a985cf255..015ea10d721 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -578,7 +578,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                     hir_id,
                     no_sanitize_span,
                     "`no_sanitize` will have no effect after inlining",
-                    |lint| lint.span_note(inline_span, "inlining requested here"),
+                    |lint| {
+                        lint.span_note(inline_span, "inlining requested here");
+                    },
                 )
             }
         }
diff --git a/compiler/rustc_data_structures/src/sorted_map.rs b/compiler/rustc_data_structures/src/sorted_map.rs
index 60b343afbed..ed2e558bffa 100644
--- a/compiler/rustc_data_structures/src/sorted_map.rs
+++ b/compiler/rustc_data_structures/src/sorted_map.rs
@@ -198,7 +198,7 @@ impl<K: Ord, V> SortedMap<K, V> {
                 if index == self.data.len() || elements.last().unwrap().0 < self.data[index].0 {
                     // We can copy the whole range without having to mix with
                     // existing elements.
-                    self.data.splice(index..index, elements.into_iter());
+                    self.data.splice(index..index, elements);
                     return;
                 }
 
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 4fb63d67e78..403e0ec7950 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -91,10 +91,7 @@ where
 #[rustc_diagnostic_item = "DecorateLint"]
 pub trait DecorateLint<'a, G: EmissionGuarantee> {
     /// Decorate and emit a lint.
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut DiagnosticBuilder<'a, G>,
-    ) -> &'b mut DiagnosticBuilder<'a, G>;
+    fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, G>);
 
     fn msg(&self) -> DiagnosticMessage;
 }
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 379883a0c18..ec37240e394 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -2677,10 +2677,7 @@ fn from_stderr(color: ColorConfig) -> Destination {
 /// On Windows, BRIGHT_BLUE is hard to read on black. Use cyan instead.
 ///
 /// See #36178.
-#[cfg(windows)]
-const BRIGHT_BLUE: Color = Color::Cyan;
-#[cfg(not(windows))]
-const BRIGHT_BLUE: Color = Color::Blue;
+const BRIGHT_BLUE: Color = if cfg!(windows) { Color::Cyan } else { Color::Blue };
 
 impl Style {
     fn color_spec(&self, lvl: Level) -> ColorSpec {
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index d2c26668ea8..4f439c15fbb 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -426,6 +426,10 @@ impl server::Types for Rustc<'_, '_> {
 }
 
 impl server::FreeFunctions for Rustc<'_, '_> {
+    fn injected_env_var(&mut self, var: &str) -> Option<String> {
+        self.ecx.sess.opts.logical_env.get(var).cloned()
+    }
+
     fn track_env_var(&mut self, var: &str, value: Option<&str>) {
         self.sess()
             .env_depinfo
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 5c252c3f9f2..760945554f0 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -435,8 +435,6 @@ pub enum TraitBoundModifier {
 #[derive(Clone, Copy, Debug, HashStable_Generic)]
 pub enum GenericBound<'hir> {
     Trait(PolyTraitRef<'hir>, TraitBoundModifier),
-    // FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
-    LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
     Outlives(&'hir Lifetime),
 }
 
@@ -451,7 +449,6 @@ impl GenericBound<'_> {
     pub fn span(&self) -> Span {
         match self {
             GenericBound::Trait(t, ..) => t.span,
-            GenericBound::LangItemTrait(_, span, ..) => *span,
             GenericBound::Outlives(l) => l.ident.span,
         }
     }
@@ -1560,7 +1557,7 @@ impl Expr<'_> {
             ExprKind::Call(..) => ExprPrecedence::Call,
             ExprKind::MethodCall(..) => ExprPrecedence::MethodCall,
             ExprKind::Tup(_) => ExprPrecedence::Tup,
-            ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node.into()),
+            ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
             ExprKind::Unary(..) => ExprPrecedence::Unary,
             ExprKind::Lit(_) => ExprPrecedence::Lit,
             ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
@@ -1700,11 +1697,9 @@ impl Expr<'_> {
                 // them being used only for its side-effects.
                 base.can_have_side_effects()
             }
-            ExprKind::Struct(_, fields, init) => fields
-                .iter()
-                .map(|field| field.expr)
-                .chain(init.into_iter())
-                .any(|e| e.can_have_side_effects()),
+            ExprKind::Struct(_, fields, init) => {
+                fields.iter().map(|field| field.expr).chain(init).any(|e| e.can_have_side_effects())
+            }
 
             ExprKind::Array(args)
             | ExprKind::Tup(args)
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 9cf1db166a5..67e058a3219 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -1075,10 +1075,6 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB
         GenericBound::Trait(ref typ, _modifier) => {
             visitor.visit_poly_trait_ref(typ);
         }
-        GenericBound::LangItemTrait(_, _span, hir_id, args) => {
-            visitor.visit_id(hir_id);
-            visitor.visit_generic_args(args);
-        }
         GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
     }
 }
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 0d65ddb5642..8948a03e4a6 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -67,6 +67,42 @@ impl Display for Target {
 }
 
 impl Target {
+    pub fn is_associated_item(self) -> bool {
+        match self {
+            Target::AssocConst | Target::AssocTy | Target::Method(_) => true,
+            Target::ExternCrate
+            | Target::Use
+            | Target::Static
+            | Target::Const
+            | Target::Fn
+            | Target::Closure
+            | Target::Mod
+            | Target::ForeignMod
+            | Target::GlobalAsm
+            | Target::TyAlias
+            | Target::OpaqueTy
+            | Target::Enum
+            | Target::Variant
+            | Target::Struct
+            | Target::Field
+            | Target::Union
+            | Target::Trait
+            | Target::TraitAlias
+            | Target::Impl
+            | Target::Expression
+            | Target::Statement
+            | Target::Arm
+            | Target::ForeignFn
+            | Target::ForeignStatic
+            | Target::ForeignTy
+            | Target::GenericParam(_)
+            | Target::MacroDef
+            | Target::Param
+            | Target::PatField
+            | Target::ExprField => false,
+        }
+    }
+
     pub fn from_item(item: &Item<'_>) -> Target {
         match item.kind {
             ItemKind::ExternCrate(..) => Target::ExternCrate,
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index dfec3c5e829..0748644cc0a 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -134,17 +134,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
                         only_self_bounds,
                     );
                 }
-                &hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
-                    self.instantiate_lang_item_trait_ref(
-                        lang_item,
-                        span,
-                        hir_id,
-                        args,
-                        param_ty,
-                        bounds,
-                        only_self_bounds,
-                    );
-                }
                 hir::GenericBound::Outlives(lifetime) => {
                     let region = self.ast_region_to_region(lifetime, None);
                     bounds.push_region_bound(
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 47fbed45b91..be73c027fdc 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -661,7 +661,7 @@ pub(crate) fn prohibit_explicit_late_bound_lifetimes(
                 args.args[0].hir_id(),
                 multispan,
                 msg,
-                |lint| lint,
+                |_| {},
             );
         }
 
diff --git a/compiler/rustc_hir_analysis/src/astconv/lint.rs b/compiler/rustc_hir_analysis/src/astconv/lint.rs
index 43d4248ab74..9afb04b7470 100644
--- a/compiler/rustc_hir_analysis/src/astconv/lint.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/lint.rs
@@ -122,7 +122,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             Applicability::MachineApplicable,
                         );
                         self.maybe_lint_blanket_trait_impl(self_ty, lint);
-                        lint
                     },
                 );
             }
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 2ae9f87f296..6f8e80172dd 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -678,36 +678,57 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         )
     }
 
-    fn instantiate_poly_trait_ref_inner(
+    /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
+    /// a full trait reference. The resulting trait reference is returned. This may also generate
+    /// auxiliary bounds, which are added to `bounds`.
+    ///
+    /// Example:
+    ///
+    /// ```ignore (illustrative)
+    /// poly_trait_ref = Iterator<Item = u32>
+    /// self_ty = Foo
+    /// ```
+    ///
+    /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
+    ///
+    /// **A note on binders:** against our usual convention, there is an implied binder around
+    /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
+    /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
+    /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
+    /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
+    /// however.
+    #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
+    pub(crate) fn instantiate_poly_trait_ref(
         &self,
-        hir_id: hir::HirId,
+        trait_ref: &hir::TraitRef<'_>,
         span: Span,
-        binding_span: Option<Span>,
         constness: ty::BoundConstness,
         polarity: ty::ImplPolarity,
+        self_ty: Ty<'tcx>,
         bounds: &mut Bounds<'tcx>,
         speculative: bool,
-        trait_ref_span: Span,
-        trait_def_id: DefId,
-        trait_segment: &hir::PathSegment<'_>,
-        args: &GenericArgs<'_>,
-        infer_args: bool,
-        self_ty: Ty<'tcx>,
         only_self_bounds: OnlySelfBounds,
     ) -> GenericArgCountResult {
+        let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
+        let trait_segment = trait_ref.path.segments.last().unwrap();
+        let args = trait_segment.args();
+
+        self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
+        self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
+
         let (generic_args, arg_count) = self.create_args_for_ast_path(
-            trait_ref_span,
+            trait_ref.path.span,
             trait_def_id,
             &[],
             trait_segment,
             args,
-            infer_args,
+            trait_segment.infer_args,
             Some(self_ty),
             constness,
         );
 
         let tcx = self.tcx();
-        let bound_vars = tcx.late_bound_vars(hir_id);
+        let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
         debug!(?bound_vars);
 
         let assoc_bindings = self.create_assoc_bindings_for_generic_args(args);
@@ -735,13 +756,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
             // Specify type to assert that error was already reported in `Err` case.
             let _: Result<_, ErrorGuaranteed> = self.add_predicates_for_ast_type_binding(
-                hir_id,
+                trait_ref.hir_ref_id,
                 poly_trait_ref,
                 binding,
                 bounds,
                 speculative,
                 &mut dup_bindings,
-                binding_span.unwrap_or(binding.span),
+                binding.span,
                 constness,
                 only_self_bounds,
                 polarity,
@@ -752,102 +773,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         arg_count
     }
 
-    /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct
-    /// a full trait reference. The resulting trait reference is returned. This may also generate
-    /// auxiliary bounds, which are added to `bounds`.
-    ///
-    /// Example:
-    ///
-    /// ```ignore (illustrative)
-    /// poly_trait_ref = Iterator<Item = u32>
-    /// self_ty = Foo
-    /// ```
-    ///
-    /// this would return `Foo: Iterator` and add `<Foo as Iterator>::Item = u32` into `bounds`.
-    ///
-    /// **A note on binders:** against our usual convention, there is an implied bounder around
-    /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions.
-    /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>`
-    /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be
-    /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly,
-    /// however.
-    #[instrument(level = "debug", skip(self, span, constness, bounds, speculative))]
-    pub(crate) fn instantiate_poly_trait_ref(
-        &self,
-        trait_ref: &hir::TraitRef<'_>,
-        span: Span,
-        constness: ty::BoundConstness,
-        polarity: ty::ImplPolarity,
-        self_ty: Ty<'tcx>,
-        bounds: &mut Bounds<'tcx>,
-        speculative: bool,
-        only_self_bounds: OnlySelfBounds,
-    ) -> GenericArgCountResult {
-        let hir_id = trait_ref.hir_ref_id;
-        let binding_span = None;
-        let trait_ref_span = trait_ref.path.span;
-        let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise());
-        let trait_segment = trait_ref.path.segments.last().unwrap();
-        let args = trait_segment.args();
-        let infer_args = trait_segment.infer_args;
-
-        self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
-        self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
-
-        self.instantiate_poly_trait_ref_inner(
-            hir_id,
-            span,
-            binding_span,
-            constness,
-            polarity,
-            bounds,
-            speculative,
-            trait_ref_span,
-            trait_def_id,
-            trait_segment,
-            args,
-            infer_args,
-            self_ty,
-            only_self_bounds,
-        )
-    }
-
-    pub(crate) fn instantiate_lang_item_trait_ref(
-        &self,
-        lang_item: hir::LangItem,
-        span: Span,
-        hir_id: hir::HirId,
-        args: &GenericArgs<'_>,
-        self_ty: Ty<'tcx>,
-        bounds: &mut Bounds<'tcx>,
-        only_self_bounds: OnlySelfBounds,
-    ) {
-        let binding_span = Some(span);
-        let constness = ty::BoundConstness::NotConst;
-        let speculative = false;
-        let trait_ref_span = span;
-        let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
-        let trait_segment = &hir::PathSegment::invalid();
-        let infer_args = false;
-
-        self.instantiate_poly_trait_ref_inner(
-            hir_id,
-            span,
-            binding_span,
-            constness,
-            ty::ImplPolarity::Positive,
-            bounds,
-            speculative,
-            trait_ref_span,
-            trait_def_id,
-            trait_segment,
-            args,
-            infer_args,
-            self_ty,
-            only_self_bounds,
-        );
-    }
-
     fn ast_path_to_mono_trait_ref(
         &self,
         span: Span,
@@ -1509,8 +1434,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         format!("<{} as {}>::{}", qself_ty, tcx.item_name(trait_did), assoc_ident),
                         Applicability::MachineApplicable,
                     );
-
-                    lint
                 },
             );
         }
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index e6245e4d0b1..8413a1cc0db 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -51,7 +51,7 @@ pub fn check_abi(tcx: TyCtxt<'_>, hir_id: hir::HirId, span: Span, abi: Abi) {
                 hir_id,
                 span,
                 "use of calling convention not supported on this target",
-                |lint| lint,
+                |_| {},
             );
         }
     }
@@ -190,7 +190,7 @@ fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
             "static of uninhabited type",
             |lint| {
                 lint
-                .note("uninhabited statics cannot be initialized, and any access would be an immediate error")
+                .note("uninhabited statics cannot be initialized, and any access would be an immediate error");
             },
         );
     }
@@ -1093,7 +1093,7 @@ pub(super) fn check_transparent<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>)
                             "this {descr} contains `{field_ty}`, which {note}, \
                                 and makes it not a breaking change to become \
                                 non-zero-sized in the future."
-                        ))
+                        ));
                     },
                 )
             } else {
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 4705d9350b0..264868fdfc7 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -2,9 +2,7 @@ use super::potentially_plural_count;
 use crate::errors::LifetimesOrBoundsMismatchOnTrait;
 use hir::def_id::{DefId, LocalDefId};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
-use rustc_errors::{
-    pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed, MultiSpan,
-};
+use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit;
@@ -50,13 +48,7 @@ pub(super) fn compare_impl_method<'tcx>(
 
     let _: Result<_, ErrorGuaranteed> = try {
         check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, false)?;
-        compare_method_predicate_entailment(
-            tcx,
-            impl_m,
-            trait_m,
-            impl_trait_ref,
-            CheckImpliedWfMode::Check,
-        )?;
+        compare_method_predicate_entailment(tcx, impl_m, trait_m, impl_trait_ref)?;
         refine::check_refining_return_position_impl_trait_in_trait(
             tcx,
             impl_m,
@@ -170,7 +162,6 @@ fn compare_method_predicate_entailment<'tcx>(
     impl_m: ty::AssocItem,
     trait_m: ty::AssocItem,
     impl_trait_ref: ty::TraitRef<'tcx>,
-    check_implied_wf: CheckImpliedWfMode,
 ) -> Result<(), ErrorGuaranteed> {
     let trait_to_impl_args = impl_trait_ref.args;
 
@@ -317,7 +308,7 @@ fn compare_method_predicate_entailment<'tcx>(
         return Err(emitted);
     }
 
-    if check_implied_wf == CheckImpliedWfMode::Check && !(impl_sig, trait_sig).references_error() {
+    if !(impl_sig, trait_sig).references_error() {
         // Select obligations to make progress on inference before processing
         // the wf obligation below.
         // FIXME(-Znext-solver): Not needed when the hack below is removed.
@@ -333,8 +324,9 @@ fn compare_method_predicate_entailment<'tcx>(
         // trigger the lint. Instead, let's only consider type outlives and
         // region outlives obligations.
         //
-        // FIXME(-Znext-solver): Try removing this hack again once
-        // the new solver is stable.
+        // FIXME(-Znext-solver): Try removing this hack again once the new
+        // solver is stable. We should just be able to register a WF pred for
+        // the fn sig.
         let mut wf_args: smallvec::SmallVec<[_; 4]> =
             unnormalized_impl_sig.inputs_and_output.iter().map(|ty| ty.into()).collect();
         // Annoyingly, asking for the WF predicates of an array (with an unevaluated const (only?))
@@ -357,7 +349,7 @@ fn compare_method_predicate_entailment<'tcx>(
                     // We need to register Projection oblgiations too, because we may end up with
                     // an implied `X::Item: 'a`, which gets desugared into `X::Item = ?0`, `?0: 'a`.
                     // If we only register the region outlives obligation, this leads to an unconstrained var.
-                    // See `implied_bounds_entailment_alias_var` test.
+                    // See `implied_bounds_entailment_alias_var.rs` test.
                     ty::PredicateKind::Clause(
                         ty::ClauseKind::RegionOutlives(..)
                         | ty::ClauseKind::TypeOutlives(..)
@@ -378,26 +370,8 @@ fn compare_method_predicate_entailment<'tcx>(
     // version.
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
-        match check_implied_wf {
-            CheckImpliedWfMode::Check => {
-                let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
-                return compare_method_predicate_entailment(
-                    tcx,
-                    impl_m,
-                    trait_m,
-                    impl_trait_ref,
-                    CheckImpliedWfMode::Skip,
-                )
-                .map(|()| {
-                    // If the skip-mode was successful, emit a lint.
-                    emit_implied_wf_lint(infcx.tcx, impl_m, impl_m_hir_id, vec![]);
-                });
-            }
-            CheckImpliedWfMode::Skip => {
-                let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
-                return Err(reported);
-            }
-        }
+        let reported = infcx.err_ctxt().report_fulfillment_errors(errors);
+        return Err(reported);
     }
 
     // Finally, resolve all regions. This catches wily misuses of
@@ -408,119 +382,14 @@ fn compare_method_predicate_entailment<'tcx>(
     );
     let errors = infcx.resolve_regions(&outlives_env);
     if !errors.is_empty() {
-        // FIXME(compiler-errors): This can be simplified when IMPLIED_BOUNDS_ENTAILMENT
-        // becomes a hard error (i.e. ideally we'd just call `resolve_regions_and_report_errors`
-        let impl_m_hir_id = tcx.local_def_id_to_hir_id(impl_m_def_id);
-        match check_implied_wf {
-            CheckImpliedWfMode::Check => {
-                return compare_method_predicate_entailment(
-                    tcx,
-                    impl_m,
-                    trait_m,
-                    impl_trait_ref,
-                    CheckImpliedWfMode::Skip,
-                )
-                .map(|()| {
-                    let bad_args = extract_bad_args_for_implies_lint(
-                        tcx,
-                        &errors,
-                        (trait_m, trait_sig),
-                        // Unnormalized impl sig corresponds to the HIR types written
-                        (impl_m, unnormalized_impl_sig),
-                        impl_m_hir_id,
-                    );
-                    // If the skip-mode was successful, emit a lint.
-                    emit_implied_wf_lint(tcx, impl_m, impl_m_hir_id, bad_args);
-                });
-            }
-            CheckImpliedWfMode::Skip => {
-                if infcx.tainted_by_errors().is_none() {
-                    infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors);
-                }
-                return Err(tcx
-                    .sess
-                    .span_delayed_bug(rustc_span::DUMMY_SP, "error should have been emitted"));
-            }
-        }
+        return Err(infcx
+            .tainted_by_errors()
+            .unwrap_or_else(|| infcx.err_ctxt().report_region_errors(impl_m_def_id, &errors)));
     }
 
     Ok(())
 }
 
-fn extract_bad_args_for_implies_lint<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    errors: &[infer::RegionResolutionError<'tcx>],
-    (trait_m, trait_sig): (ty::AssocItem, ty::FnSig<'tcx>),
-    (impl_m, impl_sig): (ty::AssocItem, ty::FnSig<'tcx>),
-    hir_id: hir::HirId,
-) -> Vec<(Span, Option<String>)> {
-    let mut blame_generics = vec![];
-    for error in errors {
-        // Look for the subregion origin that contains an input/output type
-        let origin = match error {
-            infer::RegionResolutionError::ConcreteFailure(o, ..) => o,
-            infer::RegionResolutionError::GenericBoundFailure(o, ..) => o,
-            infer::RegionResolutionError::SubSupConflict(_, _, o, ..) => o,
-            infer::RegionResolutionError::UpperBoundUniverseConflict(.., o, _) => o,
-        };
-        // Extract (possible) input/output types from origin
-        match origin {
-            infer::SubregionOrigin::Subtype(trace) => {
-                if let Some((a, b)) = trace.values.ty() {
-                    blame_generics.extend([a, b]);
-                }
-            }
-            infer::SubregionOrigin::RelateParamBound(_, ty, _) => blame_generics.push(*ty),
-            infer::SubregionOrigin::ReferenceOutlivesReferent(ty, _) => blame_generics.push(*ty),
-            _ => {}
-        }
-    }
-
-    let fn_decl = tcx.hir().fn_decl_by_hir_id(hir_id).unwrap();
-    let opt_ret_ty = match fn_decl.output {
-        hir::FnRetTy::DefaultReturn(_) => None,
-        hir::FnRetTy::Return(ty) => Some(ty),
-    };
-
-    // Map late-bound regions from trait to impl, so the names are right.
-    let mapping = std::iter::zip(
-        tcx.fn_sig(trait_m.def_id).skip_binder().bound_vars(),
-        tcx.fn_sig(impl_m.def_id).skip_binder().bound_vars(),
-    )
-    .filter_map(|(impl_bv, trait_bv)| {
-        if let ty::BoundVariableKind::Region(impl_bv) = impl_bv
-            && let ty::BoundVariableKind::Region(trait_bv) = trait_bv
-        {
-            Some((impl_bv, trait_bv))
-        } else {
-            None
-        }
-    })
-    .collect();
-
-    // For each arg, see if it was in the "blame" of any of the region errors.
-    // If so, then try to produce a suggestion to replace the argument type with
-    // one from the trait.
-    let mut bad_args = vec![];
-    for (idx, (ty, hir_ty)) in
-        std::iter::zip(impl_sig.inputs_and_output, fn_decl.inputs.iter().chain(opt_ret_ty))
-            .enumerate()
-    {
-        let expected_ty = trait_sig.inputs_and_output[idx]
-            .fold_with(&mut RemapLateBound { tcx, mapping: &mapping });
-        if blame_generics.iter().any(|blame| ty.contains(*blame)) {
-            let expected_ty_sugg = expected_ty.to_string();
-            bad_args.push((
-                hir_ty.span,
-                // Only suggest something if it actually changed.
-                (expected_ty_sugg != ty.to_string()).then_some(expected_ty_sugg),
-            ));
-        }
-    }
-
-    bad_args
-}
-
 struct RemapLateBound<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     mapping: &'a FxHashMap<ty::BoundRegionKind, ty::BoundRegionKind>,
@@ -544,53 +413,6 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
     }
 }
 
-fn emit_implied_wf_lint<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    impl_m: ty::AssocItem,
-    hir_id: hir::HirId,
-    bad_args: Vec<(Span, Option<String>)>,
-) {
-    let span: MultiSpan = if bad_args.is_empty() {
-        tcx.def_span(impl_m.def_id).into()
-    } else {
-        bad_args.iter().map(|(span, _)| *span).collect::<Vec<_>>().into()
-    };
-    tcx.struct_span_lint_hir(
-        rustc_session::lint::builtin::IMPLIED_BOUNDS_ENTAILMENT,
-        hir_id,
-        span,
-        "impl method assumes more implied bounds than the corresponding trait method",
-        |lint| {
-            let bad_args: Vec<_> =
-                bad_args.into_iter().filter_map(|(span, sugg)| Some((span, sugg?))).collect();
-            if !bad_args.is_empty() {
-                lint.multipart_suggestion(
-                    format!(
-                        "replace {} type{} to make the impl signature compatible",
-                        pluralize!("this", bad_args.len()),
-                        pluralize!(bad_args.len())
-                    ),
-                    bad_args,
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            lint
-        },
-    );
-}
-
-#[derive(Debug, PartialEq, Eq)]
-enum CheckImpliedWfMode {
-    /// Checks implied well-formedness of the impl method. If it fails, we will
-    /// re-check with `Skip`, and emit a lint if it succeeds.
-    Check,
-    /// Skips checking implied well-formedness of the impl method, but will emit
-    /// a lint if the `compare_method_predicate_entailment` succeeded. This means that
-    /// the reason that we had failed earlier during `Check` was due to the impl
-    /// having stronger requirements than the trait.
-    Skip,
-}
-
 fn compare_asyncness<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_m: ty::AssocItem,
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index 7c9624206e5..d86ebc2c9c3 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -276,7 +276,6 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                         lint.help(format!(
                             "or use `{{{idx}:{default_modifier}}}` to keep the default formatting of `{default_result}`",
                         ));
-                        lint
                     },
                 );
             }
diff --git a/compiler/rustc_hir_analysis/src/check_unused.rs b/compiler/rustc_hir_analysis/src/check_unused.rs
index 9ad73eeffc6..36cb8f7a202 100644
--- a/compiler/rustc_hir_analysis/src/check_unused.rs
+++ b/compiler/rustc_hir_analysis/src/check_unused.rs
@@ -45,7 +45,7 @@ fn check_unused_traits(tcx: TyCtxt<'_>, (): ()) {
             item.hir_id(),
             path.span,
             msg,
-            |lint| lint,
+            |_| {},
         );
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index 45100457629..88128d22a3d 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -522,7 +522,7 @@ fn lint_auto_trait_impl<'tcx>(
                 format!(
                     "try using the same sequence of generic parameters as the {self_descr} definition",
                 ),
-            )
+            );
         },
     );
 }
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index c1c2bb62c66..3ee2822edd8 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -279,7 +279,7 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                             param.hir_id,
                             param.span,
                             TYPE_DEFAULT_NOT_ALLOWED,
-                            |lint| lint,
+                            |_| {},
                         );
                     }
                     Defaults::Deny => {
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 5769fc5fe64..9f0742dade8 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -350,7 +350,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                     // Nested poly trait refs have the binders concatenated
                     let mut full_binders =
                         self.map.late_bound_vars.entry(*hir_id).or_default().clone();
-                    full_binders.extend(supertrait_bound_vars.into_iter());
+                    full_binders.extend(supertrait_bound_vars);
                     break (full_binders, BinderScopeType::Concatenating);
                 }
             }
@@ -925,7 +925,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                                     "you can use the `'static` lifetime directly, in place of `{}`",
                                     lifetime.ident,
                                 );
-                                lint.help(help)
+                                lint.help(help);
                             },
                         );
                     }
@@ -938,32 +938,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
         }
     }
 
-    fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) {
-        match bound {
-            hir::GenericBound::LangItemTrait(_, _, hir_id, _) => {
-                // FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
-                // through the regular poly trait ref code, so we don't get another
-                // chance to introduce a binder. For now, I'm keeping the existing logic
-                // of "if there isn't a Binder scope above us, add one", but I
-                // imagine there's a better way to go about this.
-                let (binders, scope_type) = self.poly_trait_ref_binder_info();
-
-                self.record_late_bound_vars(*hir_id, binders);
-                let scope = Scope::Binder {
-                    hir_id: *hir_id,
-                    bound_vars: FxIndexMap::default(),
-                    s: self.scope,
-                    scope_type,
-                    where_bound_origin: None,
-                };
-                self.with(scope, |this| {
-                    intravisit::walk_param_bound(this, bound);
-                });
-            }
-            _ => intravisit::walk_param_bound(self, bound),
-        }
-    }
-
     fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
         self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow);
     }
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 82e687135eb..21a50b94a37 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -2084,11 +2084,6 @@ impl<'a> State<'a> {
                     }
                     self.print_poly_trait_ref(tref);
                 }
-                GenericBound::LangItemTrait(lang_item, span, ..) => {
-                    self.word("#[lang = \"");
-                    self.print_ident(Ident::new(lang_item.name(), *span));
-                    self.word("\"]");
-                }
                 GenericBound::Outlives(lt) => {
                     self.print_lifetime(lt);
                 }
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 74aec897f95..ff03cf16a27 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -573,13 +573,13 @@ impl rustc_errors::AddToDiagnostic for CastUnknownPointerSub {
     {
         match self {
             CastUnknownPointerSub::To(span) => {
-                let msg = f(diag, crate::fluent_generated::hir_typeck_label_to.into());
+                let msg = f(diag, crate::fluent_generated::hir_typeck_label_to);
                 diag.span_label(span, msg);
-                let msg = f(diag, crate::fluent_generated::hir_typeck_note.into());
+                let msg = f(diag, crate::fluent_generated::hir_typeck_note);
                 diag.note(msg);
             }
             CastUnknownPointerSub::From(span) => {
-                let msg = f(diag, crate::fluent_generated::hir_typeck_label_from.into());
+                let msg = f(diag, crate::fluent_generated::hir_typeck_label_from);
                 diag.span_label(span, msg);
             }
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 7744f75121e..3bee42eb89c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -72,7 +72,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             orig_span,
                             custom_note
                                 .unwrap_or("any code following this expression is unreachable"),
-                        )
+                        );
                     },
                 )
             }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 1650aaeb495..668e547571f 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -825,9 +825,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     && let hir::Node::Item(hir::Item {
                         kind: hir::ItemKind::OpaqueTy(op_ty), ..
                     }) = self.tcx.hir_node(item_id.hir_id())
-                    && let [
-                        hir::GenericBound::LangItemTrait(hir::LangItem::Future, _, _, generic_args),
-                    ] = op_ty.bounds
+                    && let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
+                    && let Some(hir::PathSegment { args: Some(generic_args), .. }) =
+                        trait_ref.trait_ref.path.segments.last()
                     && let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
                     && let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } =
                         ty_binding.kind
diff --git a/compiler/rustc_hir_typeck/src/method/prelude2021.rs b/compiler/rustc_hir_typeck/src/method/prelude2021.rs
index 3f1dca5b1de..43d258de6ca 100644
--- a/compiler/rustc_hir_typeck/src/method/prelude2021.rs
+++ b/compiler/rustc_hir_typeck/src/method/prelude2021.rs
@@ -122,8 +122,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             format!("disambiguate the method call with `({self_adjusted})`",),
                         );
                     }
-
-                    lint
                 },
             );
         } else {
@@ -187,8 +185,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             ),
                         );
                     }
-
-                    lint
                 },
             );
         }
@@ -307,8 +303,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
                     Applicability::MachineApplicable,
                 );
-
-                lint
             },
         );
     }
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 4243bce377f..fe2d43a3c92 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -445,7 +445,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         scope_expr_id,
                         span,
                         "type annotations needed",
-                        |lint| lint,
+                        |_| {},
                     );
                 }
             } else {
@@ -1427,8 +1427,6 @@ impl<'tcx> Pick<'tcx> {
                         ));
                     }
                 }
-
-                lint
             },
         );
     }
@@ -1548,9 +1546,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     );
 
                     let candidate_obligations = impl_obligations
-                        .chain(norm_obligations.into_iter())
+                        .chain(norm_obligations)
                         .chain(ref_obligations.iter().cloned())
-                        .chain(normalization_obligations.into_iter());
+                        .chain(normalization_obligations);
 
                     // Evaluate those obligations to see if they might possibly hold.
                     for o in candidate_obligations {
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index be21fd5f0a6..56a420fab4f 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -1849,8 +1849,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         lint.note(format!(
             "the pattern is of type `{ty}` and the `non_exhaustive_omitted_patterns` attribute was found",
         ));
-
-        lint
     });
     }
 
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 998ee339ae2..69d6fb8e2ea 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -912,8 +912,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             Applicability::HasPlaceholders
                         );
                     }
-
-                    lint
                 },
             );
         }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
index b762778122b..bbe07b8ed72 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/suggest.rs
@@ -668,26 +668,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     (
                         hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }),
                         hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }),
-                    ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| {
-                        match (left, right) {
-                            (
-                                hir::GenericBound::Trait(tl, ml),
-                                hir::GenericBound::Trait(tr, mr),
-                            ) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
+                    ) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match (
+                        left, right,
+                    ) {
+                        (hir::GenericBound::Trait(tl, ml), hir::GenericBound::Trait(tr, mr))
+                            if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
                                 && ml == mr =>
-                            {
-                                true
-                            }
-                            (
-                                hir::GenericBound::LangItemTrait(langl, _, _, argsl),
-                                hir::GenericBound::LangItemTrait(langr, _, _, argsr),
-                            ) if langl == langr => {
-                                // FIXME: consider the bounds!
-                                debug!("{:?} {:?}", argsl, argsr);
-                                true
-                            }
-                            _ => false,
+                        {
+                            true
                         }
+                        _ => false,
                     }) =>
                     {
                         StatementAsExpression::NeedsBoxing
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index e8a8808428c..3de269da22d 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -5,7 +5,7 @@ pub use self::BoundRegionConversionTime::*;
 pub use self::RegionVariableOrigin::*;
 pub use self::SubregionOrigin::*;
 pub use self::ValuePairs::*;
-pub use combine::ObligationEmittingRelation;
+pub use relate::combine::ObligationEmittingRelation;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::undo_log::UndoLogs;
 use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
@@ -43,7 +43,6 @@ use rustc_span::{Span, DUMMY_SP};
 use std::cell::{Cell, RefCell};
 use std::fmt;
 
-use self::combine::CombineFields;
 use self::error_reporting::TypeErrCtxt;
 use self::free_regions::RegionRelations;
 use self::lexical_region_resolve::LexicalRegionResolutions;
@@ -51,29 +50,23 @@ use self::region_constraints::{GenericKind, VarInfos, VerifyBound};
 use self::region_constraints::{
     RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot,
 };
+pub use self::relate::combine::CombineFields;
+pub use self::relate::nll as nll_relate;
 use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 
 pub mod at;
 pub mod canonical;
-mod combine;
-mod equate;
 pub mod error_reporting;
 pub mod free_regions;
 mod freshen;
 mod fudge;
-mod generalize;
-mod glb;
-mod higher_ranked;
-pub mod lattice;
 mod lexical_region_resolve;
-mod lub;
-pub mod nll_relate;
 pub mod opaque_types;
 pub mod outlives;
 mod projection;
 pub mod region_constraints;
+mod relate;
 pub mod resolve;
-mod sub;
 pub mod type_variable;
 mod undo_log;
 
diff --git a/compiler/rustc_infer/src/infer/outlives/verify.rs b/compiler/rustc_infer/src/infer/outlives/verify.rs
index ce619ae8a0d..bb578a482e4 100644
--- a/compiler/rustc_infer/src/infer/outlives/verify.rs
+++ b/compiler/rustc_infer/src/infer/outlives/verify.rs
@@ -130,12 +130,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         // see the extensive comment in projection_must_outlive
         let recursive_bound = {
             let mut components = smallvec![];
-            compute_alias_components_recursive(
-                self.tcx,
-                alias_ty_as_ty.into(),
-                &mut components,
-                visited,
-            );
+            compute_alias_components_recursive(self.tcx, alias_ty_as_ty, &mut components, visited);
             self.bound_from_components(&components, visited)
         };
 
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index fe58fc7122c..dfaca3458d6 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -3,7 +3,7 @@
 //! combining two instances of various things and yielding a new instance.
 //! These combiner methods always yield a `Result<T>`. To relate two
 //! types, you can use `infcx.at(cause, param_env)` which then allows
-//! you to use the relevant methods of [At](super::at::At).
+//! you to use the relevant methods of [At](crate::infer::at::At).
 //!
 //! Combiners mostly do their specific behavior and then hand off the
 //! bulk of the work to [InferCtxt::super_combine_tys] and
@@ -23,11 +23,11 @@
 //! this should be correctly updated.
 
 use super::equate::Equate;
+use super::generalize::{self, CombineDelegate, Generalization};
 use super::glb::Glb;
 use super::lub::Lub;
 use super::sub::Sub;
-use super::{DefineOpaqueTypes, InferCtxt, TypeTrace};
-use crate::infer::generalize::{self, CombineDelegate, Generalization};
+use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
 use crate::traits::{Obligation, PredicateObligations};
 use rustc_middle::infer::canonical::OriginalQueryValues;
 use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVarValue};
@@ -552,7 +552,7 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
     }
 
     pub fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>) {
-        self.obligations.extend(obligations.into_iter());
+        self.obligations.extend(obligations);
     }
 
     pub fn register_predicates(&mut self, obligations: impl IntoIterator<Item: ToPredicate<'tcx>>) {
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/relate/equate.rs
index 5d929394eb0..9943c638a91 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/relate/equate.rs
@@ -1,8 +1,6 @@
-use crate::infer::DefineOpaqueTypes;
-use crate::traits::PredicateObligations;
-
 use super::combine::{CombineFields, ObligationEmittingRelation};
-use super::Subtype;
+use crate::infer::{DefineOpaqueTypes, SubregionOrigin};
+use crate::traits::PredicateObligations;
 
 use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::GenericArgsRef;
@@ -133,7 +131,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
         b: ty::Region<'tcx>,
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
-        let origin = Subtype(Box::new(self.fields.trace.clone()));
+        let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
         self.fields
             .infcx
             .inner
diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 383f3bdbe23..66f7b08ee12 100644
--- a/compiler/rustc_infer/src/infer/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -16,7 +16,7 @@ use crate::infer::{InferCtxt, RegionVariableOrigin};
 /// Attempts to generalize `term` for the type variable `for_vid`.
 /// This checks for cycles -- that is, whether the type `term`
 /// references `for_vid`.
-pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
+pub fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>> + Relate<'tcx>>(
     infcx: &InferCtxt<'tcx>,
     delegate: &mut D,
     term: T,
@@ -54,7 +54,7 @@ pub(super) fn generalize<'tcx, D: GeneralizerDelegate<'tcx>, T: Into<Term<'tcx>>
 
 /// Abstracts the handling of region vars between HIR and MIR/NLL typechecking
 /// in the generalizer code.
-pub(super) trait GeneralizerDelegate<'tcx> {
+pub trait GeneralizerDelegate<'tcx> {
     fn param_env(&self) -> ty::ParamEnv<'tcx>;
 
     fn forbid_inference_vars() -> bool;
@@ -64,7 +64,7 @@ pub(super) trait GeneralizerDelegate<'tcx> {
     fn generalize_region(&mut self, universe: ty::UniverseIndex) -> ty::Region<'tcx>;
 }
 
-pub(super) struct CombineDelegate<'cx, 'tcx> {
+pub struct CombineDelegate<'cx, 'tcx> {
     pub infcx: &'cx InferCtxt<'tcx>,
     pub param_env: ty::ParamEnv<'tcx>,
     pub span: Span,
@@ -515,7 +515,7 @@ where
 /// not only the generalized type, but also a bool flag
 /// indicating whether further WF checks are needed.
 #[derive(Debug)]
-pub(super) struct Generalization<T> {
+pub struct Generalization<T> {
     /// When generalizing `<?0 as Trait>::Assoc` or
     /// `<T as Bar<<?0 as Foo>::Assoc>>::Assoc`
     /// for `?0` generalization returns an inference
@@ -524,7 +524,7 @@ pub(super) struct Generalization<T> {
     /// This has to be handled wotj care as it can
     /// otherwise very easily result in infinite
     /// recursion.
-    pub(super) value_may_be_infer: T,
+    pub value_may_be_infer: T,
 
     /// If true, then the generalized type may not be well-formed,
     /// even if the source type is well-formed, so we should add an
@@ -551,5 +551,5 @@ pub(super) struct Generalization<T> {
     /// will force the calling code to check that `WF(Foo<?C, ?D>)`
     /// holds, which in turn implies that `?C::Item == ?D`. So once
     /// `?C` is constrained, that should suffice to restrict `?D`.
-    pub(super) needs_wf: bool,
+    pub needs_wf: bool,
 }
diff --git a/compiler/rustc_infer/src/infer/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs
index 2f659d9a665..6a3413879c4 100644
--- a/compiler/rustc_infer/src/infer/glb.rs
+++ b/compiler/rustc_infer/src/infer/relate/glb.rs
@@ -1,13 +1,12 @@
 //! Greatest lower bound. See [`lattice`].
 
+use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+
 use super::combine::{CombineFields, ObligationEmittingRelation};
 use super::lattice::{self, LatticeDir};
-use super::Subtype;
-use super::{DefineOpaqueTypes, InferCtxt};
-
+use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
 use crate::traits::{ObligationCause, PredicateObligations};
-use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 
 /// "Greatest lower bound" (common subtype)
 pub struct Glb<'combine, 'infcx, 'tcx> {
@@ -68,7 +67,7 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
 
-        let origin = Subtype(Box::new(self.fields.trace.clone()));
+        let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
         // GLB(&'static u8, &'a u8) == &RegionLUB('static, 'a) u8 == &'static u8
         Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().lub_regions(
             self.tcx(),
diff --git a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
index 510b1797d3c..440df8c8936 100644
--- a/compiler/rustc_infer/src/infer/higher_ranked/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/higher_ranked.rs
@@ -2,8 +2,8 @@
 //! the end of the file for details.
 
 use super::combine::CombineFields;
-use super::{HigherRankedType, InferCtxt};
 use crate::infer::CombinedSnapshot;
+use crate::infer::{HigherRankedType, InferCtxt};
 use rustc_middle::ty::fold::FnMutDelegate;
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable};
diff --git a/compiler/rustc_infer/src/infer/lattice.rs b/compiler/rustc_infer/src/infer/relate/lattice.rs
index 9ef35429fe3..744e2dfa380 100644
--- a/compiler/rustc_infer/src/infer/lattice.rs
+++ b/compiler/rustc_infer/src/infer/relate/lattice.rs
@@ -18,10 +18,10 @@
 //! [lattices]: https://en.wikipedia.org/wiki/Lattice_(order)
 
 use super::combine::ObligationEmittingRelation;
-use super::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use super::{DefineOpaqueTypes, InferCtxt};
-
+use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use crate::infer::{DefineOpaqueTypes, InferCtxt};
 use crate::traits::ObligationCause;
+
 use rustc_middle::ty::relate::RelateResult;
 use rustc_middle::ty::TyVar;
 use rustc_middle::ty::{self, Ty};
diff --git a/compiler/rustc_infer/src/infer/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs
index e41ec7e6c01..41cd98ed0cf 100644
--- a/compiler/rustc_infer/src/infer/lub.rs
+++ b/compiler/rustc_infer/src/infer/relate/lub.rs
@@ -2,10 +2,9 @@
 
 use super::combine::{CombineFields, ObligationEmittingRelation};
 use super::lattice::{self, LatticeDir};
-use super::Subtype;
-use super::{DefineOpaqueTypes, InferCtxt};
-
+use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
 use crate::traits::{ObligationCause, PredicateObligations};
+
 use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
 
@@ -68,7 +67,7 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
     ) -> RelateResult<'tcx, ty::Region<'tcx>> {
         debug!("{}.regions({:?}, {:?})", self.tag(), a, b);
 
-        let origin = Subtype(Box::new(self.fields.trace.clone()));
+        let origin = SubregionOrigin::Subtype(Box::new(self.fields.trace.clone()));
         // LUB(&'static u8, &'a u8) == &RegionGLB('static, 'a) u8 == &'a u8
         Ok(self.fields.infcx.inner.borrow_mut().unwrap_region_constraints().glb_regions(
             self.tcx(),
diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs
new file mode 100644
index 00000000000..f688c2b74a6
--- /dev/null
+++ b/compiler/rustc_infer/src/infer/relate/mod.rs
@@ -0,0 +1,12 @@
+//! This module contains the definitions of most `TypeRelation`s in the type system
+//! (except for some relations used for diagnostics and heuristics in the compiler).
+
+pub(super) mod combine;
+mod equate;
+pub(super) mod generalize;
+mod glb;
+mod higher_ranked;
+mod lattice;
+mod lub;
+pub mod nll;
+mod sub;
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/relate/nll.rs
index ab3c976a351..afc2a8b2f62 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/nll.rs
@@ -30,8 +30,8 @@ use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
 use rustc_span::{Span, Symbol};
 use std::fmt::Debug;
 
-use crate::infer::combine::ObligationEmittingRelation;
-use crate::infer::generalize::{self, Generalization};
+use super::combine::ObligationEmittingRelation;
+use super::generalize::{self, Generalization};
 use crate::infer::InferCtxt;
 use crate::infer::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::traits::{Obligation, PredicateObligations};
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/relate/sub.rs
index 0c3bb633b53..5a623e48c93 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/relate/sub.rs
@@ -1,7 +1,7 @@
 use super::combine::CombineFields;
-use super::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin};
-
+use crate::infer::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin};
 use crate::traits::{Obligation, PredicateObligations};
+
 use rustc_middle::ty::relate::{Cause, Relate, RelateResult, TypeRelation};
 use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::TyVar;
diff --git a/compiler/rustc_lexer/src/unescape.rs b/compiler/rustc_lexer/src/unescape.rs
index 249126a269e..abec12f52a6 100644
--- a/compiler/rustc_lexer/src/unescape.rs
+++ b/compiler/rustc_lexer/src/unescape.rs
@@ -92,8 +92,8 @@ where
             let res = unescape_char_or_byte(&mut chars, mode);
             callback(0..(src.len() - chars.as_str().len()), res);
         }
-        Str | ByteStr => unescape_str_common(src, mode, callback),
-        RawStr | RawByteStr => unescape_raw_str_or_raw_byte_str(src, mode, callback),
+        Str | ByteStr => unescape_non_raw_common(src, mode, callback),
+        RawStr | RawByteStr => check_raw_common(src, mode, callback),
         CStr | RawCStr => unreachable!(),
     }
 }
@@ -122,12 +122,10 @@ where
 {
     match mode {
         CStr => {
-            unescape_str_common(src, mode, callback);
+            unescape_non_raw_common(src, mode, callback);
         }
         RawCStr => {
-            unescape_raw_str_or_raw_byte_str(src, mode, &mut |r, result| {
-                callback(r, result.map(CStrUnit::Char))
-            });
+            check_raw_common(src, mode, &mut |r, result| callback(r, result.map(CStrUnit::Char)));
         }
         Char | Byte | Str | RawStr | ByteStr | RawByteStr => unreachable!(),
     }
@@ -191,8 +189,9 @@ impl Mode {
     /// Byte literals do not allow unicode escape.
     fn is_unicode_escape_disallowed(self) -> bool {
         match self {
-            Byte | ByteStr | RawByteStr => true,
-            Char | Str | RawStr | CStr | RawCStr => false,
+            Byte | ByteStr => true,
+            Char | Str | CStr => false,
+            RawByteStr | RawStr | RawCStr => unreachable!(),
         }
     }
 
@@ -324,7 +323,7 @@ fn unescape_char_or_byte(chars: &mut Chars<'_>, mode: Mode) -> Result<char, Esca
 
 /// Takes a contents of a string literal (without quotes) and produces a
 /// sequence of escaped characters or errors.
-fn unescape_str_common<F, T: From<u8> + From<char>>(src: &str, mode: Mode, callback: &mut F)
+fn unescape_non_raw_common<F, T: From<u8> + From<char>>(src: &str, mode: Mode, callback: &mut F)
 where
     F: FnMut(Range<usize>, Result<T, EscapeError>),
 {
@@ -391,7 +390,7 @@ where
 /// sequence of characters or errors.
 /// NOTE: Raw strings do not perform any explicit character escaping, here we
 /// only produce errors on bare CR.
-fn unescape_raw_str_or_raw_byte_str<F>(src: &str, mode: Mode, callback: &mut F)
+fn check_raw_common<F>(src: &str, mode: Mode, callback: &mut F)
 where
     F: FnMut(Range<usize>, Result<char, EscapeError>),
 {
@@ -399,7 +398,7 @@ where
     let chars_should_be_ascii = mode.chars_should_be_ascii(); // get this outside the loop
 
     // The `start` and `end` computation here matches the one in
-    // `unescape_str_common` for consistency, even though this function
+    // `unescape_non_raw_common` for consistency, even though this function
     // doesn't have to worry about skipping any chars.
     while let Some(c) = chars.next() {
         let start = src.len() - chars.as_str().len() - c.len_utf8();
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 32eb67ba3a1..045ff38c056 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -2800,7 +2800,7 @@ impl<'tcx> LateLintPass<'tcx> for NamedAsmLabels {
                             NAMED_ASM_LABELS,
                             Some(target_spans),
                             fluent::lint_builtin_asm_labels,
-                            |lint| lint,
+                            |_| {},
                             BuiltinLintDiagnostics::NamedAsmLabel(
                                 "only local labels of the form `<number>:` should be used in inline asm"
                                     .to_string(),
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 0911fa70f97..c7a9d5e80ac 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -520,9 +520,6 @@ pub trait LintContext {
     /// Emit a lint at the appropriate level, with an optional associated span and an existing
     /// diagnostic.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed
-    /// explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     fn lookup_with_diagnostics(
@@ -530,9 +527,7 @@ pub trait LintContext {
         lint: &'static Lint,
         span: Option<impl Into<MultiSpan>>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
         diagnostic: BuiltinLintDiagnostics,
     ) {
         // We first generate a blank diagnostic.
@@ -986,8 +981,6 @@ pub trait LintContext {
     // set the span in their `decorate` function (preferably using set_span).
     /// Emit a lint at the appropriate level, with an optional associated span.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     fn lookup<S: Into<MultiSpan>>(
@@ -995,9 +988,7 @@ pub trait LintContext {
         lint: &'static Lint,
         span: Option<S>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     );
 
     /// Emit a lint at `span` from a lint struct (some type that implements `DecorateLint`,
@@ -1008,13 +999,13 @@ pub trait LintContext {
         span: S,
         decorator: impl for<'a> DecorateLint<'a, ()>,
     ) {
-        self.lookup(lint, Some(span), decorator.msg(), |diag| decorator.decorate_lint(diag));
+        self.lookup(lint, Some(span), decorator.msg(), |diag| {
+            decorator.decorate_lint(diag);
+        });
     }
 
     /// Emit a lint at the appropriate level, with an associated span.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     fn struct_span_lint<S: Into<MultiSpan>>(
@@ -1022,9 +1013,7 @@ pub trait LintContext {
         lint: &'static Lint,
         span: S,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         self.lookup(lint, Some(span), msg, decorate);
     }
@@ -1033,23 +1022,19 @@ pub trait LintContext {
     /// generated by `#[derive(LintDiagnostic)]`).
     fn emit_lint(&self, lint: &'static Lint, decorator: impl for<'a> DecorateLint<'a, ()>) {
         self.lookup(lint, None as Option<Span>, decorator.msg(), |diag| {
-            decorator.decorate_lint(diag)
+            decorator.decorate_lint(diag);
         });
     }
 
     /// Emit a lint at the appropriate level, with no associated span.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     fn lint(
         &self,
         lint: &'static Lint,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         self.lookup(lint, None as Option<Span>, msg, decorate);
     }
@@ -1113,9 +1098,7 @@ impl<'tcx> LintContext for LateContext<'tcx> {
         lint: &'static Lint,
         span: Option<S>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         let hir_id = self.last_node_with_lint_attrs;
 
@@ -1142,9 +1125,7 @@ impl LintContext for EarlyContext<'_> {
         lint: &'static Lint,
         span: Option<S>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         self.builder.struct_lint(lint, span.map(|s| s.into()), msg, decorate)
     }
diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs
index 4c7f9eeff8c..b9add9e9f06 100644
--- a/compiler/rustc_lint/src/early.rs
+++ b/compiler/rustc_lint/src/early.rs
@@ -45,13 +45,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
     fn inlined_check_id(&mut self, id: ast::NodeId) {
         for early_lint in self.context.buffered.take(id) {
             let BufferedEarlyLint { span, msg, node_id: _, lint_id, diagnostic } = early_lint;
-            self.context.lookup_with_diagnostics(
-                lint_id.lint,
-                Some(span),
-                msg,
-                |lint| lint,
-                diagnostic,
-            );
+            self.context.lookup_with_diagnostics(lint_id.lint, Some(span), msg, |_| {}, diagnostic);
         }
     }
 
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index c1d4ed37627..8c8ff3fc650 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -1077,7 +1077,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
                             GateIssue::Language,
                             lint_from_cli,
                         );
-                        lint
                     },
                 );
                 return false;
@@ -1094,8 +1093,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     /// Used to emit a lint-related diagnostic based on the current state of
     /// this lint context.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     #[track_caller]
@@ -1104,9 +1101,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
         lint: &'static Lint,
         span: Option<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         let (level, src) = self.lint_level(lint);
         struct_lint_level(self.sess, lint, level, src, span, msg, decorate)
@@ -1121,7 +1116,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     ) {
         let (level, src) = self.lint_level(lint);
         struct_lint_level(self.sess, lint, level, src, Some(span), decorate.msg(), |lint| {
-            decorate.decorate_lint(lint)
+            decorate.decorate_lint(lint);
         });
     }
 
@@ -1129,7 +1124,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
     pub fn emit_lint(&self, lint: &'static Lint, decorate: impl for<'a> DecorateLint<'a, ()>) {
         let (level, src) = self.lint_level(lint);
         struct_lint_level(self.sess, lint, level, src, None, decorate.msg(), |lint| {
-            decorate.decorate_lint(lint)
+            decorate.decorate_lint(lint);
         });
     }
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 83414ee702f..a4ab5527e3f 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -509,6 +509,11 @@ fn register_builtins(store: &mut LintStore) {
         "converted into hard error, see PR #104616 \
          <https://github.com/rust-lang/rust/pull/104616> for more information",
     );
+    store.register_removed(
+        "implied_bounds_entailment",
+        "converted into hard error, see PR #117984 \
+        <https://github.com/rust-lang/rust/pull/117984> for more information",
+    );
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index d0b895f7354..ca6408bdf3d 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -134,12 +134,8 @@ pub struct BuiltinMissingDebugImpl<'a> {
 
 // Needed for def_path_str
 impl<'a> DecorateLint<'a, ()> for BuiltinMissingDebugImpl<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("debug", self.tcx.def_path_str(self.def_id));
-        diag
     }
 
     fn msg(&self) -> DiagnosticMessage {
@@ -243,17 +239,13 @@ pub struct BuiltinUngatedAsyncFnTrackCaller<'a> {
 }
 
 impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.span_label(self.label, fluent::lint_label);
         rustc_session::parse::add_feature_diagnostics(
             diag,
             self.parse_sess,
             sym::async_fn_track_caller,
         );
-        diag
     }
 
     fn msg(&self) -> DiagnosticMessage {
@@ -433,10 +425,7 @@ pub struct BuiltinUnpermittedTypeInit<'a> {
 }
 
 impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("ty", self.ty);
         diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
         if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) {
@@ -447,7 +436,6 @@ impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
             );
         }
         self.sub.add_to_diagnostic(diag);
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1159,10 +1147,7 @@ pub struct NonFmtPanicUnused {
 
 // Used because of two suggestions based on one Option<Span>
 impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("count", self.count);
         diag.note(fluent::lint_note);
         if let Some(span) = self.suggestion {
@@ -1179,7 +1164,6 @@ impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
                 Applicability::MachineApplicable,
             );
         }
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1358,12 +1342,9 @@ pub struct DropTraitConstraintsDiag<'a> {
 
 // Needed for def_path_str
 impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("predicate", self.predicate);
-        diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
+        diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1378,11 +1359,8 @@ pub struct DropGlue<'a> {
 
 // Needed for def_path_str
 impl<'a> DecorateLint<'a, ()> for DropGlue<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
-        diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
+        diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1655,10 +1633,7 @@ pub struct ImproperCTypes<'a> {
 
 // Used because of the complexity of Option<DiagnosticMessage>, DiagnosticMessage, and Option<Span>
 impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("ty", self.ty);
         diag.set_arg("desc", self.desc);
         diag.span_label(self.label, fluent::lint_label);
@@ -1669,7 +1644,6 @@ impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
         if let Some(note) = self.span_note {
             diag.span_note(note, fluent::lint_note);
         }
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1802,10 +1776,7 @@ pub enum UnusedDefSuggestion {
 
 // Needed because of def_path_str
 impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.set_arg("pre", self.pre);
         diag.set_arg("post", self.post);
         diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
@@ -1816,7 +1787,6 @@ impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
         if let Some(sugg) = self.suggestion {
             diag.subdiagnostic(sugg);
         }
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
@@ -1889,15 +1859,11 @@ pub struct AsyncFnInTraitDiag {
 }
 
 impl<'a> DecorateLint<'a, ()> for AsyncFnInTraitDiag {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.note(fluent::lint_note);
         if let Some(sugg) = self.sugg {
             diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect);
         }
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index f0e415492ae..9fcd70ba0b5 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -126,7 +126,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
         lint.note(fluent::lint_more_info_note);
         if !is_arg_inside_call(arg_span, span) {
             // No clue where this argument is coming from.
-            return lint;
+            return;
         }
         if arg_macro.is_some_and(|id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
             // A case of `panic!(format!(..))`.
@@ -207,7 +207,6 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
                 }
             }
         }
-        lint
     });
 }
 
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index e6e445c54b1..f9b66239bf9 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -47,7 +47,6 @@ declare_lint_pass! {
         HIDDEN_GLOB_REEXPORTS,
         ILL_FORMED_ATTRIBUTE_INPUT,
         ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
-        IMPLIED_BOUNDS_ENTAILMENT,
         INCOMPLETE_INCLUDE,
         INDIRECT_STRUCTURAL_MATCH,
         INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
@@ -4236,47 +4235,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `implied_bounds_entailment` lint detects cases where the arguments of an impl method
-    /// have stronger implied bounds than those from the trait method it's implementing.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,compile_fail
-    /// #![deny(implied_bounds_entailment)]
-    ///
-    /// trait Trait {
-    ///     fn get<'s>(s: &'s str, _: &'static &'static ()) -> &'static str;
-    /// }
-    ///
-    /// impl Trait for () {
-    ///     fn get<'s>(s: &'s str, _: &'static &'s ()) -> &'static str {
-    ///         s
-    ///     }
-    /// }
-    ///
-    /// let val = <() as Trait>::get(&String::from("blah blah blah"), &&());
-    /// println!("{}", val);
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// Neither the trait method, which provides no implied bounds about `'s`, nor the impl,
-    /// requires the main function to prove that 's: 'static, but the impl method is allowed
-    /// to assume that `'s: 'static` within its own body.
-    ///
-    /// This can be used to implement an unsound API if used incorrectly.
-    pub IMPLIED_BOUNDS_ENTAILMENT,
-    Deny,
-    "impl method assumes more implied bounds than its corresponding trait method",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
-        reference: "issue #105572 <https://github.com/rust-lang/rust/issues/105572>",
-    };
-}
-
-declare_lint! {
     /// The `byte_slice_in_packed_struct_with_derive` lint detects cases where a byte slice field
     /// (`[u8]`) or string slice field (`str`) is used in a `packed` struct that derives one or
     /// more built-in traits.
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 556dc890a84..cf3f526400d 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -468,6 +468,14 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
     // it prevents control flow from "falling through" into whatever code
     // happens to be laid out next in memory.
     Options.TrapUnreachable = true;
+    // But don't emit traps after other traps or no-returns unnecessarily.
+    // ...except for when targeting WebAssembly, because the NoTrapAfterNoreturn
+    // option causes bugs in the LLVM WebAssembly backend. You should be able to
+    // remove this check when Rust's minimum supported LLVM version is >= 18
+    // https://github.com/llvm/llvm-project/pull/65876
+    if (!Trip.isWasm()) {
+      Options.NoTrapAfterNoreturn = true;
+    }
   }
 
   if (Singlethread) {
diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
index 31ad9cdb216..cd61544f69d 100644
--- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs
+++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs
@@ -175,9 +175,9 @@ impl<'a> LintDiagnosticDerive<'a> {
                 fn decorate_lint<'__b>(
                     self,
                     #diag: &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()>
-                ) -> &'__b mut rustc_errors::DiagnosticBuilder<'__a, ()> {
+                ) {
                     use rustc_errors::IntoDiagnosticArg;
-                    #implementation
+                    #implementation;
                 }
 
                 fn msg(&self) -> rustc_errors::DiagnosticMessage {
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 59593ae1c63..e544c2a26e8 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -341,13 +341,13 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
             Entry::Occupied(e) => {
                 let (canonical, var_values) = e.get();
                 state.var_values.extend_from_slice(var_values);
-                canonical.clone()
+                *canonical
             }
             Entry::Vacant(e) => {
                 let canonical = canonicalize_op(tcx, key, state);
                 let OriginalQueryValues { var_values, universe_map } = state;
                 assert_eq!(universe_map.len(), 1);
-                e.insert((canonical.clone(), tcx.arena.alloc_slice(var_values)));
+                e.insert((canonical, tcx.arena.alloc_slice(var_values)));
                 canonical
             }
         }
diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs
index eada116f896..4c4f38d1ad8 100644
--- a/compiler/rustc_middle/src/lint.rs
+++ b/compiler/rustc_middle/src/lint.rs
@@ -253,29 +253,10 @@ pub fn explain_lint_level_source(
 /// - [`TyCtxt::struct_lint_node`]
 /// - `LintContext::lookup`
 ///
-/// ## `decorate` signature
+/// ## `decorate`
 ///
-/// The return value of `decorate` is ignored by this function. So what is the
-/// point of returning `&'b mut DiagnosticBuilder<'a, ()>`?
-///
-/// There are 2 reasons for this signature.
-///
-/// First of all, it prevents accidental use of `.emit()` -- it's clear that the
-/// builder will be later used and shouldn't be emitted right away (this is
-/// especially important because the old API expected you to call `.emit()` in
-/// the closure).
-///
-/// Second of all, it makes the most common case of adding just a single label
-/// /suggestion much nicer, since [`DiagnosticBuilder`] methods return
-/// `&mut DiagnosticBuilder`, you can just chain methods, without needed
-/// awkward `{ ...; }`:
-/// ```ignore pseudo-code
-/// struct_lint_level(
-///     ...,
-///     |lint| lint.span_label(sp, "lbl")
-///     //          ^^^^^^^^^^^^^^^^^^^^^ returns `&mut DiagnosticBuilder` by default
-/// )
-/// ```
+/// It is not intended to call `emit`/`cancel` on the `DiagnosticBuilder` passed
+/// in the `decorate` callback.
 #[track_caller]
 pub fn struct_lint_level(
     sess: &Session,
@@ -284,9 +265,7 @@ pub fn struct_lint_level(
     src: LintLevelSource,
     span: Option<MultiSpan>,
     msg: impl Into<DiagnosticMessage>,
-    decorate: impl for<'a, 'b> FnOnce(
-        &'b mut DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut DiagnosticBuilder<'a, ()>,
+    decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
 ) {
     // Avoid codegen bloat from monomorphization by immediately doing dyn dispatch of `decorate` to
     // the "real" work.
@@ -298,12 +277,7 @@ pub fn struct_lint_level(
         src: LintLevelSource,
         span: Option<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: Box<
-            dyn '_
-                + for<'a, 'b> FnOnce(
-                    &'b mut DiagnosticBuilder<'a, ()>,
-                ) -> &'b mut DiagnosticBuilder<'a, ()>,
-        >,
+        decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>)>,
     ) {
         // Check for future incompatibility lints and issue a stronger warning.
         let future_incompatible = lint.future_incompatible;
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 564a1fad14d..0cba6d5b52a 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -223,7 +223,6 @@ fn late_report_deprecation(
             let kind = tcx.def_descr(def_id);
             deprecation_suggestion(diag, kind, suggestion, method_span);
         }
-        diag
     });
 }
 
@@ -587,7 +586,7 @@ impl<'tcx> TyCtxt<'tcx> {
         unmarked: impl FnOnce(Span, DefId),
     ) -> bool {
         let soft_handler = |lint, span, msg: String| {
-            self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |lint| lint)
+            self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, msg, |_| {})
         };
         let eval_result =
             self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index 34068a9da37..092b59deeff 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -113,7 +113,7 @@ impl<'tcx> TyCtxt<'tcx> {
                                 self.local_def_id_to_hir_id(local_def_id),
                                 self.def_span(ct.def),
                                 "cannot use constants which depend on generic parameters in types",
-                                |err| err,
+                                |_| {},
                             )
                         }
                     }
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index a3fa568114f..2d3ee33489e 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -59,7 +59,7 @@ impl<'tcx> Const<'tcx> {
 
     #[inline]
     pub fn kind(self) -> ConstKind<'tcx> {
-        self.0.kind.clone()
+        self.0.kind
     }
 
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 5e61847a37a..6a6ed59fabf 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -2030,14 +2030,12 @@ impl<'tcx> TyCtxt<'tcx> {
         let msg = decorator.msg();
         let (level, src) = self.lint_level_at_node(lint, hir_id);
         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, |diag| {
-            decorator.decorate_lint(diag)
+            decorator.decorate_lint(diag);
         })
     }
 
     /// Emit a lint at the appropriate level for a hir node, with an associated span.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     #[track_caller]
@@ -2047,9 +2045,7 @@ impl<'tcx> TyCtxt<'tcx> {
         hir_id: HirId,
         span: impl Into<MultiSpan>,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         let (level, src) = self.lint_level_at_node(lint, hir_id);
         struct_lint_level(self.sess, lint, level, src, Some(span.into()), msg, decorate);
@@ -2064,13 +2060,13 @@ impl<'tcx> TyCtxt<'tcx> {
         id: HirId,
         decorator: impl for<'a> DecorateLint<'a, ()>,
     ) {
-        self.struct_lint_node(lint, id, decorator.msg(), |diag| decorator.decorate_lint(diag))
+        self.struct_lint_node(lint, id, decorator.msg(), |diag| {
+            decorator.decorate_lint(diag);
+        })
     }
 
     /// Emit a lint at the appropriate level for a hir node.
     ///
-    /// Return value of the `decorate` closure is ignored, see [`struct_lint_level`] for a detailed explanation.
-    ///
     /// [`struct_lint_level`]: rustc_middle::lint::struct_lint_level#decorate-signature
     #[rustc_lint_diagnostics]
     #[track_caller]
@@ -2079,9 +2075,7 @@ impl<'tcx> TyCtxt<'tcx> {
         lint: &'static Lint,
         id: HirId,
         msg: impl Into<DiagnosticMessage>,
-        decorate: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        decorate: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         let (level, src) = self.lint_level_at_node(lint, id);
         struct_lint_level(self.sess, lint, level, src, None, msg, decorate);
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index a09a5115386..febab23ea35 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -473,7 +473,7 @@ impl<'tcx> IntoKind for Ty<'tcx> {
     type Kind = TyKind<'tcx>;
 
     fn kind(self) -> TyKind<'tcx> {
-        self.kind().clone()
+        *self.kind()
     }
 }
 
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index 071024a0fa3..2802f5491be 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -956,11 +956,7 @@ impl Map {
             // The local is not tracked at all, so it does not alias anything.
             return;
         };
-        let elems = place
-            .projection
-            .iter()
-            .map(|&elem| elem.try_into())
-            .chain(tail_elem.map(Ok).into_iter());
+        let elems = place.projection.iter().map(|&elem| elem.try_into()).chain(tail_elem.map(Ok));
         for elem in elems {
             // A field aliases the parent place.
             if let Some(vi) = self.places[index].value_index {
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 146cc33e8c6..ad12bce9b02 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -496,7 +496,7 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
             FlatSet::Elem(scalar) => {
                 let ty = op.ty(self.local_decls, self.tcx);
                 self.tcx.layout_of(self.param_env.and(ty)).map_or(FlatSet::Top, |layout| {
-                    FlatSet::Elem(ImmTy::from_scalar(scalar.into(), layout))
+                    FlatSet::Elem(ImmTy::from_scalar(scalar, layout))
                 })
             }
             FlatSet::Bottom => FlatSet::Bottom,
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index dbf27ea60f8..928db471298 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -180,10 +180,7 @@ pub(crate) struct UnsafeOpInUnsafeFn {
 
 impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn {
     #[track_caller]
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, ()>) {
         let handler = diag.handler().expect("lint should not yet be emitted");
         let desc = handler.eagerly_translate_to_string(self.details.label(), [].into_iter());
         diag.set_arg("details", desc);
@@ -198,8 +195,6 @@ impl<'a> DecorateLint<'a, ()> for UnsafeOpInUnsafeFn {
                 Applicability::MaybeIncorrect,
             );
         }
-
-        diag
     }
 
     fn msg(&self) -> DiagnosticMessage {
@@ -213,10 +208,7 @@ pub(crate) enum AssertLint<P> {
 }
 
 impl<'a, P: std::fmt::Debug> DecorateLint<'a, ()> for AssertLint<P> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut DiagnosticBuilder<'a, ()>) {
         let span = self.span();
         let assert_kind = self.panic();
         let message = assert_kind.diagnostic_message();
@@ -224,8 +216,6 @@ impl<'a, P: std::fmt::Debug> DecorateLint<'a, ()> for AssertLint<P> {
             diag.set_arg(name, value);
         });
         diag.span_label(span, message);
-
-        diag
     }
 
     fn msg(&self) -> DiagnosticMessage {
@@ -284,10 +274,7 @@ pub(crate) struct MustNotSupend<'tcx, 'a> {
 
 // Needed for def_path_str
 impl<'a> DecorateLint<'a, ()> for MustNotSupend<'_, '_> {
-    fn decorate_lint<'b>(
-        self,
-        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
-    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>) {
         diag.span_label(self.yield_sp, fluent::_subdiag::label);
         if let Some(reason) = self.reason {
             diag.subdiagnostic(reason);
@@ -296,7 +283,6 @@ impl<'a> DecorateLint<'a, ()> for MustNotSupend<'_, '_> {
         diag.set_arg("pre", self.pre);
         diag.set_arg("def_path", self.tcx.def_path_str(self.def_id));
         diag.set_arg("post", self.post);
-        diag
     }
 
     fn msg(&self) -> rustc_errors::DiagnosticMessage {
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index b659c40b233..2b4c2e3c250 100644
--- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
@@ -11,12 +11,12 @@ use crate::errors::{MoreThanOneCharNote, MoreThanOneCharSugg, NoBraceUnicodeSub,
 
 pub(crate) fn emit_unescape_error(
     handler: &Handler,
-    // interior part of the literal, without quotes
+    // interior part of the literal, between quotes
     lit: &str,
-    // full span of the literal, including quotes
-    span_with_quotes: Span,
-    // interior span of the literal, without quotes
-    span: Span,
+    // full span of the literal, including quotes and any prefix
+    full_lit_span: Span,
+    // span of the error part of the literal
+    err_span: Span,
     mode: Mode,
     // range of the error inside `lit`
     range: Range<usize>,
@@ -24,19 +24,21 @@ pub(crate) fn emit_unescape_error(
 ) {
     debug!(
         "emit_unescape_error: {:?}, {:?}, {:?}, {:?}, {:?}",
-        lit, span_with_quotes, mode, range, error
+        lit, full_lit_span, mode, range, error
     );
     let last_char = || {
         let c = lit[range.clone()].chars().next_back().unwrap();
-        let span = span.with_lo(span.hi() - BytePos(c.len_utf8() as u32));
+        let span = err_span.with_lo(err_span.hi() - BytePos(c.len_utf8() as u32));
         (c, span)
     };
     match error {
         EscapeError::LoneSurrogateUnicodeEscape => {
-            handler.emit_err(UnescapeError::InvalidUnicodeEscape { span, surrogate: true });
+            handler
+                .emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: true });
         }
         EscapeError::OutOfRangeUnicodeEscape => {
-            handler.emit_err(UnescapeError::InvalidUnicodeEscape { span, surrogate: false });
+            handler
+                .emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: false });
         }
         EscapeError::MoreThanOneChar => {
             use unicode_normalization::{char::is_combining_mark, UnicodeNormalization};
@@ -49,12 +51,16 @@ pub(crate) fn emit_unescape_error(
                 let normalized = lit.nfc().to_string();
                 if normalized.chars().count() == 1 {
                     let ch = normalized.chars().next().unwrap().escape_default().to_string();
-                    sugg = Some(MoreThanOneCharSugg::NormalizedForm { span, ch, normalized });
+                    sugg = Some(MoreThanOneCharSugg::NormalizedForm {
+                        span: err_span,
+                        ch,
+                        normalized,
+                    });
                 }
                 let escaped_marks =
                     rest.iter().map(|c| c.escape_default().to_string()).collect::<Vec<_>>();
                 note = Some(MoreThanOneCharNote::AllCombining {
-                    span,
+                    span: err_span,
                     chr: format!("{first}"),
                     len: escaped_marks.len(),
                     escaped_marks: escaped_marks.join(""),
@@ -69,10 +75,12 @@ pub(crate) fn emit_unescape_error(
                     .collect();
 
                 if let &[ch] = printable.as_slice() {
-                    sugg =
-                        Some(MoreThanOneCharSugg::RemoveNonPrinting { span, ch: ch.to_string() });
+                    sugg = Some(MoreThanOneCharSugg::RemoveNonPrinting {
+                        span: err_span,
+                        ch: ch.to_string(),
+                    });
                     note = Some(MoreThanOneCharNote::NonPrinting {
-                        span,
+                        span: err_span,
                         escaped: lit.escape_default().to_string(),
                     });
                 }
@@ -91,13 +99,13 @@ pub(crate) fn emit_unescape_error(
                 }
                 let sugg = format!("{prefix}\"{escaped}\"");
                 MoreThanOneCharSugg::Quotes {
-                    span: span_with_quotes,
+                    span: full_lit_span,
                     is_byte: mode == Mode::Byte,
                     sugg,
                 }
             });
             handler.emit_err(UnescapeError::MoreThanOneChar {
-                span: span_with_quotes,
+                span: full_lit_span,
                 note,
                 suggestion: sugg,
             });
@@ -105,7 +113,7 @@ pub(crate) fn emit_unescape_error(
         EscapeError::EscapeOnlyChar => {
             let (c, char_span) = last_char();
             handler.emit_err(UnescapeError::EscapeOnlyChar {
-                span,
+                span: err_span,
                 char_span,
                 escaped_sugg: c.escape_default().to_string(),
                 escaped_msg: escaped_char(c),
@@ -114,11 +122,11 @@ pub(crate) fn emit_unescape_error(
         }
         EscapeError::BareCarriageReturn => {
             let double_quotes = mode.in_double_quotes();
-            handler.emit_err(UnescapeError::BareCr { span, double_quotes });
+            handler.emit_err(UnescapeError::BareCr { span: err_span, double_quotes });
         }
         EscapeError::BareCarriageReturnInRawString => {
             assert!(mode.in_double_quotes());
-            handler.emit_err(UnescapeError::BareCrRawString(span));
+            handler.emit_err(UnescapeError::BareCrRawString(err_span));
         }
         EscapeError::InvalidEscape => {
             let (c, span) = last_char();
@@ -143,7 +151,7 @@ pub(crate) fn emit_unescape_error(
             } else {
                 if mode == Mode::Str || mode == Mode::Char {
                     diag.span_suggestion(
-                        span_with_quotes,
+                        full_lit_span,
                         "if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal",
                         format!("r\"{lit}\""),
                         Applicability::MaybeIncorrect,
@@ -158,7 +166,7 @@ pub(crate) fn emit_unescape_error(
             diag.emit();
         }
         EscapeError::TooShortHexEscape => {
-            handler.emit_err(UnescapeError::TooShortHexEscape(span));
+            handler.emit_err(UnescapeError::TooShortHexEscape(err_span));
         }
         EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => {
             let (c, span) = last_char();
@@ -210,7 +218,7 @@ pub(crate) fn emit_unescape_error(
             err.emit();
         }
         EscapeError::OutOfRangeHexEscape => {
-            handler.emit_err(UnescapeError::OutOfRangeHexEscape(span));
+            handler.emit_err(UnescapeError::OutOfRangeHexEscape(err_span));
         }
         EscapeError::LeadingUnderscoreUnicodeEscape => {
             let (c, span) = last_char();
@@ -220,10 +228,11 @@ pub(crate) fn emit_unescape_error(
             });
         }
         EscapeError::OverlongUnicodeEscape => {
-            handler.emit_err(UnescapeError::OverlongUnicodeEscape(span));
+            handler.emit_err(UnescapeError::OverlongUnicodeEscape(err_span));
         }
         EscapeError::UnclosedUnicodeEscape => {
-            handler.emit_err(UnescapeError::UnclosedUnicodeEscape(span, span.shrink_to_hi()));
+            handler
+                .emit_err(UnescapeError::UnclosedUnicodeEscape(err_span, err_span.shrink_to_hi()));
         }
         EscapeError::NoBraceInUnicodeEscape => {
             let mut suggestion = "\\u{".to_owned();
@@ -238,34 +247,34 @@ pub(crate) fn emit_unescape_error(
             let (label, sub) = if suggestion_len > 0 {
                 suggestion.push('}');
                 let hi = char_span.lo() + BytePos(suggestion_len as u32);
-                (None, NoBraceUnicodeSub::Suggestion { span: span.with_hi(hi), suggestion })
+                (None, NoBraceUnicodeSub::Suggestion { span: err_span.with_hi(hi), suggestion })
             } else {
-                (Some(span), NoBraceUnicodeSub::Help)
+                (Some(err_span), NoBraceUnicodeSub::Help)
             };
-            handler.emit_err(UnescapeError::NoBraceInUnicodeEscape { span, label, sub });
+            handler.emit_err(UnescapeError::NoBraceInUnicodeEscape { span: err_span, label, sub });
         }
         EscapeError::UnicodeEscapeInByte => {
-            handler.emit_err(UnescapeError::UnicodeEscapeInByte(span));
+            handler.emit_err(UnescapeError::UnicodeEscapeInByte(err_span));
         }
         EscapeError::EmptyUnicodeEscape => {
-            handler.emit_err(UnescapeError::EmptyUnicodeEscape(span));
+            handler.emit_err(UnescapeError::EmptyUnicodeEscape(err_span));
         }
         EscapeError::ZeroChars => {
-            handler.emit_err(UnescapeError::ZeroChars(span));
+            handler.emit_err(UnescapeError::ZeroChars(err_span));
         }
         EscapeError::LoneSlash => {
-            handler.emit_err(UnescapeError::LoneSlash(span));
+            handler.emit_err(UnescapeError::LoneSlash(err_span));
         }
         EscapeError::UnskippedWhitespaceWarning => {
             let (c, char_span) = last_char();
             handler.emit_warning(UnescapeError::UnskippedWhitespace {
-                span,
+                span: err_span,
                 ch: escaped_char(c),
                 char_span,
             });
         }
         EscapeError::MultipleSkippedLinesWarning => {
-            handler.emit_warning(UnescapeError::MultipleSkippedLinesWarning(span));
+            handler.emit_warning(UnescapeError::MultipleSkippedLinesWarning(err_span));
         }
     }
 }
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 89919247e82..fd7dad36c9d 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -923,7 +923,7 @@ impl<'a> Parser<'a> {
         );
         let where_predicates_split = before_where_clause.predicates.len();
         let mut predicates = before_where_clause.predicates;
-        predicates.extend(after_where_clause.predicates.into_iter());
+        predicates.extend(after_where_clause.predicates);
         let where_clause = WhereClause {
             has_where_token: before_where_clause.has_where_token
                 || after_where_clause.has_where_token,
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 81055431f64..d10c8c92257 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -215,7 +215,7 @@ fn emit_malformed_attribute(
                 } else {
                     "the following are the possible correct uses"
                 },
-                suggestions.into_iter(),
+                suggestions,
                 Applicability::HasPlaceholders,
             )
             .emit();
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 85969b72d23..c2392620cb2 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -429,7 +429,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
     fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) {
         record_variants!(
             (self, b, b, Id::None, hir, GenericBound, GenericBound),
-            [Trait, LangItemTrait, Outlives]
+            [Trait, Outlives]
         );
         hir_visit::walk_param_bound(self, b)
     }
diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs
index 83b7d8d71bc..6d14a14096d 100644
--- a/compiler/rustc_passes/src/lang_items.rs
+++ b/compiler/rustc_passes/src/lang_items.rs
@@ -7,18 +7,18 @@
 //! * Traits that represent operators; e.g., `Add`, `Sub`, `Index`.
 //! * Functions called by the compiler itself.
 
-use crate::check_attr::target_from_impl_item;
 use crate::errors::{
     DuplicateLangItem, IncorrectTarget, LangItemOnIncorrectTarget, UnknownLangItem,
 };
 use crate::weak_lang_items;
 
-use rustc_hir as hir;
-use rustc_hir::def::DefKind;
+use rustc_ast as ast;
+use rustc_ast::visit;
+use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::{extract, GenericRequirement};
-use rustc_hir::{LangItem, LanguageItems, Target};
-use rustc_middle::ty::TyCtxt;
+use rustc_hir::{LangItem, LanguageItems, MethodKind, Target};
+use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
 use rustc_session::cstore::ExternCrate;
 use rustc_span::symbol::kw::Empty;
 use rustc_span::Span;
@@ -31,28 +31,55 @@ pub(crate) enum Duplicate {
     CrateDepends,
 }
 
-struct LanguageItemCollector<'tcx> {
+struct LanguageItemCollector<'ast, 'tcx> {
     items: LanguageItems,
     tcx: TyCtxt<'tcx>,
+    resolver: &'ast ResolverAstLowering,
+    // FIXME(#118552): We should probably feed def_span eagerly on def-id creation
+    // so we can avoid constructing this map for local def-ids.
+    item_spans: FxHashMap<DefId, Span>,
+    parent_item: Option<&'ast ast::Item>,
 }
 
-impl<'tcx> LanguageItemCollector<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>) -> LanguageItemCollector<'tcx> {
-        LanguageItemCollector { tcx, items: LanguageItems::new() }
+impl<'ast, 'tcx> LanguageItemCollector<'ast, 'tcx> {
+    fn new(
+        tcx: TyCtxt<'tcx>,
+        resolver: &'ast ResolverAstLowering,
+    ) -> LanguageItemCollector<'ast, 'tcx> {
+        LanguageItemCollector {
+            tcx,
+            resolver,
+            items: LanguageItems::new(),
+            item_spans: FxHashMap::default(),
+            parent_item: None,
+        }
     }
 
-    fn check_for_lang(&mut self, actual_target: Target, def_id: LocalDefId) {
-        let attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id));
-        if let Some((name, span)) = extract(attrs) {
+    fn check_for_lang(
+        &mut self,
+        actual_target: Target,
+        def_id: LocalDefId,
+        attrs: &'ast [ast::Attribute],
+        item_span: Span,
+        generics: Option<&'ast ast::Generics>,
+    ) {
+        if let Some((name, attr_span)) = extract(attrs) {
             match LangItem::from_name(name) {
                 // Known lang item with attribute on correct target.
                 Some(lang_item) if actual_target == lang_item.target() => {
-                    self.collect_item_extended(lang_item, def_id, span);
+                    self.collect_item_extended(
+                        lang_item,
+                        def_id,
+                        item_span,
+                        attr_span,
+                        generics,
+                        actual_target,
+                    );
                 }
                 // Known lang item with attribute on incorrect target.
                 Some(lang_item) => {
                     self.tcx.sess.emit_err(LangItemOnIncorrectTarget {
-                        span,
+                        span: attr_span,
                         name,
                         expected_target: lang_item.target(),
                         actual_target,
@@ -60,127 +87,131 @@ impl<'tcx> LanguageItemCollector<'tcx> {
                 }
                 // Unknown lang item.
                 _ => {
-                    self.tcx.sess.emit_err(UnknownLangItem { span, name });
+                    self.tcx.sess.emit_err(UnknownLangItem { span: attr_span, name });
                 }
             }
         }
     }
 
-    fn collect_item(&mut self, lang_item: LangItem, item_def_id: DefId) {
+    fn collect_item(&mut self, lang_item: LangItem, item_def_id: DefId, item_span: Option<Span>) {
         // Check for duplicates.
-        if let Some(original_def_id) = self.items.get(lang_item) {
-            if original_def_id != item_def_id {
-                let local_span = self.tcx.hir().span_if_local(item_def_id);
-                let lang_item_name = lang_item.name();
-                let crate_name = self.tcx.crate_name(item_def_id.krate);
-                let mut dependency_of = Empty;
-                let is_local = item_def_id.is_local();
-                let path = if is_local {
-                    String::new()
-                } else {
-                    self.tcx
-                        .crate_extern_paths(item_def_id.krate)
-                        .iter()
-                        .map(|p| p.display().to_string())
-                        .collect::<Vec<_>>()
-                        .join(", ")
-                };
-                let first_defined_span = self.tcx.hir().span_if_local(original_def_id);
-                let mut orig_crate_name = Empty;
-                let mut orig_dependency_of = Empty;
-                let orig_is_local = original_def_id.is_local();
-                let orig_path = if orig_is_local {
-                    String::new()
-                } else {
-                    self.tcx
-                        .crate_extern_paths(original_def_id.krate)
-                        .iter()
-                        .map(|p| p.display().to_string())
-                        .collect::<Vec<_>>()
-                        .join(", ")
-                };
-                if first_defined_span.is_none() {
-                    orig_crate_name = self.tcx.crate_name(original_def_id.krate);
-                    if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) =
-                        self.tcx.extern_crate(original_def_id)
-                    {
-                        orig_dependency_of = self.tcx.crate_name(*inner_dependency_of);
-                    }
+        if let Some(original_def_id) = self.items.get(lang_item)
+            && original_def_id != item_def_id
+        {
+            let lang_item_name = lang_item.name();
+            let crate_name = self.tcx.crate_name(item_def_id.krate);
+            let mut dependency_of = Empty;
+            let is_local = item_def_id.is_local();
+            let path = if is_local {
+                String::new()
+            } else {
+                self.tcx
+                    .crate_extern_paths(item_def_id.krate)
+                    .iter()
+                    .map(|p| p.display().to_string())
+                    .collect::<Vec<_>>()
+                    .join(", ")
+            };
+
+            let first_defined_span = self.item_spans.get(&original_def_id).copied();
+            let mut orig_crate_name = Empty;
+            let mut orig_dependency_of = Empty;
+            let orig_is_local = original_def_id.is_local();
+            let orig_path = if orig_is_local {
+                String::new()
+            } else {
+                self.tcx
+                    .crate_extern_paths(original_def_id.krate)
+                    .iter()
+                    .map(|p| p.display().to_string())
+                    .collect::<Vec<_>>()
+                    .join(", ")
+            };
+
+            if first_defined_span.is_none() {
+                orig_crate_name = self.tcx.crate_name(original_def_id.krate);
+                if let Some(ExternCrate { dependency_of: inner_dependency_of, .. }) =
+                    self.tcx.extern_crate(original_def_id)
+                {
+                    orig_dependency_of = self.tcx.crate_name(*inner_dependency_of);
                 }
+            }
 
-                let duplicate = if local_span.is_some() {
-                    Duplicate::Plain
-                } else {
-                    match self.tcx.extern_crate(item_def_id) {
-                        Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => {
-                            dependency_of = self.tcx.crate_name(*inner_dependency_of);
-                            Duplicate::CrateDepends
-                        }
-                        _ => Duplicate::Crate,
+            let duplicate = if item_span.is_some() {
+                Duplicate::Plain
+            } else {
+                match self.tcx.extern_crate(item_def_id) {
+                    Some(ExternCrate { dependency_of: inner_dependency_of, .. }) => {
+                        dependency_of = self.tcx.crate_name(*inner_dependency_of);
+                        Duplicate::CrateDepends
                     }
-                };
-
-                self.tcx.sess.emit_err(DuplicateLangItem {
-                    local_span,
-                    lang_item_name,
-                    crate_name,
-                    dependency_of,
-                    is_local,
-                    path,
-                    first_defined_span,
-                    orig_crate_name,
-                    orig_dependency_of,
-                    orig_is_local,
-                    orig_path,
-                    duplicate,
-                });
+                    _ => Duplicate::Crate,
+                }
+            };
+
+            self.tcx.sess.emit_err(DuplicateLangItem {
+                local_span: item_span,
+                lang_item_name,
+                crate_name,
+                dependency_of,
+                is_local,
+                path,
+                first_defined_span,
+                orig_crate_name,
+                orig_dependency_of,
+                orig_is_local,
+                orig_path,
+                duplicate,
+            });
+        } else {
+            // Matched.
+            self.items.set(lang_item, item_def_id);
+            // Collect span for error later
+            if let Some(item_span) = item_span {
+                self.item_spans.insert(item_def_id, item_span);
             }
         }
-
-        // Matched.
-        self.items.set(lang_item, item_def_id);
     }
 
     // Like collect_item() above, but also checks whether the lang item is declared
     // with the right number of generic arguments.
-    fn collect_item_extended(&mut self, lang_item: LangItem, item_def_id: LocalDefId, span: Span) {
+    fn collect_item_extended(
+        &mut self,
+        lang_item: LangItem,
+        item_def_id: LocalDefId,
+        item_span: Span,
+        attr_span: Span,
+        generics: Option<&'ast ast::Generics>,
+        target: Target,
+    ) {
         let name = lang_item.name();
 
-        // Now check whether the lang_item has the expected number of generic
-        // arguments. Generally speaking, binary and indexing operations have
-        // one (for the RHS/index), unary operations have none, the closure
-        // traits have one for the argument list, coroutines have one for the
-        // resume argument, and ordering/equality relations have one for the RHS
-        // Some other types like Box and various functions like drop_in_place
-        // have minimum requirements.
+        if let Some(generics) = generics {
+            // Now check whether the lang_item has the expected number of generic
+            // arguments. Generally speaking, binary and indexing operations have
+            // one (for the RHS/index), unary operations have none, the closure
+            // traits have one for the argument list, coroutines have one for the
+            // resume argument, and ordering/equality relations have one for the RHS
+            // Some other types like Box and various functions like drop_in_place
+            // have minimum requirements.
 
-        if let hir::Node::Item(hir::Item { kind, span: item_span, .. }) =
-            self.tcx.hir_node_by_def_id(item_def_id)
-        {
-            let (actual_num, generics_span) = match kind.generics() {
-                Some(generics) => (
-                    generics
-                        .params
-                        .iter()
-                        .filter(|p| {
-                            !matches!(
-                                p.kind,
-                                hir::GenericParamKind::Const { is_host_effect: true, .. }
-                            )
-                        })
-                        .count(),
-                    generics.span,
-                ),
-                None => (0, *item_span),
-            };
+            // FIXME: This still doesn't count, e.g., elided lifetimes and APITs.
+            let mut actual_num = generics.params.len();
+            if target.is_associated_item() {
+                actual_num += self
+                    .parent_item
+                    .unwrap()
+                    .opt_generics()
+                    .map_or(0, |generics| generics.params.len());
+            }
 
             let mut at_least = false;
             let required = match lang_item.required_generics() {
                 GenericRequirement::Exact(num) if num != actual_num => Some(num),
                 GenericRequirement::Minimum(num) if actual_num < num => {
                     at_least = true;
-                    Some(num)}
-                ,
+                    Some(num)
+                }
                 // If the number matches, or there is no requirement, handle it normally
                 _ => None,
             };
@@ -190,10 +221,10 @@ impl<'tcx> LanguageItemCollector<'tcx> {
                 // item kind of the target is correct, the target is still wrong
                 // because of the wrong number of generic arguments.
                 self.tcx.sess.emit_err(IncorrectTarget {
-                    span,
-                    generics_span,
+                    span: attr_span,
+                    generics_span: generics.span,
                     name: name.as_str(),
-                    kind: kind.descr(),
+                    kind: target.name(),
                     num,
                     actual_num,
                     at_least,
@@ -204,58 +235,117 @@ impl<'tcx> LanguageItemCollector<'tcx> {
             }
         }
 
-        self.collect_item(lang_item, item_def_id.to_def_id());
+        self.collect_item(lang_item, item_def_id.to_def_id(), Some(item_span));
     }
 }
 
 /// Traverses and collects all the lang items in all crates.
 fn get_lang_items(tcx: TyCtxt<'_>, (): ()) -> LanguageItems {
+    let resolver = tcx.resolver_for_lowering(()).borrow();
+    let (resolver, krate) = &*resolver;
+
     // Initialize the collector.
-    let mut collector = LanguageItemCollector::new(tcx);
+    let mut collector = LanguageItemCollector::new(tcx, resolver);
 
     // Collect lang items in other crates.
     for &cnum in tcx.crates(()).iter() {
         for &(def_id, lang_item) in tcx.defined_lang_items(cnum).iter() {
-            collector.collect_item(lang_item, def_id);
+            collector.collect_item(lang_item, def_id, None);
         }
     }
 
-    // Collect lang items in this crate.
-    let crate_items = tcx.hir_crate_items(());
+    // Collect lang items local to this crate.
+    visit::Visitor::visit_crate(&mut collector, krate);
 
-    for id in crate_items.items() {
-        collector
-            .check_for_lang(Target::from_def_kind(tcx.def_kind(id.owner_id)), id.owner_id.def_id);
+    // Find all required but not-yet-defined lang items.
+    weak_lang_items::check_crate(tcx, &mut collector.items, krate);
 
-        if matches!(tcx.def_kind(id.owner_id), DefKind::Enum) {
-            let item = tcx.hir().item(id);
-            if let hir::ItemKind::Enum(def, ..) = &item.kind {
-                for variant in def.variants {
-                    collector.check_for_lang(Target::Variant, variant.def_id);
-                }
-            }
-        }
-    }
+    // Return all the lang items that were found.
+    collector.items
+}
+
+impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> {
+    fn visit_item(&mut self, i: &'ast ast::Item) {
+        let target = match &i.kind {
+            ast::ItemKind::ExternCrate(_) => Target::ExternCrate,
+            ast::ItemKind::Use(_) => Target::Use,
+            ast::ItemKind::Static(_) => Target::Static,
+            ast::ItemKind::Const(_) => Target::Const,
+            ast::ItemKind::Fn(_) => Target::Fn,
+            ast::ItemKind::Mod(_, _) => Target::Mod,
+            ast::ItemKind::ForeignMod(_) => Target::ForeignFn,
+            ast::ItemKind::GlobalAsm(_) => Target::GlobalAsm,
+            ast::ItemKind::TyAlias(_) => Target::TyAlias,
+            ast::ItemKind::Enum(_, _) => Target::Enum,
+            ast::ItemKind::Struct(_, _) => Target::Struct,
+            ast::ItemKind::Union(_, _) => Target::Union,
+            ast::ItemKind::Trait(_) => Target::Trait,
+            ast::ItemKind::TraitAlias(_, _) => Target::TraitAlias,
+            ast::ItemKind::Impl(_) => Target::Impl,
+            ast::ItemKind::MacroDef(_) => Target::MacroDef,
+            ast::ItemKind::MacCall(_) => unreachable!("macros should have been expanded"),
+        };
 
-    // FIXME: avoid calling trait_item() when possible
-    for id in crate_items.trait_items() {
-        let item = tcx.hir().trait_item(id);
-        collector.check_for_lang(Target::from_trait_item(item), item.owner_id.def_id)
+        self.check_for_lang(
+            target,
+            self.resolver.node_id_to_def_id[&i.id],
+            &i.attrs,
+            i.span,
+            i.opt_generics(),
+        );
+
+        let parent_item = self.parent_item.replace(i);
+        visit::walk_item(self, i);
+        self.parent_item = parent_item;
     }
 
-    // FIXME: avoid calling impl_item() when possible
-    for id in crate_items.impl_items() {
-        let item = tcx.hir().impl_item(id);
-        collector.check_for_lang(target_from_impl_item(tcx, item), item.owner_id.def_id)
+    fn visit_enum_def(&mut self, enum_definition: &'ast ast::EnumDef) {
+        for variant in &enum_definition.variants {
+            self.check_for_lang(
+                Target::Variant,
+                self.resolver.node_id_to_def_id[&variant.id],
+                &variant.attrs,
+                variant.span,
+                None,
+            );
+        }
+
+        visit::walk_enum_def(self, enum_definition);
     }
 
-    // Extract out the found lang items.
-    let LanguageItemCollector { mut items, .. } = collector;
+    fn visit_assoc_item(&mut self, i: &'ast ast::AssocItem, ctxt: visit::AssocCtxt) {
+        let (target, generics) = match &i.kind {
+            ast::AssocItemKind::Fn(fun) => (
+                match &self.parent_item.unwrap().kind {
+                    ast::ItemKind::Impl(i) => {
+                        if i.of_trait.is_some() {
+                            Target::Method(MethodKind::Trait { body: fun.body.is_some() })
+                        } else {
+                            Target::Method(MethodKind::Inherent)
+                        }
+                    }
+                    ast::ItemKind::Trait(_) => {
+                        Target::Method(MethodKind::Trait { body: fun.body.is_some() })
+                    }
+                    _ => unreachable!(),
+                },
+                &fun.generics,
+            ),
+            ast::AssocItemKind::Const(ct) => (Target::AssocConst, &ct.generics),
+            ast::AssocItemKind::Type(ty) => (Target::AssocTy, &ty.generics),
+            ast::AssocItemKind::MacCall(_) => unreachable!("macros should have been expanded"),
+        };
 
-    // Find all required but not-yet-defined lang items.
-    weak_lang_items::check_crate(tcx, &mut items);
+        self.check_for_lang(
+            target,
+            self.resolver.node_id_to_def_id[&i.id],
+            &i.attrs,
+            i.span,
+            Some(generics),
+        );
 
-    items
+        visit::walk_assoc_item(self, i, ctxt);
+    }
 }
 
 pub fn provide(providers: &mut Providers) {
diff --git a/compiler/rustc_passes/src/weak_lang_items.rs b/compiler/rustc_passes/src/weak_lang_items.rs
index 9a6fb88c281..b226c65e96c 100644
--- a/compiler/rustc_passes/src/weak_lang_items.rs
+++ b/compiler/rustc_passes/src/weak_lang_items.rs
@@ -1,5 +1,7 @@
 //! Validity checking for weak lang items
 
+use rustc_ast as ast;
+use rustc_ast::visit;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::lang_items::{self, LangItem};
 use rustc_hir::weak_lang_items::WEAK_LANG_ITEMS;
@@ -11,7 +13,7 @@ use crate::errors::{MissingLangItem, MissingPanicHandler, UnknownExternLangItem}
 
 /// Checks the crate for usage of weak lang items, returning a vector of all the
 /// language items required by this crate, but not defined yet.
-pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
+pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems, krate: &ast::Crate) {
     // These are never called by user code, they're generated by the compiler.
     // They will never implicitly be added to the `missing` array unless we do
     // so here.
@@ -22,24 +24,30 @@ pub fn check_crate(tcx: TyCtxt<'_>, items: &mut lang_items::LanguageItems) {
         items.missing.push(LangItem::EhCatchTypeinfo);
     }
 
-    let crate_items = tcx.hir_crate_items(());
-    for id in crate_items.foreign_items() {
-        let attrs = tcx.hir().attrs(id.hir_id());
-        if let Some((lang_item, _)) = lang_items::extract(attrs) {
+    visit::Visitor::visit_crate(&mut WeakLangItemVisitor { tcx, items }, krate);
+
+    verify(tcx, items);
+}
+
+struct WeakLangItemVisitor<'a, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    items: &'a mut lang_items::LanguageItems,
+}
+
+impl<'ast> visit::Visitor<'ast> for WeakLangItemVisitor<'_, '_> {
+    fn visit_foreign_item(&mut self, i: &'ast ast::ForeignItem) {
+        if let Some((lang_item, _)) = lang_items::extract(&i.attrs) {
             if let Some(item) = LangItem::from_name(lang_item)
                 && item.is_weak()
             {
-                if items.get(item).is_none() {
-                    items.missing.push(item);
+                if self.items.get(item).is_none() {
+                    self.items.missing.push(item);
                 }
             } else {
-                let span = tcx.def_span(id.owner_id);
-                tcx.sess.emit_err(UnknownExternLangItem { span, lang_item });
+                self.tcx.sess.emit_err(UnknownExternLangItem { span: i.span, lang_item });
             }
         }
     }
-
-    verify(tcx, items);
 }
 
 fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index 3bca7894a29..6486ad8b483 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -923,7 +923,7 @@ impl ConstructorSet {
             }
             ConstructorSet::Integers { range_1, range_2 } => {
                 let seen_ranges: Vec<_> =
-                    seen.iter().map(|ctor| ctor.as_int_range().unwrap().clone()).collect();
+                    seen.iter().map(|ctor| *ctor.as_int_range().unwrap()).collect();
                 for (seen, splitted_range) in range_1.split(seen_ranges.iter().cloned()) {
                     match seen {
                         Presence::Unseen => missing.push(IntRange(splitted_range)),
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index f95c0acd750..4ff4ccf5e98 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -407,8 +407,7 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
         doc,
         main_body_opts(),
         Some(&mut broken_link_callback),
-    )
-    .into_iter();
+    );
     let mut links = Vec::new();
 
     while let Some(event) = event_iter.next() {
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index d46a309df55..20d18fa4b83 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1579,7 +1579,7 @@ impl CheckCfg {
 pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
     // Combine the configuration requested by the session (command line) with
     // some default and generated configuration items.
-    user_cfg.extend(default_configuration(sess).into_iter());
+    user_cfg.extend(default_configuration(sess));
     user_cfg
 }
 
diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs
index 70313cc021e..3a8289f38bd 100644
--- a/compiler/rustc_smir/src/rustc_smir/context.rs
+++ b/compiler/rustc_smir/src/rustc_smir/context.rs
@@ -158,7 +158,6 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
                 let crate_name = tables.tcx.crate_name(*crate_num).to_string();
                 (name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))
             })
-            .into_iter()
             .flatten()
             .collect();
         crates
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 818d1436659..533fe32f70d 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -273,7 +273,6 @@ fn overlap<'tcx>(
                                     causing the impls to overlap",
                                 infcx.resolve_vars_if_possible(failing_obligation.predicate)
                             ));
-                            lint
                         },
                     );
                 }
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 9073cd6ac47..a1b896d2251 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -4665,7 +4665,7 @@ pub trait NextTypeParamName {
 impl NextTypeParamName for &[hir::GenericParam<'_>] {
     fn next_type_param_name(&self, name: Option<&str>) -> String {
         // This is the list of possible parameter names that we might suggest.
-        let name = name.and_then(|n| n.chars().next()).map(|c| c.to_string().to_uppercase());
+        let name = name.and_then(|n| n.chars().next()).map(|c| c.to_uppercase().to_string());
         let name = name.as_deref();
         let possible_names = [name.unwrap_or("T"), "T", "U", "V", "X", "Y", "Z", "A", "B", "C"];
         let used_names = self
@@ -4783,8 +4783,14 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
     };
 
     let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
-    let Some(hir::GenericBound::LangItemTrait(_, _, _, generics)) = future.bounds.get(0) else {
-        // `async fn` should always lower to a lang item bound... but don't ICE.
+    let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else {
+        // `async fn` should always lower to a single bound... but don't ICE.
+        return None;
+    };
+    let Some(hir::PathSegment { args: Some(generics), .. }) =
+        trait_ref.trait_ref.path.segments.last()
+    else {
+        // desugaring to a single path segment for `Future<...>`.
         return None;
     };
     let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) =
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index fbde7455145..47a79bfa9ab 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -194,7 +194,6 @@ fn lint_object_unsafe_trait(
                 // Only provide the help if its a local trait, otherwise it's not
                 violation.solution().add_to(err);
             }
-            err
         },
     );
 }
@@ -345,7 +344,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     // Search for a predicate like `Self : Sized` amongst the trait bounds.
     let predicates = tcx.predicates_of(def_id);
     let predicates = predicates.instantiate_identity(tcx).predicates;
-    elaborate(tcx, predicates.into_iter()).any(|pred| match pred.kind().skip_binder() {
+    elaborate(tcx, predicates).any(|pred| match pred.kind().skip_binder() {
         ty::ClauseKind::Trait(ref trait_pred) => {
             trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0)
         }
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 39f5ff52eba..71a88f5f07c 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -450,7 +450,6 @@ fn report_conflicting_impls<'tcx>(
                 msg,
                 |err| {
                     decorate(tcx, &overlap, impl_span, err);
-                    err
                 },
             );
         }
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 98da3bc2fe9..575010ff46d 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -220,9 +220,8 @@ pub fn impl_subject_and_oblig<'a, 'tcx>(
         selcx.infcx.at(&ObligationCause::dummy(), param_env).normalize(predicates);
     let impl_obligations = super::predicates_for_generics(cause, param_env, predicates);
 
-    let impl_obligations = impl_obligations
-        .chain(normalization_obligations1.into_iter())
-        .chain(normalization_obligations2.into_iter());
+    let impl_obligations =
+        impl_obligations.chain(normalization_obligations1).chain(normalization_obligations2);
 
     (subject, impl_obligations)
 }
diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs
index 62856fc9a49..4a4a3abd47f 100644
--- a/library/alloc/src/ffi/c_str.rs
+++ b/library/alloc/src/ffi/c_str.rs
@@ -421,7 +421,7 @@ impl CString {
     /// Failure to call [`CString::from_raw`] will lead to a memory leak.
     ///
     /// The C side must **not** modify the length of the string (by writing a
-    /// `null` somewhere inside the string or removing the final one) before
+    /// nul byte somewhere inside the string or removing the final one) before
     /// it makes it back into Rust using [`CString::from_raw`]. See the safety section
     /// in [`CString::from_raw`].
     ///
@@ -797,7 +797,7 @@ impl From<Box<CStr>> for CString {
 #[stable(feature = "cstring_from_vec_of_nonzerou8", since = "1.43.0")]
 impl From<Vec<NonZeroU8>> for CString {
     /// Converts a <code>[Vec]<[NonZeroU8]></code> into a [`CString`] without
-    /// copying nor checking for inner null bytes.
+    /// copying nor checking for inner nul bytes.
     #[inline]
     fn from(v: Vec<NonZeroU8>) -> CString {
         unsafe {
@@ -809,7 +809,7 @@ impl From<Vec<NonZeroU8>> for CString {
                 let (ptr, len, cap): (*mut NonZeroU8, _, _) = Vec::into_raw_parts(v);
                 Vec::from_raw_parts(ptr.cast::<u8>(), len, cap)
             };
-            // SAFETY: `v` cannot contain null bytes, given the type-level
+            // SAFETY: `v` cannot contain nul bytes, given the type-level
             // invariant of `NonZeroU8`.
             Self::_from_vec_unchecked(v)
         }
diff --git a/library/core/src/any.rs b/library/core/src/any.rs
index 22777fb078a..c82984d5c6b 100644
--- a/library/core/src/any.rs
+++ b/library/core/src/any.rs
@@ -695,44 +695,41 @@ pub const fn type_name<T: ?Sized>() -> &'static str {
     intrinsics::type_name::<T>()
 }
 
-/// Returns the name of the type of the pointed-to value as a string slice.
+/// Returns the type name of the pointed-to value as a string slice.
+///
 /// This is the same as `type_name::<T>()`, but can be used where the type of a
 /// variable is not easily available.
 ///
 /// # Note
 ///
-/// This is intended for diagnostic use. The exact contents and format of the
-/// string are not specified, other than being a best-effort description of the
-/// type. For example, `type_name_of_val::<Option<String>>(None)` could return
-/// `"Option<String>"` or `"std::option::Option<std::string::String>"`, but not
-/// `"foobar"`. In addition, the output may change between versions of the
-/// compiler.
-///
-/// This function does not resolve trait objects,
-/// meaning that `type_name_of_val(&7u32 as &dyn Debug)`
-/// may return `"dyn Debug"`, but not `"u32"`.
+/// Like [`type_name`], this is intended for diagnostic use and the exact output is not
+/// guaranteed. It provides a best-effort description, but the output may change between
+/// versions of the compiler.
 ///
-/// The type name should not be considered a unique identifier of a type;
-/// multiple types may share the same type name.
+/// In short: use this for debugging, avoid using the output to affect program behavior. More
+/// information is available at [`type_name`].
 ///
-/// The current implementation uses the same infrastructure as compiler
-/// diagnostics and debuginfo, but this is not guaranteed.
+/// Additionally, this function does not resolve trait objects. This means that
+/// `type_name_of_val(&7u32 as &dyn Debug)` may return `"dyn Debug"`, but will not return `"u32"`
+/// at this time.
 ///
 /// # Examples
 ///
 /// Prints the default integer and float types.
 ///
 /// ```rust
-/// #![feature(type_name_of_val)]
 /// use std::any::type_name_of_val;
 ///
-/// let x = 1;
-/// println!("{}", type_name_of_val(&x));
-/// let y = 1.0;
-/// println!("{}", type_name_of_val(&y));
+/// let s = "foo";
+/// let x: i32 = 1;
+/// let y: f32 = 1.0;
+///
+/// assert!(type_name_of_val(&s).contains("str"));
+/// assert!(type_name_of_val(&x).contains("i32"));
+/// assert!(type_name_of_val(&y).contains("f32"));
 /// ```
 #[must_use]
-#[unstable(feature = "type_name_of_val", issue = "66359")]
+#[stable(feature = "type_name_of_val", since = "CURRENT_RUSTC_VERSION")]
 #[rustc_const_unstable(feature = "const_type_name", issue = "63084")]
 pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
     type_name::<T>()
diff --git a/library/core/src/ffi/c_str.rs b/library/core/src/ffi/c_str.rs
index e7ec1fb73cd..bb839a71e90 100644
--- a/library/core/src/ffi/c_str.rs
+++ b/library/core/src/ffi/c_str.rs
@@ -205,7 +205,7 @@ impl CStr {
     /// * The memory pointed to by `ptr` must contain a valid nul terminator at the
     ///   end of the string.
     ///
-    /// * `ptr` must be [valid] for reads of bytes up to and including the null terminator.
+    /// * `ptr` must be [valid] for reads of bytes up to and including the nul terminator.
     ///   This means in particular:
     ///
     ///     * The entire memory range of this `CStr` must be contained within a single allocated object!
@@ -415,7 +415,7 @@ impl CStr {
             let mut i = bytes.len().saturating_sub(1);
             assert!(!bytes.is_empty() && bytes[i] == 0, "input was not nul-terminated");
 
-            // Ending null byte exists, skip to the rest.
+            // Ending nul byte exists, skip to the rest.
             while i != 0 {
                 i -= 1;
                 let byte = bytes[i];
diff --git a/library/core/src/net/ip_addr.rs b/library/core/src/net/ip_addr.rs
index dafc58d3a7d..8bf15c736c3 100644
--- a/library/core/src/net/ip_addr.rs
+++ b/library/core/src/net/ip_addr.rs
@@ -1437,7 +1437,7 @@ impl Ipv6Addr {
     /// - The [unspecified address] ([`is_unspecified`](Ipv6Addr::is_unspecified))
     /// - The [loopback address] ([`is_loopback`](Ipv6Addr::is_loopback))
     /// - IPv4-mapped addresses
-    /// - Addresses reserved for benchmarking
+    /// - Addresses reserved for benchmarking ([`is_benchmarking`](Ipv6Addr::is_benchmarking))
     /// - Addresses reserved for documentation ([`is_documentation`](Ipv6Addr::is_documentation))
     /// - Unique local addresses ([`is_unique_local`](Ipv6Addr::is_unique_local))
     /// - Unicast addresses with link-local scope ([`is_unicast_link_local`](Ipv6Addr::is_unicast_link_local))
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index d6603681a0b..eed793186b9 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -720,7 +720,8 @@ where
 /// type or mutability, in particular if the code is refactored.
 #[inline(always)]
 #[must_use]
-#[unstable(feature = "ptr_from_ref", issue = "106116")]
+#[stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")]
 #[rustc_never_returns_null_ptr]
 #[rustc_diagnostic_item = "ptr_from_ref"]
 pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
@@ -733,7 +734,9 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
 /// type or mutability, in particular if the code is refactored.
 #[inline(always)]
 #[must_use]
-#[unstable(feature = "ptr_from_ref", issue = "106116")]
+#[stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_const_stable(feature = "ptr_from_ref", since = "CURRENT_RUSTC_VERSION")]
+#[rustc_allow_const_fn_unstable(const_mut_refs)]
 #[rustc_never_returns_null_ptr]
 pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
     r
diff --git a/library/core/src/slice/ascii.rs b/library/core/src/slice/ascii.rs
index 4cfccd2e3ce..ce04a9f4089 100644
--- a/library/core/src/slice/ascii.rs
+++ b/library/core/src/slice/ascii.rs
@@ -125,6 +125,7 @@ impl [u8] {
     /// assert_eq!(b"".trim_ascii_start(), b"");
     /// ```
     #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[inline]
     pub const fn trim_ascii_start(&self) -> &[u8] {
         let mut bytes = self;
         // Note: A pattern matching based approach (instead of indexing) allows
@@ -154,6 +155,7 @@ impl [u8] {
     /// assert_eq!(b"".trim_ascii_end(), b"");
     /// ```
     #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[inline]
     pub const fn trim_ascii_end(&self) -> &[u8] {
         let mut bytes = self;
         // Note: A pattern matching based approach (instead of indexing) allows
@@ -184,6 +186,7 @@ impl [u8] {
     /// assert_eq!(b"".trim_ascii(), b"");
     /// ```
     #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[inline]
     pub const fn trim_ascii(&self) -> &[u8] {
         self.trim_ascii_start().trim_ascii_end()
     }
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 27178328be5..a22c46edce2 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -2423,6 +2423,85 @@ impl str {
         me.make_ascii_lowercase()
     }
 
+    /// Returns a string slice with leading ASCII whitespace removed.
+    ///
+    /// 'Whitespace' refers to the definition used by
+    /// [`u8::is_ascii_whitespace`].
+    ///
+    /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(byte_slice_trim_ascii)]
+    ///
+    /// assert_eq!(" \t \u{3000}hello world\n".trim_ascii_start(), "\u{3000}hello world\n");
+    /// assert_eq!("  ".trim_ascii_start(), "");
+    /// assert_eq!("".trim_ascii_start(), "");
+    /// ```
+    #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[must_use = "this returns the trimmed string as a new slice, \
+                  without modifying the original"]
+    #[inline]
+    pub const fn trim_ascii_start(&self) -> &str {
+        // SAFETY: Removing ASCII characters from a `&str` does not invalidate
+        // UTF-8.
+        unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii_start()) }
+    }
+
+    /// Returns a string slice with trailing ASCII whitespace removed.
+    ///
+    /// 'Whitespace' refers to the definition used by
+    /// [`u8::is_ascii_whitespace`].
+    ///
+    /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(byte_slice_trim_ascii)]
+    ///
+    /// assert_eq!("\r hello world\u{3000}\n ".trim_ascii_end(), "\r hello world\u{3000}");
+    /// assert_eq!("  ".trim_ascii_end(), "");
+    /// assert_eq!("".trim_ascii_end(), "");
+    /// ```
+    #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[must_use = "this returns the trimmed string as a new slice, \
+                  without modifying the original"]
+    #[inline]
+    pub const fn trim_ascii_end(&self) -> &str {
+        // SAFETY: Removing ASCII characters from a `&str` does not invalidate
+        // UTF-8.
+        unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii_end()) }
+    }
+
+    /// Returns a string slice with leading and trailing ASCII whitespace
+    /// removed.
+    ///
+    /// 'Whitespace' refers to the definition used by
+    /// [`u8::is_ascii_whitespace`].
+    ///
+    /// [`u8::is_ascii_whitespace`]: u8::is_ascii_whitespace
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(byte_slice_trim_ascii)]
+    ///
+    /// assert_eq!("\r hello world\n ".trim_ascii(), "hello world");
+    /// assert_eq!("  ".trim_ascii(), "");
+    /// assert_eq!("".trim_ascii(), "");
+    /// ```
+    #[unstable(feature = "byte_slice_trim_ascii", issue = "94035")]
+    #[must_use = "this returns the trimmed string as a new slice, \
+                  without modifying the original"]
+    #[inline]
+    pub const fn trim_ascii(&self) -> &str {
+        // SAFETY: Removing ASCII characters from a `&str` does not invalidate
+        // UTF-8.
+        unsafe { core::str::from_utf8_unchecked(self.as_bytes().trim_ascii()) }
+    }
+
     /// Return an iterator that escapes each char in `self` with [`char::escape_debug`].
     ///
     /// Note: only extended grapheme codepoints that begin the string will be
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 86ce5d9c6d5..75bf3329786 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -55,6 +55,7 @@ macro_rules! with_api {
         $m! {
             FreeFunctions {
                 fn drop($self: $S::FreeFunctions);
+                fn injected_env_var(var: &str) -> Option<String>;
                 fn track_env_var(var: &str, value: Option<&str>);
                 fn track_path(path: &str);
                 fn literal_from_str(s: &str) -> Result<Literal<$S::Span, $S::Symbol>, ()>;
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 7ebb6810b3e..6e664a162df 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -1503,7 +1503,8 @@ pub mod tracked_env {
     #[unstable(feature = "proc_macro_tracked_env", issue = "99515")]
     pub fn var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
         let key: &str = key.as_ref();
-        let value = env::var(key);
+        let value = crate::bridge::client::FreeFunctions::injected_env_var(key)
+            .map_or_else(|| env::var(key), Ok);
         crate::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok());
         value
     }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index f666b18887c..fe66788b564 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -30,8 +30,13 @@ rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] }
 [target.'cfg(not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))))'.dependencies]
 miniz_oxide = { version = "0.7.0", optional = true, default-features = false }
 addr2line = { version = "0.21.0", optional = true, default-features = false }
+
+[target.'cfg(all(not(target_os = "aix"), not(all(windows, target_env = "msvc", not(target_vendor = "uwp")))))'.dependencies]
 object = { version = "0.32.0", default-features = false, optional = true, features = ['read_core', 'elf', 'macho', 'pe', 'unaligned', 'archive'] }
 
+[target.'cfg(target_os = "aix")'.dependencies]
+object = { version = "0.32.0", default-features = false, optional = true, features = ['read_core', 'xcoff', 'unaligned', 'archive'] }
+
 [dev-dependencies]
 rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
 rand_xorshift = "0.3.0"
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index d08f0b1c9d0..76081833e05 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -338,7 +338,6 @@
 #![feature(portable_simd)]
 #![feature(prelude_2024)]
 #![feature(ptr_as_uninit)]
-#![feature(ptr_from_ref)]
 #![feature(raw_os_nonzero)]
 #![feature(round_ties_even)]
 #![feature(slice_internals)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index 55f4917a937..66b4ec37c8e 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -588,7 +588,7 @@ pub fn panicking() -> bool {
 }
 
 /// Entry point of panics from the core crate (`panic_impl` lang item).
-#[cfg(not(test))]
+#[cfg(not(any(test, doctest)))]
 #[panic_handler]
 pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
     struct FormatStringPayload<'a> {
@@ -669,7 +669,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
 /// panic!() and assert!(). In particular, this is the only entry point that supports
 /// arbitrary payloads, not just format strings.
 #[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")]
-#[cfg_attr(not(test), lang = "begin_panic")]
+#[cfg_attr(not(any(test, doctest)), lang = "begin_panic")]
 // lang item for CTFE panic support
 // never inline unless panic_immediate_abort to avoid code
 // bloat at the call sites as much as possible
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 6004ed51bd1..4a7f5d8e0be 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -2311,7 +2311,7 @@ pub fn id() -> u32 {
 /// of the `main` function, this trait is likely to be available only on
 /// standard library's runtime for convenience. Other runtimes are not required
 /// to provide similar functionality.
-#[cfg_attr(not(test), lang = "termination")]
+#[cfg_attr(not(any(test, doctest)), lang = "termination")]
 #[stable(feature = "termination_trait_lib", since = "1.61.0")]
 #[rustc_on_unimplemented(on(
     cause = "MainFunctionType",
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index f1eeb75be7c..335944845ae 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -154,7 +154,7 @@ fn lang_start_internal(
     ret_code
 }
 
-#[cfg(not(test))]
+#[cfg(not(any(test, doctest)))]
 #[lang = "start"]
 fn lang_start<T: crate::process::Termination + 'static>(
     main: fn() -> T,
diff --git a/library/std/src/sys/personality/mod.rs b/library/std/src/sys/personality/mod.rs
index 0fff53f1887..d37b8ce6346 100644
--- a/library/std/src/sys/personality/mod.rs
+++ b/library/std/src/sys/personality/mod.rs
@@ -12,7 +12,7 @@
 
 mod dwarf;
 
-#[cfg(not(test))]
+#[cfg(not(any(test, doctest)))]
 cfg_if::cfg_if! {
     if #[cfg(target_os = "emscripten")] {
         mod emcc;
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 2328dd822af..fea194a80ef 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -616,22 +616,6 @@ class RustBuild(object):
             with output(self.rustc_stamp()) as rust_stamp:
                 rust_stamp.write(key)
 
-    def _download_component_helper(
-        self, filename, pattern, tarball_suffix, rustc_cache,
-    ):
-        key = self.stage0_compiler.date
-
-        tarball = os.path.join(rustc_cache, filename)
-        if not os.path.exists(tarball):
-            get(
-                self.download_url,
-                "dist/{}/{}".format(key, filename),
-                tarball,
-                self.checksums_sha256,
-                verbose=self.verbose,
-            )
-        unpack(tarball, tarball_suffix, self.bin_root(), match=pattern, verbose=self.verbose)
-
     def should_fix_bins_and_dylibs(self):
         """Whether or not `fix_bin_or_dylib` needs to be run; can only be True
         on NixOS or if config.toml has `build.patch-binaries-for-nix` set.
diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs
index 18136635c42..38c55b20344 100644
--- a/src/bootstrap/src/bin/rustc.rs
+++ b/src/bootstrap/src/bin/rustc.rs
@@ -16,11 +16,11 @@
 //! never get replaced.
 
 use std::env;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::process::{Child, Command};
 use std::time::Instant;
 
-use dylib_util::{dylib_path, dylib_path_var};
+use dylib_util::{dylib_path, dylib_path_var, exe};
 
 #[path = "../utils/bin_helpers.rs"]
 mod bin_helpers;
@@ -29,8 +29,10 @@ mod bin_helpers;
 mod dylib_util;
 
 fn main() {
-    let args = env::args_os().skip(1).collect::<Vec<_>>();
-    let arg = |name| args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str());
+    let orig_args = env::args_os().skip(1).collect::<Vec<_>>();
+    let mut args = orig_args.clone();
+    let arg =
+        |name| orig_args.windows(2).find(|args| args[0] == name).and_then(|args| args[1].to_str());
 
     let stage = bin_helpers::parse_rustc_stage();
     let verbose = bin_helpers::parse_rustc_verbose();
@@ -45,7 +47,8 @@ fn main() {
     // determine the version of the compiler, the real compiler needs to be
     // used. Currently, these two states are differentiated based on whether
     // --target and -vV is/isn't passed.
-    let (rustc, libdir) = if target.is_none() && version.is_none() {
+    let is_build_script = target.is_none() && version.is_none();
+    let (rustc, libdir) = if is_build_script {
         ("RUSTC_SNAPSHOT", "RUSTC_SNAPSHOT_LIBDIR")
     } else {
         ("RUSTC_REAL", "RUSTC_LIBDIR")
@@ -54,12 +57,47 @@ fn main() {
     let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");
     let on_fail = env::var_os("RUSTC_ON_FAIL").map(Command::new);
 
-    let rustc = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc));
+    let rustc_real = env::var_os(rustc).unwrap_or_else(|| panic!("{:?} was not set", rustc));
     let libdir = env::var_os(libdir).unwrap_or_else(|| panic!("{:?} was not set", libdir));
     let mut dylib_path = dylib_path();
     dylib_path.insert(0, PathBuf::from(&libdir));
 
-    let mut cmd = Command::new(rustc);
+    // if we're running clippy, trust cargo-clippy to set clippy-driver appropriately (and don't override it with rustc).
+    // otherwise, substitute whatever cargo thinks rustc should be with RUSTC_REAL.
+    // NOTE: this means we ignore RUSTC in the environment.
+    // FIXME: We might want to consider removing RUSTC_REAL and setting RUSTC directly?
+    // NOTE: we intentionally pass the name of the host, not the target.
+    let host = env::var("CFG_COMPILER_BUILD_TRIPLE").unwrap();
+    let is_clippy = args[0].to_string_lossy().ends_with(&exe("clippy-driver", &host));
+    let rustc_driver = if is_clippy {
+        if is_build_script {
+            // Don't run clippy on build scripts (for one thing, we may not have libstd built with
+            // the appropriate version yet, e.g. for stage 1 std).
+            // Also remove the `clippy-driver` param in addition to the RUSTC param.
+            args.drain(..2);
+            rustc_real
+        } else {
+            args.remove(0)
+        }
+    } else {
+        // Cargo doesn't respect RUSTC_WRAPPER for version information >:(
+        // don't remove the first arg if we're being run as RUSTC instead of RUSTC_WRAPPER.
+        // Cargo also sometimes doesn't pass the `.exe` suffix on Windows - add it manually.
+        let current_exe = env::current_exe().expect("couldn't get path to rustc shim");
+        let arg0 = exe(args[0].to_str().expect("only utf8 paths are supported"), &host);
+        if Path::new(&arg0) == current_exe {
+            args.remove(0);
+        }
+        rustc_real
+    };
+
+    let mut cmd = if let Some(wrapper) = env::var_os("RUSTC_WRAPPER_REAL") {
+        let mut cmd = Command::new(wrapper);
+        cmd.arg(rustc_driver);
+        cmd
+    } else {
+        Command::new(rustc_driver)
+    };
     cmd.args(&args).env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
 
     // Get the name of the crate we're compiling, if any.
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 11e789a996a..df4d1a43dab 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1809,10 +1809,6 @@ pub fn run_cargo(
     is_check: bool,
     rlib_only_metadata: bool,
 ) -> Vec<PathBuf> {
-    if builder.config.dry_run() {
-        return Vec::new();
-    }
-
     // `target_root_dir` looks like $dir/$target/release
     let target_root_dir = stamp.parent().unwrap();
     // `target_deps_dir` looks like $dir/$target/release/deps
@@ -1919,6 +1915,10 @@ pub fn run_cargo(
         crate::exit!(1);
     }
 
+    if builder.config.dry_run() {
+        return Vec::new();
+    }
+
     // Ok now we need to actually find all the files listed in `toplevel`. We've
     // got a list of prefix/extensions and we basically just need to find the
     // most recent file in the `deps` folder corresponding to each one.
@@ -1974,9 +1974,6 @@ pub fn stream_cargo(
     cb: &mut dyn FnMut(CargoMessage<'_>),
 ) -> bool {
     let mut cargo = Command::from(cargo);
-    if builder.config.dry_run() {
-        return true;
-    }
     // Instruct Cargo to give us json messages on stdout, critically leaving
     // stderr as piped so we can get those pretty colors.
     let mut message_format = if builder.config.json_output {
@@ -1995,6 +1992,11 @@ pub fn stream_cargo(
     }
 
     builder.verbose(&format!("running: {cargo:?}"));
+
+    if builder.config.dry_run() {
+        return true;
+    }
+
     let mut child = match cargo.spawn() {
         Ok(child) => child,
         Err(e) => panic!("failed to execute command: {cargo:?}\nERROR: {e}"),
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index 28761a7ee4b..e1809644350 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -1152,6 +1152,44 @@ impl<'a> Builder<'a> {
         self.ensure(tool::Rustdoc { compiler })
     }
 
+    pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> Command {
+        let initial_sysroot_bin = self.initial_rustc.parent().unwrap();
+        // Set PATH to include the sysroot bin dir so clippy can find cargo.
+        // FIXME: once rust-clippy#11944 lands on beta, set `CARGO` directly instead.
+        let path = t!(env::join_paths(
+            // The sysroot comes first in PATH to avoid using rustup's cargo.
+            std::iter::once(PathBuf::from(initial_sysroot_bin))
+                .chain(env::split_paths(&t!(env::var("PATH"))))
+        ));
+
+        if run_compiler.stage == 0 {
+            // `ensure(Clippy { stage: 0 })` *builds* clippy with stage0, it doesn't use the beta clippy.
+            let cargo_clippy = self.build.config.download_clippy();
+            let mut cmd = Command::new(cargo_clippy);
+            cmd.env("PATH", &path);
+            return cmd;
+        }
+
+        let build_compiler = self.compiler(run_compiler.stage - 1, self.build.build);
+        self.ensure(tool::Clippy {
+            compiler: build_compiler,
+            target: self.build.build,
+            extra_features: vec![],
+        });
+        let cargo_clippy = self.ensure(tool::CargoClippy {
+            compiler: build_compiler,
+            target: self.build.build,
+            extra_features: vec![],
+        });
+        let mut dylib_path = helpers::dylib_path();
+        dylib_path.insert(0, self.sysroot(run_compiler).join("lib"));
+
+        let mut cmd = Command::new(cargo_clippy.unwrap());
+        cmd.env(helpers::dylib_path_var(), env::join_paths(&dylib_path).unwrap());
+        cmd.env("PATH", path);
+        cmd
+    }
+
     pub fn rustdoc_cmd(&self, compiler: Compiler) -> Command {
         let mut cmd = Command::new(&self.bootstrap_out.join("rustdoc"));
         cmd.env("RUSTC_STAGE", compiler.stage.to_string())
@@ -1200,7 +1238,12 @@ impl<'a> Builder<'a> {
         target: TargetSelection,
         cmd: &str,
     ) -> Command {
-        let mut cargo = Command::new(&self.initial_cargo);
+        let mut cargo = if cmd == "clippy" {
+            self.cargo_clippy_cmd(compiler)
+        } else {
+            Command::new(&self.initial_cargo)
+        };
+
         // Run cargo from the source root so it can find .cargo/config.
         // This matters when using vendoring and the working directory is outside the repository.
         cargo.current_dir(&self.src);
@@ -1324,6 +1367,23 @@ impl<'a> Builder<'a> {
             compiler.stage
         };
 
+        // We synthetically interpret a stage0 compiler used to build tools as a
+        // "raw" compiler in that it's the exact snapshot we download. Normally
+        // the stage0 build means it uses libraries build by the stage0
+        // compiler, but for tools we just use the precompiled libraries that
+        // we've downloaded
+        let use_snapshot = mode == Mode::ToolBootstrap;
+        assert!(!use_snapshot || stage == 0 || self.local_rebuild);
+
+        let maybe_sysroot = self.sysroot(compiler);
+        let sysroot = if use_snapshot { self.rustc_snapshot_sysroot() } else { &maybe_sysroot };
+        let libdir = self.rustc_libdir(compiler);
+
+        let sysroot_str = sysroot.as_os_str().to_str().expect("sysroot should be UTF-8");
+        if !matches!(self.config.dry_run, DryRun::SelfCheck) {
+            self.verbose_than(0, &format!("using sysroot {sysroot_str}"));
+        }
+
         let mut rustflags = Rustflags::new(target);
         if stage != 0 {
             if let Ok(s) = env::var("CARGOFLAGS_NOT_BOOTSTRAP") {
@@ -1335,41 +1395,16 @@ impl<'a> Builder<'a> {
                 cargo.args(s.split_whitespace());
             }
             rustflags.env("RUSTFLAGS_BOOTSTRAP");
-            if cmd == "clippy" {
-                // clippy overwrites sysroot if we pass it to cargo.
-                // Pass it directly to clippy instead.
-                // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
-                // so it has no way of knowing the sysroot.
-                rustflags.arg("--sysroot");
-                rustflags.arg(
-                    self.sysroot(compiler)
-                        .as_os_str()
-                        .to_str()
-                        .expect("sysroot must be valid UTF-8"),
-                );
-                // Only run clippy on a very limited subset of crates (in particular, not build scripts).
-                cargo.arg("-Zunstable-options");
-                // Explicitly does *not* set `--cfg=bootstrap`, since we're using a nightly clippy.
-                let host_version = Command::new("rustc").arg("--version").output().map_err(|_| ());
-                let output = host_version.and_then(|output| {
-                    if output.status.success() {
-                        Ok(output)
-                    } else {
-                        Err(())
-                    }
-                }).unwrap_or_else(|_| {
-                    eprintln!(
-                        "ERROR: `x.py clippy` requires a host `rustc` toolchain with the `clippy` component"
-                    );
-                    eprintln!("HELP: try `rustup component add clippy`");
-                    crate::exit!(1);
-                });
-                if !t!(std::str::from_utf8(&output.stdout)).contains("nightly") {
-                    rustflags.arg("--cfg=bootstrap");
-                }
-            } else {
-                rustflags.arg("--cfg=bootstrap");
-            }
+            rustflags.arg("--cfg=bootstrap");
+        }
+
+        if cmd == "clippy" {
+            // clippy overwrites sysroot if we pass it to cargo.
+            // Pass it directly to clippy instead.
+            // NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
+            // so it has no way of knowing the sysroot.
+            rustflags.arg("--sysroot");
+            rustflags.arg(sysroot_str);
         }
 
         let use_new_symbol_mangling = match self.config.rust_new_symbol_mangling {
@@ -1564,18 +1599,6 @@ impl<'a> Builder<'a> {
 
         let want_rustdoc = self.doc_tests != DocTests::No;
 
-        // We synthetically interpret a stage0 compiler used to build tools as a
-        // "raw" compiler in that it's the exact snapshot we download. Normally
-        // the stage0 build means it uses libraries build by the stage0
-        // compiler, but for tools we just use the precompiled libraries that
-        // we've downloaded
-        let use_snapshot = mode == Mode::ToolBootstrap;
-        assert!(!use_snapshot || stage == 0 || self.local_rebuild);
-
-        let maybe_sysroot = self.sysroot(compiler);
-        let sysroot = if use_snapshot { self.rustc_snapshot_sysroot() } else { &maybe_sysroot };
-        let libdir = self.rustc_libdir(compiler);
-
         // Clear the output directory if the real rustc we're using has changed;
         // Cargo cannot detect this as it thinks rustc is bootstrap/debug/rustc.
         //
@@ -1611,10 +1634,19 @@ impl<'a> Builder<'a> {
             )
             .env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir())
             .env("RUSTC_BREAK_ON_ICE", "1");
-        // Clippy support is a hack and uses the default `cargo-clippy` in path.
-        // Don't override RUSTC so that the `cargo-clippy` in path will be run.
-        if cmd != "clippy" {
-            cargo.env("RUSTC", self.bootstrap_out.join("rustc"));
+
+        // Set RUSTC_WRAPPER to the bootstrap shim, which switches between beta and in-tree
+        // sysroot depending on whether we're building build scripts.
+        // NOTE: we intentionally use RUSTC_WRAPPER so that we can support clippy - RUSTC is not
+        // respected by clippy-driver; RUSTC_WRAPPER happens earlier, before clippy runs.
+        cargo.env("RUSTC_WRAPPER", self.bootstrap_out.join("rustc"));
+        // NOTE: we also need to set RUSTC so cargo can run `rustc -vV`; apparently that ignores RUSTC_WRAPPER >:(
+        cargo.env("RUSTC", self.bootstrap_out.join("rustc"));
+
+        // Someone might have set some previous rustc wrapper (e.g.
+        // sccache) before bootstrap overrode it. Respect that variable.
+        if let Some(existing_wrapper) = env::var_os("RUSTC_WRAPPER") {
+            cargo.env("RUSTC_WRAPPER_REAL", existing_wrapper);
         }
 
         // Dealing with rpath here is a little special, so let's go into some
@@ -1991,7 +2023,11 @@ impl<'a> Builder<'a> {
         // Environment variables *required* throughout the build
         //
         // FIXME: should update code to not require this env var
+
+        // The host this new compiler will *run* on.
         cargo.env("CFG_COMPILER_HOST_TRIPLE", target.triple);
+        // The host this new compiler is being *built* on.
+        cargo.env("CFG_COMPILER_BUILD_TRIPLE", compiler.host.triple);
 
         // Set this for all builds to make sure doc builds also get it.
         cargo.env("CFG_RELEASE_CHANNEL", &self.config.channel);
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 0a5844a6859..1f2ee6a6b73 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -208,7 +208,10 @@ impl Config {
             Some(other) => panic!("unsupported protocol {other} in {url}"),
             None => panic!("no protocol in {url}"),
         }
-        t!(std::fs::rename(&tempfile, dest_path));
+        t!(
+            std::fs::rename(&tempfile, dest_path),
+            format!("failed to rename {tempfile:?} to {dest_path:?}")
+        );
     }
 
     fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
@@ -375,6 +378,32 @@ enum DownloadSource {
 
 /// Functions that are only ever called once, but named for clarify and to avoid thousand-line functions.
 impl Config {
+    pub(crate) fn download_clippy(&self) -> PathBuf {
+        self.verbose("downloading stage0 clippy artifacts");
+
+        let date = &self.stage0_metadata.compiler.date;
+        let version = &self.stage0_metadata.compiler.version;
+        let host = self.build;
+
+        let bin_root = self.out.join(host.triple).join("stage0");
+        let clippy_stamp = bin_root.join(".clippy-stamp");
+        let cargo_clippy = bin_root.join("bin").join(exe("cargo-clippy", host));
+        if cargo_clippy.exists() && !program_out_of_date(&clippy_stamp, &date) {
+            return cargo_clippy;
+        }
+
+        let filename = format!("clippy-{version}-{host}.tar.xz");
+        self.download_component(DownloadSource::Dist, filename, "clippy-preview", date, "stage0");
+        if self.should_fix_bins_and_dylibs() {
+            self.fix_bin_or_dylib(&cargo_clippy);
+            self.fix_bin_or_dylib(&cargo_clippy.with_file_name(exe("clippy-driver", host)));
+        }
+
+        cargo_clippy
+    }
+
+    /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't
+    /// reuse target directories or artifacts
     pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> {
         let RustfmtMetadata { date, version } = self.stage0_metadata.rustfmt.as_ref()?;
         let channel = format!("{version}-{date}");
@@ -544,6 +573,10 @@ impl Config {
         key: &str,
         destination: &str,
     ) {
+        if self.dry_run() {
+            return;
+        }
+
         let cache_dst = self.out.join("cache");
         let cache_dir = cache_dst.join(key);
         if !cache_dir.exists() {
diff --git a/src/bootstrap/src/utils/dylib.rs b/src/bootstrap/src/utils/dylib.rs
index 279a6a010f1..b6e7aec1756 100644
--- a/src/bootstrap/src/utils/dylib.rs
+++ b/src/bootstrap/src/utils/dylib.rs
@@ -25,3 +25,16 @@ pub fn dylib_path() -> Vec<std::path::PathBuf> {
     };
     std::env::split_paths(&var).collect()
 }
+
+/// Given an executable called `name`, return the filename for the
+/// executable for a particular target.
+#[allow(dead_code)]
+pub fn exe(name: &str, target: &str) -> String {
+    if target.contains("windows") {
+        format!("{name}.exe")
+    } else if target.contains("uefi") {
+        format!("{name}.efi")
+    } else {
+        name.to_string()
+    }
+}
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index d96608db22c..031d56beb67 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -46,16 +46,8 @@ macro_rules! t {
 }
 pub use t;
 
-/// Given an executable called `name`, return the filename for the
-/// executable for a particular target.
 pub fn exe(name: &str, target: TargetSelection) -> String {
-    if target.is_windows() {
-        format!("{name}.exe")
-    } else if target.contains("uefi") {
-        format!("{name}.efi")
-    } else {
-        name.to_string()
-    }
+    crate::utils::dylib::exe(name, &target.triple)
 }
 
 /// Returns `true` if the file name given looks like a dynamic library.
diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
index 82d37f0f633..f8fcda5070f 100644
--- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile
+++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile
@@ -39,8 +39,14 @@ COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
 COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/
 
 ENV RUN_CHECK_WITH_PARALLEL_QUERIES 1
+
+# Run clippy just to make sure it doesn't error out; we don't actually want to gate on the warnings
+# though.
+# Ideally we'd use stage 1, but that ICEs: https://github.com/rust-lang/rust-clippy/issues/11230
+
 ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \
            python3 ../x.py check --target=i686-pc-windows-gnu --host=i686-pc-windows-gnu && \
+           python3 ../x.py clippy --stage 0 -Awarnings && \
            python3 ../x.py build --stage 0 src/tools/build-manifest && \
            python3 ../x.py test --stage 0 src/tools/compiletest && \
            python3 ../x.py test --stage 0 core alloc std test proc_macro && \
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 6631c427270..828e7f959b4 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -184,22 +184,6 @@ fn clean_generic_bound<'tcx>(
 ) -> Option<GenericBound> {
     Some(match *bound {
         hir::GenericBound::Outlives(lt) => GenericBound::Outlives(clean_lifetime(lt, cx)),
-        hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
-            let def_id = cx.tcx.require_lang_item(lang_item, Some(span));
-
-            let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(cx.tcx, def_id));
-
-            let generic_args = clean_generic_args(generic_args, cx);
-            let GenericArgs::AngleBracketed { bindings, .. } = generic_args else {
-                bug!("clean: parenthesized `GenericBound::LangItemTrait`");
-            };
-
-            let trait_ = clean_trait_ref_with_bindings(cx, trait_ref, bindings);
-            GenericBound::TraitBound(
-                PolyTrait { trait_, generic_params: vec![] },
-                hir::TraitBoundModifier::None,
-            )
-        }
         hir::GenericBound::Trait(ref t, modifier) => {
             // `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
             if modifier == hir::TraitBoundModifier::MaybeConst
@@ -743,7 +727,7 @@ pub(crate) fn clean_generics<'tcx>(
                     .into_iter()
                     .map(|(lifetime, bounds)| WherePredicate::RegionPredicate { lifetime, bounds }),
             )
-            .chain(eq_predicates.into_iter())
+            .chain(eq_predicates)
             .collect(),
     }
 }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 8215926ee33..0150496990d 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -380,7 +380,9 @@ pub(crate) fn run_global_ctxt(
             crate::lint::MISSING_CRATE_LEVEL_DOCS,
             DocContext::as_local_hir_id(tcx, krate.module.item_id).unwrap(),
             "no documentation found for this crate's top-level module",
-            |lint| lint.help(help),
+            |lint| {
+                lint.help(help);
+            },
         );
     }
 
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index dbd78ea0dc9..642265f5f6b 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -835,7 +835,7 @@ impl<'tcx> ExtraInfo<'tcx> {
                 self.tcx.local_def_id_to_hir_id(def_id),
                 self.sp,
                 msg,
-                |l| l,
+                |_| {},
             );
         }
     }
@@ -843,9 +843,7 @@ impl<'tcx> ExtraInfo<'tcx> {
     fn error_invalid_codeblock_attr_with_help(
         &self,
         msg: impl Into<DiagnosticMessage>,
-        f: impl for<'a, 'b> FnOnce(
-            &'b mut DiagnosticBuilder<'a, ()>,
-        ) -> &'b mut DiagnosticBuilder<'a, ()>,
+        f: impl for<'a, 'b> FnOnce(&'b mut DiagnosticBuilder<'a, ()>),
     ) {
         if let Some(def_id) = self.def_id.as_local() {
             self.tcx.struct_span_lint_hir(
@@ -1296,7 +1294,7 @@ impl LangString {
                                     lint.help(format!(
                                         "there is an attribute with a similar name: `edition{}`",
                                         &x[4..],
-                                    ))
+                                    ));
                                 },
                             );
                         }
@@ -1350,7 +1348,7 @@ impl LangString {
                                         lint.help(format!(
                                             "there is an attribute with a similar name: `{flag}`"
                                         ))
-                                        .help(help)
+                                        .help(help);
                                     },
                                 );
                             }
@@ -1383,7 +1381,7 @@ impl LangString {
         };
 
         if custom_code_classes_in_docs {
-            call(&mut TagIterator::new(string, extra).into_iter())
+            call(&mut TagIterator::new(string, extra))
         } else {
             call(&mut tokens(string))
         }
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index c4a6e920031..6408e97df50 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -328,8 +328,8 @@ pub(super) fn write_shared(
         v.push_str(
             r#"\
 ]'));
-if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)};
-if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex};
+if (typeof exports !== 'undefined') exports.searchIndex = searchIndex;
+else if (window.initSearch) window.initSearch(searchIndex);
 "#,
         );
         Ok(v.into_bytes())
diff --git a/src/librustdoc/html/static/js/src-script.js b/src/librustdoc/html/static/js/src-script.js
index bbb0527a833..fc1d2d37845 100644
--- a/src/librustdoc/html/static/js/src-script.js
+++ b/src/librustdoc/html/static/js/src-script.js
@@ -146,12 +146,8 @@ function createSrcSidebar() {
     }
 }
 
-const lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/;
-
-function highlightSrcLines(match) {
-    if (typeof match === "undefined") {
-        match = window.location.hash.match(lineNumbersRegex);
-    }
+function highlightSrcLines() {
+    const match = window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);
     if (!match) {
         return;
     }
@@ -233,12 +229,7 @@ const handleSrcHighlight = (function() {
     };
 }());
 
-window.addEventListener("hashchange", () => {
-    const match = window.location.hash.match(lineNumbersRegex);
-    if (match) {
-        return highlightSrcLines(match);
-    }
-});
+window.addEventListener("hashchange", highlightSrcLines);
 
 onEachLazy(document.getElementsByClassName("src-line-numbers"), el => {
     el.addEventListener("click", handleSrcHighlight);
diff --git a/src/librustdoc/lint.rs b/src/librustdoc/lint.rs
index d45040e348a..267f1cb0b72 100644
--- a/src/librustdoc/lint.rs
+++ b/src/librustdoc/lint.rs
@@ -33,7 +33,7 @@ where
     let lints = || {
         lint::builtin::HardwiredLints::get_lints()
             .into_iter()
-            .chain(rustc_lint::SoftLints::get_lints().into_iter())
+            .chain(rustc_lint::SoftLints::get_lints())
     };
 
     let lint_opts = lints()
@@ -46,7 +46,7 @@ where
                 filter_call(lint)
             }
         })
-        .chain(lint_opts.into_iter())
+        .chain(lint_opts)
         .collect::<Vec<_>>();
 
     let lint_caps = lints()
diff --git a/src/librustdoc/passes/check_custom_code_classes.rs b/src/librustdoc/passes/check_custom_code_classes.rs
index 6266d3ff51d..f246e2962fe 100644
--- a/src/librustdoc/passes/check_custom_code_classes.rs
+++ b/src/librustdoc/passes/check_custom_code_classes.rs
@@ -48,7 +48,7 @@ struct TestsWithCustomClasses {
 
 impl crate::doctest::Tester for TestsWithCustomClasses {
     fn add_test(&mut self, _: String, config: LangString, _: usize) {
-        self.custom_classes_found.extend(config.added_classes.into_iter());
+        self.custom_classes_found.extend(config.added_classes);
     }
 }
 
diff --git a/src/librustdoc/passes/check_doc_test_visibility.rs b/src/librustdoc/passes/check_doc_test_visibility.rs
index 8d5b17f43cd..a931e8804d9 100644
--- a/src/librustdoc/passes/check_doc_test_visibility.rs
+++ b/src/librustdoc/passes/check_doc_test_visibility.rs
@@ -131,7 +131,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
                 hir_id,
                 sp,
                 "missing code example in this documentation",
-                |lint| lint,
+                |_| {},
             );
         }
     } else if tests.found_tests > 0
@@ -142,7 +142,7 @@ pub(crate) fn look_for_tests<'tcx>(cx: &DocContext<'tcx>, dox: &str, item: &Item
             hir_id,
             item.attr_span(cx.tcx),
             "documentation test in private item",
-            |lint| lint,
+            |_| {},
         );
     }
 }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 6b536e97c43..ee185ab9892 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1755,8 +1755,6 @@ fn report_diagnostic(
         }
 
         decorate(lint, span, link_range);
-
-        lint
     });
 }
 
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
index 0c5cfffe1be..bffa17da3b4 100644
--- a/src/librustdoc/passes/lint/bare_urls.rs
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -31,7 +31,7 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) {
                             "use an automatic link instead",
                             format!("<{url}>"),
                             Applicability::MachineApplicable,
-                        )
+                        );
                 });
             };
 
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index e9b9e36a530..b5583ae4520 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -131,8 +131,6 @@ fn check_rust_syntax(
         for message in buffer.messages.iter() {
             lint.note(message.clone());
         }
-
-        lint
     });
 }
 
diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs
index 4a80c22ed08..90874c01102 100644
--- a/src/librustdoc/passes/lint/html_tags.rs
+++ b/src/librustdoc/passes/lint/html_tags.rs
@@ -89,7 +89,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
                     if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
                         || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
                     {
-                        return lint;
+                        return;
                     }
                     // multipart form is chosen here because ``Vec<i32>`` would be confusing.
                     lint.multipart_suggestion(
@@ -101,8 +101,6 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
                         Applicability::MaybeIncorrect,
                     );
                 }
-
-                lint
             });
         };
 
diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs
index 472781e7d22..4491d20b478 100644
--- a/src/librustdoc/passes/lint/redundant_explicit_links.rs
+++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs
@@ -181,8 +181,6 @@ fn check_inline_or_reference_unknown_redundancy(
                 .span_label(display_span, "because label contains path that resolves to same destination")
                 .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links")
                 .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways);
-
-            lint
         });
     }
 
@@ -234,8 +232,6 @@ fn check_reference_redundancy(
                 .span_note(def_span, "referenced explicit link target defined here")
                 .note("when a link's destination is not specified,\nthe label is used to resolve intra-doc links")
                 .span_suggestion_with_style(link_span, "remove explicit link target", format!("[{}]", link_data.display_link), Applicability::MaybeIncorrect, SuggestionStyle::ShowAlways);
-
-            lint
         });
     }
 
diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs
index 8b7fdd6ab1f..0893cd0b40b 100644
--- a/src/librustdoc/passes/lint/unescaped_backticks.rs
+++ b/src/librustdoc/passes/lint/unescaped_backticks.rs
@@ -111,8 +111,6 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
                     }
 
                     suggest_insertion(cx, item, &dox, lint, backtick_index, '\\', "if you meant to use a literal backtick, escape it");
-
-                    lint
                 });
             }
             Event::Code(_) => {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index bbc7e5b48d1..42ff1210f23 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -168,10 +168,11 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     })
                     .collect::<Vec<_>>()
             })
-            .chain(
-                [Cfg::Cfg(sym::test, None), Cfg::Cfg(sym::doc, None), Cfg::Cfg(sym::doctest, None)]
-                    .into_iter(),
-            )
+            .chain([
+                Cfg::Cfg(sym::test, None),
+                Cfg::Cfg(sym::doc, None),
+                Cfg::Cfg(sym::doctest, None),
+            ])
             .collect();
 
         self.cx.cache.exact_paths = self.exact_paths;
diff --git a/src/stage0.json b/src/stage0.json
index 3fb6a0d4ed0..5625e7219f8 100644
--- a/src/stage0.json
+++ b/src/stage0.json
@@ -74,6 +74,54 @@
     "dist/2023-11-13/cargo-beta-x86_64-unknown-linux-musl.tar.xz": "790a859eaf49da5fdef1ea1ebf8b7f1f001bdaa62798a745d791bc915d886094",
     "dist/2023-11-13/cargo-beta-x86_64-unknown-netbsd.tar.gz": "f14395b57c0eca7c8ac9012b303c3781e16a2287698f68705fcbbc5c7c5916c9",
     "dist/2023-11-13/cargo-beta-x86_64-unknown-netbsd.tar.xz": "2c759c8bfc9cc556eb3464ac7e5589b573c46bd3938ac288ba52549121d3333d",
+    "dist/2023-11-13/clippy-beta-aarch64-apple-darwin.tar.gz": "258b55f0db78c93f14952fc3e2d9fc49f1121de5268ec49d03d4f197bd7c9773",
+    "dist/2023-11-13/clippy-beta-aarch64-apple-darwin.tar.xz": "554bd9488a9887c4acfb7c24775365108aef049feb15c93926128f805183f5e1",
+    "dist/2023-11-13/clippy-beta-aarch64-pc-windows-msvc.tar.gz": "d120adaec65b5f44f40fba38fa10a0cda33769756ac7fc2878d64154acc7e06c",
+    "dist/2023-11-13/clippy-beta-aarch64-pc-windows-msvc.tar.xz": "1dd23152a87fb8fa60569c304a3bbfd93f97c52d533fe53c8d9a5a4a72912938",
+    "dist/2023-11-13/clippy-beta-aarch64-unknown-linux-gnu.tar.gz": "41198264d015ccf624e0fca876bee16f8c3cbb07596f5f4d4f271b9843b10e30",
+    "dist/2023-11-13/clippy-beta-aarch64-unknown-linux-gnu.tar.xz": "1c889aad06c73dd2212403ff2aa5f256eba490cb8f1c81d7c75199a267052648",
+    "dist/2023-11-13/clippy-beta-aarch64-unknown-linux-musl.tar.gz": "db784d117c156d0e8854518a5df6e9adbf0b2d24f3504358b1a371b8e7954eef",
+    "dist/2023-11-13/clippy-beta-aarch64-unknown-linux-musl.tar.xz": "a946d40d32be1c5477f1740648e18af5792ceed38fe255e8cf09160acb27d02f",
+    "dist/2023-11-13/clippy-beta-arm-unknown-linux-gnueabi.tar.gz": "1b760fadecb9f4c4c1780b36d9bd651fa6c8a8fb6b48dc0dfbfb2ecd9359ca92",
+    "dist/2023-11-13/clippy-beta-arm-unknown-linux-gnueabi.tar.xz": "9e21f778eee57b067f411faa15425317158abd22f7c60dd4fc24214536ff7415",
+    "dist/2023-11-13/clippy-beta-arm-unknown-linux-gnueabihf.tar.gz": "fbe3d7776b9353782d2690ff1c98a0ce5d8d23de2381ecd3d4eff4ce165b66d5",
+    "dist/2023-11-13/clippy-beta-arm-unknown-linux-gnueabihf.tar.xz": "bfabf9e2419065173bf709166b0c81db66e1b2514003b28d08ec4410e04525a3",
+    "dist/2023-11-13/clippy-beta-armv7-unknown-linux-gnueabihf.tar.gz": "5371c798687aece2b98e22cf5bca02e568913011393a86a1aa3b0ff79eeabb57",
+    "dist/2023-11-13/clippy-beta-armv7-unknown-linux-gnueabihf.tar.xz": "82723066f2ec52fb5854a397f71df79db54976f4c03113034627c1a5c92ceffb",
+    "dist/2023-11-13/clippy-beta-i686-pc-windows-gnu.tar.gz": "0214eee5dc37f3a780ca62f1e7a66c5e19d583542dbfca047e383dfacca604b3",
+    "dist/2023-11-13/clippy-beta-i686-pc-windows-gnu.tar.xz": "cee7d7039b1ee909fa4a188d7fd0bae14d718bad98209d8df2dc087cc28d7a9c",
+    "dist/2023-11-13/clippy-beta-i686-pc-windows-msvc.tar.gz": "b6f1042f0d4652e941d975af8aeb4a61e335c585c1cd6dad7f85ba5b03c6face",
+    "dist/2023-11-13/clippy-beta-i686-pc-windows-msvc.tar.xz": "a31c1951abdff06c3709472acede08cd000b940a7a65f9afd664ca276fc724c1",
+    "dist/2023-11-13/clippy-beta-i686-unknown-linux-gnu.tar.gz": "1e0f2f2ea38988cd0012ceedacfa9828b4b6c6dfd3dca9eee5a98483fd90f439",
+    "dist/2023-11-13/clippy-beta-i686-unknown-linux-gnu.tar.xz": "f19b56068a40af2aee7c828a4688289a8142f98a81b80d66d12ddc6725209628",
+    "dist/2023-11-13/clippy-beta-loongarch64-unknown-linux-gnu.tar.gz": "e0f02e3ba303bef68a7cd1ea5effaa126eedbdc892b01dac85f4b3e6d4b2f522",
+    "dist/2023-11-13/clippy-beta-loongarch64-unknown-linux-gnu.tar.xz": "17a01e484f238bff790ad6cfededa8d9c7df0f6f36af336a1e8a7414a43271f5",
+    "dist/2023-11-13/clippy-beta-powerpc-unknown-linux-gnu.tar.gz": "ea4bc3aed8739bcecaa97f01972bbbba45e838c811ca0c408824b1409f9ac7c6",
+    "dist/2023-11-13/clippy-beta-powerpc-unknown-linux-gnu.tar.xz": "9ddb71b1f35f6953aedc6a1f93dde4a9b014255b5bd7d4448e4dd9b1a65c7f5a",
+    "dist/2023-11-13/clippy-beta-powerpc64-unknown-linux-gnu.tar.gz": "ccb95c3ce3dd4ee2776201ce1bd79122e97916c555126393f1839d301824e746",
+    "dist/2023-11-13/clippy-beta-powerpc64-unknown-linux-gnu.tar.xz": "9aad65fcefe5789670bc85cd177bd72eac469eb0a33db54685132a7ce5115a83",
+    "dist/2023-11-13/clippy-beta-powerpc64le-unknown-linux-gnu.tar.gz": "eb50e6349423c963fdce3193f361572a47e4d7fe5b90f8a297471c0a5df31feb",
+    "dist/2023-11-13/clippy-beta-powerpc64le-unknown-linux-gnu.tar.xz": "aa72d573b344953b9224ceb6eff484b6f012febfc009bc7773d398a3ffa69ea0",
+    "dist/2023-11-13/clippy-beta-riscv64gc-unknown-linux-gnu.tar.gz": "8546ac9a9e5081384d7ef889254e41998f60c04bbdca319128039e8a4e7cbc68",
+    "dist/2023-11-13/clippy-beta-riscv64gc-unknown-linux-gnu.tar.xz": "15fa574f7f7de2d8fcd124f44b1880a78bdd6a2ba77fe6b392299dd746ea9c63",
+    "dist/2023-11-13/clippy-beta-s390x-unknown-linux-gnu.tar.gz": "ee27937b85c142ebf46bb59ad9e113414cc9d631179a2f8df2b32980aa57b515",
+    "dist/2023-11-13/clippy-beta-s390x-unknown-linux-gnu.tar.xz": "e6e99e486418cb23a0cb80a2b145413bfeb62746b60fd9a0ff3959424b7ee07e",
+    "dist/2023-11-13/clippy-beta-x86_64-apple-darwin.tar.gz": "8a37545cef25abdd3c722a21385b843cb9d8d06fed8f302880beecbcb9373f98",
+    "dist/2023-11-13/clippy-beta-x86_64-apple-darwin.tar.xz": "f572586fc28bb5b2b77464d89b41c374de4002b453c297a8fc1468cee10db972",
+    "dist/2023-11-13/clippy-beta-x86_64-pc-windows-gnu.tar.gz": "5add2dab913488a482be6849887d9fa8c3cd197d3c423595a7133b511efcefca",
+    "dist/2023-11-13/clippy-beta-x86_64-pc-windows-gnu.tar.xz": "1d0d97a6b8703166616b6ae56d2b344e85dfa1db36976585d21cda65362cfff8",
+    "dist/2023-11-13/clippy-beta-x86_64-pc-windows-msvc.tar.gz": "4069dc9296cdc54af7e14d4ba5fc12ee5e6445be74f39c39526e4ed77378112f",
+    "dist/2023-11-13/clippy-beta-x86_64-pc-windows-msvc.tar.xz": "fdf4dfaef5f8fb24075bf8b24bdbd71804a49acda40921de84c61bc2250ade6c",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-freebsd.tar.gz": "4554eee1b1bd7e5575eaf5e7a815686da88fb395a80084c7a0fad3f338ac83b1",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-freebsd.tar.xz": "b0f1718df2a1e88ff4aa239bf4b9dc7a971fbc64cfa1ef8f399760fe09117097",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-illumos.tar.gz": "035400e01edb1a91ddcac72fe3ca1ea94465c4fe9047546d057f6867d8b068d1",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-illumos.tar.xz": "3ad1b06c3bc1e327ea7a3b30908b48bf6b59b7222101e5a30fb054b1be579087",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-linux-gnu.tar.gz": "88d611c40a30922515d09425ecd1a8b87f46131ab61f3c4bf841a41f281134b3",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-linux-gnu.tar.xz": "9908227c8a684aa5c24f3272997fc9688044580f792375ec9fc8f775e394953f",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-linux-musl.tar.gz": "10a7b2427ee8a4e83d271023e6bd00573266f317789cff3b75e68d7bddc41cbc",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-linux-musl.tar.xz": "cb1f3c2be55e11920340344d2f2f796098b7f13c9ddd2fb8a38ac1b29c5d6925",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-netbsd.tar.gz": "2b29461b085f0af1bb50d10ef8bf6448550c9b5867a364da3d921daea8e0a13d",
+    "dist/2023-11-13/clippy-beta-x86_64-unknown-netbsd.tar.xz": "e9d2ff4c8c63a9cfb7d8b12df4942f5b90c33c4fa3f755bbdc3c5df1b2b877fe",
     "dist/2023-11-13/rust-std-beta-aarch64-apple-darwin.tar.gz": "818e3554a6bd82c3533e68f8597c09563af1dc08d6b23bbd2323b8ebcce251f6",
     "dist/2023-11-13/rust-std-beta-aarch64-apple-darwin.tar.xz": "6f9333c281859e40b1c1c20e9f07ac1633ca2c99e86268b521945b8ed6cf6a50",
     "dist/2023-11-13/rust-std-beta-aarch64-apple-ios-sim.tar.gz": "fa4bb7a5d4dcecb2dfd8596e3ad442a5fe05468c939de3b36e44a43e10ea9d30",
diff --git a/src/tools/bump-stage0/src/main.rs b/src/tools/bump-stage0/src/main.rs
index b007f9a22c3..bd97b4eaa3e 100644
--- a/src/tools/bump-stage0/src/main.rs
+++ b/src/tools/bump-stage0/src/main.rs
@@ -4,7 +4,7 @@ use indexmap::IndexMap;
 use std::collections::HashMap;
 
 const PATH: &str = "src/stage0.json";
-const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo"];
+const COMPILER_COMPONENTS: &[&str] = &["rustc", "rust-std", "cargo", "clippy-preview"];
 const RUSTFMT_COMPONENTS: &[&str] = &["rustfmt-preview", "rustc"];
 
 struct Tool {
diff --git a/src/tools/clippy/.github/workflows/clippy_bors.yml b/src/tools/clippy/.github/workflows/clippy_bors.yml
index f67233dec62..73c25550742 100644
--- a/src/tools/clippy/.github/workflows/clippy_bors.yml
+++ b/src/tools/clippy/.github/workflows/clippy_bors.yml
@@ -206,6 +206,7 @@ jobs:
       max-parallel: 6
       matrix:
         integration:
+        - 'matthiaskrgr/clippy_ci_panic_test'
         - 'rust-lang/cargo'
         - 'rust-lang/chalk'
         - 'rust-lang/rustfmt'
@@ -220,7 +221,6 @@ jobs:
         - 'rust-itertools/itertools'
         - 'rust-lang-nursery/failure'
         - 'rust-lang/log'
-        - 'matthiaskrgr/clippy_ci_panic_test'
 
     runs-on: ubuntu-latest
 
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 2e9b755caa0..70aff7f60e0 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -4946,6 +4946,7 @@ Released 2018-09-13
 [`blanket_clippy_restriction_lints`]: https://rust-lang.github.io/rust-clippy/master/index.html#blanket_clippy_restriction_lints
 [`block_in_if_condition_expr`]: https://rust-lang.github.io/rust-clippy/master/index.html#block_in_if_condition_expr
 [`block_in_if_condition_stmt`]: https://rust-lang.github.io/rust-clippy/master/index.html#block_in_if_condition_stmt
+[`blocks_in_conditions`]: https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_conditions
 [`blocks_in_if_conditions`]: https://rust-lang.github.io/rust-clippy/master/index.html#blocks_in_if_conditions
 [`bool_assert_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_assert_comparison
 [`bool_comparison`]: https://rust-lang.github.io/rust-clippy/master/index.html#bool_comparison
@@ -5145,9 +5146,11 @@ Released 2018-09-13
 [`index_refutable_slice`]: https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice
 [`indexing_slicing`]: https://rust-lang.github.io/rust-clippy/master/index.html#indexing_slicing
 [`ineffective_bit_mask`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_bit_mask
+[`ineffective_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#ineffective_open_options
 [`inefficient_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inefficient_to_string
 [`infallible_destructuring_match`]: https://rust-lang.github.io/rust-clippy/master/index.html#infallible_destructuring_match
 [`infinite_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#infinite_iter
+[`infinite_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#infinite_loop
 [`inherent_to_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string
 [`inherent_to_string_shadow_display`]: https://rust-lang.github.io/rust-clippy/master/index.html#inherent_to_string_shadow_display
 [`init_numbered_fields`]: https://rust-lang.github.io/rust-clippy/master/index.html#init_numbered_fields
@@ -5462,6 +5465,7 @@ Released 2018-09-13
 [`ref_patterns`]: https://rust-lang.github.io/rust-clippy/master/index.html#ref_patterns
 [`regex_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#regex_macro
 [`repeat_once`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_once
+[`repeat_vec_with_capacity`]: https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity
 [`replace_consts`]: https://rust-lang.github.io/rust-clippy/master/index.html#replace_consts
 [`reserve_after_initialization`]: https://rust-lang.github.io/rust-clippy/master/index.html#reserve_after_initialization
 [`rest_pat_in_fully_bound_structs`]: https://rust-lang.github.io/rust-clippy/master/index.html#rest_pat_in_fully_bound_structs
@@ -5582,6 +5586,7 @@ Released 2018-09-13
 [`undropped_manually_drops`]: https://rust-lang.github.io/rust-clippy/master/index.html#undropped_manually_drops
 [`unicode_not_nfc`]: https://rust-lang.github.io/rust-clippy/master/index.html#unicode_not_nfc
 [`unimplemented`]: https://rust-lang.github.io/rust-clippy/master/index.html#unimplemented
+[`uninhabited_references`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninhabited_references
 [`uninit_assumed_init`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_assumed_init
 [`uninit_vec`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninit_vec
 [`uninlined_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
diff --git a/src/tools/clippy/clippy_dev/src/lint.rs b/src/tools/clippy/clippy_dev/src/lint.rs
index a19be1bca6c..906a9727810 100644
--- a/src/tools/clippy/clippy_dev/src/lint.rs
+++ b/src/tools/clippy/clippy_dev/src/lint.rs
@@ -1,6 +1,6 @@
 use crate::{cargo_clippy_path, exit_if_err};
-use std::fs;
 use std::process::{self, Command};
+use std::{env, fs};
 
 pub fn run<'a>(path: &str, args: impl Iterator<Item = &'a String>) {
     let is_file = match fs::metadata(path) {
@@ -13,7 +13,7 @@ pub fn run<'a>(path: &str, args: impl Iterator<Item = &'a String>) {
 
     if is_file {
         exit_if_err(
-            Command::new("cargo")
+            Command::new(env::var("CARGO").unwrap_or("cargo".into()))
                 .args(["run", "--bin", "clippy-driver", "--"])
                 .args(["-L", "./target/debug"])
                 .args(["-Z", "no-codegen"])
@@ -23,7 +23,11 @@ pub fn run<'a>(path: &str, args: impl Iterator<Item = &'a String>) {
                 .status(),
         );
     } else {
-        exit_if_err(Command::new("cargo").arg("build").status());
+        exit_if_err(
+            Command::new(env::var("CARGO").unwrap_or("cargo".into()))
+                .arg("build")
+                .status(),
+        );
 
         let status = Command::new(cargo_clippy_path())
             .arg("clippy")
diff --git a/src/tools/clippy/clippy_dev/src/serve.rs b/src/tools/clippy/clippy_dev/src/serve.rs
index 535c25e69f1..ea925f6709f 100644
--- a/src/tools/clippy/clippy_dev/src/serve.rs
+++ b/src/tools/clippy/clippy_dev/src/serve.rs
@@ -2,8 +2,8 @@ use std::ffi::OsStr;
 use std::num::ParseIntError;
 use std::path::Path;
 use std::process::Command;
-use std::thread;
 use std::time::{Duration, SystemTime};
+use std::{env, thread};
 
 /// # Panics
 ///
@@ -16,7 +16,7 @@ pub fn run(port: u16, lint: Option<&String>) -> ! {
 
     loop {
         if mtime("util/gh-pages/lints.json") < mtime("clippy_lints/src") {
-            Command::new("cargo")
+            Command::new(env::var("CARGO").unwrap_or("cargo".into()))
                 .arg("collect-metadata")
                 .spawn()
                 .unwrap()
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index a9375214be4..ad8b7ded46b 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -16,7 +16,7 @@ clippy_utils = { path = "../clippy_utils" }
 declare_clippy_lint = { path = "../declare_clippy_lint" }
 itertools = "0.11"
 quine-mc_cluskey = "0.2"
-regex-syntax = "0.7"
+regex-syntax = "0.8"
 serde = { version = "1.0", features = ["derive"] }
 serde_json = { version = "1.0", optional = true }
 tempfile = { version = "3.3.0", optional = true }
diff --git a/src/tools/clippy/clippy_lints/src/as_conversions.rs b/src/tools/clippy/clippy_lints/src/as_conversions.rs
index e052d36f115..e3daf75c3eb 100644
--- a/src/tools/clippy/clippy_lints/src/as_conversions.rs
+++ b/src/tools/clippy/clippy_lints/src/as_conversions.rs
@@ -48,11 +48,10 @@ declare_lint_pass!(AsConversions => [AS_CONVERSIONS]);
 
 impl<'tcx> LateLintPass<'tcx> for AsConversions {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
-        if in_external_macro(cx.sess(), expr.span) || is_from_proc_macro(cx, expr) {
-            return;
-        }
-
-        if let ExprKind::Cast(_, _) = expr.kind {
+        if let ExprKind::Cast(_, _) = expr.kind
+            && !in_external_macro(cx.sess(), expr.span)
+            && !is_from_proc_macro(cx, expr)
+        {
             span_lint_and_help(
                 cx,
                 AS_CONVERSIONS,
diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
new file mode 100644
index 00000000000..1417e230aee
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
@@ -0,0 +1,137 @@
+use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
+use clippy_utils::source::snippet_block_with_applicability;
+use clippy_utils::ty::implements_trait;
+use clippy_utils::visitors::{for_each_expr, Descend};
+use clippy_utils::{get_parent_expr, higher};
+use core::ops::ControlFlow;
+use rustc_errors::Applicability;
+use rustc_hir::{BlockCheckMode, Expr, ExprKind, MatchSource};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_session::declare_lint_pass;
+use rustc_span::sym;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for `if` conditions that use blocks containing an
+    /// expression, statements or conditions that use closures with blocks.
+    ///
+    /// ### Why is this bad?
+    /// Style, using blocks in the condition makes it hard to read.
+    ///
+    /// ### Examples
+    /// ```no_run
+    /// # fn somefunc() -> bool { true };
+    /// if { true } { /* ... */ }
+    ///
+    /// if { let x = somefunc(); x } { /* ... */ }
+    /// ```
+    ///
+    /// Use instead:
+    /// ```no_run
+    /// # fn somefunc() -> bool { true };
+    /// if true { /* ... */ }
+    ///
+    /// let res = { let x = somefunc(); x };
+    /// if res { /* ... */ }
+    /// ```
+    #[clippy::version = "1.45.0"]
+    pub BLOCKS_IN_CONDITIONS,
+    style,
+    "useless or complex blocks that can be eliminated in conditions"
+}
+
+declare_lint_pass!(BlocksInConditions => [BLOCKS_IN_CONDITIONS]);
+
+const BRACED_EXPR_MESSAGE: &str = "omit braces around single expression condition";
+
+impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if in_external_macro(cx.sess(), expr.span) {
+            return;
+        }
+
+        let Some((cond, keyword, desc)) = higher::If::hir(expr)
+            .map(|hif| (hif.cond, "if", "an `if` condition"))
+            .or(if let ExprKind::Match(match_ex, _, MatchSource::Normal) = expr.kind {
+                Some((match_ex, "match", "a `match` scrutinee"))
+            } else {
+                None
+            })
+        else {
+            return;
+        };
+        let complex_block_message = &format!(
+            "in {desc}, avoid complex blocks or closures with blocks; \
+            instead, move the block or closure higher and bind it with a `let`",
+        );
+
+        if let ExprKind::Block(block, _) = &cond.kind {
+            if block.rules == BlockCheckMode::DefaultBlock {
+                if block.stmts.is_empty() {
+                    if let Some(ex) = &block.expr {
+                        // don't dig into the expression here, just suggest that they remove
+                        // the block
+                        if expr.span.from_expansion() || ex.span.from_expansion() {
+                            return;
+                        }
+                        let mut applicability = Applicability::MachineApplicable;
+                        span_lint_and_sugg(
+                            cx,
+                            BLOCKS_IN_CONDITIONS,
+                            cond.span,
+                            BRACED_EXPR_MESSAGE,
+                            "try",
+                            snippet_block_with_applicability(cx, ex.span, "..", Some(expr.span), &mut applicability)
+                                .to_string(),
+                            applicability,
+                        );
+                    }
+                } else {
+                    let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
+                    if span.from_expansion() || expr.span.from_expansion() {
+                        return;
+                    }
+                    // move block higher
+                    let mut applicability = Applicability::MachineApplicable;
+                    span_lint_and_sugg(
+                        cx,
+                        BLOCKS_IN_CONDITIONS,
+                        expr.span.with_hi(cond.span.hi()),
+                        complex_block_message,
+                        "try",
+                        format!(
+                            "let res = {}; {keyword} res",
+                            snippet_block_with_applicability(cx, block.span, "..", Some(expr.span), &mut applicability),
+                        ),
+                        applicability,
+                    );
+                }
+            }
+        } else {
+            let _: Option<!> = for_each_expr(cond, |e| {
+                if let ExprKind::Closure(closure) = e.kind {
+                    // do not lint if the closure is called using an iterator (see #1141)
+                    if let Some(parent) = get_parent_expr(cx, e)
+                        && let ExprKind::MethodCall(_, self_arg, _, _) = &parent.kind
+                        && let caller = cx.typeck_results().expr_ty(self_arg)
+                        && let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator)
+                        && implements_trait(cx, caller, iter_id, &[])
+                    {
+                        return ControlFlow::Continue(Descend::No);
+                    }
+
+                    let body = cx.tcx.hir().body(closure.body);
+                    let ex = &body.value;
+                    if let ExprKind::Block(block, _) = ex.kind {
+                        if !body.value.span.from_expansion() && !block.stmts.is_empty() {
+                            span_lint(cx, BLOCKS_IN_CONDITIONS, ex.span, complex_block_message);
+                            return ControlFlow::Continue(Descend::No);
+                        }
+                    }
+                }
+                ControlFlow::Continue(Descend::Yes)
+            });
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs
deleted file mode 100644
index 692309629b7..00000000000
--- a/src/tools/clippy/clippy_lints/src/blocks_in_if_conditions.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
-use clippy_utils::source::snippet_block_with_applicability;
-use clippy_utils::ty::implements_trait;
-use clippy_utils::visitors::{for_each_expr, Descend};
-use clippy_utils::{get_parent_expr, higher};
-use core::ops::ControlFlow;
-use rustc_errors::Applicability;
-use rustc_hir::{BlockCheckMode, Expr, ExprKind};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
-use rustc_session::declare_lint_pass;
-use rustc_span::sym;
-
-declare_clippy_lint! {
-    /// ### What it does
-    /// Checks for `if` conditions that use blocks containing an
-    /// expression, statements or conditions that use closures with blocks.
-    ///
-    /// ### Why is this bad?
-    /// Style, using blocks in the condition makes it hard to read.
-    ///
-    /// ### Examples
-    /// ```no_run
-    /// # fn somefunc() -> bool { true };
-    /// if { true } { /* ... */ }
-    ///
-    /// if { let x = somefunc(); x } { /* ... */ }
-    /// ```
-    ///
-    /// Use instead:
-    /// ```no_run
-    /// # fn somefunc() -> bool { true };
-    /// if true { /* ... */ }
-    ///
-    /// let res = { let x = somefunc(); x };
-    /// if res { /* ... */ }
-    /// ```
-    #[clippy::version = "1.45.0"]
-    pub BLOCKS_IN_IF_CONDITIONS,
-    style,
-    "useless or complex blocks that can be eliminated in conditions"
-}
-
-declare_lint_pass!(BlocksInIfConditions => [BLOCKS_IN_IF_CONDITIONS]);
-
-const BRACED_EXPR_MESSAGE: &str = "omit braces around single expression condition";
-const COMPLEX_BLOCK_MESSAGE: &str = "in an `if` condition, avoid complex blocks or closures with blocks; \
-                                    instead, move the block or closure higher and bind it with a `let`";
-
-impl<'tcx> LateLintPass<'tcx> for BlocksInIfConditions {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if in_external_macro(cx.sess(), expr.span) {
-            return;
-        }
-        if let Some(higher::If { cond, .. }) = higher::If::hir(expr) {
-            if let ExprKind::Block(block, _) = &cond.kind {
-                if block.rules == BlockCheckMode::DefaultBlock {
-                    if block.stmts.is_empty() {
-                        if let Some(ex) = &block.expr {
-                            // don't dig into the expression here, just suggest that they remove
-                            // the block
-                            if expr.span.from_expansion() || ex.span.from_expansion() {
-                                return;
-                            }
-                            let mut applicability = Applicability::MachineApplicable;
-                            span_lint_and_sugg(
-                                cx,
-                                BLOCKS_IN_IF_CONDITIONS,
-                                cond.span,
-                                BRACED_EXPR_MESSAGE,
-                                "try",
-                                format!(
-                                    "{}",
-                                    snippet_block_with_applicability(
-                                        cx,
-                                        ex.span,
-                                        "..",
-                                        Some(expr.span),
-                                        &mut applicability
-                                    )
-                                ),
-                                applicability,
-                            );
-                        }
-                    } else {
-                        let span = block.expr.as_ref().map_or_else(|| block.stmts[0].span, |e| e.span);
-                        if span.from_expansion() || expr.span.from_expansion() {
-                            return;
-                        }
-                        // move block higher
-                        let mut applicability = Applicability::MachineApplicable;
-                        span_lint_and_sugg(
-                            cx,
-                            BLOCKS_IN_IF_CONDITIONS,
-                            expr.span.with_hi(cond.span.hi()),
-                            COMPLEX_BLOCK_MESSAGE,
-                            "try",
-                            format!(
-                                "let res = {}; if res",
-                                snippet_block_with_applicability(
-                                    cx,
-                                    block.span,
-                                    "..",
-                                    Some(expr.span),
-                                    &mut applicability
-                                ),
-                            ),
-                            applicability,
-                        );
-                    }
-                }
-            } else {
-                let _: Option<!> = for_each_expr(cond, |e| {
-                    if let ExprKind::Closure(closure) = e.kind {
-                        // do not lint if the closure is called using an iterator (see #1141)
-                        if let Some(parent) = get_parent_expr(cx, e)
-                            && let ExprKind::MethodCall(_, self_arg, _, _) = &parent.kind
-                            && let caller = cx.typeck_results().expr_ty(self_arg)
-                            && let Some(iter_id) = cx.tcx.get_diagnostic_item(sym::Iterator)
-                            && implements_trait(cx, caller, iter_id, &[])
-                        {
-                            return ControlFlow::Continue(Descend::No);
-                        }
-
-                        let body = cx.tcx.hir().body(closure.body);
-                        let ex = &body.value;
-                        if let ExprKind::Block(block, _) = ex.kind {
-                            if !body.value.span.from_expansion() && !block.stmts.is_empty() {
-                                span_lint(cx, BLOCKS_IN_IF_CONDITIONS, ex.span, COMPLEX_BLOCK_MESSAGE);
-                                return ControlFlow::Continue(Descend::No);
-                            }
-                        }
-                    }
-                    ControlFlow::Continue(Descend::Yes)
-                });
-            }
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
index d3d4f3c41c8..0ca4a0e067d 100644
--- a/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/borrow_deref_ref.rs
@@ -57,7 +57,6 @@ impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
             && !matches!(deref_target.kind, ExprKind::Unary(UnOp::Deref, ..))
             && let ref_ty = cx.typeck_results().expr_ty(deref_target)
             && let ty::Ref(_, inner_ty, Mutability::Not) = ref_ty.kind()
-            && !is_from_proc_macro(cx, e)
         {
             if let Some(parent_expr) = get_parent_expr(cx, e) {
                 if matches!(parent_expr.kind, ExprKind::Unary(UnOp::Deref, ..))
@@ -75,6 +74,9 @@ impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
                     return;
                 }
             }
+            if is_from_proc_macro(cx, e) {
+                return;
+            }
 
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
index b55cd8833b7..8bfb7383f14 100644
--- a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
@@ -9,11 +9,10 @@ use rustc_middle::ty::{self, Ty, TypeAndMut};
 use super::AS_PTR_CAST_MUT;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_to: Ty<'_>) {
-    if let ty::RawPtr(
-        TypeAndMut {
-            mutbl: Mutability::Mut, ty: ptrty,
-        },
-    ) = cast_to.kind()
+    if let ty::RawPtr(TypeAndMut {
+        mutbl: Mutability::Mut,
+        ty: ptrty,
+    }) = cast_to.kind()
         && let ty::RawPtr(TypeAndMut {
             mutbl: Mutability::Not, ..
         }) = cx.typeck_results().node_type(cast_expr.hir_id).kind()
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
index 0c555c1acc5..35e36e9ef3f 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -3,12 +3,29 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
-use rustc_hir::{Expr, ExprKind, Mutability, TyKind};
+use rustc_hir::{Expr, ExprKind, Mutability, QPath, TyKind};
+use rustc_hir_pretty::qpath_to_string;
 use rustc_lint::LateContext;
 use rustc_middle::ty::{self, TypeAndMut};
+use rustc_span::sym;
 
 use super::PTR_AS_PTR;
 
+enum OmitFollowedCastReason<'a> {
+    None,
+    Null(&'a QPath<'a>),
+    NullMut(&'a QPath<'a>),
+}
+
+impl OmitFollowedCastReason<'_> {
+    fn corresponding_item(&self) -> Option<&QPath<'_>> {
+        match self {
+            OmitFollowedCastReason::None => None,
+            OmitFollowedCastReason::Null(x) | OmitFollowedCastReason::NullMut(x) => Some(*x),
+        }
+    }
+}
+
 pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
     if !msrv.meets(msrvs::POINTER_CAST) {
         return;
@@ -25,7 +42,6 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
         && to_pointee_ty.is_sized(cx.tcx, cx.param_env)
     {
         let mut app = Applicability::MachineApplicable;
-        let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app);
         let turbofish = match &cast_to_hir_ty.kind {
             TyKind::Infer => String::new(),
             TyKind::Ptr(mut_ty) => {
@@ -41,13 +57,44 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
             _ => return,
         };
 
+        // following `cast` does not compile because it fails to infer what type is expected
+        // as type argument to `std::ptr::ptr_null` or `std::ptr::ptr_null_mut`, so
+        // we omit following `cast`:
+        let omit_cast = if let ExprKind::Call(func, []) = cast_expr.kind
+            && let ExprKind::Path(ref qpath @ QPath::Resolved(None, path)) = func.kind
+        {
+            let method_defid = path.res.def_id();
+            if cx.tcx.is_diagnostic_item(sym::ptr_null, method_defid) {
+                OmitFollowedCastReason::Null(qpath)
+            } else if cx.tcx.is_diagnostic_item(sym::ptr_null_mut, method_defid) {
+                OmitFollowedCastReason::NullMut(qpath)
+            } else {
+                OmitFollowedCastReason::None
+            }
+        } else {
+            OmitFollowedCastReason::None
+        };
+
+        let (help, final_suggestion) = if let Some(method) = omit_cast.corresponding_item() {
+            // don't force absolute path
+            let method = qpath_to_string(method);
+            ("try call directly", format!("{method}{turbofish}()"))
+        } else {
+            let cast_expr_sugg = Sugg::hir_with_applicability(cx, cast_expr, "_", &mut app);
+
+            (
+                "try `pointer::cast`, a safer alternative",
+                format!("{}.cast{turbofish}()", cast_expr_sugg.maybe_par()),
+            )
+        };
+
         span_lint_and_sugg(
             cx,
             PTR_AS_PTR,
             expr.span,
             "`as` casting between raw pointers without changing its mutability",
-            "try `pointer::cast`, a safer alternative",
-            format!("{}.cast{turbofish}()", cast_expr_sugg.maybe_par()),
+            help,
+            final_suggestion,
             app,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 3627096ed91..1220eb89013 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -63,7 +63,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::await_holding_invalid::AWAIT_HOLDING_INVALID_TYPE_INFO,
     crate::await_holding_invalid::AWAIT_HOLDING_LOCK_INFO,
     crate::await_holding_invalid::AWAIT_HOLDING_REFCELL_REF_INFO,
-    crate::blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS_INFO,
+    crate::blocks_in_conditions::BLOCKS_IN_CONDITIONS_INFO,
     crate::bool_assert_comparison::BOOL_ASSERT_COMPARISON_INFO,
     crate::bool_to_int_with_if::BOOL_TO_INT_WITH_IF_INFO,
     crate::booleans::NONMINIMAL_BOOL_INFO,
@@ -215,6 +215,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::index_refutable_slice::INDEX_REFUTABLE_SLICE_INFO,
     crate::indexing_slicing::INDEXING_SLICING_INFO,
     crate::indexing_slicing::OUT_OF_BOUNDS_INDEXING_INFO,
+    crate::ineffective_open_options::INEFFECTIVE_OPEN_OPTIONS_INFO,
     crate::infinite_iter::INFINITE_ITER_INFO,
     crate::infinite_iter::MAYBE_INFINITE_ITER_INFO,
     crate::inherent_impl::MULTIPLE_INHERENT_IMPL_INFO,
@@ -265,6 +266,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::loops::EXPLICIT_INTO_ITER_LOOP_INFO,
     crate::loops::EXPLICIT_ITER_LOOP_INFO,
     crate::loops::FOR_KV_MAP_INFO,
+    crate::loops::INFINITE_LOOP_INFO,
     crate::loops::ITER_NEXT_LOOP_INFO,
     crate::loops::MANUAL_FIND_INFO,
     crate::loops::MANUAL_FLATTEN_INFO,
@@ -598,6 +600,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::reference::DEREF_ADDROF_INFO,
     crate::regex::INVALID_REGEX_INFO,
     crate::regex::TRIVIAL_REGEX_INFO,
+    crate::repeat_vec_with_capacity::REPEAT_VEC_WITH_CAPACITY_INFO,
     crate::reserve_after_initialization::RESERVE_AFTER_INITIALIZATION_INFO,
     crate::return_self_not_must_use::RETURN_SELF_NOT_MUST_USE_INFO,
     crate::returns::LET_AND_RETURN_INFO,
@@ -678,6 +681,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::unicode::INVISIBLE_CHARACTERS_INFO,
     crate::unicode::NON_ASCII_LITERAL_INFO,
     crate::unicode::UNICODE_NOT_NFC_INFO,
+    crate::uninhabited_references::UNINHABITED_REFERENCES_INFO,
     crate::uninit_vec::UNINIT_VEC_INFO,
     crate::unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD_INFO,
     crate::unit_types::LET_UNIT_VALUE_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/doc/markdown.rs b/src/tools/clippy/clippy_lints/src/doc/markdown.rs
index c0b11eb0dd1..a58219c2946 100644
--- a/src/tools/clippy/clippy_lints/src/doc/markdown.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/markdown.rs
@@ -9,11 +9,21 @@ use url::Url;
 use crate::doc::DOC_MARKDOWN;
 
 pub fn check(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, text: &str, span: Span) {
-    for word in text.split(|c: char| c.is_whitespace() || c == '\'') {
+    for orig_word in text.split(|c: char| c.is_whitespace() || c == '\'') {
         // Trim punctuation as in `some comment (see foo::bar).`
         //                                                   ^^
         // Or even as in `_foo bar_` which is emphasized. Also preserve `::` as a prefix/suffix.
-        let mut word = word.trim_matches(|c: char| !c.is_alphanumeric() && c != ':');
+        let trim_pattern = |c: char| !c.is_alphanumeric() && c != ':';
+        let mut word = orig_word.trim_end_matches(trim_pattern);
+
+        // If word is immediately followed by `()`, claw it back.
+        if let Some(tmp_word) = orig_word.get(..word.len() + 2)
+            && tmp_word.ends_with("()")
+        {
+            word = tmp_word;
+        }
+
+        word = word.trim_start_matches(trim_pattern);
 
         // Remove leading or trailing single `:` which may be part of a sentence.
         if word.starts_with(':') && !word.starts_with("::") {
@@ -84,7 +94,7 @@ fn check_word(cx: &LateContext<'_>, word: &str, span: Span) {
         return;
     }
 
-    if has_underscore(word) || word.contains("::") || is_camel_case(word) {
+    if has_underscore(word) || word.contains("::") || is_camel_case(word) || word.ends_with("()") {
         let mut applicability = Applicability::MachineApplicable;
 
         span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index f1366c434f4..e8c1e5db35e 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -15,7 +15,7 @@ declare_clippy_lint! {
     /// replaced with `(e)print!()` / `(e)println!()`
     ///
     /// ### Why is this bad?
-    /// Using `(e)println! is clearer and more concise
+    /// Using `(e)println!` is clearer and more concise
     ///
     /// ### Example
     /// ```no_run
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index 4811691c80d..0f5a9ea5d84 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -194,7 +194,12 @@ fn is_same_generics<'tcx>(
         .enumerate()
         .skip(1) // skip `Self` implicit arg
         .all(|(arg_index, arg)| {
-            if [implied_by_generics.host_effect_index, implied_generics.host_effect_index].contains(&Some(arg_index)) {
+            if [
+                implied_by_generics.host_effect_index,
+                implied_generics.host_effect_index,
+            ]
+            .contains(&Some(arg_index))
+            {
                 // skip host effect params in determining whether generics are same
                 return true;
             }
diff --git a/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs b/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs
new file mode 100644
index 00000000000..955f90d4262
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/ineffective_open_options.rs
@@ -0,0 +1,95 @@
+use crate::methods::method_call;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::peel_blocks;
+use rustc_ast::LitKind;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty;
+use rustc_session::declare_lint_pass;
+use rustc_span::{sym, BytePos, Span};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks if both `.write(true)` and `.append(true)` methods are called
+    /// on a same `OpenOptions`.
+    ///
+    /// ### Why is this bad?
+    /// `.append(true)` already enables `write(true)`, making this one
+    /// superflous.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// # use std::fs::OpenOptions;
+    /// let _ = OpenOptions::new()
+    ///            .write(true)
+    ///            .append(true)
+    ///            .create(true)
+    ///            .open("file.json");
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// # use std::fs::OpenOptions;
+    /// let _ = OpenOptions::new()
+    ///            .append(true)
+    ///            .create(true)
+    ///            .open("file.json");
+    /// ```
+    #[clippy::version = "1.76.0"]
+    pub INEFFECTIVE_OPEN_OPTIONS,
+    suspicious,
+    "usage of both `write(true)` and `append(true)` on same `OpenOptions`"
+}
+
+declare_lint_pass!(IneffectiveOpenOptions => [INEFFECTIVE_OPEN_OPTIONS]);
+
+fn index_if_arg_is_boolean(args: &[Expr<'_>], call_span: Span) -> Option<Span> {
+    if let [arg] = args
+        && let ExprKind::Lit(lit) = peel_blocks(arg).kind
+        && lit.node == LitKind::Bool(true)
+    {
+        // The `.` is not included in the span so we cheat a little bit to include it as well.
+        Some(call_span.with_lo(call_span.lo() - BytePos(1)))
+    } else {
+        None
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for IneffectiveOpenOptions {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        let Some(("open", mut receiver, [_arg], _, _)) = method_call(expr) else {
+            return;
+        };
+        let receiver_ty = cx.typeck_results().expr_ty(receiver);
+        match receiver_ty.peel_refs().kind() {
+            ty::Adt(adt, _) if cx.tcx.is_diagnostic_item(sym::FsOpenOptions, adt.did()) => {},
+            _ => return,
+        }
+
+        let mut append = None;
+        let mut write = None;
+
+        while let Some((name, recv, args, _, span)) = method_call(receiver) {
+            if name == "append" {
+                append = index_if_arg_is_boolean(args, span);
+            } else if name == "write" {
+                write = index_if_arg_is_boolean(args, span);
+            }
+            receiver = recv;
+        }
+
+        if let Some(write_span) = write
+            && append.is_some()
+        {
+            span_lint_and_sugg(
+                cx,
+                INEFFECTIVE_OPEN_OPTIONS,
+                write_span,
+                "unnecessary use of `.write(true)` because there is `.append(true)`",
+                "remove `.write(true)`",
+                String::new(),
+                Applicability::MachineApplicable,
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index 83af551fcd3..8c032b17023 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -8,8 +8,8 @@ use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, DefIdSet};
 use rustc_hir::{
     AssocItemKind, BinOpKind, Expr, ExprKind, FnRetTy, GenericArg, GenericBound, ImplItem, ImplItemKind,
-    ImplicitSelfKind, Item, ItemKind, LangItem, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef,
-    TyKind, TypeBindingKind,
+    ImplicitSelfKind, Item, ItemKind, Mutability, Node, PatKind, PathSegment, PrimTy, QPath, TraitItemRef,
+    TyKind, TypeBindingKind, OpaqueTyOrigin,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{self, AssocKind, FnSig, Ty};
@@ -289,8 +289,10 @@ fn extract_future_output<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<&
             kind: ItemKind::OpaqueTy(opaque),
             ..
         } = item
-        && opaque.bounds.len() == 1
-        && let GenericBound::LangItemTrait(LangItem::Future, _, _, generic_args) = &opaque.bounds[0]
+        && let OpaqueTyOrigin::AsyncFn(_) = opaque.origin
+        && let [GenericBound::Trait(trait_ref, _)] = &opaque.bounds
+        && let Some(segment) = trait_ref.trait_ref.path.segments.last()
+        && let Some(generic_args) = segment.args
         && generic_args.bindings.len() == 1
         && let TypeBindingKind::Equality {
             term:
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 1c59b2df853..7758d6a58e6 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -50,6 +50,8 @@ extern crate clippy_utils;
 #[macro_use]
 extern crate declare_clippy_lint;
 
+use std::collections::BTreeMap;
+
 use rustc_data_structures::fx::FxHashSet;
 use rustc_lint::{Lint, LintId};
 
@@ -74,7 +76,7 @@ mod assertions_on_result_states;
 mod async_yields_async;
 mod attrs;
 mod await_holding_invalid;
-mod blocks_in_if_conditions;
+mod blocks_in_conditions;
 mod bool_assert_comparison;
 mod bool_to_int_with_if;
 mod booleans;
@@ -153,6 +155,7 @@ mod implied_bounds_in_impls;
 mod inconsistent_struct_constructor;
 mod index_refutable_slice;
 mod indexing_slicing;
+mod ineffective_open_options;
 mod infinite_iter;
 mod inherent_impl;
 mod inherent_to_string;
@@ -289,6 +292,7 @@ mod ref_option_ref;
 mod ref_patterns;
 mod reference;
 mod regex;
+mod repeat_vec_with_capacity;
 mod reserve_after_initialization;
 mod return_self_not_must_use;
 mod returns;
@@ -325,6 +329,7 @@ mod tuple_array_conversions;
 mod types;
 mod undocumented_unsafe_blocks;
 mod unicode;
+mod uninhabited_references;
 mod uninit_vec;
 mod unit_return_expecting_ord;
 mod unit_types;
@@ -653,7 +658,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(|_| Box::<significant_drop_tightening::SignificantDropTightening<'_>>::default());
     store.register_late_pass(|_| Box::new(len_zero::LenZero));
     store.register_late_pass(|_| Box::new(attrs::Attributes));
-    store.register_late_pass(|_| Box::new(blocks_in_if_conditions::BlocksInIfConditions));
+    store.register_late_pass(|_| Box::new(blocks_in_conditions::BlocksInConditions));
     store.register_late_pass(|_| Box::new(unicode::Unicode));
     store.register_late_pass(|_| Box::new(uninit_vec::UninitVec));
     store.register_late_pass(|_| Box::new(unit_return_expecting_ord::UnitReturnExpectingOrd));
@@ -722,6 +727,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         Box::new(vec::UselessVec {
             too_large_for_stack,
             msrv: msrv(),
+            span_to_lint_map: BTreeMap::new(),
         })
     });
     store.register_late_pass(|_| Box::new(panic_unimplemented::PanicUnimplemented));
@@ -1069,6 +1075,9 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(|_| Box::new(iter_without_into_iter::IterWithoutIntoIter));
     store.register_late_pass(|_| Box::new(iter_over_hash_type::IterOverHashType));
     store.register_late_pass(|_| Box::new(impl_hash_with_borrow_str_and_bytes::ImplHashWithBorrowStrBytes));
+    store.register_late_pass(|_| Box::new(repeat_vec_with_capacity::RepeatVecWithCapacity));
+    store.register_late_pass(|_| Box::new(uninhabited_references::UninhabitedReferences));
+    store.register_late_pass(|_| Box::new(ineffective_open_options::IneffectiveOpenOptions));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
new file mode 100644
index 00000000000..9b88dd76e5c
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/loops/infinite_loop.rs
@@ -0,0 +1,125 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::{fn_def_id, is_lint_allowed};
+use hir::intravisit::{walk_expr, Visitor};
+use hir::{Expr, ExprKind, FnRetTy, FnSig, Node};
+use rustc_ast::Label;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::LateContext;
+
+use super::INFINITE_LOOP;
+
+pub(super) fn check<'tcx>(
+    cx: &LateContext<'tcx>,
+    expr: &Expr<'_>,
+    loop_block: &'tcx hir::Block<'_>,
+    label: Option<Label>,
+) {
+    if is_lint_allowed(cx, INFINITE_LOOP, expr.hir_id) {
+        return;
+    }
+
+    // Skip check if this loop is not in a function/method/closure. (In some weird case)
+    let Some(parent_fn_ret) = get_parent_fn_ret_ty(cx, expr) else {
+        return;
+    };
+    // Or, its parent function is already returning `Never`
+    if matches!(
+        parent_fn_ret,
+        FnRetTy::Return(hir::Ty {
+            kind: hir::TyKind::Never,
+            ..
+        })
+    ) {
+        return;
+    }
+
+    let mut loop_visitor = LoopVisitor {
+        cx,
+        label,
+        is_finite: false,
+        loop_depth: 0,
+    };
+    loop_visitor.visit_block(loop_block);
+
+    let is_finite_loop = loop_visitor.is_finite;
+
+    if !is_finite_loop {
+        span_lint_and_then(cx, INFINITE_LOOP, expr.span, "infinite loop detected", |diag| {
+            if let FnRetTy::DefaultReturn(ret_span) = parent_fn_ret {
+                diag.span_suggestion(
+                    ret_span,
+                    "if this is intentional, consider specifing `!` as function return",
+                    " -> !",
+                    Applicability::MaybeIncorrect,
+                );
+            } else {
+                diag.help("if this is not intended, try adding a `break` or `return` condition in the loop");
+            }
+        });
+    }
+}
+
+fn get_parent_fn_ret_ty<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<FnRetTy<'tcx>> {
+    for (_, parent_node) in cx.tcx.hir().parent_iter(expr.hir_id) {
+        match parent_node {
+            Node::Item(hir::Item {
+                kind: hir::ItemKind::Fn(FnSig { decl, .. }, _, _),
+                ..
+            })
+            | Node::TraitItem(hir::TraitItem {
+                kind: hir::TraitItemKind::Fn(FnSig { decl, .. }, _),
+                ..
+            })
+            | Node::ImplItem(hir::ImplItem {
+                kind: hir::ImplItemKind::Fn(FnSig { decl, .. }, _),
+                ..
+            })
+            | Node::Expr(Expr {
+                kind: ExprKind::Closure(hir::Closure { fn_decl: decl, .. }),
+                ..
+            }) => return Some(decl.output),
+            _ => (),
+        }
+    }
+    None
+}
+
+struct LoopVisitor<'hir, 'tcx> {
+    cx: &'hir LateContext<'tcx>,
+    label: Option<Label>,
+    loop_depth: usize,
+    is_finite: bool,
+}
+
+impl<'hir> Visitor<'hir> for LoopVisitor<'hir, '_> {
+    fn visit_expr(&mut self, ex: &'hir Expr<'_>) {
+        match &ex.kind {
+            ExprKind::Break(hir::Destination { label, .. }, ..) => {
+                // Assuming breaks the loop when `loop_depth` is 0,
+                // as it could only means this `break` breaks current loop or any of its upper loop.
+                // Or, the depth is not zero but the label is matched.
+                if self.loop_depth == 0 || (label.is_some() && *label == self.label) {
+                    self.is_finite = true;
+                }
+            },
+            ExprKind::Ret(..) => self.is_finite = true,
+            ExprKind::Loop(..) => {
+                self.loop_depth += 1;
+                walk_expr(self, ex);
+                self.loop_depth = self.loop_depth.saturating_sub(1);
+            },
+            _ => {
+                // Calls to a function that never return
+                if let Some(did) = fn_def_id(self.cx, ex) {
+                    let fn_ret_ty = self.cx.tcx.fn_sig(did).skip_binder().output().skip_binder();
+                    if fn_ret_ty.is_never() {
+                        self.is_finite = true;
+                        return;
+                    }
+                }
+                walk_expr(self, ex);
+            },
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/loops/mod.rs b/src/tools/clippy/clippy_lints/src/loops/mod.rs
index 892336878c7..3c9bde86bb6 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mod.rs
@@ -3,6 +3,7 @@ mod explicit_counter_loop;
 mod explicit_into_iter_loop;
 mod explicit_iter_loop;
 mod for_kv_map;
+mod infinite_loop;
 mod iter_next_loop;
 mod manual_find;
 mod manual_flatten;
@@ -635,6 +636,48 @@ declare_clippy_lint! {
     "checking for emptiness of a `Vec` in the loop condition and popping an element in the body"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for infinite loops in a function where the return type is not `!`
+    /// and lint accordingly.
+    ///
+    /// ### Why is this bad?
+    /// A loop should be gently exited somewhere, or at least mark its parent function as
+    /// never return (`!`).
+    ///
+    /// ### Example
+    /// ```no_run,ignore
+    /// fn run_forever() {
+    ///     loop {
+    ///         // do something
+    ///     }
+    /// }
+    /// ```
+    /// If infinite loops are as intended:
+    /// ```no_run,ignore
+    /// fn run_forever() -> ! {
+    ///     loop {
+    ///         // do something
+    ///     }
+    /// }
+    /// ```
+    /// Otherwise add a `break` or `return` condition:
+    /// ```no_run,ignore
+    /// fn run_forever() {
+    ///     loop {
+    ///         // do something
+    ///         if condition {
+    ///             break;
+    ///         }
+    ///     }
+    /// }
+    /// ```
+    #[clippy::version = "1.75.0"]
+    pub INFINITE_LOOP,
+    restriction,
+    "possibly unintended infinite loop"
+}
+
 pub struct Loops {
     msrv: Msrv,
     enforce_iter_loop_reborrow: bool,
@@ -669,6 +712,7 @@ impl_lint_pass!(Loops => [
     MANUAL_FIND,
     MANUAL_WHILE_LET_SOME,
     UNUSED_ENUMERATE_INDEX,
+    INFINITE_LOOP,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Loops {
@@ -707,10 +751,11 @@ impl<'tcx> LateLintPass<'tcx> for Loops {
         // check for `loop { if let {} else break }` that could be `while let`
         // (also matches an explicit "match" instead of "if let")
         // (even if the "match" or "if let" is used for declaration)
-        if let ExprKind::Loop(block, _, LoopSource::Loop, _) = expr.kind {
+        if let ExprKind::Loop(block, label, LoopSource::Loop, _) = expr.kind {
             // also check for empty `loop {}` statements, skipping those in #[panic_handler]
             empty_loop::check(cx, expr, block);
             while_let_loop::check(cx, expr, block);
+            infinite_loop::check(cx, expr, block, label);
         }
 
         while_let_on_iterator::check(cx, expr);
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index 28abecd0429..4acf46f73c9 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -13,8 +13,7 @@ use rustc_lint::LateContext;
 use rustc_middle::middle::region;
 use rustc_middle::ty::{self, Ty};
 use rustc_span::symbol::{sym, Symbol};
-use std::iter::{self};
-use std::mem;
+use std::{iter, mem};
 
 /// Checks for looping over a range and then indexing a sequence with it.
 /// The iteratee must be a range literal.
diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
index 31cfb41640d..72cf1d7a354 100644
--- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
@@ -105,7 +105,6 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
             // case somebody does that for some reason
             && (is_infinity(const_1) && is_neg_infinity(const_2)
                 || is_neg_infinity(const_1) && is_infinity(const_2))
-            && !is_from_proc_macro(cx, expr)
             && let Some(local_snippet) = snippet_opt(cx, first.span)
         {
             let variant = match (kind.node, lhs_kind.node, rhs_kind.node) {
@@ -113,6 +112,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
                 (BinOpKind::And, BinOpKind::Ne, BinOpKind::Ne) => Variant::ManualIsFinite,
                 _ => return,
             };
+            if is_from_proc_macro(cx, expr) {
+                return;
+            }
 
             span_lint_and_then(cx, variant.lint(), expr.span, variant.msg(), |diag| {
                 match variant {
diff --git a/src/tools/clippy/clippy_lints/src/manual_string_new.rs b/src/tools/clippy/clippy_lints/src/manual_string_new.rs
index 737c70496c2..781db4b97f0 100644
--- a/src/tools/clippy/clippy_lints/src/manual_string_new.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_string_new.rs
@@ -108,18 +108,16 @@ fn parse_call(cx: &LateContext<'_>, span: Span, func: &Expr<'_>, args: &[Expr<'_
 
     let arg_kind = &args[0].kind;
     if let ExprKind::Path(qpath) = &func.kind {
-        if let QPath::TypeRelative(_, _) = qpath {
-            // String::from(...) or String::try_from(...)
-            if let QPath::TypeRelative(ty, path_seg) = qpath
-                && [sym::from, sym::try_from].contains(&path_seg.ident.name)
-                && let TyKind::Path(qpath) = &ty.kind
-                && let QPath::Resolved(_, path) = qpath
-                && let [path_seg] = path.segments
-                && path_seg.ident.name == sym::String
-                && is_expr_kind_empty_str(arg_kind)
-            {
-                warn_then_suggest(cx, span);
-            }
+        // String::from(...) or String::try_from(...)
+        if let QPath::TypeRelative(ty, path_seg) = qpath
+            && [sym::from, sym::try_from].contains(&path_seg.ident.name)
+            && let TyKind::Path(qpath) = &ty.kind
+            && let QPath::Resolved(_, path) = qpath
+            && let [path_seg] = path.segments
+            && path_seg.ident.name == sym::String
+            && is_expr_kind_empty_str(arg_kind)
+        {
+            warn_then_suggest(cx, span);
         } else if let QPath::Resolved(_, path) = qpath {
             // From::from(...) or TryFrom::try_from(...)
             if let [path_seg1, path_seg2] = path.segments
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 25c681bb9d9..b4f60ffadd7 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -3906,7 +3906,7 @@ impl_lint_pass!(Methods => [
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
-fn method_call<'tcx>(
+pub fn method_call<'tcx>(
     recv: &'tcx hir::Expr<'tcx>,
 ) -> Option<(&'tcx str, &'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], Span, Span)> {
     if let ExprKind::MethodCall(path, receiver, args, call_span) = recv.kind {
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
index 4a651396f14..4429f032605 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_lazy_eval.rs
@@ -19,10 +19,6 @@ pub(super) fn check<'tcx>(
     arg: &'tcx hir::Expr<'_>,
     simplify_using: &str,
 ) {
-    if is_from_proc_macro(cx, expr) {
-        return;
-    }
-
     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);
     let is_bool = cx.typeck_results().expr_ty(recv).is_bool();
@@ -32,7 +28,7 @@ pub(super) fn check<'tcx>(
             let body = cx.tcx.hir().body(body);
             let body_expr = &body.value;
 
-            if usage::BindingUsageFinder::are_params_used(cx, body) {
+            if usage::BindingUsageFinder::are_params_used(cx, body) || is_from_proc_macro(cx, expr) {
                 return;
             }
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 395b22ebc5d..c4775b6bd04 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -15,8 +15,7 @@ use rustc_lint::LateContext;
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
 use rustc_middle::ty::{
-    self, ClauseKind, EarlyBinder, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate,
-    TraitPredicate, Ty,
+    self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate, TraitPredicate, Ty,
 };
 use rustc_span::{sym, Symbol};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -359,6 +358,7 @@ fn get_input_traits_and_projections<'tcx>(
     (trait_predicates, projection_predicates)
 }
 
+#[expect(clippy::too_many_lines)]
 fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<'a>) -> bool {
     for (_, node) in cx.tcx.hir().parent_iter(expr.hir_id) {
         match node {
@@ -387,22 +387,21 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                 if let Some((callee_def_id, call_generic_args, recv, call_args)) =
                     get_callee_generic_args_and_args(cx, parent_expr)
                 {
-                    // FIXME: the `instantiate_identity()` below seems incorrect, since we eventually
-                    // call `tcx.try_instantiate_and_normalize_erasing_regions` further down
-                    // (i.e., we are explicitly not in the identity context).
-                    let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder();
+                    let bound_fn_sig = cx.tcx.fn_sig(callee_def_id);
+                    let fn_sig = bound_fn_sig.skip_binder();
                     if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
-                        && let Some(param_ty) = fn_sig.inputs().get(arg_index)
-                        && let ty::Param(ParamTy { index: param_index , ..}) = param_ty.kind()
+                        && let param_ty = fn_sig.input(arg_index).skip_binder()
+                        && let ty::Param(ParamTy { index: param_index , ..}) = *param_ty.kind()
                         // https://github.com/rust-lang/rust-clippy/issues/9504 and https://github.com/rust-lang/rust-clippy/issues/10021
-                        && (*param_index as usize) < call_generic_args.len()
+                        && (param_index as usize) < call_generic_args.len()
                     {
                         if fn_sig
+                            .skip_binder()
                             .inputs()
                             .iter()
                             .enumerate()
                             .filter(|(i, _)| *i != arg_index)
-                            .any(|(_, ty)| ty.contains(*param_ty))
+                            .any(|(_, ty)| ty.contains(param_ty))
                         {
                             return false;
                         }
@@ -414,7 +413,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                                 .iter()
                                 .filter(|predicate| {
                                     if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
-                                        && trait_predicate.trait_ref.self_ty() == *param_ty
+                                        && trait_predicate.trait_ref.self_ty() == param_ty
                                     {
                                         true
                                     } else {
@@ -425,7 +424,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                         let new_subst = cx
                             .tcx
                             .mk_args_from_iter(call_generic_args.iter().enumerate().map(|(i, t)| {
-                                if i == (*param_index as usize) {
+                                if i == param_index as usize {
                                     GenericArg::from(ty)
                                 } else {
                                     t
@@ -433,7 +432,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                             }));
 
                         if trait_predicates.any(|predicate| {
-                            let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, new_subst);
+                            let predicate = bound_fn_sig.rebind(predicate).instantiate(cx.tcx, new_subst);
                             let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
                             !cx.tcx
                                 .infer_ctxt()
@@ -443,12 +442,12 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                             return false;
                         }
 
-                        let output_ty = fn_sig.output();
-                        if output_ty.contains(*param_ty) {
+                        let output_ty = cx.tcx.instantiate_bound_regions_with_erased(fn_sig.output());
+                        if output_ty.contains(param_ty) {
                             if let Ok(new_ty) = cx.tcx.try_instantiate_and_normalize_erasing_regions(
                                 new_subst,
                                 cx.param_env,
-                                EarlyBinder::bind(output_ty),
+                                bound_fn_sig.rebind(output_ty),
                             ) {
                                 expr = parent_expr;
                                 ty = new_ty;
diff --git a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
index 8f2a5390781..0f18e943451 100644
--- a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
@@ -52,7 +52,7 @@ declare_clippy_lint! {
     /// Use instead:
     /// ```no_run
     /// fn sum(v: &[u8]) -> u8 {
-    ///     assert!(v.len() > 4);
+    ///     assert!(v.len() > 3);
     ///     // no bounds checks
     ///     v[0] + v[1] + v[2] + v[3]
     /// }
@@ -87,11 +87,14 @@ enum LengthComparison {
     LengthLessThanOrEqualInt,
     /// `5 <= v.len()`
     IntLessThanOrEqualLength,
+    /// `5 == v.len()`
+    /// `v.len() == 5`
+    LengthEqualInt,
 }
 
 /// Extracts parts out of a length comparison expression.
 ///
-/// E.g. for `v.len() > 5` this returns `Some((LengthComparison::IntLessThanLength, 5, `v.len()`))`
+/// E.g. for `v.len() > 5` this returns `Some((LengthComparison::IntLessThanLength, 5, v.len()))`
 fn len_comparison<'hir>(
     bin_op: BinOp,
     left: &'hir Expr<'hir>,
@@ -114,6 +117,8 @@ fn len_comparison<'hir>(
         (Rel::Lt, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanInt, *right as usize, left)),
         (Rel::Le, int_lit_pat!(left), _) => Some((LengthComparison::IntLessThanOrEqualLength, *left as usize, right)),
         (Rel::Le, _, int_lit_pat!(right)) => Some((LengthComparison::LengthLessThanOrEqualInt, *right as usize, left)),
+        (Rel::Eq, int_lit_pat!(left), _) => Some((LengthComparison::LengthEqualInt, *left as usize, right)),
+        (Rel::Eq, _, int_lit_pat!(right)) => Some((LengthComparison::LengthEqualInt, *right as usize, left)),
         _ => None,
     }
 }
@@ -316,11 +321,11 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnhashMap<u64, Vec<IndexEntry<'_>>
                 continue;
             };
 
-            match entry {
+            match *entry {
                 IndexEntry::AssertWithIndex {
                     highest_index,
                     asserted_len,
-                    indexes,
+                    ref indexes,
                     comparison,
                     assert_span,
                     slice,
@@ -343,6 +348,12 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnhashMap<u64, Vec<IndexEntry<'_>>
                             "assert!({}.len() > {highest_index})",
                             snippet(cx, slice.span, "..")
                         )),
+                        // `highest_index` here is rather a length, so we need to add 1 to it
+                        LengthComparison::LengthEqualInt if asserted_len < highest_index + 1 => Some(format!(
+                            "assert!({}.len() == {})",
+                            snippet(cx, slice.span, ".."),
+                            highest_index + 1
+                        )),
                         _ => None,
                     };
 
@@ -354,7 +365,7 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnhashMap<u64, Vec<IndexEntry<'_>>
                             indexes,
                             |diag| {
                                 diag.span_suggestion(
-                                    *assert_span,
+                                    assert_span,
                                     "provide the highest index that is indexed with",
                                     sugg,
                                     Applicability::MachineApplicable,
@@ -364,7 +375,7 @@ fn report_indexes(cx: &LateContext<'_>, map: &UnhashMap<u64, Vec<IndexEntry<'_>>
                     }
                 },
                 IndexEntry::IndexWithoutAssert {
-                    indexes,
+                    ref indexes,
                     highest_index,
                     slice,
                 } if indexes.len() > 1 => {
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 34119c6911c..3ff40081c47 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,7 +213,9 @@ 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 Some(parent_node) = vis.cx.tcx.opt_hir_node(parent_id) else {
+            break;
+        };
 
         let stop_early = match parent_node {
             Node::Expr(expr) => check_expr(vis, expr),
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
index 85166b0dd95..a32bca3d038 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -2,7 +2,7 @@ use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap};
 use clippy_utils::source::snippet_with_context;
-use clippy_utils::ty::is_copy;
+use clippy_utils::ty::{implements_trait, is_copy};
 use clippy_utils::{expr_use_ctxt, peel_n_hir_expr_refs, DefinedTy, ExprUseNode};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
@@ -169,6 +169,7 @@ fn needless_borrow_count<'tcx>(
 ) -> usize {
     let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
     let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
+    let drop_trait_def_id = cx.tcx.lang_items().drop_trait();
 
     let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder();
     let predicates = cx.tcx.param_env(fn_id).caller_bounds();
@@ -223,7 +224,14 @@ fn needless_borrow_count<'tcx>(
     // elements are modified each time `check_referent` is called.
     let mut args_with_referent_ty = callee_args.to_vec();
 
-    let mut check_reference_and_referent = |reference, referent| {
+    let mut check_reference_and_referent = |reference: &Expr<'tcx>, referent: &Expr<'tcx>| {
+        if let ExprKind::Field(base, _) = &referent.kind {
+            let base_ty = cx.typeck_results().expr_ty(base);
+            if drop_trait_def_id.map_or(false, |id| implements_trait(cx, base_ty, id, &[])) {
+                return false;
+            }
+        }
+
         let referent_ty = cx.typeck_results().expr_ty(referent);
 
         if !is_copy(cx, referent_ty)
diff --git a/src/tools/clippy/clippy_lints/src/needless_if.rs b/src/tools/clippy/clippy_lints/src/needless_if.rs
index 41d05d72284..51bee4b51f6 100644
--- a/src/tools/clippy/clippy_lints/src/needless_if.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_if.rs
@@ -44,7 +44,6 @@ impl LateLintPass<'_> for NeedlessIf {
             && block.stmts.is_empty()
             && block.expr.is_none()
             && !in_external_macro(cx.sess(), expr.span)
-            && !is_from_proc_macro(cx, expr)
             && let Some(then_snippet) = snippet_opt(cx, then.span)
             // Ignore
             // - empty macro expansions
@@ -53,6 +52,7 @@ impl LateLintPass<'_> for NeedlessIf {
             // - #[cfg]'d out code
             && then_snippet.chars().all(|ch| matches!(ch, '{' | '}') || ch.is_ascii_whitespace())
             && let Some(cond_snippet) = snippet_opt(cx, cond.span)
+            && !is_from_proc_macro(cx, expr)
         {
             span_lint_and_sugg(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 6e65dd628a4..5978da83199 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -87,6 +87,17 @@ impl<'tcx> LateLintPass<'tcx> for NoEffect {
 
 fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
     if let StmtKind::Semi(expr) = stmt.kind {
+        // move `expr.span.from_expansion()` ahead
+        if expr.span.from_expansion() {
+            return false;
+        }
+        let expr = peel_blocks(expr);
+
+        if is_operator_overridden(cx, expr) {
+            // Return `true`, to prevent `check_unnecessary_operation` from
+            // linting on this statement as well.
+            return true;
+        }
         if has_no_effect(cx, expr) {
             span_lint_hir_and_then(
                 cx,
@@ -153,11 +164,26 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
     false
 }
 
-fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
-    if expr.span.from_expansion() {
-        return false;
+fn is_operator_overridden(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    // It's very hard or impossable to check whether overridden operator have side-effect this lint.
+    // So, this function assume user-defined operator is overridden with an side-effect.
+    // The definition of user-defined structure here is ADT-type,
+    // Althrough this will weaken the ability of this lint, less error lint-fix happen.
+    match expr.kind {
+        ExprKind::Binary(..) | ExprKind::Unary(..) => {
+            // No need to check type of `lhs` and `rhs`
+            // because if the operator is overridden, at least one operand is ADT type
+
+            // reference: rust/compiler/rustc_middle/src/ty/typeck_results.rs: `is_method_call`.
+            // use this function to check whether operator is overridden in `ExprKind::{Binary, Unary}`.
+            cx.typeck_results().is_method_call(expr)
+        },
+        _ => false,
     }
-    match peel_blocks(expr).kind {
+}
+
+fn has_no_effect(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
+    match expr.kind {
         ExprKind::Lit(..) | ExprKind::Closure { .. } => true,
         ExprKind::Path(..) => !has_drop(cx, cx.typeck_results().expr_ty(expr)),
         ExprKind::Index(a, b, _) | ExprKind::Binary(_, a, b) => has_no_effect(cx, a) && has_no_effect(cx, b),
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
index 1a2b20bf438..c081dec9b6b 100644
--- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs
@@ -132,7 +132,11 @@ impl ArithmeticSideEffects {
     }
 
     // Common entry-point to avoid code duplication.
-    fn issue_lint(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) {
+    fn issue_lint<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
+        if is_from_proc_macro(cx, expr) {
+            return;
+        }
+
         let msg = "arithmetic operation that can potentially result in unexpected side-effects";
         span_lint(cx, ARITHMETIC_SIDE_EFFECTS, expr.span, msg);
         self.expr_span = Some(expr.span);
@@ -160,10 +164,10 @@ impl ArithmeticSideEffects {
     fn manage_bin_ops<'tcx>(
         &mut self,
         cx: &LateContext<'tcx>,
-        expr: &hir::Expr<'tcx>,
+        expr: &'tcx hir::Expr<'_>,
         op: &Spanned<hir::BinOpKind>,
-        lhs: &hir::Expr<'tcx>,
-        rhs: &hir::Expr<'tcx>,
+        lhs: &'tcx hir::Expr<'_>,
+        rhs: &'tcx hir::Expr<'_>,
     ) {
         if constant_simple(cx, cx.typeck_results(), expr).is_some() {
             return;
@@ -236,10 +240,10 @@ impl ArithmeticSideEffects {
     /// provided input.
     fn manage_method_call<'tcx>(
         &mut self,
-        args: &[hir::Expr<'tcx>],
+        args: &'tcx [hir::Expr<'_>],
         cx: &LateContext<'tcx>,
-        ps: &hir::PathSegment<'tcx>,
-        receiver: &hir::Expr<'tcx>,
+        ps: &'tcx hir::PathSegment<'_>,
+        receiver: &'tcx hir::Expr<'_>,
     ) {
         let Some(arg) = args.first() else {
             return;
@@ -264,8 +268,8 @@ impl ArithmeticSideEffects {
     fn manage_unary_ops<'tcx>(
         &mut self,
         cx: &LateContext<'tcx>,
-        expr: &hir::Expr<'tcx>,
-        un_expr: &hir::Expr<'tcx>,
+        expr: &'tcx hir::Expr<'_>,
+        un_expr: &'tcx hir::Expr<'_>,
         un_op: hir::UnOp,
     ) {
         let hir::UnOp::Neg = un_op else {
@@ -287,14 +291,13 @@ impl ArithmeticSideEffects {
 
     fn should_skip_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) -> bool {
         is_lint_allowed(cx, ARITHMETIC_SIDE_EFFECTS, expr.hir_id)
-            || is_from_proc_macro(cx, expr)
             || self.expr_span.is_some()
             || self.const_span.map_or(false, |sp| sp.contains(expr.span))
     }
 }
 
 impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
         if self.should_skip_expr(cx, expr) {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/renamed_lints.rs b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
index 9f5897d2ca7..85979903b58 100644
--- a/src/tools/clippy/clippy_lints/src/renamed_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/renamed_lints.rs
@@ -4,8 +4,9 @@
 pub static RENAMED_LINTS: &[(&str, &str)] = &[
     ("clippy::almost_complete_letter_range", "clippy::almost_complete_range"),
     ("clippy::blacklisted_name", "clippy::disallowed_names"),
-    ("clippy::block_in_if_condition_expr", "clippy::blocks_in_if_conditions"),
-    ("clippy::block_in_if_condition_stmt", "clippy::blocks_in_if_conditions"),
+    ("clippy::block_in_if_condition_expr", "clippy::blocks_in_conditions"),
+    ("clippy::block_in_if_condition_stmt", "clippy::blocks_in_conditions"),
+    ("clippy::blocks_in_if_conditions", "clippy::blocks_in_conditions"),
     ("clippy::box_vec", "clippy::box_collection"),
     ("clippy::const_static_lifetime", "clippy::redundant_static_lifetimes"),
     ("clippy::cyclomatic_complexity", "clippy::cognitive_complexity"),
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
new file mode 100644
index 00000000000..5a4933a3fce
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
@@ -0,0 +1,114 @@
+use clippy_utils::consts::{constant, Constant};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::higher::VecArgs;
+use clippy_utils::macros::root_macro_call;
+use clippy_utils::source::snippet;
+use clippy_utils::{expr_or_init, fn_def_id, match_def_path, paths};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::declare_lint_pass;
+use rustc_span::{sym, Span};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Looks for patterns such as `vec![Vec::with_capacity(x); n]` or `iter::repeat(Vec::with_capacity(x))`.
+    ///
+    /// ### Why is this bad?
+    /// These constructs work by cloning the element, but cloning a `Vec<_>` does not
+    /// respect the old vector's capacity and effectively discards it.
+    ///
+    /// This makes `iter::repeat(Vec::with_capacity(x))` especially suspicious because the user most certainly
+    /// expected that the yielded `Vec<_>` will have the requested capacity, otherwise one can simply write
+    /// `iter::repeat(Vec::new())` instead and it will have the same effect.
+    ///
+    /// Similarly for `vec![x; n]`, the element `x` is cloned to fill the vec.
+    /// Unlike `iter::repeat` however, the vec repeat macro does not have to clone the value `n` times
+    /// but just `n - 1` times, because it can reuse the passed value for the last slot.
+    /// That means that the last `Vec<_>` gets the requested capacity but all other ones do not.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # use std::iter;
+    ///
+    /// let _: Vec<Vec<u8>> = vec![Vec::with_capacity(42); 123];
+    /// let _: Vec<Vec<u8>> = iter::repeat(Vec::with_capacity(42)).take(123).collect();
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// # use std::iter;
+    ///
+    /// let _: Vec<Vec<u8>> = iter::repeat_with(|| Vec::with_capacity(42)).take(123).collect();
+    /// //                                      ^^^ this closure executes 123 times
+    /// //                                          and the vecs will have the expected capacity
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub REPEAT_VEC_WITH_CAPACITY,
+    suspicious,
+    "repeating a `Vec::with_capacity` expression which does not retain capacity"
+}
+
+declare_lint_pass!(RepeatVecWithCapacity => [REPEAT_VEC_WITH_CAPACITY]);
+
+fn emit_lint(cx: &LateContext<'_>, span: Span, kind: &str, note: &'static str, sugg_msg: &'static str, sugg: String) {
+    span_lint_and_then(
+        cx,
+        REPEAT_VEC_WITH_CAPACITY,
+        span,
+        &format!("repeating `Vec::with_capacity` using `{kind}`, which does not retain capacity"),
+        |diag| {
+            diag.note(note);
+            diag.span_suggestion_verbose(span, sugg_msg, sugg, Applicability::MaybeIncorrect);
+        },
+    );
+}
+
+/// Checks `vec![Vec::with_capacity(x); n]`
+fn check_vec_macro(cx: &LateContext<'_>, expr: &Expr<'_>) {
+    if let Some(mac_call) = root_macro_call(expr.span)
+        && cx.tcx.is_diagnostic_item(sym::vec_macro, mac_call.def_id)
+        && let Some(VecArgs::Repeat(repeat_expr, len_expr)) = VecArgs::hir(cx, expr)
+        && fn_def_id(cx, repeat_expr).is_some_and(|did| match_def_path(cx, did, &paths::VEC_WITH_CAPACITY))
+        && !len_expr.span.from_expansion()
+        && let Some(Constant::Int(2..)) = constant(cx, cx.typeck_results(), expr_or_init(cx, len_expr))
+    {
+        emit_lint(
+            cx,
+            expr.span.source_callsite(),
+            "vec![x; n]",
+            "only the last `Vec` will have the capacity",
+            "if you intended to initialize multiple `Vec`s with an initial capacity, try",
+            format!(
+                "(0..{}).map(|_| {}).collect::<Vec<_>>()",
+                snippet(cx, len_expr.span, ""),
+                snippet(cx, repeat_expr.span, "..")
+            ),
+        );
+    }
+}
+
+/// Checks `iter::repeat(Vec::with_capacity(x))`
+fn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>) {
+    if !expr.span.from_expansion()
+        && fn_def_id(cx, expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::iter_repeat, did))
+        && let ExprKind::Call(_, [repeat_expr]) = expr.kind
+        && fn_def_id(cx, repeat_expr).is_some_and(|did| match_def_path(cx, did, &paths::VEC_WITH_CAPACITY))
+        && !repeat_expr.span.from_expansion()
+    {
+        emit_lint(
+            cx,
+            expr.span,
+            "iter::repeat",
+            "none of the yielded `Vec`s will have the requested capacity",
+            "if you intended to create an iterator that yields `Vec`s with an initial capacity, try",
+            format!("std::iter::repeat_with(|| {})", snippet(cx, repeat_expr.span, "..")),
+        );
+    }
+}
+
+impl LateLintPass<'_> for RepeatVecWithCapacity {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
+        check_vec_macro(cx, expr);
+        check_repeat_fn(cx, expr);
+    }
+}
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 1316343e0c2..7a351dab2d4 100644
--- a/src/tools/clippy/clippy_lints/src/same_name_method.rs
+++ b/src/tools/clippy/clippy_lints/src/same_name_method.rs
@@ -55,11 +55,11 @@ impl<'tcx> LateLintPass<'tcx> for SameNameMethod {
             if matches!(cx.tcx.def_kind(id.owner_id), DefKind::Impl { .. })
                 && let item = cx.tcx.hir().item(id)
                 && let ItemKind::Impl(Impl {
-                  items,
-                  of_trait,
-                  self_ty,
-                  ..
-                                      }) = &item.kind
+                    items,
+                    of_trait,
+                    self_ty,
+                    ..
+                }) = &item.kind
                 && let TyKind::Path(QPath::Resolved(_, Path { res, .. })) = self_ty.kind
             {
                 if !map.contains_key(res) {
@@ -75,24 +75,24 @@ 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)
-                            && let Res::Def(DefKind::Trait, did) = path.res
-                        {
-                            // FIXME: if
-                            // `rustc_middle::ty::assoc::AssocItems::items` is public,
-                            // we can iterate its keys instead of `in_definition_order`,
-                            // which's more efficient
-                            cx.tcx
-                                .associated_items(did)
-                                .in_definition_order()
-                                .filter(|assoc_item| matches!(assoc_item.kind, AssocKind::Fn))
-                                .map(|assoc_item| assoc_item.name)
-                                .collect()
-                        } else {
-                            BTreeSet::new()
-                        };
+                        let mut methods_in_trait: BTreeSet<Symbol> =
+                            if let Some(Node::TraitRef(TraitRef { path, .. })) =
+                                cx.tcx.opt_hir_node(trait_ref.hir_ref_id)
+                                && let Res::Def(DefKind::Trait, did) = path.res
+                            {
+                                // FIXME: if
+                                // `rustc_middle::ty::assoc::AssocItems::items` is public,
+                                // we can iterate its keys instead of `in_definition_order`,
+                                // which's more efficient
+                                cx.tcx
+                                    .associated_items(did)
+                                    .in_definition_order()
+                                    .filter(|assoc_item| matches!(assoc_item.kind, AssocKind::Fn))
+                                    .map(|assoc_item| assoc_item.name)
+                                    .collect()
+                            } else {
+                                BTreeSet::new()
+                            };
 
                         let mut check_trait_method = |method_name: Symbol, trait_method_span: Span| {
                             if let Some((impl_span, hir_id)) = existing_name.impl_methods.get(&method_name) {
diff --git a/src/tools/clippy/clippy_lints/src/single_call_fn.rs b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
index 396d2717a13..8e181c3ccc7 100644
--- a/src/tools/clippy/clippy_lints/src/single_call_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/single_call_fn.rs
@@ -72,8 +72,8 @@ impl<'tcx> LateLintPass<'tcx> for SingleCallFn {
     ) {
         if self.avoid_breaking_exported_api && cx.effective_visibilities.is_exported(def_id)
             || in_external_macro(cx.sess(), span)
-            || is_from_proc_macro(cx, &(&kind, body, cx.tcx.local_def_id_to_hir_id(def_id), span))
             || is_in_test_function(cx.tcx, body.value.hir_id)
+            || is_from_proc_macro(cx, &(&kind, body, cx.tcx.local_def_id_to_hir_id(def_id), span))
         {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/uninhabited_references.rs b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
new file mode 100644
index 00000000000..d41576cadad
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/uninhabited_references.rs
@@ -0,0 +1,84 @@
+use clippy_utils::diagnostics::span_lint;
+use rustc_hir::intravisit::FnKind;
+use rustc_hir::{Body, Expr, ExprKind, FnDecl, FnRetTy, TyKind, UnOp};
+use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::lint::in_external_macro;
+use rustc_session::declare_lint_pass;
+use rustc_span::def_id::LocalDefId;
+use rustc_span::Span;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// It detects references to uninhabited types, such as `!` and
+    /// warns when those are either dereferenced or returned from a function.
+    ///
+    /// ### Why is this bad?
+    /// Dereferencing a reference to an uninhabited type would create
+    /// an instance of such a type, which cannot exist. This constitutes
+    /// undefined behaviour. Such a reference could have been created
+    /// by `unsafe` code.
+    ///
+    /// ### Example
+    /// The following function can return a reference to an uninhabited type
+    /// (`Infallible`) because it uses `unsafe` code to create it. However,
+    /// the user of such a function could dereference the return value and
+    /// trigger an undefined behavior from safe code.
+    ///
+    /// ```no_run
+    /// fn create_ref() -> &'static std::convert::Infallible {
+    ///     unsafe { std::mem::transmute(&()) }
+    /// }
+    /// ```
+    #[clippy::version = "1.76.0"]
+    pub UNINHABITED_REFERENCES,
+    suspicious,
+    "reference to uninhabited type"
+}
+
+declare_lint_pass!(UninhabitedReferences => [UNINHABITED_REFERENCES]);
+
+impl LateLintPass<'_> for UninhabitedReferences {
+    fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
+        if in_external_macro(cx.tcx.sess, expr.span) {
+            return;
+        }
+
+        if let ExprKind::Unary(UnOp::Deref, _) = expr.kind {
+            let ty = cx.typeck_results().expr_ty_adjusted(expr);
+            if ty.is_privately_uninhabited(cx.tcx, cx.param_env) {
+                span_lint(
+                    cx,
+                    UNINHABITED_REFERENCES,
+                    expr.span,
+                    "dereferencing a reference to an uninhabited type is undefined behavior",
+                );
+            }
+        }
+    }
+
+    fn check_fn(
+        &mut self,
+        cx: &LateContext<'_>,
+        kind: FnKind<'_>,
+        fndecl: &'_ FnDecl<'_>,
+        _: &'_ Body<'_>,
+        span: Span,
+        _: LocalDefId,
+    ) {
+        if in_external_macro(cx.tcx.sess, span) || matches!(kind, FnKind::Closure) {
+            return;
+        }
+        if let FnRetTy::Return(hir_ty) = fndecl.output
+            && let TyKind::Ref(_, mut_ty) = hir_ty.kind
+            && hir_ty_to_ty(cx.tcx, mut_ty.ty).is_privately_uninhabited(cx.tcx, cx.param_env)
+        {
+            span_lint(
+                cx,
+                UNINHABITED_REFERENCES,
+                hir_ty.span,
+                "dereferencing a reference to an uninhabited type would be undefined behavior",
+            );
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs b/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
index 9979e02297e..2b0d2d61d20 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
@@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
             };
             match constructor_symbol {
                 sym::Some | sym::Ok if path.ident.name == rustc_span::sym::map => (),
-                sym::Err if path.ident.name == sym!(map_err) => (),
+                sym::Err if path.ident.name == sym::map_err => (),
                 _ => return,
             }
 
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index 373b076f92c..fae1b90ace2 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -28,12 +28,12 @@ use rustc_span::{sym, Loc, Span, Symbol};
 use serde::ser::SerializeStruct;
 use serde::{Serialize, Serializer};
 use std::collections::{BTreeSet, BinaryHeap};
-use std::fmt;
 use std::fmt::Write as _;
 use std::fs::{self, File};
 use std::io::prelude::*;
 use std::path::{Path, PathBuf};
 use std::process::Command;
+use std::{env, fmt};
 
 /// This is the json output file of the lint collector.
 const JSON_OUTPUT_FILE: &str = "../util/gh-pages/lints.json";
@@ -415,7 +415,7 @@ fn get_lint_output(lint_name: &str, example: &[&mut String], clippy_project_root
 
     let prefixed_name = format!("{CLIPPY_LINT_GROUP_PREFIX}{lint_name}");
 
-    let mut cmd = Command::new("cargo");
+    let mut cmd = Command::new(env::var("CARGO").unwrap_or("cargo".into()));
 
     cmd.current_dir(clippy_project_root)
         .env("CARGO_INCREMENTAL", "0")
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index 31a81a52497..6e449dc9806 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -218,7 +218,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
         ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) {
             Res::Local(hir_id) => {
                 let parent_id = cx.tcx.hir().parent_id(hir_id);
-                if let Some(Node::Local(Local { init: Some(init), .. })) = cx.tcx.hir_node(parent_id) {
+                if let Node::Local(Local { init: Some(init), .. }) = cx.tcx.hir_node(parent_id) {
                     path_to_matched_type(cx, init)
                 } else {
                     None
@@ -246,7 +246,7 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
 fn read_mir_alloc_def_path<'tcx>(cx: &LateContext<'tcx>, alloc: &'tcx Allocation, ty: Ty<'_>) -> Option<Vec<String>> {
     let (alloc, ty) = if let ty::Ref(_, ty, Mutability::Not) = *ty.kind() {
         let &alloc = alloc.provenance().ptrs().values().next()?;
-        if let GlobalAlloc::Memory(alloc) = cx.tcx.global_alloc(alloc) {
+        if let GlobalAlloc::Memory(alloc) = cx.tcx.global_alloc(alloc.alloc_id()) {
             (alloc.inner(), ty)
         } else {
             return None;
@@ -264,7 +264,7 @@ fn read_mir_alloc_def_path<'tcx>(cx: &LateContext<'tcx>, alloc: &'tcx Allocation
             .ptrs()
             .values()
             .map(|&alloc| {
-                if let GlobalAlloc::Memory(alloc) = cx.tcx.global_alloc(alloc) {
+                if let GlobalAlloc::Memory(alloc) = cx.tcx.global_alloc(alloc.alloc_id()) {
                     let alloc = alloc.inner();
                     str::from_utf8(alloc.inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len()))
                         .ok()
diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs
index ba958c5b392..5e13c73f035 100644
--- a/src/tools/clippy/clippy_lints/src/vec.rs
+++ b/src/tools/clippy/clippy_lints/src/vec.rs
@@ -1,25 +1,27 @@
+use std::collections::BTreeMap;
 use std::ops::ControlFlow;
 
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::consts::{constant, Constant};
-use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::is_copy;
 use clippy_utils::visitors::for_each_local_use_after_expr;
 use clippy_utils::{get_parent_expr, higher, is_trait_method};
 use rustc_errors::Applicability;
-use rustc_hir::{BorrowKind, Expr, ExprKind, Mutability, Node, PatKind};
+use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Node, PatKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::impl_lint_pass;
-use rustc_span::{sym, Span};
+use rustc_span::{sym, DesugaringKind, Span};
 
 #[expect(clippy::module_name_repetitions)]
 #[derive(Clone)]
 pub struct UselessVec {
     pub too_large_for_stack: u64,
     pub msrv: Msrv,
+    pub span_to_lint_map: BTreeMap<Span, Option<(HirId, SuggestedType, String, Applicability)>>,
 }
 
 declare_clippy_lint! {
@@ -69,64 +71,88 @@ pub fn is_allowed_vec_method(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
 
 impl<'tcx> LateLintPass<'tcx> for UselessVec {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        // search for `&vec![_]` or `vec![_]` expressions where the adjusted type is `&[_]`
-        if adjusts_to_slice(cx, expr)
-            && let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows())
-        {
-            let (suggest_slice, span) = if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind {
-                // `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.)
-                (SuggestedType::SliceRef(mutability), expr.span)
-            } else {
-                // `expr` is the `vec![_]` expansion, so suggest `[_]`
-                // and also use the span of the actual `vec![_]` expression
-                (SuggestedType::Array, expr.span.ctxt().outer_expn_data().call_site)
-            };
-
-            self.check_vec_macro(cx, &vec_args, span, suggest_slice);
-        }
+        if let Some(vec_args) = higher::VecArgs::hir(cx, expr.peel_borrows()) {
+            // search for `let foo = vec![_]` expressions where all uses of `foo`
+            // adjust to slices or call a method that exist on slices (e.g. len)
+            if let Node::Local(local) = cx.tcx.hir().get_parent(expr.hir_id)
+                // for now ignore locals with type annotations.
+                // this is to avoid compile errors when doing the suggestion here: let _: Vec<_> = vec![..];
+                && local.ty.is_none()
+                && let PatKind::Binding(_, id, ..) = local.pat.kind
+                && is_copy(cx, vec_type(cx.typeck_results().expr_ty_adjusted(expr.peel_borrows())))
+            {
+                let only_slice_uses = for_each_local_use_after_expr(cx, id, expr.hir_id, |expr| {
+                    // allow indexing into a vec and some set of allowed method calls that exist on slices, too
+                    if let Some(parent) = get_parent_expr(cx, expr)
+                        && (adjusts_to_slice(cx, expr)
+                            || matches!(parent.kind, ExprKind::Index(..))
+                            || is_allowed_vec_method(cx, parent))
+                    {
+                        ControlFlow::Continue(())
+                    } else {
+                        ControlFlow::Break(())
+                    }
+                })
+                .is_continue();
 
-        // search for `let foo = vec![_]` expressions where all uses of `foo`
-        // adjust to slices or call a method that exist on slices (e.g. len)
-        if let Some(vec_args) = higher::VecArgs::hir(cx, expr)
-            && let Node::Local(local) = cx.tcx.hir().get_parent(expr.hir_id)
-            // for now ignore locals with type annotations.
-            // this is to avoid compile errors when doing the suggestion here: let _: Vec<_> = vec![..];
-            && local.ty.is_none()
-            && let PatKind::Binding(_, id, ..) = local.pat.kind
-            && is_copy(cx, vec_type(cx.typeck_results().expr_ty_adjusted(expr)))
-        {
-            let only_slice_uses = for_each_local_use_after_expr(cx, id, expr.hir_id, |expr| {
-                // allow indexing into a vec and some set of allowed method calls that exist on slices, too
-                if let Some(parent) = get_parent_expr(cx, expr)
-                    && (adjusts_to_slice(cx, expr)
-                        || matches!(parent.kind, ExprKind::Index(..))
-                        || is_allowed_vec_method(cx, parent))
-                {
-                    ControlFlow::Continue(())
+                let span = expr.span.ctxt().outer_expn_data().call_site;
+                if only_slice_uses {
+                    self.check_vec_macro(cx, &vec_args, span, expr.hir_id, SuggestedType::Array);
                 } else {
-                    ControlFlow::Break(())
+                    self.span_to_lint_map.insert(span, None);
+                }
+            }
+            // if the local pattern has a specified type, do not lint.
+            else if let Some(_) = higher::VecArgs::hir(cx, expr)
+                && let Node::Local(local) = cx.tcx.hir().get_parent(expr.hir_id)
+                && local.ty.is_some()
+            {
+                let span = expr.span.ctxt().outer_expn_data().call_site;
+                self.span_to_lint_map.insert(span, None);
+            }
+            // search for `for _ in vec![...]`
+            else if let Some(parent) = get_parent_expr(cx, expr)
+                && parent.span.is_desugaring(DesugaringKind::ForLoop)
+                && self.msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
+            {
+                // report the error around the `vec!` not inside `<std macros>:`
+                let span = expr.span.ctxt().outer_expn_data().call_site;
+                self.check_vec_macro(cx, &vec_args, span, expr.hir_id, SuggestedType::Array);
+            }
+            // search for `&vec![_]` or `vec![_]` expressions where the adjusted type is `&[_]`
+            else {
+                let (suggest_slice, span) = if let ExprKind::AddrOf(BorrowKind::Ref, mutability, _) = expr.kind {
+                    // `expr` is `&vec![_]`, so suggest `&[_]` (or `&mut[_]` resp.)
+                    (SuggestedType::SliceRef(mutability), expr.span)
+                } else {
+                    // `expr` is the `vec![_]` expansion, so suggest `[_]`
+                    // and also use the span of the actual `vec![_]` expression
+                    (SuggestedType::Array, expr.span.ctxt().outer_expn_data().call_site)
+                };
+
+                if adjusts_to_slice(cx, expr) {
+                    self.check_vec_macro(cx, &vec_args, span, expr.hir_id, suggest_slice);
+                } else {
+                    self.span_to_lint_map.insert(span, None);
                 }
-            })
-            .is_continue();
-
-            if only_slice_uses {
-                self.check_vec_macro(
-                    cx,
-                    &vec_args,
-                    expr.span.ctxt().outer_expn_data().call_site,
-                    SuggestedType::Array,
-                );
             }
         }
+    }
 
-        // search for `for _ in vec![…]`
-        if let Some(higher::ForLoop { arg, .. }) = higher::ForLoop::hir(expr)
-            && let Some(vec_args) = higher::VecArgs::hir(cx, arg)
-            && self.msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
-        {
-            // report the error around the `vec!` not inside `<std macros>:`
-            let span = arg.span.ctxt().outer_expn_data().call_site;
-            self.check_vec_macro(cx, &vec_args, span, SuggestedType::Array);
+    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
+        for (span, lint_opt) in &self.span_to_lint_map {
+            if let Some((hir_id, suggest_slice, snippet, applicability)) = lint_opt {
+                let help_msg = format!(
+                    "you can use {} directly",
+                    match suggest_slice {
+                        SuggestedType::SliceRef(_) => "a slice",
+                        SuggestedType::Array => "an array",
+                    }
+                );
+                span_lint_hir_and_then(cx, USELESS_VEC, *hir_id, *span, "useless use of `vec!`", |diag| {
+                    diag.span_suggestion(*span, help_msg, snippet, *applicability);
+                });
+            }
         }
     }
 
@@ -134,7 +160,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessVec {
 }
 
 #[derive(Copy, Clone)]
-enum SuggestedType {
+pub(crate) enum SuggestedType {
     /// Suggest using a slice `&[..]` / `&mut [..]`
     SliceRef(Mutability),
     /// Suggest using an array: `[..]`
@@ -147,6 +173,7 @@ impl UselessVec {
         cx: &LateContext<'tcx>,
         vec_args: &higher::VecArgs<'tcx>,
         span: Span,
+        hir_id: HirId,
         suggest_slice: SuggestedType,
     ) {
         if span.from_expansion() {
@@ -204,21 +231,9 @@ impl UselessVec {
             },
         };
 
-        span_lint_and_sugg(
-            cx,
-            USELESS_VEC,
-            span,
-            "useless use of `vec!`",
-            &format!(
-                "you can use {} directly",
-                match suggest_slice {
-                    SuggestedType::SliceRef(_) => "a slice",
-                    SuggestedType::Array => "an array",
-                }
-            ),
-            snippet,
-            applicability,
-        );
+        self.span_to_lint_map
+            .entry(span)
+            .or_insert(Some((hir_id, suggest_slice, snippet, applicability)));
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 47237de4fef..e36f2fa87a7 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -206,7 +206,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
         ) => {
             eq_closure_binder(lb, rb)
                 && lc == rc
-                && la.map_or(false, |la| la.is_async()) == ra.map_or(false, |ra| ra.is_async())
+                && la.map_or(false, CoroutineKind::is_async) == ra.map_or(false, CoroutineKind::is_async)
                 && lm == rm
                 && eq_fn_decl(lf, rf)
                 && eq_expr(le, re)
@@ -564,13 +564,16 @@ pub fn eq_fn_sig(l: &FnSig, r: &FnSig) -> bool {
 }
 
 fn eq_opt_coroutine_kind(l: Option<CoroutineKind>, r: Option<CoroutineKind>) -> bool {
-    match (l, r) {
+    matches!(
+        (l, r),
         (Some(CoroutineKind::Async { .. }), Some(CoroutineKind::Async { .. }))
-        | (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
-        | (Some(CoroutineKind::AsyncGen { .. }), Some(CoroutineKind::AsyncGen { .. })) => true,
-        (None, None) => true,
-        _ => false,
-    }
+            | (Some(CoroutineKind::Gen { .. }), Some(CoroutineKind::Gen { .. }))
+            | (
+                Some(CoroutineKind::AsyncGen { .. }),
+                Some(CoroutineKind::AsyncGen { .. })
+            )
+            | (None, None)
+    )
 }
 
 pub fn eq_fn_header(l: &FnHeader, r: &FnHeader) -> bool {
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index 3f68b6d75b5..470d31fa3e1 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -12,14 +12,14 @@
 //! code was written, and check if the span contains that text. Note this will only work correctly
 //! if the span is not from a `macro_rules` based macro.
 
-use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, UintTy};
+use rustc_ast::ast::{AttrKind, Attribute, IntTy, LitIntType, LitKind, StrStyle, TraitObjectSyntax, UintTy};
 use rustc_ast::token::CommentKind;
 use rustc_ast::AttrStyle;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
-    Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, HirId, Impl, ImplItem,
-    ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, MutTy, Node, QPath, TraitItem, TraitItemKind, Ty,
-    TyKind, UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource,
+    Block, BlockCheckMode, Body, Closure, Destination, Expr, ExprKind, FieldDef, FnHeader, FnRetTy, HirId, Impl,
+    ImplItem, ImplItemKind, IsAuto, Item, ItemKind, LoopSource, MatchSource, MutTy, Node, QPath, TraitItem,
+    TraitItemKind, Ty, TyKind, UnOp, UnsafeSource, Unsafety, Variant, VariantData, YieldSource,
 };
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::ty::TyCtxt;
@@ -33,8 +33,6 @@ use rustc_target::spec::abi::Abi;
 pub enum Pat {
     /// A single string.
     Str(&'static str),
-    /// A single string.
-    OwnedStr(String),
     /// Any of the given strings.
     MultiStr(&'static [&'static str]),
     /// Any of the given strings.
@@ -59,14 +57,12 @@ fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) ->
         let end_str = s.trim_end_matches(|c: char| c.is_whitespace() || c == ')' || c == ',');
         (match start_pat {
             Pat::Str(text) => start_str.starts_with(text),
-            Pat::OwnedStr(text) => start_str.starts_with(&text),
             Pat::MultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
             Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
             Pat::Sym(sym) => start_str.starts_with(sym.as_str()),
             Pat::Num => start_str.as_bytes().first().map_or(false, u8::is_ascii_digit),
         } && match end_pat {
             Pat::Str(text) => end_str.ends_with(text),
-            Pat::OwnedStr(text) => end_str.starts_with(&text),
             Pat::MultiStr(texts) => texts.iter().any(|s| start_str.ends_with(s)),
             Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
             Pat::Sym(sym) => end_str.ends_with(sym.as_str()),
@@ -125,6 +121,8 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) {
 fn expr_search_pat(tcx: TyCtxt<'_>, e: &Expr<'_>) -> (Pat, Pat) {
     match e.kind {
         ExprKind::ConstBlock(_) => (Pat::Str("const"), Pat::Str("}")),
+        // Parenthesis are trimmed from the text before the search patterns are matched.
+        // See: `span_matches_pat`
         ExprKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")),
         ExprKind::Unary(UnOp::Deref, e) => (Pat::Str("*"), expr_search_pat(tcx, e).1),
         ExprKind::Unary(UnOp::Not, e) => (Pat::Str("!"), expr_search_pat(tcx, e).1),
@@ -286,23 +284,17 @@ fn fn_kind_pat(tcx: TyCtxt<'_>, kind: &FnKind<'_>, body: &Body<'_>, hir_id: HirI
 fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) {
     match attr.kind {
         AttrKind::Normal(..) => {
-            let mut pat = if matches!(attr.style, AttrStyle::Outer) {
-                (Pat::Str("#["), Pat::Str("]"))
-            } else {
-                (Pat::Str("#!["), Pat::Str("]"))
-            };
-
-            if let Some(ident) = attr.ident()
-                && let Pat::Str(old_pat) = pat.0
-            {
+            if let Some(ident) = attr.ident() {
                 // TODO: I feel like it's likely we can use `Cow` instead but this will require quite a bit of
                 // refactoring
                 // NOTE: This will likely have false positives, like `allow = 1`
-                pat.0 = Pat::OwnedMultiStr(vec![ident.to_string(), old_pat.to_owned()]);
-                pat.1 = Pat::Str("");
+                (
+                    Pat::OwnedMultiStr(vec![ident.to_string(), "#".to_owned()]),
+                    Pat::Str(""),
+                )
+            } else {
+                (Pat::Str("#"), Pat::Str("]"))
             }
-
-            pat
         },
         AttrKind::DocComment(_kind @ CommentKind::Line, ..) => {
             if matches!(attr.style, AttrStyle::Outer) {
@@ -324,32 +316,42 @@ fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) {
 fn ty_search_pat(ty: &Ty<'_>) -> (Pat, Pat) {
     match ty.kind {
         TyKind::Slice(..) | TyKind::Array(..) => (Pat::Str("["), Pat::Str("]")),
-        TyKind::Ptr(MutTy { mutbl, ty }) => (
-            if mutbl.is_mut() {
-                Pat::Str("*const")
-            } else {
-                Pat::Str("*mut")
-            },
-            ty_search_pat(ty).1,
-        ),
+        TyKind::Ptr(MutTy { ty, .. }) => (Pat::Str("*"), ty_search_pat(ty).1),
         TyKind::Ref(_, MutTy { ty, .. }) => (Pat::Str("&"), ty_search_pat(ty).1),
         TyKind::BareFn(bare_fn) => (
-            Pat::OwnedStr(format!("{}{} fn", bare_fn.unsafety.prefix_str(), bare_fn.abi.name())),
-            ty_search_pat(ty).1,
+            if bare_fn.unsafety == Unsafety::Unsafe {
+                Pat::Str("unsafe")
+            } else if bare_fn.abi != Abi::Rust {
+                Pat::Str("extern")
+            } else {
+                Pat::MultiStr(&["fn", "extern"])
+            },
+            match bare_fn.decl.output {
+                FnRetTy::DefaultReturn(_) => {
+                    if let [.., ty] = bare_fn.decl.inputs {
+                        ty_search_pat(ty).1
+                    } else {
+                        Pat::Str("(")
+                    }
+                },
+                FnRetTy::Return(ty) => ty_search_pat(ty).1,
+            },
         ),
-        TyKind::Never => (Pat::Str("!"), Pat::Str("")),
-        TyKind::Tup(..) => (Pat::Str("("), Pat::Str(")")),
+        TyKind::Never => (Pat::Str("!"), Pat::Str("!")),
+        // Parenthesis are trimmed from the text before the search patterns are matched.
+        // See: `span_matches_pat`
+        TyKind::Tup([]) => (Pat::Str(")"), Pat::Str("(")),
+        TyKind::Tup([ty]) => ty_search_pat(ty),
+        TyKind::Tup([head, .., tail]) => (ty_search_pat(head).0, ty_search_pat(tail).1),
         TyKind::OpaqueDef(..) => (Pat::Str("impl"), Pat::Str("")),
         TyKind::Path(qpath) => qpath_search_pat(&qpath),
-        // NOTE: This is missing `TraitObject`. It will always return true then.
+        TyKind::Infer => (Pat::Str("_"), Pat::Str("_")),
+        TyKind::TraitObject(_, _, TraitObjectSyntax::Dyn) => (Pat::Str("dyn"), Pat::Str("")),
+        // NOTE: `TraitObject` is incomplete. It will always return true then.
         _ => (Pat::Str(""), Pat::Str("")),
     }
 }
 
-fn ident_search_pat(ident: Ident) -> (Pat, Pat) {
-    (Pat::OwnedStr(ident.name.as_str().to_owned()), Pat::Str(""))
-}
-
 pub trait WithSearchPat<'cx> {
     type Context: LintContext;
     fn search_pat(&self, cx: &Self::Context) -> (Pat, Pat);
@@ -408,7 +410,7 @@ impl<'cx> WithSearchPat<'cx> for Ident {
     type Context = LateContext<'cx>;
 
     fn search_pat(&self, _cx: &Self::Context) -> (Pat, Pat) {
-        ident_search_pat(*self)
+        (Pat::Sym(self.name), Pat::Sym(self.name))
     }
 
     fn span(&self) -> Span {
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index fa56e5b0ba2..7562961538e 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -49,7 +49,6 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
     #[expect(clippy::disallowed_methods)]
     cx.struct_span_lint(lint, sp, msg.to_string(), |diag| {
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -90,7 +89,6 @@ pub fn span_lint_and_help<T: LintContext>(
             diag.help(help.to_string());
         }
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -134,7 +132,6 @@ pub fn span_lint_and_note<T: LintContext>(
             diag.note(note);
         }
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -152,7 +149,6 @@ where
     cx.struct_span_lint(lint, sp, msg.to_string(), |diag| {
         f(diag);
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -160,7 +156,6 @@ pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, s
     #[expect(clippy::disallowed_methods)]
     cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| {
         docs_link(diag, lint);
-        diag
     });
 }
 
@@ -176,7 +171,6 @@ pub fn span_lint_hir_and_then(
     cx.tcx.struct_span_lint_hir(lint, hir_id, sp, msg.to_string(), |diag| {
         f(diag);
         docs_link(diag, lint);
-        diag
     });
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 868c92f2f54..61d0663aa83 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -214,8 +214,17 @@ pub fn implements_trait<'tcx>(
     trait_id: DefId,
     args: &[GenericArg<'tcx>],
 ) -> bool {
-    let callee_id = cx.enclosing_body.map(|body| cx.tcx.hir().body_owner(body).owner.to_def_id());
-    implements_trait_with_env_from_iter(cx.tcx, cx.param_env, ty, trait_id, callee_id, args.iter().map(|&x| Some(x)))
+    let callee_id = cx
+        .enclosing_body
+        .map(|body| cx.tcx.hir().body_owner(body).owner.to_def_id());
+    implements_trait_with_env_from_iter(
+        cx.tcx,
+        cx.param_env,
+        ty,
+        trait_id,
+        callee_id,
+        args.iter().map(|&x| Some(x)),
+    )
 }
 
 /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
@@ -227,7 +236,14 @@ pub fn implements_trait_with_env<'tcx>(
     callee_id: DefId,
     args: &[GenericArg<'tcx>],
 ) -> bool {
-    implements_trait_with_env_from_iter(tcx, param_env, ty, trait_id, Some(callee_id), args.iter().map(|&x| Some(x)))
+    implements_trait_with_env_from_iter(
+        tcx,
+        param_env,
+        ty,
+        trait_id,
+        Some(callee_id),
+        args.iter().map(|&x| Some(x)),
+    )
 }
 
 /// Same as `implements_trait_from_env` but takes the arguments as an iterator.
@@ -248,19 +264,28 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
     }
 
     let infcx = tcx.infer_ctxt().build();
-    let args = args.into_iter().map(|arg| {
-        arg.into().unwrap_or_else(|| {
-            let orig = TypeVariableOrigin {
-                kind: TypeVariableOriginKind::MiscVariable,
-                span: DUMMY_SP,
-            };
-            infcx.next_ty_var(orig).into()
+    let args = args
+        .into_iter()
+        .map(|arg| {
+            arg.into().unwrap_or_else(|| {
+                let orig = TypeVariableOrigin {
+                    kind: TypeVariableOriginKind::MiscVariable,
+                    span: DUMMY_SP,
+                };
+                infcx.next_ty_var(orig).into()
+            })
         })
-    }).collect::<Vec<_>>();
+        .collect::<Vec<_>>();
 
     // If an effect arg was not specified, we need to specify it.
-    let effect_arg = if tcx.generics_of(trait_id).host_effect_index.is_some_and(|x| args.get(x - 1).is_none()) {
-        Some(GenericArg::from(callee_id.map(|def_id| tcx.expected_host_effect_param_for_body(def_id)).unwrap_or(tcx.consts.true_)))
+    let effect_arg = if tcx
+        .generics_of(trait_id)
+        .host_effect_index
+        .is_some_and(|x| args.get(x - 1).is_none())
+    {
+        Some(GenericArg::from(callee_id.map_or(tcx.consts.true_, |def_id| {
+            tcx.expected_host_effect_param_for_body(def_id)
+        })))
     } else {
         None
     };
@@ -268,9 +293,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
     let trait_ref = TraitRef::new(
         tcx,
         trait_id,
-        Some(GenericArg::from(ty))
-            .into_iter()
-            .chain(args).chain(effect_arg),
+        Some(GenericArg::from(ty)).into_iter().chain(args).chain(effect_arg),
     );
 
     debug_assert_matches!(
diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index 841b605f5fb..88966b41f69 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -367,7 +367,7 @@ impl Crate {
             //
             // The wrapper is set to the `lintcheck` so we can force enable linting and ignore certain crates
             // (see `crate::driver`)
-            let status = Command::new("cargo")
+            let status = Command::new(env::var("CARGO").unwrap_or("cargo".into()))
                 .arg("check")
                 .arg("--quiet")
                 .current_dir(&self.path)
@@ -441,7 +441,7 @@ impl Crate {
 
 /// Builds clippy inside the repo to make sure we have a clippy executable we can use.
 fn build_clippy() {
-    let status = Command::new("cargo")
+    let status = Command::new(env::var("CARGO").unwrap_or("cargo".into()))
         .arg("build")
         .status()
         .expect("Failed to build clippy!");
@@ -816,7 +816,7 @@ fn lintcheck_test() {
         "--crates-toml",
         "lintcheck/test_sources.toml",
     ];
-    let status = std::process::Command::new("cargo")
+    let status = std::process::Command::new(env::var("CARGO").unwrap_or("cargo".into()))
         .args(args)
         .current_dir("..") // repo root
         .status();
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 684cf4574b9..d575da6dece 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2023-12-01"
+channel = "nightly-2023-12-16"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs
index bbf7d22c850..dffa854177b 100644
--- a/src/tools/clippy/src/main.rs
+++ b/src/tools/clippy/src/main.rs
@@ -105,7 +105,7 @@ impl ClippyCmd {
     }
 
     fn into_std_cmd(self) -> Command {
-        let mut cmd = Command::new("cargo");
+        let mut cmd = Command::new(env::var("CARGO").unwrap_or("cargo".into()));
         let clippy_args: String = self
             .clippy_args
             .iter()
diff --git a/src/tools/clippy/tests/headers.rs b/src/tools/clippy/tests/headers.rs
index 7eec9a9cdd2..d1f986ef526 100644
--- a/src/tools/clippy/tests/headers.rs
+++ b/src/tools/clippy/tests/headers.rs
@@ -12,7 +12,12 @@ fn old_test_headers() {
 
     for entry in WalkDir::new("tests") {
         let entry = entry.unwrap();
-        if !entry.file_type().is_file() {
+        let is_hidden_file = entry
+            .file_name()
+            .to_str()
+            .expect("non-UTF-8 file name")
+            .starts_with('.');
+        if is_hidden_file || !entry.file_type().is_file() {
             continue;
         }
 
diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr
index d776feb7f2e..bdceb752608 100644
--- a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod_remap/Cargo.stderr
@@ -8,4 +8,4 @@ error: `mod.rs` files are required, found `src/bad.rs`
   = note: `-D clippy::self-named-module-files` implied by `-D warnings`
   = help: to override `-D warnings` add `#[allow(clippy::self_named_module_files)]`
 
-error: could not compile `fail-mod-remap` (bin "fail-mod-remap") due to previous error
+error: could not compile `fail-mod-remap` (bin "fail-mod-remap") due to 1 previous error
diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr
index 22558bc4ce8..06eaa071e82 100644
--- a/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/Cargo.stderr
@@ -8,4 +8,4 @@ error: `mod.rs` files are not allowed, found `src/bad/mod.rs`
   = note: `-D clippy::mod-module-files` implied by `-D warnings`
   = help: to override `-D warnings` add `#[allow(clippy::mod_module_files)]`
 
-error: could not compile `fail-no-mod` (bin "fail-no-mod") due to previous error
+error: could not compile `fail-no-mod` (bin "fail-no-mod") due to 1 previous error
diff --git a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr
index 4beedc10830..39f7176ade2 100644
--- a/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/multiple_crate_versions/fail/Cargo.stderr
@@ -3,4 +3,4 @@ error: multiple versions for dependency `winapi`: 0.2.8, 0.3.9
   = note: `-D clippy::multiple-crate-versions` implied by `-D warnings`
   = help: to override `-D warnings` add `#[allow(clippy::multiple_crate_versions)]`
 
-error: could not compile `multiple_crate_versions` (bin "multiple_crate_versions") due to previous error
+error: could not compile `multiple_crate_versions` (bin "multiple_crate_versions") due to 1 previous error
diff --git a/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr b/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr
index 65a19bb0718..a3539051b4d 100644
--- a/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr
+++ b/src/tools/clippy/tests/ui-cargo/wildcard_dependencies/fail/Cargo.stderr
@@ -3,4 +3,4 @@ error: wildcard dependency for `regex`
   = note: `-D clippy::wildcard-dependencies` implied by `-D warnings`
   = help: to override `-D warnings` add `#[allow(clippy::wildcard_dependencies)]`
 
-error: could not compile `wildcard_dependencies` (bin "wildcard_dependencies") due to previous error
+error: could not compile `wildcard_dependencies` (bin "wildcard_dependencies") due to 1 previous error
diff --git a/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs b/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs
index d737a832dd1..4375f324aca 100644
--- a/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs
+++ b/src/tools/clippy/tests/ui-toml/excessive_nesting/excessive_nesting.rs
@@ -9,7 +9,7 @@
 #![allow(clippy::never_loop)]
 #![allow(clippy::needless_if)]
 #![warn(clippy::excessive_nesting)]
-#![allow(clippy::collapsible_if)]
+#![allow(clippy::collapsible_if, clippy::blocks_in_conditions)]
 
 #[macro_use]
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed
index 8cbadc67d71..8c77039b3c0 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.fixed
@@ -1,5 +1,5 @@
 #![deny(clippy::bind_instead_of_map)]
-#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::blocks_in_conditions)]
 
 pub fn main() {
     let _ = Some("42").map(|s| if s.len() < 42 { 0 } else { s.len() });
diff --git a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs
index 91d9d11e3c1..44257f3a469 100644
--- a/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs
+++ b/src/tools/clippy/tests/ui/bind_instead_of_map_multipart.rs
@@ -1,5 +1,5 @@
 #![deny(clippy::bind_instead_of_map)]
-#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::blocks_in_conditions)]
 
 pub fn main() {
     let _ = Some("42").and_then(|s| if s.len() < 42 { Some(0) } else { Some(s.len()) });
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
index f89c465047e..2ab441bbd0c 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.fixed
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
@@ -1,4 +1,4 @@
-#![warn(clippy::blocks_in_if_conditions)]
+#![warn(clippy::blocks_in_conditions)]
 #![allow(unused, clippy::let_and_return, clippy::needless_if)]
 #![warn(clippy::nonminimal_bool)]
 
@@ -21,6 +21,7 @@ fn macro_if() {
 
 fn condition_has_block() -> i32 {
     let res = {
+        //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
         let x = 3;
         x == 3
     }; if res {
@@ -32,6 +33,7 @@ fn condition_has_block() -> i32 {
 
 fn condition_has_block_with_single_expression() -> i32 {
     if true { 6 } else { 10 }
+    //~^ ERROR: omit braces around single expression condition
 }
 
 fn condition_is_normal() -> i32 {
@@ -61,4 +63,26 @@ fn block_in_assert() {
     );
 }
 
+// issue #11814
+fn block_in_match_expr(num: i32) -> i32 {
+    let res = {
+        //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
+        let opt = Some(2);
+        opt
+    }; match res {
+        Some(0) => 1,
+        Some(n) => num * 2,
+        None => 0,
+    };
+
+    match unsafe {
+        let hearty_hearty_hearty = vec![240, 159, 146, 150];
+        String::from_utf8_unchecked(hearty_hearty_hearty).as_str()
+    } {
+        "💖" => 1,
+        "what" => 2,
+        _ => 3,
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
index 34febc5fa2c..dd5ae4fb486 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.rs
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
@@ -1,4 +1,4 @@
-#![warn(clippy::blocks_in_if_conditions)]
+#![warn(clippy::blocks_in_conditions)]
 #![allow(unused, clippy::let_and_return, clippy::needless_if)]
 #![warn(clippy::nonminimal_bool)]
 
@@ -21,6 +21,7 @@ fn macro_if() {
 
 fn condition_has_block() -> i32 {
     if {
+        //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
         let x = 3;
         x == 3
     } {
@@ -32,6 +33,7 @@ fn condition_has_block() -> i32 {
 
 fn condition_has_block_with_single_expression() -> i32 {
     if { true } { 6 } else { 10 }
+    //~^ ERROR: omit braces around single expression condition
 }
 
 fn condition_is_normal() -> i32 {
@@ -61,4 +63,26 @@ fn block_in_assert() {
     );
 }
 
+// issue #11814
+fn block_in_match_expr(num: i32) -> i32 {
+    match {
+        //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
+        let opt = Some(2);
+        opt
+    } {
+        Some(0) => 1,
+        Some(n) => num * 2,
+        None => 0,
+    };
+
+    match unsafe {
+        let hearty_hearty_hearty = vec![240, 159, 146, 150];
+        String::from_utf8_unchecked(hearty_hearty_hearty).as_str()
+    } {
+        "💖" => 1,
+        "what" => 2,
+        _ => 3,
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr
index d80ef9c0fd8..b00fe2f632c 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions.stderr
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr
@@ -1,30 +1,32 @@
 error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
-  --> $DIR/blocks_in_if_conditions.rs:23:5
+  --> $DIR/blocks_in_conditions.rs:23:5
    |
 LL | /     if {
+LL | |
 LL | |         let x = 3;
 LL | |         x == 3
 LL | |     } {
    | |_____^
    |
-   = note: `-D clippy::blocks-in-if-conditions` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::blocks_in_if_conditions)]`
+   = note: `-D clippy::blocks-in-conditions` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]`
 help: try
    |
 LL ~     let res = {
+LL +
 LL +         let x = 3;
 LL +         x == 3
 LL ~     }; if res {
    |
 
 error: omit braces around single expression condition
-  --> $DIR/blocks_in_if_conditions.rs:34:8
+  --> $DIR/blocks_in_conditions.rs:35:8
    |
 LL |     if { true } { 6 } else { 10 }
    |        ^^^^^^^^ help: try: `true`
 
 error: this boolean expression can be simplified
-  --> $DIR/blocks_in_if_conditions.rs:39:8
+  --> $DIR/blocks_in_conditions.rs:41:8
    |
 LL |     if true && x == 3 { 6 } else { 10 }
    |        ^^^^^^^^^^^^^^ help: try: `x == 3`
@@ -32,5 +34,24 @@ LL |     if true && x == 3 { 6 } else { 10 }
    = note: `-D clippy::nonminimal-bool` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
 
-error: aborting due to 3 previous errors
+error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
+  --> $DIR/blocks_in_conditions.rs:68:5
+   |
+LL | /     match {
+LL | |
+LL | |         let opt = Some(2);
+LL | |         opt
+LL | |     } {
+   | |_____^
+   |
+help: try
+   |
+LL ~     let res = {
+LL +
+LL +         let opt = Some(2);
+LL +         opt
+LL ~     }; match res {
+   |
+
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs b/src/tools/clippy/tests/ui/blocks_in_conditions_closure.rs
index 539f2df15bd..db31e4ae1a9 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.rs
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions_closure.rs
@@ -1,4 +1,4 @@
-#![warn(clippy::blocks_in_if_conditions)]
+#![warn(clippy::blocks_in_conditions)]
 #![allow(
     unused,
     clippy::let_and_return,
@@ -22,7 +22,7 @@ fn pred_test() {
         && predicate(
             |x| {
                 //~^ ERROR: in an `if` condition, avoid complex blocks or closures with blocks
-                //~| NOTE: `-D clippy::blocks-in-if-conditions` implied by `-D warnings`
+                //~| NOTE: `-D clippy::blocks-in-conditions` implied by `-D warnings`
                 let target = 3;
                 x == target
             },
@@ -60,6 +60,23 @@ fn function_with_empty_closure() {
     if closure(|| {}) {}
 }
 
+// issue #11814
+fn match_with_pred() {
+    let v = 3;
+    match Some(predicate(
+        |x| {
+            //~^ ERROR: in a `match` scrutinee, avoid complex blocks or closures with blocks
+            let target = 3;
+            x == target
+        },
+        v,
+    )) {
+        Some(true) => 1,
+        Some(false) => 2,
+        None => 3,
+    };
+}
+
 #[rustfmt::skip]
 fn main() {
     let mut range = 0..10;
diff --git a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr b/src/tools/clippy/tests/ui/blocks_in_conditions_closure.stderr
index ab68997d477..08b98f1b4fc 100644
--- a/src/tools/clippy/tests/ui/blocks_in_if_conditions_closure.stderr
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions_closure.stderr
@@ -1,5 +1,5 @@
 error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
-  --> $DIR/blocks_in_if_conditions_closure.rs:23:17
+  --> $DIR/blocks_in_conditions_closure.rs:23:17
    |
 LL |               |x| {
    |  _________________^
@@ -10,11 +10,11 @@ LL | |                 x == target
 LL | |             },
    | |_____________^
    |
-   = note: `-D clippy::blocks-in-if-conditions` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::blocks_in_if_conditions)]`
+   = note: `-D clippy::blocks-in-conditions` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::blocks_in_conditions)]`
 
 error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
-  --> $DIR/blocks_in_if_conditions_closure.rs:34:13
+  --> $DIR/blocks_in_conditions_closure.rs:34:13
    |
 LL |           |x| {
    |  _____________^
@@ -24,5 +24,16 @@ LL | |             x == target
 LL | |         },
    | |_________^
 
-error: aborting due to 2 previous errors
+error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
+  --> $DIR/blocks_in_conditions_closure.rs:67:13
+   |
+LL |           |x| {
+   |  _____________^
+LL | |
+LL | |             let target = 3;
+LL | |             x == target
+LL | |         },
+   | |_________^
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
index aee89719728..708ac666675 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -227,3 +227,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: {
 
 /// this checks if the lowerCamelCase issue is fixed
 fn issue_11568() {}
+
+/// There is no try (`do()` or `do_not()`).
+fn parenthesized_word() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index b6346b881ad..040d6352c52 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -227,3 +227,6 @@ where [(); N.checked_next_power_of_two().unwrap()]: {
 
 /// this checks if the lowerCamelCase issue is fixed
 fn issue_11568() {}
+
+/// There is no try (do() or do_not()).
+fn parenthesized_word() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
index 4c9ff41d918..033604e030a 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.stderr
@@ -319,5 +319,27 @@ help: try
 LL | /// Foo \[bar\] \[baz\] \[qux\]. `DocMarkdownLint`
    |                                  ~~~~~~~~~~~~~~~~~
 
-error: aborting due to 29 previous errors
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:231:22
+   |
+LL | /// There is no try (do() or do_not()).
+   |                      ^^^^
+   |
+help: try
+   |
+LL | /// There is no try (`do()` or do_not()).
+   |                      ~~~~~~
+
+error: item in documentation is missing backticks
+  --> $DIR/doc-fixable.rs:231:30
+   |
+LL | /// There is no try (do() or do_not()).
+   |                              ^^^^^^^^
+   |
+help: try
+   |
+LL | /// There is no try (do() or `do_not()`).
+   |                              ~~~~~~~~~~
+
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/doc_unsafe.rs b/src/tools/clippy/tests/ui/doc_unsafe.rs
index 0c8eac5ccff..f7f41c915e3 100644
--- a/src/tools/clippy/tests/ui/doc_unsafe.rs
+++ b/src/tools/clippy/tests/ui/doc_unsafe.rs
@@ -1,6 +1,6 @@
 //@aux-build:proc_macros.rs
 
-#![allow(clippy::let_unit_value)]
+#![allow(clippy::let_unit_value, clippy::needless_pass_by_ref_mut)]
 
 extern crate proc_macros;
 use proc_macros::external;
diff --git a/src/tools/clippy/tests/ui/ineffective_open_options.fixed b/src/tools/clippy/tests/ui/ineffective_open_options.fixed
new file mode 100644
index 00000000000..3af8f3c5aaa
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ineffective_open_options.fixed
@@ -0,0 +1,41 @@
+#![warn(clippy::ineffective_open_options)]
+
+use std::fs::OpenOptions;
+
+fn main() {
+    let file = OpenOptions::new()
+        .create(true)
+         //~ ERROR: unnecessary use of `.write(true)`
+        .append(true)
+        .open("dump.json")
+        .unwrap();
+
+    let file = OpenOptions::new()
+        .create(true)
+        .append(true)
+         //~ ERROR: unnecessary use of `.write(true)`
+        .open("dump.json")
+        .unwrap();
+
+    // All the next calls are ok.
+    let file = OpenOptions::new()
+        .create(true)
+        .write(false)
+        .append(true)
+        .open("dump.json")
+        .unwrap();
+    let file = OpenOptions::new()
+        .create(true)
+        .write(true)
+        .append(false)
+        .open("dump.json")
+        .unwrap();
+    let file = OpenOptions::new()
+        .create(true)
+        .write(false)
+        .append(false)
+        .open("dump.json")
+        .unwrap();
+    let file = OpenOptions::new().create(true).append(true).open("dump.json").unwrap();
+    let file = OpenOptions::new().create(true).write(true).open("dump.json").unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/ineffective_open_options.rs b/src/tools/clippy/tests/ui/ineffective_open_options.rs
new file mode 100644
index 00000000000..4eaf6293c40
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ineffective_open_options.rs
@@ -0,0 +1,41 @@
+#![warn(clippy::ineffective_open_options)]
+
+use std::fs::OpenOptions;
+
+fn main() {
+    let file = OpenOptions::new()
+        .create(true)
+        .write(true) //~ ERROR: unnecessary use of `.write(true)`
+        .append(true)
+        .open("dump.json")
+        .unwrap();
+
+    let file = OpenOptions::new()
+        .create(true)
+        .append(true)
+        .write(true) //~ ERROR: unnecessary use of `.write(true)`
+        .open("dump.json")
+        .unwrap();
+
+    // All the next calls are ok.
+    let file = OpenOptions::new()
+        .create(true)
+        .write(false)
+        .append(true)
+        .open("dump.json")
+        .unwrap();
+    let file = OpenOptions::new()
+        .create(true)
+        .write(true)
+        .append(false)
+        .open("dump.json")
+        .unwrap();
+    let file = OpenOptions::new()
+        .create(true)
+        .write(false)
+        .append(false)
+        .open("dump.json")
+        .unwrap();
+    let file = OpenOptions::new().create(true).append(true).open("dump.json").unwrap();
+    let file = OpenOptions::new().create(true).write(true).open("dump.json").unwrap();
+}
diff --git a/src/tools/clippy/tests/ui/ineffective_open_options.stderr b/src/tools/clippy/tests/ui/ineffective_open_options.stderr
new file mode 100644
index 00000000000..7dc5322232c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/ineffective_open_options.stderr
@@ -0,0 +1,17 @@
+error: unnecessary use of `.write(true)` because there is `.append(true)`
+  --> $DIR/ineffective_open_options.rs:8:9
+   |
+LL |         .write(true)
+   |         ^^^^^^^^^^^^ help: remove `.write(true)`
+   |
+   = note: `-D clippy::ineffective-open-options` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ineffective_open_options)]`
+
+error: unnecessary use of `.write(true)` because there is `.append(true)`
+  --> $DIR/ineffective_open_options.rs:16:9
+   |
+LL |         .write(true)
+   |         ^^^^^^^^^^^^ help: remove `.write(true)`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed
index 60304177b42..ecf1b14e5b6 100644
--- a/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed
+++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.fixed
@@ -1,6 +1,6 @@
 #![feature(exhaustive_patterns, never_type)]
 #![allow(dead_code, unreachable_code, unused_variables)]
-#![allow(clippy::let_and_return)]
+#![allow(clippy::let_and_return, clippy::uninhabited_references)]
 
 enum SingleVariantEnum {
     Variant(i32),
diff --git a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs
index b77aac4a16c..7cc7cb9d687 100644
--- a/src/tools/clippy/tests/ui/infallible_destructuring_match.rs
+++ b/src/tools/clippy/tests/ui/infallible_destructuring_match.rs
@@ -1,6 +1,6 @@
 #![feature(exhaustive_patterns, never_type)]
 #![allow(dead_code, unreachable_code, unused_variables)]
-#![allow(clippy::let_and_return)]
+#![allow(clippy::let_and_return, clippy::uninhabited_references)]
 
 enum SingleVariantEnum {
     Variant(i32),
diff --git a/src/tools/clippy/tests/ui/infinite_loops.rs b/src/tools/clippy/tests/ui/infinite_loops.rs
new file mode 100644
index 00000000000..646f1eca56d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/infinite_loops.rs
@@ -0,0 +1,366 @@
+//@no-rustfix
+#![allow(clippy::never_loop)]
+#![warn(clippy::infinite_loop)]
+
+fn do_something() {}
+
+fn no_break() {
+    loop {
+        //~^ ERROR: infinite loop detected
+        do_something();
+    }
+}
+
+fn all_inf() {
+    loop {
+        //~^ ERROR: infinite loop detected
+        loop {
+            //~^ ERROR: infinite loop detected
+            loop {
+                //~^ ERROR: infinite loop detected
+                do_something();
+            }
+        }
+        do_something();
+    }
+}
+
+fn no_break_return_some_ty() -> Option<u8> {
+    loop {
+        do_something();
+        return None;
+    }
+    loop {
+        //~^ ERROR: infinite loop detected
+        do_something();
+    }
+}
+
+fn no_break_never_ret() -> ! {
+    loop {
+        do_something();
+    }
+}
+
+fn no_break_never_ret_noise() {
+    loop {
+        fn inner_fn() -> ! {
+            std::process::exit(0);
+        }
+        do_something();
+    }
+}
+
+fn has_direct_break_1() {
+    loop {
+        do_something();
+        break;
+    }
+}
+
+fn has_direct_break_2() {
+    'outer: loop {
+        do_something();
+        break 'outer;
+    }
+}
+
+fn has_indirect_break_1(cond: bool) {
+    'outer: loop {
+        loop {
+            if cond {
+                break 'outer;
+            }
+        }
+    }
+}
+
+fn has_indirect_break_2(stop_num: i32) {
+    'outer: loop {
+        for x in 0..5 {
+            if x == stop_num {
+                break 'outer;
+            }
+        }
+    }
+}
+
+fn break_inner_but_not_outer_1(cond: bool) {
+    loop {
+        //~^ ERROR: infinite loop detected
+        loop {
+            if cond {
+                break;
+            }
+        }
+    }
+}
+
+fn break_inner_but_not_outer_2(cond: bool) {
+    loop {
+        //~^ ERROR: infinite loop detected
+        'inner: loop {
+            loop {
+                if cond {
+                    break 'inner;
+                }
+            }
+        }
+    }
+}
+
+fn break_outer_but_not_inner() {
+    loop {
+        loop {
+            //~^ ERROR: infinite loop detected
+            do_something();
+        }
+        break;
+    }
+}
+
+fn can_break_both_inner_and_outer(cond: bool) {
+    'outer: loop {
+        loop {
+            if cond {
+                break 'outer;
+            } else {
+                break;
+            }
+        }
+    }
+}
+
+fn break_wrong_loop(cond: bool) {
+    // 'inner has statement to break 'outer loop, but it was breaked early by a labeled child loop
+    'outer: loop {
+        loop {
+            //~^ ERROR: infinite loop detected
+            'inner: loop {
+                loop {
+                    loop {
+                        break 'inner;
+                    }
+                    break 'outer;
+                }
+            }
+        }
+    }
+}
+
+fn has_direct_return(cond: bool) {
+    loop {
+        if cond {
+            return;
+        }
+    }
+}
+
+fn ret_in_inner(cond: bool) {
+    loop {
+        loop {
+            if cond {
+                return;
+            }
+        }
+    }
+}
+
+enum Foo {
+    A,
+    B,
+    C,
+}
+
+fn match_like() {
+    let opt: Option<u8> = Some(1);
+    loop {
+        //~^ ERROR: infinite loop detected
+        match opt {
+            Some(v) => {
+                println!("{v}");
+            },
+            None => {
+                do_something();
+            },
+        }
+    }
+
+    loop {
+        match opt {
+            Some(v) => {
+                println!("{v}");
+            },
+            None => {
+                do_something();
+                break;
+            },
+        }
+    }
+
+    let result: Result<u8, u16> = Ok(1);
+    loop {
+        let _val = match result {
+            Ok(1) => 1 + 1,
+            Ok(v) => v / 2,
+            Err(_) => return,
+        };
+    }
+
+    loop {
+        let Ok(_val) = result else { return };
+    }
+
+    loop {
+        let Ok(_val) = result.map(|v| 10) else { break };
+    }
+
+    loop {
+        //~^ ERROR: infinite loop detected
+        let _x = matches!(result, Ok(v) if v != 0).then_some(0);
+    }
+
+    loop {
+        //~^ ERROR: infinite loop detected
+        // This `return` does not return the function, so it doesn't count
+        let _x = matches!(result, Ok(v) if v != 0).then(|| {
+            if true {
+                return;
+            }
+            do_something();
+        });
+    }
+
+    let mut val = 0;
+    let mut fooc = Foo::C;
+
+    loop {
+        val = match fooc {
+            Foo::A => 0,
+            Foo::B => {
+                fooc = Foo::C;
+                1
+            },
+            Foo::C => break,
+        };
+    }
+
+    loop {
+        val = match fooc {
+            Foo::A => 0,
+            Foo::B => 1,
+            Foo::C => {
+                break;
+            },
+        };
+    }
+}
+
+macro_rules! set_or_ret {
+    ($opt:expr, $a:expr) => {{
+        match $opt {
+            Some(val) => $a = val,
+            None => return,
+        }
+    }};
+}
+
+fn ret_in_macro(opt: Option<u8>) {
+    let opt: Option<u8> = Some(1);
+    let mut a: u8 = 0;
+    loop {
+        set_or_ret!(opt, a);
+    }
+
+    let res: Result<bool, u8> = Ok(true);
+    loop {
+        match res {
+            Ok(true) => set_or_ret!(opt, a),
+            _ => do_something(),
+        }
+    }
+}
+
+fn panic_like_macros_1() {
+    loop {
+        do_something();
+        panic!();
+    }
+}
+
+fn panic_like_macros_2() {
+    let mut x = 0;
+
+    loop {
+        do_something();
+        if true {
+            todo!();
+        }
+    }
+    loop {
+        do_something();
+        x += 1;
+        assert_eq!(x, 0);
+    }
+    loop {
+        do_something();
+        assert!(x % 2 == 0);
+    }
+    loop {
+        do_something();
+        match Some(1) {
+            Some(n) => println!("{n}"),
+            None => unreachable!("It won't happen"),
+        }
+    }
+}
+
+fn exit_directly(cond: bool) {
+    loop {
+        if cond {
+            std::process::exit(0);
+        }
+    }
+}
+
+trait MyTrait {
+    fn problematic_trait_method() {
+        loop {
+            //~^ ERROR: infinite loop detected
+            do_something();
+        }
+    }
+    fn could_be_problematic();
+}
+
+impl MyTrait for String {
+    fn could_be_problematic() {
+        loop {
+            //~^ ERROR: infinite loop detected
+            do_something();
+        }
+    }
+}
+
+fn inf_loop_in_closure() {
+    let _loop_forever = || {
+        loop {
+            //~^ ERROR: infinite loop detected
+            do_something();
+        }
+    };
+
+    let _somehow_ok = || -> ! {
+        loop {
+            do_something();
+        }
+    };
+}
+
+fn inf_loop_in_res() -> Result<(), i32> {
+    Ok(loop {
+        do_something()
+    })
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/infinite_loops.stderr b/src/tools/clippy/tests/ui/infinite_loops.stderr
new file mode 100644
index 00000000000..f58b3cebbc3
--- /dev/null
+++ b/src/tools/clippy/tests/ui/infinite_loops.stderr
@@ -0,0 +1,259 @@
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:8:5
+   |
+LL | /     loop {
+LL | |
+LL | |         do_something();
+LL | |     }
+   | |_____^
+   |
+   = note: `-D clippy::infinite-loop` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::infinite_loop)]`
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn no_break() -> ! {
+   |               ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:15:5
+   |
+LL | /     loop {
+LL | |
+LL | |         loop {
+LL | |
+...  |
+LL | |         do_something();
+LL | |     }
+   | |_____^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn all_inf() -> ! {
+   |              ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:17:9
+   |
+LL | /         loop {
+LL | |
+LL | |             loop {
+LL | |
+LL | |                 do_something();
+LL | |             }
+LL | |         }
+   | |_________^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn all_inf() -> ! {
+   |              ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:19:13
+   |
+LL | /             loop {
+LL | |
+LL | |                 do_something();
+LL | |             }
+   | |_____________^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn all_inf() -> ! {
+   |              ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:33:5
+   |
+LL | /     loop {
+LL | |
+LL | |         do_something();
+LL | |     }
+   | |_____^
+   |
+   = help: if this is not intended, try adding a `break` or `return` condition in the loop
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:46:5
+   |
+LL | /     loop {
+LL | |         fn inner_fn() -> ! {
+LL | |             std::process::exit(0);
+LL | |         }
+LL | |         do_something();
+LL | |     }
+   | |_____^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn no_break_never_ret_noise() -> ! {
+   |                               ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:89:5
+   |
+LL | /     loop {
+LL | |
+LL | |         loop {
+LL | |             if cond {
+...  |
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn break_inner_but_not_outer_1(cond: bool) -> ! {
+   |                                            ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:100:5
+   |
+LL | /     loop {
+LL | |
+LL | |         'inner: loop {
+LL | |             loop {
+...  |
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn break_inner_but_not_outer_2(cond: bool) -> ! {
+   |                                            ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:114:9
+   |
+LL | /         loop {
+LL | |
+LL | |             do_something();
+LL | |         }
+   | |_________^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn break_outer_but_not_inner() -> ! {
+   |                                ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:137:9
+   |
+LL | /         loop {
+LL | |
+LL | |             'inner: loop {
+LL | |                 loop {
+...  |
+LL | |             }
+LL | |         }
+   | |_________^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn break_wrong_loop(cond: bool) -> ! {
+   |                                 ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:177:5
+   |
+LL | /     loop {
+LL | |
+LL | |         match opt {
+LL | |             Some(v) => {
+...  |
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn match_like() -> ! {
+   |                 ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:218:5
+   |
+LL | /     loop {
+LL | |
+LL | |         let _x = matches!(result, Ok(v) if v != 0).then_some(0);
+LL | |     }
+   | |_____^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn match_like() -> ! {
+   |                 ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:223:5
+   |
+LL | /     loop {
+LL | |
+LL | |         // This `return` does not return the function, so it doesn't count
+LL | |         let _x = matches!(result, Ok(v) if v != 0).then(|| {
+...  |
+LL | |         });
+LL | |     }
+   | |_____^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL | fn match_like() -> ! {
+   |                 ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:328:9
+   |
+LL | /         loop {
+LL | |
+LL | |             do_something();
+LL | |         }
+   | |_________^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL |     fn problematic_trait_method() -> ! {
+   |                                   ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:338:9
+   |
+LL | /         loop {
+LL | |
+LL | |             do_something();
+LL | |         }
+   | |_________^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL |     fn could_be_problematic() -> ! {
+   |                               ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:347:9
+   |
+LL | /         loop {
+LL | |
+LL | |             do_something();
+LL | |         }
+   | |_________^
+   |
+help: if this is intentional, consider specifing `!` as function return
+   |
+LL |     let _loop_forever = || -> ! {
+   |                            ++++
+
+error: infinite loop detected
+  --> $DIR/infinite_loops.rs:361:8
+   |
+LL |       Ok(loop {
+   |  ________^
+LL | |         do_something()
+LL | |     })
+   | |_____^
+   |
+   = help: if this is not intended, try adding a `break` or `return` condition in the loop
+
+error: aborting due to 17 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_filter.fixed b/src/tools/clippy/tests/ui/manual_filter.fixed
index c1bc4aae92e..a0fb0e32d60 100644
--- a/src/tools/clippy/tests/ui/manual_filter.fixed
+++ b/src/tools/clippy/tests/ui/manual_filter.fixed
@@ -40,7 +40,7 @@ fn main() {
         };
     }
 
-    #[allow(clippy::blocks_in_if_conditions)]
+    #[allow(clippy::blocks_in_conditions)]
     Some(11).filter(|&x| {
                 println!("foo");
                 x > 10 && x < 100
diff --git a/src/tools/clippy/tests/ui/manual_filter.rs b/src/tools/clippy/tests/ui/manual_filter.rs
index ee44909f37e..0ac6cbefc4e 100644
--- a/src/tools/clippy/tests/ui/manual_filter.rs
+++ b/src/tools/clippy/tests/ui/manual_filter.rs
@@ -135,7 +135,7 @@ fn main() {
         };
     }
 
-    #[allow(clippy::blocks_in_if_conditions)]
+    #[allow(clippy::blocks_in_conditions)]
     match Some(11) {
         // Lint, statement is preserved by `.filter`
         Some(x) => {
diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed
index a96827259f5..ac44a6f3fdb 100644
--- a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed
+++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.fixed
@@ -118,4 +118,19 @@ fn index_different_slice_in_same_expr(v1: &[u8], v2: &[u8]) {
     let _ = v1[0] + v2[1];
 }
 
+fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {
+    assert!(v1.len() == 3);
+    assert!(v2.len() == 4);
+    assert!(v3.len() == 3);
+    assert!(4 == v4.len());
+
+    let _ = v1[0] + v1[1] + v1[2];
+    //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+    let _ = v2[0] + v2[1] + v2[2];
+
+    let _ = v3[0] + v3[1] + v3[2];
+    //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+    let _ = v4[0] + v4[1] + v4[2];
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs
index 0b4b883acf8..f05d5fea57d 100644
--- a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs
+++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.rs
@@ -118,4 +118,19 @@ fn index_different_slice_in_same_expr(v1: &[u8], v2: &[u8]) {
     let _ = v1[0] + v2[1];
 }
 
+fn issue11835(v1: &[u8], v2: &[u8], v3: &[u8], v4: &[u8]) {
+    assert!(v1.len() == 2);
+    assert!(v2.len() == 4);
+    assert!(2 == v3.len());
+    assert!(4 == v4.len());
+
+    let _ = v1[0] + v1[1] + v1[2];
+    //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+    let _ = v2[0] + v2[1] + v2[2];
+
+    let _ = v3[0] + v3[1] + v3[2];
+    //~^ ERROR: indexing into a slice multiple times with an `assert` that does not cover the
+    let _ = v4[0] + v4[1] + v4[2];
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr
index a3e66d7958e..61dce6ccc6c 100644
--- a/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr
+++ b/src/tools/clippy/tests/ui/missing_asserts_for_indexing.stderr
@@ -249,5 +249,57 @@ LL |     let _ = v1[0] + v1[12];
    |                     ^^^^^^
    = note: asserting the length before indexing will elide bounds checks
 
-error: aborting due to 9 previous errors
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+  --> $DIR/missing_asserts_for_indexing.rs:127:13
+   |
+LL |     assert!(v1.len() == 2);
+   |     ---------------------- help: provide the highest index that is indexed with: `assert!(v1.len() == 3)`
+...
+LL |     let _ = v1[0] + v1[1] + v1[2];
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: slice indexed here
+  --> $DIR/missing_asserts_for_indexing.rs:127:13
+   |
+LL |     let _ = v1[0] + v1[1] + v1[2];
+   |             ^^^^^
+note: slice indexed here
+  --> $DIR/missing_asserts_for_indexing.rs:127:21
+   |
+LL |     let _ = v1[0] + v1[1] + v1[2];
+   |                     ^^^^^
+note: slice indexed here
+  --> $DIR/missing_asserts_for_indexing.rs:127:29
+   |
+LL |     let _ = v1[0] + v1[1] + v1[2];
+   |                             ^^^^^
+   = note: asserting the length before indexing will elide bounds checks
+
+error: indexing into a slice multiple times with an `assert` that does not cover the highest index
+  --> $DIR/missing_asserts_for_indexing.rs:131:13
+   |
+LL |     assert!(2 == v3.len());
+   |     ---------------------- help: provide the highest index that is indexed with: `assert!(v3.len() == 3)`
+...
+LL |     let _ = v3[0] + v3[1] + v3[2];
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+note: slice indexed here
+  --> $DIR/missing_asserts_for_indexing.rs:131:13
+   |
+LL |     let _ = v3[0] + v3[1] + v3[2];
+   |             ^^^^^
+note: slice indexed here
+  --> $DIR/missing_asserts_for_indexing.rs:131:21
+   |
+LL |     let _ = v3[0] + v3[1] + v3[2];
+   |                     ^^^^^
+note: slice indexed here
+  --> $DIR/missing_asserts_for_indexing.rs:131:29
+   |
+LL |     let _ = v3[0] + v3[1] + v3[2];
+   |                             ^^^^^
+   = note: asserting the length before indexing will elide bounds checks
+
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed
index 2a335516f51..bd7a9a0b984 100644
--- a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed
@@ -284,4 +284,19 @@ fn main() {
         {
         }
     }
+    // address of field when operand impl Drop
+    {
+        struct CustomDrop(String);
+
+        impl Drop for CustomDrop {
+            fn drop(&mut self) {}
+        }
+
+        fn check_str<P: AsRef<str>>(_to: P) {}
+
+        fn test() {
+            let owner = CustomDrop(String::default());
+            check_str(&owner.0); // Don't lint. `owner` can't be partially moved because it impl Drop
+        }
+    }
 }
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs
index f0567f486ac..5cfd4ce30cc 100644
--- a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs
@@ -284,4 +284,19 @@ fn main() {
         {
         }
     }
+    // address of field when operand impl Drop
+    {
+        struct CustomDrop(String);
+
+        impl Drop for CustomDrop {
+            fn drop(&mut self) {}
+        }
+
+        fn check_str<P: AsRef<str>>(_to: P) {}
+
+        fn test() {
+            let owner = CustomDrop(String::default());
+            check_str(&owner.0); // Don't lint. `owner` can't be partially moved because it impl Drop
+        }
+    }
 }
diff --git a/src/tools/clippy/tests/ui/needless_if.fixed b/src/tools/clippy/tests/ui/needless_if.fixed
index be35dcddbe6..1086ae2c984 100644
--- a/src/tools/clippy/tests/ui/needless_if.fixed
+++ b/src/tools/clippy/tests/ui/needless_if.fixed
@@ -1,7 +1,7 @@
 //@aux-build:proc_macros.rs
 #![feature(let_chains)]
 #![allow(
-    clippy::blocks_in_if_conditions,
+    clippy::blocks_in_conditions,
     clippy::if_same_then_else,
     clippy::ifs_same_cond,
     clippy::let_unit_value,
diff --git a/src/tools/clippy/tests/ui/needless_if.rs b/src/tools/clippy/tests/ui/needless_if.rs
index e2ad17e69a8..131cceaf712 100644
--- a/src/tools/clippy/tests/ui/needless_if.rs
+++ b/src/tools/clippy/tests/ui/needless_if.rs
@@ -1,7 +1,7 @@
 //@aux-build:proc_macros.rs
 #![feature(let_chains)]
 #![allow(
-    clippy::blocks_in_if_conditions,
+    clippy::blocks_in_conditions,
     clippy::if_same_then_else,
     clippy::ifs_same_cond,
     clippy::let_unit_value,
diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed
index 891b2b01437..6db87049044 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.fixed
+++ b/src/tools/clippy/tests/ui/needless_late_init.fixed
@@ -3,7 +3,7 @@
 #![allow(unused)]
 #![allow(
     clippy::assign_op_pattern,
-    clippy::blocks_in_if_conditions,
+    clippy::blocks_in_conditions,
     clippy::let_and_return,
     clippy::let_unit_value,
     clippy::nonminimal_bool,
diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs
index 55399511639..c1e86212a08 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.rs
+++ b/src/tools/clippy/tests/ui/needless_late_init.rs
@@ -3,7 +3,7 @@
 #![allow(unused)]
 #![allow(
     clippy::assign_op_pattern,
-    clippy::blocks_in_if_conditions,
+    clippy::blocks_in_conditions,
     clippy::let_and_return,
     clippy::let_unit_value,
     clippy::nonminimal_bool,
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
index 25a02bdd2f2..a92197fb0af 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
@@ -307,6 +307,19 @@ fn filter_copy<T: Copy>(predicate: &mut impl FnMut(T) -> bool) -> impl FnMut(&T)
     move |&item| predicate(item)
 }
 
+// `is_from_proc_macro` stress tests
+fn _empty_tup(x: &mut (())) {}
+fn _single_tup(x: &mut ((i32,))) {}
+fn _multi_tup(x: &mut ((i32, u32))) {}
+fn _fn(x: &mut (fn())) {}
+#[rustfmt::skip]
+fn _extern_rust_fn(x: &mut extern "Rust" fn()) {}
+fn _extern_c_fn(x: &mut extern "C" fn()) {}
+fn _unsafe_fn(x: &mut unsafe fn()) {}
+fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {}
+fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {}
+fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {}
+
 fn main() {
     let mut u = 0;
     let mut v = vec![0];
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
index 92b753276ac..5d1e9515de1 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
@@ -139,5 +139,65 @@ LL | pub async fn closure4(n: &mut usize) {
    |
    = warning: changing this function will impact semver compatibility
 
-error: aborting due to 21 previous errors
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:311:18
+   |
+LL | fn _empty_tup(x: &mut (())) {}
+   |                  ^^^^^^^^^ help: consider changing to: `&()`
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:312:19
+   |
+LL | fn _single_tup(x: &mut ((i32,))) {}
+   |                   ^^^^^^^^^^^^^ help: consider changing to: `&(i32,)`
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:313:18
+   |
+LL | fn _multi_tup(x: &mut ((i32, u32))) {}
+   |                  ^^^^^^^^^^^^^^^^^ help: consider changing to: `&(i32, u32)`
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:314:11
+   |
+LL | fn _fn(x: &mut (fn())) {}
+   |           ^^^^^^^^^^^ help: consider changing to: `&fn()`
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:316:23
+   |
+LL | fn _extern_rust_fn(x: &mut extern "Rust" fn()) {}
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "Rust" fn()`
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:317:20
+   |
+LL | fn _extern_c_fn(x: &mut extern "C" fn()) {}
+   |                    ^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&extern "C" fn()`
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:318:18
+   |
+LL | fn _unsafe_fn(x: &mut unsafe fn()) {}
+   |                  ^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe fn()`
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:319:25
+   |
+LL | fn _unsafe_extern_fn(x: &mut unsafe extern "C" fn()) {}
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn()`
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:320:20
+   |
+LL | fn _fn_with_arg(x: &mut unsafe extern "C" fn(i32)) {}
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn(i32)`
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:321:20
+   |
+LL | fn _fn_with_ret(x: &mut unsafe extern "C" fn() -> (i32)) {}
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&unsafe extern "C" fn() -> (i32)`
+
+error: aborting due to 31 previous errors
 
diff --git a/src/tools/clippy/tests/ui/no_effect.rs b/src/tools/clippy/tests/ui/no_effect.rs
index c52f4389192..777b1e52c2d 100644
--- a/src/tools/clippy/tests/ui/no_effect.rs
+++ b/src/tools/clippy/tests/ui/no_effect.rs
@@ -9,6 +9,30 @@
     clippy::useless_vec
 )]
 
+use std::fmt::Display;
+use std::ops::{Neg, Shl};
+
+struct Cout;
+
+impl<T> Shl<T> for Cout
+where
+    T: Display,
+{
+    type Output = Self;
+    fn shl(self, rhs: T) -> Self::Output {
+        println!("{}", rhs);
+        self
+    }
+}
+
+impl Neg for Cout {
+    type Output = Self;
+    fn neg(self) -> Self::Output {
+        println!("hello world");
+        self
+    }
+}
+
 struct Unit;
 struct Tuple(i32);
 struct Struct {
@@ -174,4 +198,11 @@ fn main() {
     GreetStruct1("world");
     GreetStruct2()("world");
     GreetStruct3 {}("world");
+
+    fn n() -> i32 {
+        42
+    }
+
+    Cout << 142;
+    -Cout;
 }
diff --git a/src/tools/clippy/tests/ui/no_effect.stderr b/src/tools/clippy/tests/ui/no_effect.stderr
index feba35697f5..f5ba234b4cb 100644
--- a/src/tools/clippy/tests/ui/no_effect.stderr
+++ b/src/tools/clippy/tests/ui/no_effect.stderr
@@ -1,5 +1,5 @@
 error: statement with no effect
-  --> $DIR/no_effect.rs:98:5
+  --> $DIR/no_effect.rs:122:5
    |
 LL |     0;
    |     ^^
@@ -8,151 +8,151 @@ LL |     0;
    = help: to override `-D warnings` add `#[allow(clippy::no_effect)]`
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:101:5
+  --> $DIR/no_effect.rs:125:5
    |
 LL |     s2;
    |     ^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:103:5
+  --> $DIR/no_effect.rs:127:5
    |
 LL |     Unit;
    |     ^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:105:5
+  --> $DIR/no_effect.rs:129:5
    |
 LL |     Tuple(0);
    |     ^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:107:5
+  --> $DIR/no_effect.rs:131:5
    |
 LL |     Struct { field: 0 };
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:109:5
+  --> $DIR/no_effect.rs:133:5
    |
 LL |     Struct { ..s };
    |     ^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:111:5
+  --> $DIR/no_effect.rs:135:5
    |
 LL |     Union { a: 0 };
    |     ^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:113:5
+  --> $DIR/no_effect.rs:137:5
    |
 LL |     Enum::Tuple(0);
    |     ^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:115:5
+  --> $DIR/no_effect.rs:139:5
    |
 LL |     Enum::Struct { field: 0 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:117:5
+  --> $DIR/no_effect.rs:141:5
    |
 LL |     5 + 6;
    |     ^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:119:5
+  --> $DIR/no_effect.rs:143:5
    |
 LL |     *&42;
    |     ^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:121:5
+  --> $DIR/no_effect.rs:145:5
    |
 LL |     &6;
    |     ^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:123:5
+  --> $DIR/no_effect.rs:147:5
    |
 LL |     (5, 6, 7);
    |     ^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:125:5
+  --> $DIR/no_effect.rs:149:5
    |
 LL |     ..;
    |     ^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:127:5
+  --> $DIR/no_effect.rs:151:5
    |
 LL |     5..;
    |     ^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:129:5
+  --> $DIR/no_effect.rs:153:5
    |
 LL |     ..5;
    |     ^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:131:5
+  --> $DIR/no_effect.rs:155:5
    |
 LL |     5..6;
    |     ^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:133:5
+  --> $DIR/no_effect.rs:157:5
    |
 LL |     5..=6;
    |     ^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:135:5
+  --> $DIR/no_effect.rs:159:5
    |
 LL |     [42, 55];
    |     ^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:137:5
+  --> $DIR/no_effect.rs:161:5
    |
 LL |     [42, 55][1];
    |     ^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:139:5
+  --> $DIR/no_effect.rs:163:5
    |
 LL |     (42, 55).1;
    |     ^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:141:5
+  --> $DIR/no_effect.rs:165:5
    |
 LL |     [42; 55];
    |     ^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:143:5
+  --> $DIR/no_effect.rs:167:5
    |
 LL |     [42; 55][13];
    |     ^^^^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:146:5
+  --> $DIR/no_effect.rs:170:5
    |
 LL |     || x += 5;
    |     ^^^^^^^^^^
 
 error: statement with no effect
-  --> $DIR/no_effect.rs:149:5
+  --> $DIR/no_effect.rs:173:5
    |
 LL |     FooString { s: s };
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:151:5
+  --> $DIR/no_effect.rs:175:5
    |
 LL |     let _unused = 1;
    |     ^^^^^^^^^^^^^^^^
@@ -161,19 +161,19 @@ LL |     let _unused = 1;
    = help: to override `-D warnings` add `#[allow(clippy::no_effect_underscore_binding)]`
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:154:5
+  --> $DIR/no_effect.rs:178:5
    |
 LL |     let _penguin = || println!("Some helpful closure");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:156:5
+  --> $DIR/no_effect.rs:180:5
    |
 LL |     let _duck = Struct { field: 0 };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:158:5
+  --> $DIR/no_effect.rs:182:5
    |
 LL |     let _cat = [2, 4, 6, 8][2];
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
index ca13b52ae3b..fa15c323540 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.fixed
@@ -71,3 +71,118 @@ fn _msrv_1_38() {
     let _ = ptr.cast::<i32>();
     let _ = mut_ptr.cast::<i32>();
 }
+
+#[allow(clippy::unnecessary_cast)]
+mod null {
+    fn use_path_mut() -> *mut u32 {
+        use std::ptr;
+        ptr::null_mut::<u32>()
+    }
+
+    fn full_path_mut() -> *mut u32 {
+        std::ptr::null_mut::<u32>()
+    }
+
+    fn core_path_mut() -> *mut u32 {
+        use core::ptr;
+        ptr::null_mut::<u32>()
+    }
+
+    fn full_core_path_mut() -> *mut u32 {
+        core::ptr::null_mut::<u32>()
+    }
+
+    fn use_path() -> *const u32 {
+        use std::ptr;
+        ptr::null::<u32>()
+    }
+
+    fn full_path() -> *const u32 {
+        std::ptr::null::<u32>()
+    }
+
+    fn core_path() -> *const u32 {
+        use core::ptr;
+        ptr::null::<u32>()
+    }
+
+    fn full_core_path() -> *const u32 {
+        core::ptr::null::<u32>()
+    }
+}
+
+mod null_ptr_infer {
+    fn use_path_mut() -> *mut u32 {
+        use std::ptr;
+        ptr::null_mut()
+    }
+
+    fn full_path_mut() -> *mut u32 {
+        std::ptr::null_mut()
+    }
+
+    fn core_path_mut() -> *mut u32 {
+        use core::ptr;
+        ptr::null_mut()
+    }
+
+    fn full_core_path_mut() -> *mut u32 {
+        core::ptr::null_mut()
+    }
+
+    fn use_path() -> *const u32 {
+        use std::ptr;
+        ptr::null()
+    }
+
+    fn full_path() -> *const u32 {
+        std::ptr::null()
+    }
+
+    fn core_path() -> *const u32 {
+        use core::ptr;
+        ptr::null()
+    }
+
+    fn full_core_path() -> *const u32 {
+        core::ptr::null()
+    }
+}
+
+mod null_entire_infer {
+    fn use_path_mut() -> *mut u32 {
+        use std::ptr;
+        ptr::null_mut()
+    }
+
+    fn full_path_mut() -> *mut u32 {
+        std::ptr::null_mut()
+    }
+
+    fn core_path_mut() -> *mut u32 {
+        use core::ptr;
+        ptr::null_mut()
+    }
+
+    fn full_core_path_mut() -> *mut u32 {
+        core::ptr::null_mut()
+    }
+
+    fn use_path() -> *const u32 {
+        use std::ptr;
+        ptr::null()
+    }
+
+    fn full_path() -> *const u32 {
+        std::ptr::null()
+    }
+
+    fn core_path() -> *const u32 {
+        use core::ptr;
+        ptr::null()
+    }
+
+    fn full_core_path() -> *const u32 {
+        core::ptr::null()
+    }
+}
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.rs b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
index 942c8734444..7ab52e63da5 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.rs
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.rs
@@ -71,3 +71,118 @@ fn _msrv_1_38() {
     let _ = ptr as *const i32;
     let _ = mut_ptr as *mut i32;
 }
+
+#[allow(clippy::unnecessary_cast)]
+mod null {
+    fn use_path_mut() -> *mut u32 {
+        use std::ptr;
+        ptr::null_mut() as *mut u32
+    }
+
+    fn full_path_mut() -> *mut u32 {
+        std::ptr::null_mut() as *mut u32
+    }
+
+    fn core_path_mut() -> *mut u32 {
+        use core::ptr;
+        ptr::null_mut() as *mut u32
+    }
+
+    fn full_core_path_mut() -> *mut u32 {
+        core::ptr::null_mut() as *mut u32
+    }
+
+    fn use_path() -> *const u32 {
+        use std::ptr;
+        ptr::null() as *const u32
+    }
+
+    fn full_path() -> *const u32 {
+        std::ptr::null() as *const u32
+    }
+
+    fn core_path() -> *const u32 {
+        use core::ptr;
+        ptr::null() as *const u32
+    }
+
+    fn full_core_path() -> *const u32 {
+        core::ptr::null() as *const u32
+    }
+}
+
+mod null_ptr_infer {
+    fn use_path_mut() -> *mut u32 {
+        use std::ptr;
+        ptr::null_mut() as *mut _
+    }
+
+    fn full_path_mut() -> *mut u32 {
+        std::ptr::null_mut() as *mut _
+    }
+
+    fn core_path_mut() -> *mut u32 {
+        use core::ptr;
+        ptr::null_mut() as *mut _
+    }
+
+    fn full_core_path_mut() -> *mut u32 {
+        core::ptr::null_mut() as *mut _
+    }
+
+    fn use_path() -> *const u32 {
+        use std::ptr;
+        ptr::null() as *const _
+    }
+
+    fn full_path() -> *const u32 {
+        std::ptr::null() as *const _
+    }
+
+    fn core_path() -> *const u32 {
+        use core::ptr;
+        ptr::null() as *const _
+    }
+
+    fn full_core_path() -> *const u32 {
+        core::ptr::null() as *const _
+    }
+}
+
+mod null_entire_infer {
+    fn use_path_mut() -> *mut u32 {
+        use std::ptr;
+        ptr::null_mut() as _
+    }
+
+    fn full_path_mut() -> *mut u32 {
+        std::ptr::null_mut() as _
+    }
+
+    fn core_path_mut() -> *mut u32 {
+        use core::ptr;
+        ptr::null_mut() as _
+    }
+
+    fn full_core_path_mut() -> *mut u32 {
+        core::ptr::null_mut() as _
+    }
+
+    fn use_path() -> *const u32 {
+        use std::ptr;
+        ptr::null() as _
+    }
+
+    fn full_path() -> *const u32 {
+        std::ptr::null() as _
+    }
+
+    fn core_path() -> *const u32 {
+        use core::ptr;
+        ptr::null() as _
+    }
+
+    fn full_core_path() -> *const u32 {
+        core::ptr::null() as _
+    }
+}
diff --git a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
index c0ce69b4357..ef64347e935 100644
--- a/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
+++ b/src/tools/clippy/tests/ui/ptr_as_ptr.stderr
@@ -57,5 +57,149 @@ error: `as` casting between raw pointers without changing its mutability
 LL |     let _ = mut_ptr as *mut i32;
    |             ^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `mut_ptr.cast::<i32>()`
 
-error: aborting due to 9 previous errors
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:79:9
+   |
+LL |         ptr::null_mut() as *mut u32
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:83:9
+   |
+LL |         std::ptr::null_mut() as *mut u32
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut::<u32>()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:88:9
+   |
+LL |         ptr::null_mut() as *mut u32
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut::<u32>()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:92:9
+   |
+LL |         core::ptr::null_mut() as *mut u32
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut::<u32>()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:97:9
+   |
+LL |         ptr::null() as *const u32
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:101:9
+   |
+LL |         std::ptr::null() as *const u32
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null::<u32>()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:106:9
+   |
+LL |         ptr::null() as *const u32
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null::<u32>()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:110:9
+   |
+LL |         core::ptr::null() as *const u32
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null::<u32>()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:117:9
+   |
+LL |         ptr::null_mut() as *mut _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:121:9
+   |
+LL |         std::ptr::null_mut() as *mut _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:126:9
+   |
+LL |         ptr::null_mut() as *mut _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:130:9
+   |
+LL |         core::ptr::null_mut() as *mut _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:135:9
+   |
+LL |         ptr::null() as *const _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:139:9
+   |
+LL |         std::ptr::null() as *const _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:144:9
+   |
+LL |         ptr::null() as *const _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:148:9
+   |
+LL |         core::ptr::null() as *const _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:155:9
+   |
+LL |         ptr::null_mut() as _
+   |         ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:159:9
+   |
+LL |         std::ptr::null_mut() as _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null_mut()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:164:9
+   |
+LL |         ptr::null_mut() as _
+   |         ^^^^^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null_mut()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:168:9
+   |
+LL |         core::ptr::null_mut() as _
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null_mut()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:173:9
+   |
+LL |         ptr::null() as _
+   |         ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:177:9
+   |
+LL |         std::ptr::null() as _
+   |         ^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `std::ptr::null()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:182:9
+   |
+LL |         ptr::null() as _
+   |         ^^^^^^^^^^^^^^^^ help: try call directly: `ptr::null()`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> $DIR/ptr_as_ptr.rs:186:9
+   |
+LL |         core::ptr::null() as _
+   |         ^^^^^^^^^^^^^^^^^^^^^^ help: try call directly: `core::ptr::null()`
+
+error: aborting due to 33 previous errors
 
diff --git a/src/tools/clippy/tests/ui/regex.rs b/src/tools/clippy/tests/ui/regex.rs
index 094d9574ae9..1ea0d65bf1e 100644
--- a/src/tools/clippy/tests/ui/regex.rs
+++ b/src/tools/clippy/tests/ui/regex.rs
@@ -112,6 +112,10 @@ fn trivial_regex() {
 
     // #6005: unicode classes in bytes::Regex
     let a_byte_of_unicode = BRegex::new(r"\p{C}");
+
+    // start and end word boundry, introduced in regex 0.10
+    let _ = BRegex::new(r"\<word\>");
+    let _ = BRegex::new(r"\b{start}word\b{end}");
 }
 
 fn main() {
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 31f1ee6a86d..f4ff0f0b88b 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -4,7 +4,7 @@
 
 #![allow(clippy::almost_complete_range)]
 #![allow(clippy::disallowed_names)]
-#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::blocks_in_conditions)]
 #![allow(clippy::box_collection)]
 #![allow(clippy::redundant_static_lifetimes)]
 #![allow(clippy::cognitive_complexity)]
@@ -54,8 +54,9 @@
 #![allow(ambiguous_wide_pointer_comparisons)]
 #![warn(clippy::almost_complete_range)]
 #![warn(clippy::disallowed_names)]
-#![warn(clippy::blocks_in_if_conditions)]
-#![warn(clippy::blocks_in_if_conditions)]
+#![warn(clippy::blocks_in_conditions)]
+#![warn(clippy::blocks_in_conditions)]
+#![warn(clippy::blocks_in_conditions)]
 #![warn(clippy::box_collection)]
 #![warn(clippy::redundant_static_lifetimes)]
 #![warn(clippy::cognitive_complexity)]
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index 325bc356c15..0df1098f5fb 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -4,7 +4,7 @@
 
 #![allow(clippy::almost_complete_range)]
 #![allow(clippy::disallowed_names)]
-#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::blocks_in_conditions)]
 #![allow(clippy::box_collection)]
 #![allow(clippy::redundant_static_lifetimes)]
 #![allow(clippy::cognitive_complexity)]
@@ -56,6 +56,7 @@
 #![warn(clippy::blacklisted_name)]
 #![warn(clippy::block_in_if_condition_expr)]
 #![warn(clippy::block_in_if_condition_stmt)]
+#![warn(clippy::blocks_in_if_conditions)]
 #![warn(clippy::box_vec)]
 #![warn(clippy::const_static_lifetime)]
 #![warn(clippy::cyclomatic_complexity)]
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index a6164338c20..f63ad82a757 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -13,335 +13,341 @@ error: lint `clippy::blacklisted_name` has been renamed to `clippy::disallowed_n
 LL | #![warn(clippy::blacklisted_name)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_names`
 
-error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
+error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_conditions`
   --> $DIR/rename.rs:57:9
    |
 LL | #![warn(clippy::block_in_if_condition_expr)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
 
-error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
+error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_conditions`
   --> $DIR/rename.rs:58:9
    |
 LL | #![warn(clippy::block_in_if_condition_stmt)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
 
-error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
+error: lint `clippy::blocks_in_if_conditions` has been renamed to `clippy::blocks_in_conditions`
   --> $DIR/rename.rs:59:9
    |
+LL | #![warn(clippy::blocks_in_if_conditions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_conditions`
+
+error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
+  --> $DIR/rename.rs:60:9
+   |
 LL | #![warn(clippy::box_vec)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
 
 error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
-  --> $DIR/rename.rs:60:9
+  --> $DIR/rename.rs:61:9
    |
 LL | #![warn(clippy::const_static_lifetime)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
 
 error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
-  --> $DIR/rename.rs:61:9
+  --> $DIR/rename.rs:62:9
    |
 LL | #![warn(clippy::cyclomatic_complexity)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
 
 error: lint `clippy::derive_hash_xor_eq` has been renamed to `clippy::derived_hash_with_manual_eq`
-  --> $DIR/rename.rs:62:9
+  --> $DIR/rename.rs:63:9
    |
 LL | #![warn(clippy::derive_hash_xor_eq)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::derived_hash_with_manual_eq`
 
 error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
-  --> $DIR/rename.rs:63:9
+  --> $DIR/rename.rs:64:9
    |
 LL | #![warn(clippy::disallowed_method)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
 
 error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
-  --> $DIR/rename.rs:64:9
+  --> $DIR/rename.rs:65:9
    |
 LL | #![warn(clippy::disallowed_type)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
 
 error: lint `clippy::eval_order_dependence` has been renamed to `clippy::mixed_read_write_in_expression`
-  --> $DIR/rename.rs:65:9
+  --> $DIR/rename.rs:66:9
    |
 LL | #![warn(clippy::eval_order_dependence)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::mixed_read_write_in_expression`
 
 error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
-  --> $DIR/rename.rs:66:9
+  --> $DIR/rename.rs:67:9
    |
 LL | #![warn(clippy::identity_conversion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
 
 error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
-  --> $DIR/rename.rs:67:9
+  --> $DIR/rename.rs:68:9
    |
 LL | #![warn(clippy::if_let_some_result)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
 
 error: lint `clippy::incorrect_clone_impl_on_copy_type` has been renamed to `clippy::non_canonical_clone_impl`
-  --> $DIR/rename.rs:68:9
+  --> $DIR/rename.rs:69:9
    |
 LL | #![warn(clippy::incorrect_clone_impl_on_copy_type)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_clone_impl`
 
 error: lint `clippy::incorrect_partial_ord_impl_on_ord_type` has been renamed to `clippy::non_canonical_partial_ord_impl`
-  --> $DIR/rename.rs:69:9
+  --> $DIR/rename.rs:70:9
    |
 LL | #![warn(clippy::incorrect_partial_ord_impl_on_ord_type)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::non_canonical_partial_ord_impl`
 
 error: lint `clippy::integer_arithmetic` has been renamed to `clippy::arithmetic_side_effects`
-  --> $DIR/rename.rs:70:9
+  --> $DIR/rename.rs:71:9
    |
 LL | #![warn(clippy::integer_arithmetic)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::arithmetic_side_effects`
 
 error: lint `clippy::logic_bug` has been renamed to `clippy::overly_complex_bool_expr`
-  --> $DIR/rename.rs:71:9
+  --> $DIR/rename.rs:72:9
    |
 LL | #![warn(clippy::logic_bug)]
    |         ^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::overly_complex_bool_expr`
 
 error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
-  --> $DIR/rename.rs:72:9
+  --> $DIR/rename.rs:73:9
    |
 LL | #![warn(clippy::new_without_default_derive)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
 
 error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
-  --> $DIR/rename.rs:73:9
+  --> $DIR/rename.rs:74:9
    |
 LL | #![warn(clippy::option_and_then_some)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
 
 error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
-  --> $DIR/rename.rs:74:9
+  --> $DIR/rename.rs:75:9
    |
 LL | #![warn(clippy::option_expect_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
 error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
-  --> $DIR/rename.rs:75:9
+  --> $DIR/rename.rs:76:9
    |
 LL | #![warn(clippy::option_map_unwrap_or)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
-  --> $DIR/rename.rs:76:9
+  --> $DIR/rename.rs:77:9
    |
 LL | #![warn(clippy::option_map_unwrap_or_else)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
-  --> $DIR/rename.rs:77:9
+  --> $DIR/rename.rs:78:9
    |
 LL | #![warn(clippy::option_unwrap_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
 error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
-  --> $DIR/rename.rs:78:9
+  --> $DIR/rename.rs:79:9
    |
 LL | #![warn(clippy::ref_in_deref)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
 
 error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
-  --> $DIR/rename.rs:79:9
+  --> $DIR/rename.rs:80:9
    |
 LL | #![warn(clippy::result_expect_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
 error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
-  --> $DIR/rename.rs:80:9
+  --> $DIR/rename.rs:81:9
    |
 LL | #![warn(clippy::result_map_unwrap_or_else)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
 error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
-  --> $DIR/rename.rs:81:9
+  --> $DIR/rename.rs:82:9
    |
 LL | #![warn(clippy::result_unwrap_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
 error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
-  --> $DIR/rename.rs:82:9
+  --> $DIR/rename.rs:83:9
    |
 LL | #![warn(clippy::single_char_push_str)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
 
 error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
-  --> $DIR/rename.rs:83:9
+  --> $DIR/rename.rs:84:9
    |
 LL | #![warn(clippy::stutter)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
 
 error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
-  --> $DIR/rename.rs:84:9
+  --> $DIR/rename.rs:85:9
    |
 LL | #![warn(clippy::to_string_in_display)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
 
 error: lint `clippy::unwrap_or_else_default` has been renamed to `clippy::unwrap_or_default`
-  --> $DIR/rename.rs:85:9
+  --> $DIR/rename.rs:86:9
    |
 LL | #![warn(clippy::unwrap_or_else_default)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_or_default`
 
 error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
-  --> $DIR/rename.rs:86:9
+  --> $DIR/rename.rs:87:9
    |
 LL | #![warn(clippy::zero_width_space)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
 
 error: lint `clippy::cast_ref_to_mut` has been renamed to `invalid_reference_casting`
-  --> $DIR/rename.rs:87:9
+  --> $DIR/rename.rs:88:9
    |
 LL | #![warn(clippy::cast_ref_to_mut)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_reference_casting`
 
 error: lint `clippy::clone_double_ref` has been renamed to `suspicious_double_ref_op`
-  --> $DIR/rename.rs:88:9
+  --> $DIR/rename.rs:89:9
    |
 LL | #![warn(clippy::clone_double_ref)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `suspicious_double_ref_op`
 
 error: lint `clippy::cmp_nan` has been renamed to `invalid_nan_comparisons`
-  --> $DIR/rename.rs:89:9
+  --> $DIR/rename.rs:90:9
    |
 LL | #![warn(clippy::cmp_nan)]
    |         ^^^^^^^^^^^^^^^ help: use the new name: `invalid_nan_comparisons`
 
 error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
-  --> $DIR/rename.rs:90:9
+  --> $DIR/rename.rs:91:9
    |
 LL | #![warn(clippy::drop_bounds)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
 
 error: lint `clippy::drop_copy` has been renamed to `dropping_copy_types`
-  --> $DIR/rename.rs:91:9
+  --> $DIR/rename.rs:92:9
    |
 LL | #![warn(clippy::drop_copy)]
    |         ^^^^^^^^^^^^^^^^^ help: use the new name: `dropping_copy_types`
 
 error: lint `clippy::drop_ref` has been renamed to `dropping_references`
-  --> $DIR/rename.rs:92:9
+  --> $DIR/rename.rs:93:9
    |
 LL | #![warn(clippy::drop_ref)]
    |         ^^^^^^^^^^^^^^^^ help: use the new name: `dropping_references`
 
 error: lint `clippy::fn_null_check` has been renamed to `useless_ptr_null_checks`
-  --> $DIR/rename.rs:93:9
+  --> $DIR/rename.rs:94:9
    |
 LL | #![warn(clippy::fn_null_check)]
    |         ^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `useless_ptr_null_checks`
 
 error: lint `clippy::for_loop_over_option` has been renamed to `for_loops_over_fallibles`
-  --> $DIR/rename.rs:94:9
+  --> $DIR/rename.rs:95:9
    |
 LL | #![warn(clippy::for_loop_over_option)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::for_loop_over_result` has been renamed to `for_loops_over_fallibles`
-  --> $DIR/rename.rs:95:9
+  --> $DIR/rename.rs:96:9
    |
 LL | #![warn(clippy::for_loop_over_result)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::for_loops_over_fallibles` has been renamed to `for_loops_over_fallibles`
-  --> $DIR/rename.rs:96:9
+  --> $DIR/rename.rs:97:9
    |
 LL | #![warn(clippy::for_loops_over_fallibles)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `for_loops_over_fallibles`
 
 error: lint `clippy::forget_copy` has been renamed to `forgetting_copy_types`
-  --> $DIR/rename.rs:97:9
+  --> $DIR/rename.rs:98:9
    |
 LL | #![warn(clippy::forget_copy)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_copy_types`
 
 error: lint `clippy::forget_ref` has been renamed to `forgetting_references`
-  --> $DIR/rename.rs:98:9
+  --> $DIR/rename.rs:99:9
    |
 LL | #![warn(clippy::forget_ref)]
    |         ^^^^^^^^^^^^^^^^^^ help: use the new name: `forgetting_references`
 
 error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
-  --> $DIR/rename.rs:99:9
+  --> $DIR/rename.rs:100:9
    |
 LL | #![warn(clippy::into_iter_on_array)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
 
 error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
-  --> $DIR/rename.rs:100:9
+  --> $DIR/rename.rs:101:9
    |
 LL | #![warn(clippy::invalid_atomic_ordering)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
 
 error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
-  --> $DIR/rename.rs:101:9
+  --> $DIR/rename.rs:102:9
    |
 LL | #![warn(clippy::invalid_ref)]
    |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
 
 error: lint `clippy::invalid_utf8_in_unchecked` has been renamed to `invalid_from_utf8_unchecked`
-  --> $DIR/rename.rs:102:9
+  --> $DIR/rename.rs:103:9
    |
 LL | #![warn(clippy::invalid_utf8_in_unchecked)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_from_utf8_unchecked`
 
 error: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
-  --> $DIR/rename.rs:103:9
+  --> $DIR/rename.rs:104:9
    |
 LL | #![warn(clippy::let_underscore_drop)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
 
 error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
-  --> $DIR/rename.rs:104:9
+  --> $DIR/rename.rs:105:9
    |
 LL | #![warn(clippy::mem_discriminant_non_enum)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
 
 error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
-  --> $DIR/rename.rs:105:9
+  --> $DIR/rename.rs:106:9
    |
 LL | #![warn(clippy::panic_params)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
 
 error: lint `clippy::positional_named_format_parameters` has been renamed to `named_arguments_used_positionally`
-  --> $DIR/rename.rs:106:9
+  --> $DIR/rename.rs:107:9
    |
 LL | #![warn(clippy::positional_named_format_parameters)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `named_arguments_used_positionally`
 
 error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
-  --> $DIR/rename.rs:107:9
+  --> $DIR/rename.rs:108:9
    |
 LL | #![warn(clippy::temporary_cstring_as_ptr)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
 
 error: lint `clippy::undropped_manually_drops` has been renamed to `undropped_manually_drops`
-  --> $DIR/rename.rs:108:9
+  --> $DIR/rename.rs:109:9
    |
 LL | #![warn(clippy::undropped_manually_drops)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `undropped_manually_drops`
 
 error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
-  --> $DIR/rename.rs:109:9
+  --> $DIR/rename.rs:110:9
    |
 LL | #![warn(clippy::unknown_clippy_lints)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
 
 error: lint `clippy::unused_label` has been renamed to `unused_labels`
-  --> $DIR/rename.rs:110:9
+  --> $DIR/rename.rs:111:9
    |
 LL | #![warn(clippy::unused_label)]
    |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
 
 error: lint `clippy::vtable_address_comparisons` has been renamed to `ambiguous_wide_pointer_comparisons`
-  --> $DIR/rename.rs:111:9
+  --> $DIR/rename.rs:112:9
    |
 LL | #![warn(clippy::vtable_address_comparisons)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `ambiguous_wide_pointer_comparisons`
 
-error: aborting due to 57 previous errors
+error: aborting due to 58 previous errors
 
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed
new file mode 100644
index 00000000000..2afe2f43325
--- /dev/null
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.fixed
@@ -0,0 +1,38 @@
+#![warn(clippy::repeat_vec_with_capacity)]
+
+fn main() {
+    {
+        (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
+        //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
+    }
+
+    {
+        let n = 123;
+        (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
+        //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
+    }
+
+    {
+        macro_rules! from_macro {
+            ($x:expr) => {
+                vec![$x; 123];
+            };
+        }
+        // vec expansion is from another macro, don't lint
+        from_macro!(Vec::<()>::with_capacity(42));
+    }
+
+    {
+        std::iter::repeat_with(|| Vec::<()>::with_capacity(42));
+        //~^ ERROR: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity
+    }
+
+    {
+        macro_rules! from_macro {
+            ($x:expr) => {
+                std::iter::repeat($x)
+            };
+        }
+        from_macro!(Vec::<()>::with_capacity(42));
+    }
+}
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs
new file mode 100644
index 00000000000..659f2a3953d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.rs
@@ -0,0 +1,38 @@
+#![warn(clippy::repeat_vec_with_capacity)]
+
+fn main() {
+    {
+        vec![Vec::<()>::with_capacity(42); 123];
+        //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
+    }
+
+    {
+        let n = 123;
+        vec![Vec::<()>::with_capacity(42); n];
+        //~^ ERROR: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
+    }
+
+    {
+        macro_rules! from_macro {
+            ($x:expr) => {
+                vec![$x; 123];
+            };
+        }
+        // vec expansion is from another macro, don't lint
+        from_macro!(Vec::<()>::with_capacity(42));
+    }
+
+    {
+        std::iter::repeat(Vec::<()>::with_capacity(42));
+        //~^ ERROR: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity
+    }
+
+    {
+        macro_rules! from_macro {
+            ($x:expr) => {
+                std::iter::repeat($x)
+            };
+        }
+        from_macro!(Vec::<()>::with_capacity(42));
+    }
+}
diff --git a/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr
new file mode 100644
index 00000000000..10b5f121420
--- /dev/null
+++ b/src/tools/clippy/tests/ui/repeat_vec_with_capacity.stderr
@@ -0,0 +1,40 @@
+error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
+  --> $DIR/repeat_vec_with_capacity.rs:5:9
+   |
+LL |         vec![Vec::<()>::with_capacity(42); 123];
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only the last `Vec` will have the capacity
+   = note: `-D clippy::repeat-vec-with-capacity` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::repeat_vec_with_capacity)]`
+help: if you intended to initialize multiple `Vec`s with an initial capacity, try
+   |
+LL |         (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
+   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
+  --> $DIR/repeat_vec_with_capacity.rs:11:9
+   |
+LL |         vec![Vec::<()>::with_capacity(42); n];
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: only the last `Vec` will have the capacity
+help: if you intended to initialize multiple `Vec`s with an initial capacity, try
+   |
+LL |         (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
+   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity
+  --> $DIR/repeat_vec_with_capacity.rs:26:9
+   |
+LL |         std::iter::repeat(Vec::<()>::with_capacity(42));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: none of the yielded `Vec`s will have the requested capacity
+help: if you intended to create an iterator that yields `Vec`s with an initial capacity, try
+   |
+LL |         std::iter::repeat_with(|| Vec::<()>::with_capacity(42));
+   |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/uninhabited_references.rs b/src/tools/clippy/tests/ui/uninhabited_references.rs
new file mode 100644
index 00000000000..cd07b590a61
--- /dev/null
+++ b/src/tools/clippy/tests/ui/uninhabited_references.rs
@@ -0,0 +1,22 @@
+#![warn(clippy::uninhabited_references)]
+#![feature(never_type)]
+
+fn ret_uninh_ref() -> &'static std::convert::Infallible {
+    unsafe { std::mem::transmute(&()) }
+}
+
+macro_rules! ret_something {
+    ($name:ident, $ty:ty) => {
+        fn $name(x: &$ty) -> &$ty {
+            &*x
+        }
+    };
+}
+
+ret_something!(id_u32, u32);
+ret_something!(id_never, !);
+
+fn main() {
+    let x = ret_uninh_ref();
+    let _ = *x;
+}
diff --git a/src/tools/clippy/tests/ui/uninhabited_references.stderr b/src/tools/clippy/tests/ui/uninhabited_references.stderr
new file mode 100644
index 00000000000..2cdf320b809
--- /dev/null
+++ b/src/tools/clippy/tests/ui/uninhabited_references.stderr
@@ -0,0 +1,39 @@
+error: dereferencing a reference to an uninhabited type would be undefined behavior
+  --> $DIR/uninhabited_references.rs:4:23
+   |
+LL | fn ret_uninh_ref() -> &'static std::convert::Infallible {
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::uninhabited-references` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::uninhabited_references)]`
+
+error: dereferencing a reference to an uninhabited type would be undefined behavior
+  --> $DIR/uninhabited_references.rs:10:30
+   |
+LL |         fn $name(x: &$ty) -> &$ty {
+   |                              ^^^^
+...
+LL | ret_something!(id_never, !);
+   | --------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: dereferencing a reference to an uninhabited type is undefined behavior
+  --> $DIR/uninhabited_references.rs:11:14
+   |
+LL |             &*x
+   |              ^^
+...
+LL | ret_something!(id_never, !);
+   | --------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: dereferencing a reference to an uninhabited type is undefined behavior
+  --> $DIR/uninhabited_references.rs:21:13
+   |
+LL |     let _ = *x;
+   |             ^^
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.fixed b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
index d0c0298ef4c..463412daec0 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.fixed
@@ -7,6 +7,9 @@
 )]
 #![warn(clippy::unnecessary_operation)]
 
+use std::fmt::Display;
+use std::ops::Shl;
+
 struct Tuple(i32);
 struct Struct {
     field: i32,
@@ -50,6 +53,19 @@ fn get_drop_struct() -> DropStruct {
     DropStruct { field: 0 }
 }
 
+struct Cout;
+
+impl<T> Shl<T> for Cout
+where
+    T: Display,
+{
+    type Output = Self;
+    fn shl(self, rhs: T) -> Self::Output {
+        println!("{}", rhs);
+        self
+    }
+}
+
 fn main() {
     get_number();
     get_number();
@@ -87,4 +103,7 @@ fn main() {
         ($($e:expr),*) => {{ $($e;)* }}
     }
     use_expr!(isize::MIN / -(one() as isize), i8::MIN / -one());
+
+    // Issue #11885
+    Cout << 16;
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.rs b/src/tools/clippy/tests/ui/unnecessary_operation.rs
index e8e3a2d5657..f0d28e28902 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.rs
@@ -7,6 +7,9 @@
 )]
 #![warn(clippy::unnecessary_operation)]
 
+use std::fmt::Display;
+use std::ops::Shl;
+
 struct Tuple(i32);
 struct Struct {
     field: i32,
@@ -50,6 +53,19 @@ fn get_drop_struct() -> DropStruct {
     DropStruct { field: 0 }
 }
 
+struct Cout;
+
+impl<T> Shl<T> for Cout
+where
+    T: Display,
+{
+    type Output = Self;
+    fn shl(self, rhs: T) -> Self::Output {
+        println!("{}", rhs);
+        self
+    }
+}
+
 fn main() {
     Tuple(get_number());
     Struct { field: get_number() };
@@ -91,4 +107,7 @@ fn main() {
         ($($e:expr),*) => {{ $($e;)* }}
     }
     use_expr!(isize::MIN / -(one() as isize), i8::MIN / -one());
+
+    // Issue #11885
+    Cout << 16;
 }
diff --git a/src/tools/clippy/tests/ui/unnecessary_operation.stderr b/src/tools/clippy/tests/ui/unnecessary_operation.stderr
index fbe495f518f..eeee9ad6006 100644
--- a/src/tools/clippy/tests/ui/unnecessary_operation.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_operation.stderr
@@ -1,5 +1,5 @@
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:54:5
+  --> $DIR/unnecessary_operation.rs:70:5
    |
 LL |     Tuple(get_number());
    |     ^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
@@ -8,103 +8,103 @@ LL |     Tuple(get_number());
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_operation)]`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:55:5
+  --> $DIR/unnecessary_operation.rs:71:5
    |
 LL |     Struct { field: get_number() };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:56:5
+  --> $DIR/unnecessary_operation.rs:72:5
    |
 LL |     Struct { ..get_struct() };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_struct();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:57:5
+  --> $DIR/unnecessary_operation.rs:73:5
    |
 LL |     Enum::Tuple(get_number());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:58:5
+  --> $DIR/unnecessary_operation.rs:74:5
    |
 LL |     Enum::Struct { field: get_number() };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:59:5
+  --> $DIR/unnecessary_operation.rs:75:5
    |
 LL |     5 + get_number();
    |     ^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:60:5
+  --> $DIR/unnecessary_operation.rs:76:5
    |
 LL |     *&get_number();
    |     ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:61:5
+  --> $DIR/unnecessary_operation.rs:77:5
    |
 LL |     &get_number();
    |     ^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:62:5
+  --> $DIR/unnecessary_operation.rs:78:5
    |
 LL |     (5, 6, get_number());
    |     ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;6;get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:63:5
+  --> $DIR/unnecessary_operation.rs:79:5
    |
 LL |     get_number()..;
    |     ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:64:5
+  --> $DIR/unnecessary_operation.rs:80:5
    |
 LL |     ..get_number();
    |     ^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:65:5
+  --> $DIR/unnecessary_operation.rs:81:5
    |
 LL |     5..get_number();
    |     ^^^^^^^^^^^^^^^^ help: statement can be reduced to: `5;get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:66:5
+  --> $DIR/unnecessary_operation.rs:82:5
    |
 LL |     [42, get_number()];
    |     ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:67:5
+  --> $DIR/unnecessary_operation.rs:83:5
    |
 LL |     [42, 55][get_usize()];
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42, 55].len() > get_usize());`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:68:5
+  --> $DIR/unnecessary_operation.rs:84:5
    |
 LL |     (42, get_number()).1;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `42;get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:69:5
+  --> $DIR/unnecessary_operation.rs:85:5
    |
 LL |     [get_number(); 55];
    |     ^^^^^^^^^^^^^^^^^^^ help: statement can be reduced to: `get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:70:5
+  --> $DIR/unnecessary_operation.rs:86:5
    |
 LL |     [42; 55][get_usize()];
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: statement can be written as: `assert!([42; 55].len() > get_usize());`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:71:5
+  --> $DIR/unnecessary_operation.rs:87:5
    |
 LL | /     {
 LL | |         get_number()
@@ -112,7 +112,7 @@ LL | |     };
    | |______^ help: statement can be reduced to: `get_number();`
 
 error: unnecessary operation
-  --> $DIR/unnecessary_operation.rs:74:5
+  --> $DIR/unnecessary_operation.rs:90:5
    |
 LL | /     FooString {
 LL | |         s: String::from("blah"),
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index 67faabc53cb..2dd1d746626 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -1,4 +1,10 @@
-#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
+#![allow(
+    clippy::needless_borrow,
+    clippy::needless_borrows_for_generic_args,
+    clippy::ptr_arg,
+    clippy::manual_async_fn,
+    clippy::needless_lifetimes
+)]
 #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
 
 use std::borrow::Cow;
@@ -506,3 +512,18 @@ mod issue_10033 {
         }
     }
 }
+
+mod issue_11952 {
+    use core::future::{Future, IntoFuture};
+
+    fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> {
+        async move {
+            let _y = y;
+            Ok(())
+        }
+    }
+
+    fn bar() {
+        IntoFuture::into_future(foo([], &0));
+    }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index 99f9136427d..17fad33402b 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -1,4 +1,10 @@
-#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
+#![allow(
+    clippy::needless_borrow,
+    clippy::needless_borrows_for_generic_args,
+    clippy::ptr_arg,
+    clippy::manual_async_fn,
+    clippy::needless_lifetimes
+)]
 #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
 
 use std::borrow::Cow;
@@ -506,3 +512,18 @@ mod issue_10033 {
         }
     }
 }
+
+mod issue_11952 {
+    use core::future::{Future, IntoFuture};
+
+    fn foo<'a, T: AsRef<[u8]>>(x: T, y: &'a i32) -> impl 'a + Future<Output = Result<(), ()>> {
+        async move {
+            let _y = y;
+            Ok(())
+        }
+    }
+
+    fn bar() {
+        IntoFuture::into_future(foo([].to_vec(), &0));
+    }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
index d8971b51dca..ad6fa422b8c 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:148:64
+  --> $DIR/unnecessary_to_owned.rs:154: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:148:20
+  --> $DIR/unnecessary_to_owned.rs:154: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:149:40
+  --> $DIR/unnecessary_to_owned.rs:155: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:149:21
+  --> $DIR/unnecessary_to_owned.rs:155:21
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                     ^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:150:48
+  --> $DIR/unnecessary_to_owned.rs:156: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:150:19
+  --> $DIR/unnecessary_to_owned.rs:156:19
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:151:35
+  --> $DIR/unnecessary_to_owned.rs:157: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:151:18
+  --> $DIR/unnecessary_to_owned.rs:157:18
    |
 LL |     require_str(&String::from("x").to_string());
    |                  ^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:152:39
+  --> $DIR/unnecessary_to_owned.rs:158: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:152:20
+  --> $DIR/unnecessary_to_owned.rs:158:20
    |
 LL |     require_slice(&[String::from("x")].to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:57:36
+  --> $DIR/unnecessary_to_owned.rs:63: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:58:19
+  --> $DIR/unnecessary_to_owned.rs:64: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:60:20
+  --> $DIR/unnecessary_to_owned.rs:66: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:61:38
+  --> $DIR/unnecessary_to_owned.rs:67: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:62:20
+  --> $DIR/unnecessary_to_owned.rs:68: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:64:18
+  --> $DIR/unnecessary_to_owned.rs:70:18
    |
 LL |     require_path(&path.to_path_buf());
    |                  ^^^^^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:65:34
+  --> $DIR/unnecessary_to_owned.rs:71:34
    |
 LL |     require_path(&Cow::from(path).into_owned());
    |                                  ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:66:18
+  --> $DIR/unnecessary_to_owned.rs:72:18
    |
 LL |     require_path(&path.to_owned());
    |                  ^^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:68:17
+  --> $DIR/unnecessary_to_owned.rs:74:17
    |
 LL |     require_str(&s.to_string());
    |                 ^^^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:69:30
+  --> $DIR/unnecessary_to_owned.rs:75:30
    |
 LL |     require_str(&Cow::from(s).into_owned());
    |                              ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:70:17
+  --> $DIR/unnecessary_to_owned.rs:76:17
    |
 LL |     require_str(&s.to_owned());
    |                 ^^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:71:17
+  --> $DIR/unnecessary_to_owned.rs:77: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:73:19
+  --> $DIR/unnecessary_to_owned.rs:79:19
    |
 LL |     require_slice(&slice.to_vec());
    |                   ^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:74:36
+  --> $DIR/unnecessary_to_owned.rs:80:36
    |
 LL |     require_slice(&Cow::from(slice).into_owned());
    |                                    ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:75:19
+  --> $DIR/unnecessary_to_owned.rs:81:19
    |
 LL |     require_slice(&array.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:76:19
+  --> $DIR/unnecessary_to_owned.rs:82: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:77:19
+  --> $DIR/unnecessary_to_owned.rs:83:19
    |
 LL |     require_slice(&slice.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:80:42
+  --> $DIR/unnecessary_to_owned.rs:86: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:83:25
+  --> $DIR/unnecessary_to_owned.rs:89: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:84:26
+  --> $DIR/unnecessary_to_owned.rs:90: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:85:24
+  --> $DIR/unnecessary_to_owned.rs:91:24
    |
 LL |     require_deref_path(path.to_owned());
    |                        ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:86:23
+  --> $DIR/unnecessary_to_owned.rs:92:23
    |
 LL |     require_deref_str(s.to_owned());
    |                       ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:87:25
+  --> $DIR/unnecessary_to_owned.rs:93:25
    |
 LL |     require_deref_slice(slice.to_owned());
    |                         ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:89:30
+  --> $DIR/unnecessary_to_owned.rs:95: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:90:31
+  --> $DIR/unnecessary_to_owned.rs:96: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:91:29
+  --> $DIR/unnecessary_to_owned.rs:97:29
    |
 LL |     require_impl_deref_path(path.to_owned());
    |                             ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:92:28
+  --> $DIR/unnecessary_to_owned.rs:98:28
    |
 LL |     require_impl_deref_str(s.to_owned());
    |                            ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:93:30
+  --> $DIR/unnecessary_to_owned.rs:99:30
    |
 LL |     require_impl_deref_slice(slice.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:95:29
+  --> $DIR/unnecessary_to_owned.rs:101: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:95:43
+  --> $DIR/unnecessary_to_owned.rs:101: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:96:29
+  --> $DIR/unnecessary_to_owned.rs:102: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:96:47
+  --> $DIR/unnecessary_to_owned.rs:102: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:98:26
+  --> $DIR/unnecessary_to_owned.rs:104: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:99:27
+  --> $DIR/unnecessary_to_owned.rs:105: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:100:25
+  --> $DIR/unnecessary_to_owned.rs:106:25
    |
 LL |     require_as_ref_path(path.to_owned());
    |                         ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:101:24
+  --> $DIR/unnecessary_to_owned.rs:107:24
    |
 LL |     require_as_ref_str(s.to_owned());
    |                        ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:102:24
+  --> $DIR/unnecessary_to_owned.rs:108:24
    |
 LL |     require_as_ref_str(x.to_owned());
    |                        ^^^^^^^^^^^^ help: use: `&x`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:103:26
+  --> $DIR/unnecessary_to_owned.rs:109:26
    |
 LL |     require_as_ref_slice(array.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:104:26
+  --> $DIR/unnecessary_to_owned.rs:110: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:105:26
+  --> $DIR/unnecessary_to_owned.rs:111:26
    |
 LL |     require_as_ref_slice(slice.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:107:31
+  --> $DIR/unnecessary_to_owned.rs:113: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:108:32
+  --> $DIR/unnecessary_to_owned.rs:114: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:109:30
+  --> $DIR/unnecessary_to_owned.rs:115:30
    |
 LL |     require_impl_as_ref_path(path.to_owned());
    |                              ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:110:29
+  --> $DIR/unnecessary_to_owned.rs:116:29
    |
 LL |     require_impl_as_ref_str(s.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:111:29
+  --> $DIR/unnecessary_to_owned.rs:117:29
    |
 LL |     require_impl_as_ref_str(x.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `&x`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:112:31
+  --> $DIR/unnecessary_to_owned.rs:118:31
    |
 LL |     require_impl_as_ref_slice(array.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:113:31
+  --> $DIR/unnecessary_to_owned.rs:119: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:114:31
+  --> $DIR/unnecessary_to_owned.rs:120:31
    |
 LL |     require_impl_as_ref_slice(slice.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:116:30
+  --> $DIR/unnecessary_to_owned.rs:122: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:116:44
+  --> $DIR/unnecessary_to_owned.rs:122: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:117:30
+  --> $DIR/unnecessary_to_owned.rs:123: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:117:44
+  --> $DIR/unnecessary_to_owned.rs:123: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:118:30
+  --> $DIR/unnecessary_to_owned.rs:124: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:118:44
+  --> $DIR/unnecessary_to_owned.rs:124: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:119:30
+  --> $DIR/unnecessary_to_owned.rs:125: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:119:48
+  --> $DIR/unnecessary_to_owned.rs:125: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:120:30
+  --> $DIR/unnecessary_to_owned.rs:126: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:120:52
+  --> $DIR/unnecessary_to_owned.rs:126: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:121:30
+  --> $DIR/unnecessary_to_owned.rs:127: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:121:48
+  --> $DIR/unnecessary_to_owned.rs:127: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:123:20
+  --> $DIR/unnecessary_to_owned.rs:129:20
    |
 LL |     let _ = x.join(&x_ref.to_string());
    |                    ^^^^^^^^^^^^^^^^^^ help: use: `x_ref`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:125:13
+  --> $DIR/unnecessary_to_owned.rs:131:13
    |
 LL |     let _ = slice.to_vec().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:126:13
+  --> $DIR/unnecessary_to_owned.rs:132:13
    |
 LL |     let _ = slice.to_owned().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:127:13
+  --> $DIR/unnecessary_to_owned.rs:133: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:128:13
+  --> $DIR/unnecessary_to_owned.rs:134: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:130:13
+  --> $DIR/unnecessary_to_owned.rs:136: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:131:13
+  --> $DIR/unnecessary_to_owned.rs:137: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:132:13
+  --> $DIR/unnecessary_to_owned.rs:138: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:133:13
+  --> $DIR/unnecessary_to_owned.rs:139: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:195:14
+  --> $DIR/unnecessary_to_owned.rs:201:14
    |
 LL |     for t in file_types.to_vec() {
    |              ^^^^^^^^^^^^^^^^^^^
@@ -494,28 +494,34 @@ LL +         let path = match get_file_path(t) {
    |
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:218:14
+  --> $DIR/unnecessary_to_owned.rs:224:14
    |
 LL |     let _ = &["x"][..].to_vec().into_iter();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:223:14
+  --> $DIR/unnecessary_to_owned.rs:229:14
    |
 LL |     let _ = &["x"][..].to_vec().into_iter();
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:270:24
+  --> $DIR/unnecessary_to_owned.rs:276:24
    |
 LL |         Box::new(build(y.to_string()))
    |                        ^^^^^^^^^^^^^ help: use: `y`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:378:12
+  --> $DIR/unnecessary_to_owned.rs:384:12
    |
 LL |         id("abc".to_string())
    |            ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
 
-error: aborting due to 79 previous errors
+error: unnecessary use of `to_vec`
+  --> $DIR/unnecessary_to_owned.rs:527:37
+   |
+LL |         IntoFuture::into_future(foo([].to_vec(), &0));
+   |                                     ^^^^^^^^^^^ help: use: `[]`
+
+error: aborting due to 80 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs
index 373b18470f6..5ad117eb8db 100644
--- a/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_unsafety_doc.rs
@@ -1,6 +1,6 @@
 //@aux-build:proc_macros.rs
 
-#![allow(clippy::let_unit_value)]
+#![allow(clippy::let_unit_value, clippy::needless_pass_by_ref_mut)]
 #![warn(clippy::unnecessary_safety_doc)]
 
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/vec.fixed b/src/tools/clippy/tests/ui/vec.fixed
index bcbca971a78..81b8bd7da77 100644
--- a/src/tools/clippy/tests/ui/vec.fixed
+++ b/src/tools/clippy/tests/ui/vec.fixed
@@ -176,3 +176,37 @@ fn below() {
         let _: String = a;
     }
 }
+
+fn func_needing_vec(_bar: usize, _baz: Vec<usize>) {}
+fn func_not_needing_vec(_bar: usize, _baz: usize) {}
+
+fn issue11861() {
+    macro_rules! this_macro_needs_vec {
+        ($x:expr) => {{
+            func_needing_vec($x.iter().sum(), $x);
+            for _ in $x {}
+        }};
+    }
+    macro_rules! this_macro_doesnt_need_vec {
+        ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }};
+    }
+
+    // Do not lint the next line
+    this_macro_needs_vec!(vec![1]);
+    this_macro_doesnt_need_vec!([1]); //~ ERROR: useless use of `vec!`
+
+    macro_rules! m {
+        ($x:expr) => {
+            fn f2() {
+                let _x: Vec<i32> = $x;
+            }
+            fn f() {
+                let _x = $x;
+                $x.starts_with(&[]);
+            }
+        };
+    }
+
+    // should not lint
+    m!(vec![1]);
+}
diff --git a/src/tools/clippy/tests/ui/vec.rs b/src/tools/clippy/tests/ui/vec.rs
index 087425585de..5aca9b2925c 100644
--- a/src/tools/clippy/tests/ui/vec.rs
+++ b/src/tools/clippy/tests/ui/vec.rs
@@ -176,3 +176,37 @@ fn below() {
         let _: String = a;
     }
 }
+
+fn func_needing_vec(_bar: usize, _baz: Vec<usize>) {}
+fn func_not_needing_vec(_bar: usize, _baz: usize) {}
+
+fn issue11861() {
+    macro_rules! this_macro_needs_vec {
+        ($x:expr) => {{
+            func_needing_vec($x.iter().sum(), $x);
+            for _ in $x {}
+        }};
+    }
+    macro_rules! this_macro_doesnt_need_vec {
+        ($x:expr) => {{ func_not_needing_vec($x.iter().sum(), $x.iter().sum()) }};
+    }
+
+    // Do not lint the next line
+    this_macro_needs_vec!(vec![1]);
+    this_macro_doesnt_need_vec!(vec![1]); //~ ERROR: useless use of `vec!`
+
+    macro_rules! m {
+        ($x:expr) => {
+            fn f2() {
+                let _x: Vec<i32> = $x;
+            }
+            fn f() {
+                let _x = $x;
+                $x.starts_with(&[]);
+            }
+        };
+    }
+
+    // should not lint
+    m!(vec![1]);
+}
diff --git a/src/tools/clippy/tests/ui/vec.stderr b/src/tools/clippy/tests/ui/vec.stderr
index fc261838fe3..c9018f94f9d 100644
--- a/src/tools/clippy/tests/ui/vec.stderr
+++ b/src/tools/clippy/tests/ui/vec.stderr
@@ -115,5 +115,11 @@ error: useless use of `vec!`
 LL |     for a in vec![String::new(), String::new()] {
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: you can use an array directly: `[String::new(), String::new()]`
 
-error: aborting due to 19 previous errors
+error: useless use of `vec!`
+  --> $DIR/vec.rs:196:33
+   |
+LL |     this_macro_doesnt_need_vec!(vec![1]);
+   |                                 ^^^^^^^ help: you can use an array directly: `[1]`
+
+error: aborting due to 20 previous errors
 
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index ab2fb1a3291..96085bcf9ee 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -19,6 +19,7 @@ new_pr = true
 
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
+users_on_vacation = ["blyxyas"]
 
 [assign.owners]
 "/.github" = ["@flip1995"]
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
index 54430e0d190..917d8a6e26a 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server.rs
@@ -58,6 +58,10 @@ impl server::Types for RustAnalyzer {
 }
 
 impl server::FreeFunctions for RustAnalyzer {
+    fn injected_env_var(&mut self, _var: &str) -> Option<String> {
+        None
+    }
+
     fn track_env_var(&mut self, _var: &str, _value: Option<&str>) {
         // FIXME: track env var accesses
         // https://github.com/rust-lang/rust/pull/71858
diff --git a/tests/codegen/debug-accessibility/crate-enum.rs b/tests/codegen/debug-accessibility/crate-enum.rs
new file mode 100644
index 00000000000..eeea18dd815
--- /dev/null
+++ b/tests/codegen/debug-accessibility/crate-enum.rs
@@ -0,0 +1,26 @@
+// compile-flags: -C debuginfo=2
+// ignore-tidy-linelength
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for crate-visibility enums.
+
+mod module {
+    use std::hint::black_box;
+
+    pub(crate) enum CrateFooEnum {
+        A,
+        B(u32),
+        C { x: u32 },
+    }
+
+    // NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "CrateFooEnum"{{.*}}flags: DIFlagProtected{{.*}})
+    // MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<crate_enum::module::CrateFooEnum>"{{.*}}flags: DIFlagProtected{{.*}})
+    pub fn use_everything() {
+        black_box(CrateFooEnum::A);
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/crate-struct.rs b/tests/codegen/debug-accessibility/crate-struct.rs
new file mode 100644
index 00000000000..68d126a3478
--- /dev/null
+++ b/tests/codegen/debug-accessibility/crate-struct.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for crate-visibility structs.
+
+mod module {
+    use std::hint::black_box;
+
+    pub(crate) struct CrateFooStruct {
+        x: u32,
+    }
+
+    // CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "CrateFooStruct"{{.*}}flags: DIFlagProtected{{.*}})
+
+    pub fn use_everything() {
+        black_box(CrateFooStruct { x: 2 });
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/private-enum.rs b/tests/codegen/debug-accessibility/private-enum.rs
new file mode 100644
index 00000000000..7f81026ddec
--- /dev/null
+++ b/tests/codegen/debug-accessibility/private-enum.rs
@@ -0,0 +1,21 @@
+// compile-flags: -C debuginfo=2
+// ignore-tidy-linelength
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for private enums.
+
+use std::hint::black_box;
+
+enum PrivateFooEnum {
+    A,
+    B(u32),
+    C { x: u32 },
+}
+
+// NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PrivateFooEnum"{{.*}}flags: DIFlagPrivate{{.*}})
+// MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<private_enum::PrivateFooEnum>"{{.*}}flags: DIFlagPrivate{{.*}})
+
+fn main() {
+    black_box(PrivateFooEnum::A);
+}
diff --git a/tests/codegen/debug-accessibility/private-struct.rs b/tests/codegen/debug-accessibility/private-struct.rs
new file mode 100644
index 00000000000..43b260f9024
--- /dev/null
+++ b/tests/codegen/debug-accessibility/private-struct.rs
@@ -0,0 +1,17 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for private structs.
+
+use std::hint::black_box;
+
+struct PrivateFooStruct {
+    x: u32,
+}
+
+// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PrivateFooStruct"{{.*}}flags: DIFlagPrivate{{.*}})
+
+fn main() {
+    black_box(PrivateFooStruct { x: 1 });
+}
diff --git a/tests/codegen/debug-accessibility/public-enum.rs b/tests/codegen/debug-accessibility/public-enum.rs
new file mode 100644
index 00000000000..29ae5fd6421
--- /dev/null
+++ b/tests/codegen/debug-accessibility/public-enum.rs
@@ -0,0 +1,21 @@
+// compile-flags: -C debuginfo=2
+// ignore-tidy-linelength
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for types and their fields.
+
+use std::hint::black_box;
+
+pub enum PublicFooEnum {
+    A,
+    B(u32),
+    C { x: u32 },
+}
+
+// NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PublicFooEnum"{{.*}}flags: DIFlagPublic{{.*}})
+// MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<public_enum::PublicFooEnum>"{{.*}}flags: DIFlagPublic{{.*}})
+
+fn main() {
+    black_box(PublicFooEnum::A);
+}
diff --git a/tests/codegen/debug-accessibility/public-struct.rs b/tests/codegen/debug-accessibility/public-struct.rs
new file mode 100644
index 00000000000..e7cd9b40d09
--- /dev/null
+++ b/tests/codegen/debug-accessibility/public-struct.rs
@@ -0,0 +1,17 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for public structs.
+
+use std::hint::black_box;
+
+pub struct PublicFooStruct {
+    x: u32,
+}
+
+// CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "PublicFooStruct"{{.*}}flags: DIFlagPublic{{.*}})
+
+fn main() {
+    black_box(PublicFooStruct { x: 4 });
+}
diff --git a/tests/codegen/debug-accessibility/struct-fields.rs b/tests/codegen/debug-accessibility/struct-fields.rs
new file mode 100644
index 00000000000..76831bdc6c6
--- /dev/null
+++ b/tests/codegen/debug-accessibility/struct-fields.rs
@@ -0,0 +1,30 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for struct fields.
+
+mod module {
+    use std::hint::black_box;
+
+    struct StructFields {
+        a: u32,
+        pub(crate) b: u32,
+        pub(super) c: u32,
+        pub d: u32,
+    }
+
+    // CHECK: [[StructFields:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "StructFields"{{.*}}flags: DIFlagPrivate{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: [[StructFields]]{{.*}}flags: DIFlagPrivate{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "b", scope: [[StructFields]]{{.*}}flags: DIFlagProtected{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "c", scope: [[StructFields]]{{.*}}flags: DIFlagProtected{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "d", scope: [[StructFields]]{{.*}}flags: DIFlagPublic{{.*}})
+
+    pub fn use_everything() {
+        black_box(StructFields { a: 1, b: 2, c: 3, d: 4 });
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/super-enum.rs b/tests/codegen/debug-accessibility/super-enum.rs
new file mode 100644
index 00000000000..9d83fb45bd0
--- /dev/null
+++ b/tests/codegen/debug-accessibility/super-enum.rs
@@ -0,0 +1,27 @@
+// compile-flags: -C debuginfo=2
+// ignore-tidy-linelength
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for super-visibility enums.
+
+mod module {
+    use std::hint::black_box;
+
+    pub(super) enum SuperFooEnum {
+        A,
+        B(u32),
+        C { x: u32 },
+    }
+
+    // NONMSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "SuperFooEnum"{{.*}}flags: DIFlagProtected{{.*}})
+    // MSVC: {{!.*}} = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<super_enum::module::SuperFooEnum>"{{.*}}flags: DIFlagProtected{{.*}})
+
+    pub fn use_everything() {
+        black_box(SuperFooEnum::A);
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/super-struct.rs b/tests/codegen/debug-accessibility/super-struct.rs
new file mode 100644
index 00000000000..481006c3965
--- /dev/null
+++ b/tests/codegen/debug-accessibility/super-struct.rs
@@ -0,0 +1,23 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for super-visibility structs.
+
+mod module {
+    use std::hint::black_box;
+
+    pub(super) struct SuperFooStruct {
+        x: u32,
+    }
+
+    // CHECK: {{!.*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "SuperFooStruct"{{.*}}flags: DIFlagProtected{{.*}})
+
+    pub fn use_everything() {
+        black_box(SuperFooStruct { x: 3 });
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/codegen/debug-accessibility/tuple-fields.rs b/tests/codegen/debug-accessibility/tuple-fields.rs
new file mode 100644
index 00000000000..1163ba2c7c3
--- /dev/null
+++ b/tests/codegen/debug-accessibility/tuple-fields.rs
@@ -0,0 +1,24 @@
+// compile-flags: -C debuginfo=2
+
+#![allow(dead_code)]
+
+// Checks that visibility information is present in the debuginfo for tuple struct fields.
+
+mod module {
+    use std::hint::black_box;
+
+    struct TupleFields(u32, pub(crate) u32, pub(super) u32, pub u32);
+
+    // CHECK: [[TupleFields:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "TupleFields"{{.*}}flags: DIFlagPrivate{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__0", scope: [[TupleFields]]{{.*}}flags: DIFlagPrivate{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__1", scope: [[TupleFields]]{{.*}}flags: DIFlagProtected{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__2", scope: [[TupleFields]]{{.*}}flags: DIFlagProtected{{.*}})
+    // CHECK: {{!.*}} = !DIDerivedType(tag: DW_TAG_member, name: "__3", scope: [[TupleFields]]{{.*}}flags: DIFlagPublic{{.*}})
+    pub fn use_everything() {
+        black_box(TupleFields(1, 2, 3, 4));
+    }
+}
+
+fn main() {
+    module::use_everything();
+}
diff --git a/tests/coverage/assert_not.cov-map b/tests/coverage/assert_not.cov-map
new file mode 100644
index 00000000000..788bc5dbf58
--- /dev/null
+++ b/tests/coverage/assert_not.cov-map
@@ -0,0 +1,16 @@
+Function name: assert_not::main
+Raw bytes (33): 0x[01, 01, 02, 05, 00, 0d, 00, 05, 01, 06, 01, 01, 12, 05, 02, 05, 00, 14, 02, 01, 05, 00, 14, 0d, 01, 05, 00, 16, 06, 01, 01, 00, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 2
+- expression 0 operands: lhs = Counter(1), rhs = Zero
+- expression 1 operands: lhs = Counter(3), rhs = Zero
+Number of file 0 mappings: 5
+- Code(Counter(0)) at (prev + 6, 1) to (start + 1, 18)
+- Code(Counter(1)) at (prev + 2, 5) to (start + 0, 20)
+- Code(Expression(0, Sub)) at (prev + 1, 5) to (start + 0, 20)
+    = (c1 - Zero)
+- Code(Counter(3)) at (prev + 1, 5) to (start + 0, 22)
+- Code(Expression(1, Sub)) at (prev + 1, 1) to (start + 0, 2)
+    = (c3 - Zero)
+
diff --git a/tests/coverage/assert_not.coverage b/tests/coverage/assert_not.coverage
new file mode 100644
index 00000000000..4cfdab974ed
--- /dev/null
+++ b/tests/coverage/assert_not.coverage
@@ -0,0 +1,12 @@
+   LL|       |// edition: 2021
+   LL|       |
+   LL|       |// Regression test for <https://github.com/rust-lang/rust/issues/118904>.
+   LL|       |// `assert!(true)` and `assert!(!false)` should have similar coverage spans.
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    assert!(true);
+   LL|      1|    assert!(!false);
+   LL|      1|    assert!(!!true);
+   LL|      1|    assert!(!!!false);
+   LL|      1|}
+
diff --git a/tests/coverage/assert_not.rs b/tests/coverage/assert_not.rs
new file mode 100644
index 00000000000..95204fcadd1
--- /dev/null
+++ b/tests/coverage/assert_not.rs
@@ -0,0 +1,11 @@
+// edition: 2021
+
+// Regression test for <https://github.com/rust-lang/rust/issues/118904>.
+// `assert!(true)` and `assert!(!false)` should have similar coverage spans.
+
+fn main() {
+    assert!(true);
+    assert!(!false);
+    assert!(!!true);
+    assert!(!!!false);
+}
diff --git a/tests/rustdoc-gui/globals.goml b/tests/rustdoc-gui/globals.goml
new file mode 100644
index 00000000000..53f96ff086e
--- /dev/null
+++ b/tests/rustdoc-gui/globals.goml
@@ -0,0 +1,24 @@
+// Make sure search stores its data in `window`
+// It needs to use a global to avoid racing on search-index.js and search.js
+// https://github.com/rust-lang/rust/pull/118961
+
+// URL query
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=sa'%3Bda'%3Bds"
+wait-for: "#search-tabs"
+assert-window-property-false: {"searchIndex": null}
+assert-window-property: {"srcIndex": null}
+
+// Form input
+go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+write: (".search-input", "Foo")
+press-key: 'Enter'
+wait-for: "#search-tabs"
+assert-window-property-false: {"searchIndex": null}
+assert-window-property: {"srcIndex": null}
+
+// source sidebar
+go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
+click: "#src-sidebar-toggle"
+wait-for: "#src-sidebar details"
+assert-window-property-false: {"srcIndex": null}
+assert-window-property: {"searchIndex": null}
diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr
index 69f541cba05..f64e8b39798 100644
--- a/tests/ui/coherence/occurs-check/associated-type.next.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr
@@ -1,11 +1,11 @@
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!2_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
 error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
   --> $DIR/associated-type.rs:31:1
    |
diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr
index c2c951af0db..8e852ec796e 100644
--- a/tests/ui/coherence/occurs-check/associated-type.old.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr
@@ -1,11 +1,11 @@
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
-WARN rustc_infer::infer::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
+WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: Alias(Projection, AliasTy { args: [*const ?1t, RePlaceholder(!3_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) })
 error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)`
   --> $DIR/associated-type.rs:31:1
    |
diff --git a/tests/ui/duplicate_entry_error.stderr b/tests/ui/duplicate_entry_error.stderr
index 592640a884c..3b5998df353 100644
--- a/tests/ui/duplicate_entry_error.stderr
+++ b/tests/ui/duplicate_entry_error.stderr
@@ -1,8 +1,11 @@
 error[E0152]: found duplicate lang item `panic_impl`
   --> $DIR/duplicate_entry_error.rs:11:1
    |
-LL | fn panic_impl(info: &PanicInfo) -> ! {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn panic_impl(info: &PanicInfo) -> ! {
+LL | |
+LL | |     loop {}
+LL | | }
+   | |_^
    |
    = note: the lang item is first defined in crate `std` (which `duplicate_entry_error` depends on)
    = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
diff --git a/tests/ui/error-codes/E0152.stderr b/tests/ui/error-codes/E0152.stderr
index 816ba2d569b..dbea7e6d27f 100644
--- a/tests/ui/error-codes/E0152.stderr
+++ b/tests/ui/error-codes/E0152.stderr
@@ -2,7 +2,7 @@ error[E0152]: found duplicate lang item `owned_box`
   --> $DIR/E0152.rs:5:1
    |
 LL | struct Foo<T>(T);
-   | ^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^
    |
    = note: the lang item is first defined in crate `alloc` (which `std` depends on)
    = note: first definition in `alloc` loaded from SYSROOT/liballoc-*.rlib
diff --git a/tests/ui/error-codes/E0264.stderr b/tests/ui/error-codes/E0264.stderr
index 14a4ffbe316..3503fb229e4 100644
--- a/tests/ui/error-codes/E0264.stderr
+++ b/tests/ui/error-codes/E0264.stderr
@@ -2,7 +2,7 @@ error[E0264]: unknown external lang item: `cake`
   --> $DIR/E0264.rs:5:5
    |
 LL |     fn cake();
-   |     ^^^^^^^^^
+   |     ^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/hygiene/cross-crate-define-and-use.rs b/tests/ui/hygiene/cross-crate-define-and-use.rs
index 94f1adff626..62b1820235c 100644
--- a/tests/ui/hygiene/cross-crate-define-and-use.rs
+++ b/tests/ui/hygiene/cross-crate-define-and-use.rs
@@ -6,7 +6,6 @@
 // check-pass
 // aux-build:use_by_macro.rs
 
-#![feature(type_name_of_val)]
 extern crate use_by_macro;
 
 use use_by_macro::*;
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
index 6ccbb5bb266..280856805e5 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.rs
@@ -1,5 +1,3 @@
-#![deny(implied_bounds_entailment)]
-
 trait Project {
     type Ty;
 }
@@ -11,8 +9,7 @@ trait Trait {
 }
 impl Trait for () {
     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
-        //~^ ERROR impl method assumes more implied bounds than the corresponding trait method
-        //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+        //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
         s
     }
 }
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
index 86b12cf8fa2..c8d1614a7f3 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility-unnormalized.stderr
@@ -1,31 +1,28 @@
-error: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
+  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
    |
 LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9
-   |
-LL | #![deny(implied_bounds_entailment)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
-Future incompatibility report: Future breakage diagnostic:
-error: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:13:31
+note: first, the lifetime cannot outlive the lifetime `'s` as defined here...
+  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:12
    |
 LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `()`
+   |            ^^
+note: ...so that the method type is compatible with trait
+  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:1:9
+LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `fn(&'s _, ()) -> &'static _`
+              found `fn(&_, ()) -> &'static _`
+   = note: but, the lifetime must be valid for the static lifetime...
+note: ...so that the reference type `&'static &()` does not outlive the data it points at
+  --> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
    |
-LL | #![deny(implied_bounds_entailment)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs
index d097bc16a22..7f3817b326a 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.rs
@@ -1,5 +1,3 @@
-#![deny(implied_bounds_entailment)]
-
 use std::cell::RefCell;
 
 pub struct MessageListeners<'a> {
@@ -12,8 +10,7 @@ pub trait MessageListenersInterface {
 
 impl<'a> MessageListenersInterface for MessageListeners<'a> {
     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
-        //~^ ERROR impl method assumes more implied bounds than the corresponding trait method
-        //~| WARN this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+        //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
         self
     }
 }
diff --git a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
index a89645c128b..6a412eb5e4b 100644
--- a/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
+++ b/tests/ui/implied-bounds/impl-implied-bounds-compatibility.stderr
@@ -1,31 +1,32 @@
-error: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/impl-implied-bounds-compatibility.rs:14:35
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'b in generic type due to conflicting requirements
+  --> $DIR/impl-implied-bounds-compatibility.rs:12:5
    |
 LL |     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/impl-implied-bounds-compatibility.rs:1:9
+note: first, the lifetime cannot outlive the lifetime `'c` as defined here...
+  --> $DIR/impl-implied-bounds-compatibility.rs:12:5
    |
-LL | #![deny(implied_bounds_entailment)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 1 previous error
-
-Future incompatibility report: Future breakage diagnostic:
-error: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/impl-implied-bounds-compatibility.rs:14:35
+LL |     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...so that the method type is compatible with trait
+  --> $DIR/impl-implied-bounds-compatibility.rs:12:5
    |
 LL |     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `&'b MessageListeners<'b>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `fn(&'c MessageListeners<'_>) -> &'c MessageListeners<'c>`
+              found `fn(&MessageListeners<'_>) -> &'a MessageListeners<'_>`
+note: but, the lifetime must be valid for the lifetime `'a` as defined here...
+  --> $DIR/impl-implied-bounds-compatibility.rs:11:6
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/impl-implied-bounds-compatibility.rs:1:9
+LL | impl<'a> MessageListenersInterface for MessageListeners<'a> {
+   |      ^^
+note: ...so that the reference type `&'a MessageListeners<'_>` does not outlive the data it points at
+  --> $DIR/impl-implied-bounds-compatibility.rs:12:5
    |
-LL | #![deny(implied_bounds_entailment)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn listeners<'b>(&'b self) -> &'a MessageListeners<'b> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/lang-items/lang-item-generic-requirements.rs b/tests/ui/lang-items/lang-item-generic-requirements.rs
index 3d33adf6831..21bd7187e15 100644
--- a/tests/ui/lang-items/lang-item-generic-requirements.rs
+++ b/tests/ui/lang-items/lang-item-generic-requirements.rs
@@ -22,6 +22,8 @@ trait MyIndex<'a, T> {}
 #[lang = "phantom_data"]
 //~^ ERROR `phantom_data` language item must be applied to a struct with 1 generic argument
 struct MyPhantomData<T, U>;
+//~^ ERROR parameter `T` is never used
+//~| ERROR parameter `U` is never used
 
 #[lang = "owned_box"]
 //~^ ERROR `owned_box` language item must be applied to a struct with at least 1 generic argument
@@ -40,6 +42,7 @@ fn ice() {
     let r = 5;
     let a = 6;
     r + a;
+    //~^ ERROR cannot add `{integer}` to `{integer}`
 
     // Use drop in place
     my_ptr_drop();
diff --git a/tests/ui/lang-items/lang-item-generic-requirements.stderr b/tests/ui/lang-items/lang-item-generic-requirements.stderr
index 4d349a25f9c..8072e6797e4 100644
--- a/tests/ui/lang-items/lang-item-generic-requirements.stderr
+++ b/tests/ui/lang-items/lang-item-generic-requirements.stderr
@@ -33,7 +33,7 @@ LL | struct MyPhantomData<T, U>;
    |                     ------ this struct has 2 generic arguments
 
 error[E0718]: `owned_box` language item must be applied to a struct with at least 1 generic argument
-  --> $DIR/lang-item-generic-requirements.rs:26:1
+  --> $DIR/lang-item-generic-requirements.rs:28:1
    |
 LL | #[lang = "owned_box"]
    | ^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +42,7 @@ LL | struct Foo;
    |           - this struct has 0 generic arguments
 
 error[E0718]: `start` language item must be applied to a function with 1 generic argument
-  --> $DIR/lang-item-generic-requirements.rs:32:1
+  --> $DIR/lang-item-generic-requirements.rs:34:1
    |
 LL | #[lang = "start"]
    | ^^^^^^^^^^^^^^^^^
@@ -50,6 +50,35 @@ LL |
 LL | fn start(_: *const u8, _: isize, _: *const *const u8) -> isize {
    |         - this function has 0 generic arguments
 
-error: aborting due to 6 previous errors
+error[E0392]: parameter `T` is never used
+  --> $DIR/lang-item-generic-requirements.rs:24:22
+   |
+LL | struct MyPhantomData<T, U>;
+   |                      ^ unused parameter
+   |
+   = help: consider removing `T` or referring to it in a field
+   = help: if you intended `T` to be a const parameter, use `const T: usize` instead
+
+error[E0392]: parameter `U` is never used
+  --> $DIR/lang-item-generic-requirements.rs:24:25
+   |
+LL | struct MyPhantomData<T, U>;
+   |                         ^ unused parameter
+   |
+   = help: consider removing `U` or referring to it in a field
+   = help: if you intended `U` to be a const parameter, use `const U: usize` instead
+
+error[E0369]: cannot add `{integer}` to `{integer}`
+  --> $DIR/lang-item-generic-requirements.rs:44:7
+   |
+LL |     r + a;
+   |     - ^ - {integer}
+   |     |
+   |     {integer}
+
+error: requires `copy` lang_item
+
+error: aborting due to 10 previous errors
 
-For more information about this error, try `rustc --explain E0718`.
+Some errors have detailed explanations: E0369, E0392, E0718.
+For more information about an error, try `rustc --explain E0369`.
diff --git a/tests/ui/lint/ptr_null_checks.rs b/tests/ui/lint/ptr_null_checks.rs
index 3028084e962..4925019be1e 100644
--- a/tests/ui/lint/ptr_null_checks.rs
+++ b/tests/ui/lint/ptr_null_checks.rs
@@ -1,7 +1,5 @@
 // check-pass
 
-#![feature(ptr_from_ref)]
-
 use std::ptr;
 
 extern "C" fn c_fn() {}
diff --git a/tests/ui/lint/ptr_null_checks.stderr b/tests/ui/lint/ptr_null_checks.stderr
index 0edc1b86536..70a27790c5b 100644
--- a/tests/ui/lint/ptr_null_checks.stderr
+++ b/tests/ui/lint/ptr_null_checks.stderr
@@ -1,5 +1,5 @@
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:14:8
+  --> $DIR/ptr_null_checks.rs:12:8
    |
 LL |     if (fn_ptr as *mut ()).is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^
@@ -10,7 +10,7 @@ LL |     if (fn_ptr as *mut ()).is_null() {}
    = note: `#[warn(useless_ptr_null_checks)]` on by default
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:16:8
+  --> $DIR/ptr_null_checks.rs:14:8
    |
 LL |     if (fn_ptr as *const u8).is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^
@@ -20,7 +20,7 @@ LL |     if (fn_ptr as *const u8).is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:18:8
+  --> $DIR/ptr_null_checks.rs:16:8
    |
 LL |     if (fn_ptr as *const ()) == std::ptr::null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -30,7 +30,7 @@ LL |     if (fn_ptr as *const ()) == std::ptr::null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:20:8
+  --> $DIR/ptr_null_checks.rs:18:8
    |
 LL |     if (fn_ptr as *mut ()) == std::ptr::null_mut() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     if (fn_ptr as *mut ()) == std::ptr::null_mut() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:22:8
+  --> $DIR/ptr_null_checks.rs:20:8
    |
 LL |     if (fn_ptr as *const ()) == (0 as *const ()) {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +50,7 @@ LL |     if (fn_ptr as *const ()) == (0 as *const ()) {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:24:8
+  --> $DIR/ptr_null_checks.rs:22:8
    |
 LL |     if <*const _>::is_null(fn_ptr as *const ()) {}
    |        ^^^^^^^^^^^^^^^^^^^^------^^^^^^^^^^^^^^
@@ -60,7 +60,7 @@ LL |     if <*const _>::is_null(fn_ptr as *const ()) {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:26:8
+  --> $DIR/ptr_null_checks.rs:24:8
    |
 LL |     if (fn_ptr as *mut fn() as *const fn() as *const ()).is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL |     if (fn_ptr as *mut fn() as *const fn() as *const ()).is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:28:8
+  --> $DIR/ptr_null_checks.rs:26:8
    |
 LL |     if (fn_ptr as *mut fn() as *const fn()).cast_mut().is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL |     if (fn_ptr as *mut fn() as *const fn()).cast_mut().is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:30:8
+  --> $DIR/ptr_null_checks.rs:28:8
    |
 LL |     if ((fn_ptr as *mut fn()).cast() as *const fn()).cast_mut().is_null() {}
    |        ^^------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     if ((fn_ptr as *mut fn()).cast() as *const fn()).cast_mut().is_null() {
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:32:8
+  --> $DIR/ptr_null_checks.rs:30:8
    |
 LL |     if (fn_ptr as fn() as *const ()).is_null() {}
    |        ^--------------^^^^^^^^^^^^^^^^^^^^^^^^
@@ -100,7 +100,7 @@ LL |     if (fn_ptr as fn() as *const ()).is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: function pointers are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:34:8
+  --> $DIR/ptr_null_checks.rs:32:8
    |
 LL |     if (c_fn as *const fn()).is_null() {}
    |        ^----^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -110,7 +110,7 @@ LL |     if (c_fn as *const fn()).is_null() {}
    = help: wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:38:8
+  --> $DIR/ptr_null_checks.rs:36:8
    |
 LL |     if (&mut 8 as *mut i32).is_null() {}
    |        ^------^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,13 +118,13 @@ LL |     if (&mut 8 as *mut i32).is_null() {}
    |         expression has type `&mut i32`
 
 warning: returned pointer of `from_mut` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:40:8
+  --> $DIR/ptr_null_checks.rs:38:8
    |
 LL |     if ptr::from_mut(&mut 8).is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:42:8
+  --> $DIR/ptr_null_checks.rs:40:8
    |
 LL |     if (&8 as *const i32).is_null() {}
    |        ^--^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -132,25 +132,25 @@ LL |     if (&8 as *const i32).is_null() {}
    |         expression has type `&i32`
 
 warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:44:8
+  --> $DIR/ptr_null_checks.rs:42:8
    |
 LL |     if ptr::from_ref(&8).is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:46:8
+  --> $DIR/ptr_null_checks.rs:44:8
    |
 LL |     if ptr::from_ref(&8).cast_mut().is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: returned pointer of `from_ref` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:48:8
+  --> $DIR/ptr_null_checks.rs:46:8
    |
 LL |     if (ptr::from_ref(&8).cast_mut() as *mut i32).is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:50:8
+  --> $DIR/ptr_null_checks.rs:48:8
    |
 LL |     if (&8 as *const i32) == std::ptr::null() {}
    |        ^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -158,7 +158,7 @@ LL |     if (&8 as *const i32) == std::ptr::null() {}
    |         expression has type `&i32`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:53:8
+  --> $DIR/ptr_null_checks.rs:51:8
    |
 LL |     if (ref_num as *const i32) == std::ptr::null() {}
    |        ^-------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -166,7 +166,7 @@ LL |     if (ref_num as *const i32) == std::ptr::null() {}
    |         expression has type `&i32`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:55:8
+  --> $DIR/ptr_null_checks.rs:53:8
    |
 LL |     if (b"\0" as *const u8).is_null() {}
    |        ^-----^^^^^^^^^^^^^^^^^^^^^^^^
@@ -174,7 +174,7 @@ LL |     if (b"\0" as *const u8).is_null() {}
    |         expression has type `&[u8; 1]`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:57:8
+  --> $DIR/ptr_null_checks.rs:55:8
    |
 LL |     if ("aa" as *const str).is_null() {}
    |        ^----^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -182,7 +182,7 @@ LL |     if ("aa" as *const str).is_null() {}
    |         expression has type `&str`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:59:8
+  --> $DIR/ptr_null_checks.rs:57:8
    |
 LL |     if (&[1, 2] as *const i32).is_null() {}
    |        ^-------^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -190,7 +190,7 @@ LL |     if (&[1, 2] as *const i32).is_null() {}
    |         expression has type `&[i32; 2]`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:61:8
+  --> $DIR/ptr_null_checks.rs:59:8
    |
 LL |     if (&mut [1, 2] as *mut i32) == std::ptr::null_mut() {}
    |        ^-----------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -198,7 +198,7 @@ LL |     if (&mut [1, 2] as *mut i32) == std::ptr::null_mut() {}
    |         expression has type `&mut [i32; 2]`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:63:8
+  --> $DIR/ptr_null_checks.rs:61:8
    |
 LL |     if (static_i32() as *const i32).is_null() {}
    |        ^------------^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -206,7 +206,7 @@ LL |     if (static_i32() as *const i32).is_null() {}
    |         expression has type `&i32`
 
 warning: references are not nullable, so checking them for null will always return false
-  --> $DIR/ptr_null_checks.rs:65:8
+  --> $DIR/ptr_null_checks.rs:63:8
    |
 LL |     if (&*{ static_i32() } as *const i32).is_null() {}
    |        ^------------------^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -214,13 +214,13 @@ LL |     if (&*{ static_i32() } as *const i32).is_null() {}
    |         expression has type `&i32`
 
 warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:69:8
+  --> $DIR/ptr_null_checks.rs:67:8
    |
 LL |     if ptr::NonNull::new(&mut 8).unwrap().as_ptr().is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: returned pointer of `as_ptr` call is never null, so checking it for null will always return false
-  --> $DIR/ptr_null_checks.rs:71:8
+  --> $DIR/ptr_null_checks.rs:69:8
    |
 LL |     if ptr::NonNull::<u8>::dangling().as_ptr().is_null() {}
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs
index fe8c6e3ff23..84267c0af03 100644
--- a/tests/ui/lint/reference_casting.rs
+++ b/tests/ui/lint/reference_casting.rs
@@ -1,7 +1,5 @@
 // check-fail
 
-#![feature(ptr_from_ref)]
-
 extern "C" {
     // N.B., mutability can be easily incorrect in FFI calls -- as
     // in C, the default is mutable pointers.
diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr
index 2820696508a..374a58d7b7b 100644
--- a/tests/ui/lint/reference_casting.stderr
+++ b/tests/ui/lint/reference_casting.stderr
@@ -1,5 +1,5 @@
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:19:16
+  --> $DIR/reference_casting.rs:17:16
    |
 LL |     let _num = &mut *(num as *const i32 as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let _num = &mut *(num as *const i32 as *mut i32);
    = note: `#[deny(invalid_reference_casting)]` on by default
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:21:16
+  --> $DIR/reference_casting.rs:19:16
    |
 LL |     let _num = &mut *(num as *const i32).cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL |     let _num = &mut *(num as *const i32).cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:23:16
+  --> $DIR/reference_casting.rs:21:16
    |
 LL |     let _num = &mut *std::ptr::from_ref(num).cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL |     let _num = &mut *std::ptr::from_ref(num).cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:25:16
+  --> $DIR/reference_casting.rs:23:16
    |
 LL |     let _num = &mut *std::ptr::from_ref({ num }).cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL |     let _num = &mut *std::ptr::from_ref({ num }).cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:27:16
+  --> $DIR/reference_casting.rs:25:16
    |
 LL |     let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     let _num = &mut *{ std::ptr::from_ref(num) }.cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:29:16
+  --> $DIR/reference_casting.rs:27:16
    |
 LL |     let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL |     let _num = &mut *(std::ptr::from_ref({ num }) as *mut i32);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:31:16
+  --> $DIR/reference_casting.rs:29:16
    |
 LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut();
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:33:16
+  --> $DIR/reference_casting.rs:31:16
    |
 LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_const().cast_mut();
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -64,7 +64,7 @@ LL |     let _num = &mut *(num as *const i32).cast::<i32>().cast_mut().cast_cons
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:35:16
+  --> $DIR/reference_casting.rs:33:16
    |
 LL |     let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     let _num = &mut *(std::ptr::from_ref(static_u8()) as *mut i32);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:37:16
+  --> $DIR/reference_casting.rs:35:16
    |
 LL |     let _num = &mut *std::mem::transmute::<_, *mut i32>(num);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -80,7 +80,7 @@ LL |     let _num = &mut *std::mem::transmute::<_, *mut i32>(num);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:39:16
+  --> $DIR/reference_casting.rs:37:16
    |
 LL |     let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +88,7 @@ LL |     let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:41:16
+  --> $DIR/reference_casting.rs:39:16
    |
 LL |       let _num = &mut *std::cell::UnsafeCell::raw_get(
    |  ________________^
@@ -100,7 +100,7 @@ LL | |     );
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:47:16
+  --> $DIR/reference_casting.rs:45:16
    |
 LL |     let deferred = num as *const i32 as *mut i32;
    |                    ----------------------------- casting happend here
@@ -110,7 +110,7 @@ LL |     let _num = &mut *deferred;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:50:16
+  --> $DIR/reference_casting.rs:48:16
    |
 LL |     let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32;
    |                    ---------------------------------------------------------------------------- casting happend here
@@ -120,7 +120,7 @@ LL |     let _num = &mut *deferred;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:53:16
+  --> $DIR/reference_casting.rs:51:16
    |
 LL |     let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32;
    |                    ---------------------------------------------------------------------------- casting happend here
@@ -131,7 +131,7 @@ LL |     let _num = &mut *deferred_rebind;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:55:16
+  --> $DIR/reference_casting.rs:53:16
    |
 LL |     let _num = &mut *(num as *const _ as usize as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -139,7 +139,7 @@ LL |     let _num = &mut *(num as *const _ as usize as *mut i32);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:57:16
+  --> $DIR/reference_casting.rs:55:16
    |
 LL |     let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -147,7 +147,7 @@ LL |     let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) a
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:64:16
+  --> $DIR/reference_casting.rs:62:16
    |
 LL |     let num = NUM as *const i32 as *mut i32;
    |               ----------------------------- casting happend here
@@ -158,7 +158,7 @@ LL |     let _num = &mut *num;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:68:16
+  --> $DIR/reference_casting.rs:66:16
    |
 LL |     let _num = &mut *(cell as *const _ as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -167,7 +167,7 @@ LL |     let _num = &mut *(cell as *const _ as *mut i32);
    = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:72:9
+  --> $DIR/reference_casting.rs:70:9
    |
 LL |         &mut *((this as *const _) as *mut _)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -175,7 +175,7 @@ LL |         &mut *((this as *const _) as *mut _)
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:77:18
+  --> $DIR/reference_casting.rs:75:18
    |
 LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -183,7 +183,7 @@ LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:82:18
+  --> $DIR/reference_casting.rs:80:18
    |
 LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -191,7 +191,7 @@ LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:92:5
+  --> $DIR/reference_casting.rs:90:5
    |
 LL |     *(a as *const _ as *mut _) = String::from("Replaced");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -199,7 +199,7 @@ LL |     *(a as *const _ as *mut _) = String::from("Replaced");
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:94:5
+  --> $DIR/reference_casting.rs:92:5
    |
 LL |     *(a as *const _ as *mut String) += " world";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -207,7 +207,7 @@ LL |     *(a as *const _ as *mut String) += " world";
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:96:5
+  --> $DIR/reference_casting.rs:94:5
    |
 LL |     *std::ptr::from_ref(num).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -215,7 +215,7 @@ LL |     *std::ptr::from_ref(num).cast_mut() += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:98:5
+  --> $DIR/reference_casting.rs:96:5
    |
 LL |     *std::ptr::from_ref({ num }).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -223,7 +223,7 @@ LL |     *std::ptr::from_ref({ num }).cast_mut() += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:100:5
+  --> $DIR/reference_casting.rs:98:5
    |
 LL |     *{ std::ptr::from_ref(num) }.cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -231,7 +231,7 @@ LL |     *{ std::ptr::from_ref(num) }.cast_mut() += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:102:5
+  --> $DIR/reference_casting.rs:100:5
    |
 LL |     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -239,7 +239,7 @@ LL |     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:104:5
+  --> $DIR/reference_casting.rs:102:5
    |
 LL |     *std::mem::transmute::<_, *mut i32>(num) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -247,7 +247,7 @@ LL |     *std::mem::transmute::<_, *mut i32>(num) += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:106:5
+  --> $DIR/reference_casting.rs:104:5
    |
 LL |     *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:108:5
+  --> $DIR/reference_casting.rs:106:5
    |
 LL | /     std::ptr::write(
 LL | |
@@ -267,7 +267,7 @@ LL | |     );
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:113:5
+  --> $DIR/reference_casting.rs:111:5
    |
 LL |     *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -276,7 +276,7 @@ LL |     *((&std::cell::UnsafeCell::new(0)) as *const _ as *mut i32) = 5;
    = note: even for types with interior mutability, the only legal way to obtain a mutable pointer from a shared reference is through `UnsafeCell::get`
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:117:5
+  --> $DIR/reference_casting.rs:115:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -286,7 +286,7 @@ LL |     *value = 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:121:5
+  --> $DIR/reference_casting.rs:119:5
    |
 LL |     let value = value as *mut i32;
    |                 ----------------- casting happend here
@@ -296,7 +296,7 @@ LL |     *value = 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:124:5
+  --> $DIR/reference_casting.rs:122:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -306,7 +306,7 @@ LL |     *value = 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:127:5
+  --> $DIR/reference_casting.rs:125:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -317,7 +317,7 @@ LL |     *value_rebind = 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:129:5
+  --> $DIR/reference_casting.rs:127:5
    |
 LL |     *(num as *const i32).cast::<i32>().cast_mut() = 2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -325,7 +325,7 @@ LL |     *(num as *const i32).cast::<i32>().cast_mut() = 2;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:131:5
+  --> $DIR/reference_casting.rs:129:5
    |
 LL |     *(num as *const _ as usize as *mut i32) = 2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -333,7 +333,7 @@ LL |     *(num as *const _ as usize as *mut i32) = 2;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:133:5
+  --> $DIR/reference_casting.rs:131:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -344,7 +344,7 @@ LL |     std::ptr::write(value, 2);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:135:5
+  --> $DIR/reference_casting.rs:133:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -355,7 +355,7 @@ LL |     std::ptr::write_unaligned(value, 2);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:137:5
+  --> $DIR/reference_casting.rs:135:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -366,7 +366,7 @@ LL |     std::ptr::write_volatile(value, 2);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:141:9
+  --> $DIR/reference_casting.rs:139:9
    |
 LL |         *(this as *const _ as *mut _) = a;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/panic-handler/panic-handler-duplicate.stderr b/tests/ui/panic-handler/panic-handler-duplicate.stderr
index 5c50b7016b2..299847474cd 100644
--- a/tests/ui/panic-handler/panic-handler-duplicate.stderr
+++ b/tests/ui/panic-handler/panic-handler-duplicate.stderr
@@ -1,14 +1,18 @@
 error[E0152]: found duplicate lang item `panic_impl`
   --> $DIR/panic-handler-duplicate.rs:15:1
    |
-LL | fn panic2(info: &PanicInfo) -> ! {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn panic2(info: &PanicInfo) -> ! {
+LL | |     loop {}
+LL | | }
+   | |_^
    |
 note: the lang item is first defined here
   --> $DIR/panic-handler-duplicate.rs:10:1
    |
-LL | fn panic(info: &PanicInfo) -> ! {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn panic(info: &PanicInfo) -> ! {
+LL | |     loop {}
+LL | | }
+   | |_^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/panic-handler/panic-handler-std.stderr b/tests/ui/panic-handler/panic-handler-std.stderr
index ad9addec8eb..48c216ce27e 100644
--- a/tests/ui/panic-handler/panic-handler-std.stderr
+++ b/tests/ui/panic-handler/panic-handler-std.stderr
@@ -1,8 +1,10 @@
 error[E0152]: found duplicate lang item `panic_impl`
   --> $DIR/panic-handler-std.rs:8:1
    |
-LL | fn panic(info: PanicInfo) -> ! {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | / fn panic(info: PanicInfo) -> ! {
+LL | |     loop {}
+LL | | }
+   | |_^
    |
    = note: the lang item is first defined in crate `std` (which `panic_handler_std` depends on)
    = note: first definition in `std` loaded from SYSROOT/libstd-*.rlib
diff --git a/tests/ui/proc-macro/auxiliary/env.rs b/tests/ui/proc-macro/auxiliary/env.rs
new file mode 100644
index 00000000000..58bcb08bf06
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/env.rs
@@ -0,0 +1,28 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+#![feature(proc_macro_tracked_env)]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use proc_macro::tracked_env::var;
+
+#[proc_macro]
+pub fn generate_const(input: TokenStream) -> TokenStream {
+    let the_const = match var("THE_CONST") {
+        Ok(x) if x == "12" => {
+            "const THE_CONST: u32 = 12;"
+        }
+        _ => {
+            "const THE_CONST: u32 = 0;"
+        }
+    };
+    let another = if var("ANOTHER").is_ok() {
+        "const ANOTHER: u32 = 1;"
+    } else {
+        "const ANOTHER: u32 = 2;"
+    };
+    format!("{the_const}{another}").parse().unwrap()
+}
diff --git a/tests/ui/proc-macro/env.rs b/tests/ui/proc-macro/env.rs
new file mode 100644
index 00000000000..1b1d1873eb3
--- /dev/null
+++ b/tests/ui/proc-macro/env.rs
@@ -0,0 +1,17 @@
+// aux-build:env.rs
+// run-pass
+// rustc-env: THE_CONST=1
+// compile-flags: -Zunstable-options --env THE_CONST=12 --env ANOTHER=4
+
+#![crate_name = "foo"]
+
+extern crate env;
+
+use env::generate_const;
+
+generate_const!();
+
+fn main() {
+    assert_eq!(THE_CONST, 12);
+    assert_eq!(ANOTHER, 1);
+}
diff --git a/tests/ui/regions/resolve-re-error-ice.rs b/tests/ui/regions/resolve-re-error-ice.rs
index f37b27a82b3..bf6defb9bae 100644
--- a/tests/ui/regions/resolve-re-error-ice.rs
+++ b/tests/ui/regions/resolve-re-error-ice.rs
@@ -1,8 +1,3 @@
-// check-pass
-
-// Allow this for now, can remove this UI test when this becomes a hard error.
-#![allow(implied_bounds_entailment)]
-
 use std::collections::hash_map::{Keys, HashMap};
 use std::marker::PhantomData;
 
@@ -15,6 +10,7 @@ struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>);
 impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R>
 {
     fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
+        //~^ ERROR cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements
         todo!()
     }
 }
diff --git a/tests/ui/regions/resolve-re-error-ice.stderr b/tests/ui/regions/resolve-re-error-ice.stderr
index e7003e1c32f..41c5f0fa92e 100644
--- a/tests/ui/regions/resolve-re-error-ice.stderr
+++ b/tests/ui/regions/resolve-re-error-ice.stderr
@@ -1,15 +1,37 @@
-Future incompatibility report: Future breakage diagnostic:
-warning: impl method assumes more implied bounds than the corresponding trait method
-  --> $DIR/resolve-re-error-ice.rs:17:16
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter '_ in generic type due to conflicting requirements
+  --> $DIR/resolve-re-error-ice.rs:12:5
    |
 LL |     fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
-   |                ^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this type to make the impl signature compatible: `Subject<'_, std::collections::hash_map::Keys<'_, K, V>, (), R>`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #105572 <https://github.com/rust-lang/rust/issues/105572>
-note: the lint level is defined here
-  --> $DIR/resolve-re-error-ice.rs:4:10
+note: first, the lifetime cannot outlive the anonymous lifetime defined here...
+  --> $DIR/resolve-re-error-ice.rs:5:16
    |
-LL | #![allow(implied_bounds_entailment)]
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     fn key_set(&self) -> Subject<Keys<K, V>, (), R>;
+   |                ^^^^^
+note: ...so that the method type is compatible with trait
+  --> $DIR/resolve-re-error-ice.rs:12:5
+   |
+LL |     fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: expected `fn(&Subject<'_, _, _, _>) -> Subject<'_, std::collections::hash_map::Keys<'_, _, _>, _, _>`
+              found `fn(&Subject<'_, _, _, _>) -> Subject<'a, std::collections::hash_map::Keys<'_, _, _>, _, _>`
+note: but, the lifetime must be valid for the lifetime `'a` as defined here...
+  --> $DIR/resolve-re-error-ice.rs:10:6
+   |
+LL | impl<'a, K, V, R> MapAssertion<'a, K, V, R> for Subject<'a, HashMap<K, V>, (), R>
+   |      ^^
+note: ...so that the type `std::collections::hash_map::Keys<'_, K, V>` will meet its required lifetime bounds...
+  --> $DIR/resolve-re-error-ice.rs:12:5
+   |
+LL |     fn key_set(&self) -> Subject<'a, Keys<K, V>, (), R> {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...that is required by this bound
+  --> $DIR/resolve-re-error-ice.rs:8:29
+   |
+LL | struct Subject<'a, T, V, R>(PhantomData<(&'a T, V, R)>);
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0495`.
diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs
index 406e5c8441e..490d6a2f918 100644
--- a/tests/ui/structs-enums/type-sizes.rs
+++ b/tests/ui/structs-enums/type-sizes.rs
@@ -4,7 +4,6 @@
 #![allow(dead_code)]
 #![feature(never_type)]
 #![feature(pointer_is_aligned)]
-#![feature(ptr_from_ref)]
 #![feature(strict_provenance)]
 
 use std::mem::size_of;
diff --git a/tests/ui/traits/issue-102989.rs b/tests/ui/traits/issue-102989.rs
index 216cd78e56f..f1ecee0a552 100644
--- a/tests/ui/traits/issue-102989.rs
+++ b/tests/ui/traits/issue-102989.rs
@@ -7,6 +7,7 @@ trait Sized { } //~ ERROR found duplicate lang item `sized`
 fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
     //~^ ERROR `self` parameter is only allowed in associated functions
     //~| ERROR cannot find type `Struct` in this scope
+    //~| ERROR mismatched types
     let x = x << 1;
     //~^ ERROR cannot find value `x` in this scope
 }
diff --git a/tests/ui/traits/issue-102989.stderr b/tests/ui/traits/issue-102989.stderr
index 7d0098fe885..40e49df2b2d 100644
--- a/tests/ui/traits/issue-102989.stderr
+++ b/tests/ui/traits/issue-102989.stderr
@@ -13,7 +13,7 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
    |                      ^^^^^^ not found in this scope
 
 error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-102989.rs:10:13
+  --> $DIR/issue-102989.rs:11:13
    |
 LL |     let x = x << 1;
    |             ^ help: a local variable with a similar name exists: `f`
@@ -22,13 +22,27 @@ error[E0152]: found duplicate lang item `sized`
   --> $DIR/issue-102989.rs:5:1
    |
 LL | trait Sized { }
-   | ^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^
    |
    = note: the lang item is first defined in crate `core` (which `std` depends on)
    = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib
    = note: second definition in the local crate (`issue_102989`)
 
-error: aborting due to 4 previous errors
+error[E0308]: mismatched types
+  --> $DIR/issue-102989.rs:7:42
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |    ----------                            ^^^^ expected `&u32`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+help: consider returning the local binding `f`
+   |
+LL ~     let x = x << 1;
+LL +     f
+   |
+
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0152, E0412, E0425.
+Some errors have detailed explanations: E0152, E0308, E0412, E0425.
 For more information about an error, try `rustc --explain E0152`.
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 6b43b95fef3..c16a48d5f15 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -13,14 +13,14 @@ LL | #![feature(lazy_type_alias)]
    = note: see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-WARN rustc_infer::infer::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::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) })
-WARN rustc_infer::infer::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::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) })
-WARN rustc_infer::infer::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::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) })
-WARN rustc_infer::infer::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::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) })
+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) })
+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) })
+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) })
+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
    |
diff --git a/triagebot.toml b/triagebot.toml
index 30f049c79d6..2867bbc8171 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -441,6 +441,14 @@ cc = ["@rust-lang/miri"]
 message = "Some changes occurred in need_type_info.rs"
 cc = ["@lcnr"]
 
+[mentions."compiler/rustc_middle/src/ty/relate.rs"]
+message = "Type relation code was changed"
+cc = ["@compiler-errors", "@lcnr"]
+
+[mentions."compiler/rustc_infer/src/infer/relate"]
+message = "Type relation code was changed"
+cc = ["@compiler-errors", "@lcnr"]
+
 [mentions."compiler/rustc_middle/src/mir/interpret"]
 message = "Some changes occurred to the CTFE / Miri engine"
 cc = ["@rust-lang/miri"]
@@ -555,15 +563,15 @@ cc = ["@oli-obk", "@RalfJung", "@JakobDegen", "@davidtwco", "@celinval", "@vakar
 
 [mentions."compiler/rustc_error_messages"]
 message = "`rustc_error_messages` was changed"
-cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
+cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"]
 
 [mentions."compiler/rustc_errors/src/translation.rs"]
 message = "`rustc_errors::translation` was changed"
-cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
+cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"]
 
 [mentions."compiler/rustc_macros/src/diagnostics"]
 message = "`rustc_macros::diagnostics` was changed"
-cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
+cc = ["@davidtwco", "@compiler-errors", "@TaKO8Ki"]
 
 [mentions."compiler/stable_mir"]
 message = "This PR changes Stable MIR"