about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2023-12-16 14:12:50 +0100
committerPhilipp Krones <hello@philkrones.com>2023-12-16 14:12:50 +0100
commit61f4a73c6789078ac2cd04a6555636cf6cd667cf (patch)
treea1d756065ee276d10e365c6f6f91082ad08df211
parent3ad8e2d129a67b0dc450d6ef1100ae41d2cd4b8a (diff)
parenta859e5cc1ce100df22346a1005da30532d04de59 (diff)
downloadrust-61f4a73c6789078ac2cd04a6555636cf6cd667cf.tar.gz
rust-61f4a73c6789078ac2cd04a6555636cf6cd667cf.zip
Merge commit 'a859e5cc1ce100df22346a1005da30532d04de59' into clippyup
-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/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/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
108 files changed, 3064 insertions, 637 deletions
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/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/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"]