about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/deploy.yml2
-rw-r--r--CHANGELOG.md3
-rw-r--r--README.md2
-rw-r--r--book/src/README.md2
-rw-r--r--book/src/lint_configuration.md3
-rw-r--r--clippy_config/src/conf.rs7
-rw-r--r--clippy_config/src/lib.rs1
-rw-r--r--clippy_config/src/msrvs.rs13
-rw-r--r--clippy_lints/src/booleans.rs15
-rw-r--r--clippy_lints/src/borrow_deref_ref.rs4
-rw-r--r--clippy_lints/src/casts/unnecessary_cast.rs3
-rw-r--r--clippy_lints/src/declared_lints.rs3
-rw-r--r--clippy_lints/src/functions/ref_option.rs6
-rw-r--r--clippy_lints/src/iter_without_into_iter.rs2
-rw-r--r--clippy_lints/src/large_const_arrays.rs4
-rw-r--r--clippy_lints/src/large_include_file.rs63
-rw-r--r--clippy_lints/src/matches/single_match.rs5
-rw-r--r--clippy_lints/src/methods/map_all_any_identity.rs43
-rw-r--r--clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs134
-rw-r--r--clippy_lints/src/methods/mod.rs133
-rw-r--r--clippy_lints/src/methods/needless_as_bytes.rs28
-rw-r--r--clippy_lints/src/methods/unnecessary_filter_map.rs31
-rw-r--r--clippy_lints/src/unused_io_amount.rs24
-rw-r--r--clippy_utils/src/check_proc_macro.rs26
-rw-r--r--clippy_utils/src/consts.rs6
-rw-r--r--tests/ui-toml/large_include_file/large_include_file.rs7
-rw-r--r--tests/ui-toml/large_include_file/large_include_file.stderr12
-rw-r--r--tests/ui-toml/private-doc-errors/doc_lints.rs6
-rw-r--r--tests/ui/allow_attributes.fixed7
-rw-r--r--tests/ui/allow_attributes.rs7
-rw-r--r--tests/ui/allow_attributes.stderr8
-rw-r--r--tests/ui/auxiliary/proc_macro_derive.rs50
-rw-r--r--tests/ui/borrow_deref_ref.fixed6
-rw-r--r--tests/ui/borrow_deref_ref.rs6
-rw-r--r--tests/ui/doc/doc-fixable.fixed2
-rw-r--r--tests/ui/doc/doc-fixable.rs2
-rw-r--r--tests/ui/iter_without_into_iter.stderr16
-rw-r--r--tests/ui/large_const_arrays.fixed2
-rw-r--r--tests/ui/large_const_arrays.rs2
-rw-r--r--tests/ui/large_const_arrays.stderr22
-rw-r--r--tests/ui/map_all_any_identity.fixed21
-rw-r--r--tests/ui/map_all_any_identity.rs21
-rw-r--r--tests/ui/map_all_any_identity.stderr26
-rw-r--r--tests/ui/map_with_unused_argument_over_ranges.fixed73
-rw-r--r--tests/ui/map_with_unused_argument_over_ranges.rs73
-rw-r--r--tests/ui/map_with_unused_argument_over_ranges.stderr223
-rw-r--r--tests/ui/needless_as_bytes.fixed50
-rw-r--r--tests/ui/needless_as_bytes.rs50
-rw-r--r--tests/ui/needless_as_bytes.stderr29
-rw-r--r--tests/ui/nonminimal_bool.stderr8
-rw-r--r--tests/ui/nonminimal_bool_methods.fixed30
-rw-r--r--tests/ui/nonminimal_bool_methods.rs24
-rw-r--r--tests/ui/nonminimal_bool_methods.stderr86
-rw-r--r--tests/ui/repeat_vec_with_capacity.fixed1
-rw-r--r--tests/ui/repeat_vec_with_capacity.rs1
-rw-r--r--tests/ui/repeat_vec_with_capacity.stderr6
-rw-r--r--tests/ui/suspicious_map.rs1
-rw-r--r--tests/ui/suspicious_map.stderr4
-rw-r--r--tests/ui/unnecessary_filter_map.rs13
-rw-r--r--tests/ui/unnecessary_filter_map.stderr53
-rw-r--r--tests/ui/unnecessary_find_map.rs9
-rw-r--r--tests/ui/unnecessary_find_map.stderr30
-rw-r--r--tests/ui/unused_io_amount.rs14
-rw-r--r--triagebot.toml2
64 files changed, 1400 insertions, 166 deletions
diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index 94f494b65c4..32dc251c836 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -52,7 +52,7 @@ jobs:
       run: cargo generate-lockfile
 
     - name: Cache
-      uses: Swatinem/rust-cache@v2.7.0
+      uses: Swatinem/rust-cache@v2
       with:
         save-if: ${{ github.ref == 'refs/heads/master' }}
 
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4bdbc91db93..f3a42083aa4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5689,6 +5689,7 @@ Released 2018-09-13
 [`manual_unwrap_or_default`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_unwrap_or_default
 [`manual_while_let_some`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_while_let_some
 [`many_single_char_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#many_single_char_names
+[`map_all_any_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_all_any_identity
 [`map_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_clone
 [`map_collect_result_unit`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_collect_result_unit
 [`map_entry`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
@@ -5696,6 +5697,7 @@ Released 2018-09-13
 [`map_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_flatten
 [`map_identity`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_identity
 [`map_unwrap_or`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or
+[`map_with_unused_argument_over_ranges`]: https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges
 [`match_as_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_as_ref
 [`match_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_bool
 [`match_like_matches_macro`]: https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro
@@ -5761,6 +5763,7 @@ Released 2018-09-13
 [`mutex_integer`]: https://rust-lang.github.io/rust-clippy/master/index.html#mutex_integer
 [`naive_bytecount`]: https://rust-lang.github.io/rust-clippy/master/index.html#naive_bytecount
 [`needless_arbitrary_self_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_arbitrary_self_type
+[`needless_as_bytes`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_as_bytes
 [`needless_bitwise_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bitwise_bool
 [`needless_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool
 [`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign
diff --git a/README.md b/README.md
index ec76a6dfb08..1690e2beb16 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
 
 A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code.
 
-[There are over 700 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
+[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
 
 Lints are divided into categories, each with a default [lint level](https://doc.rust-lang.org/rustc/lints/levels.html).
 You can choose how much Clippy is supposed to ~~annoy~~ help you by changing the lint level by category.
diff --git a/book/src/README.md b/book/src/README.md
index 7bdfb97c3ac..23527ba896a 100644
--- a/book/src/README.md
+++ b/book/src/README.md
@@ -6,7 +6,7 @@
 A collection of lints to catch common mistakes and improve your
 [Rust](https://github.com/rust-lang/rust) code.
 
-[There are over 700 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
+[There are over 750 lints included in this crate!](https://rust-lang.github.io/rust-clippy/master/index.html)
 
 Lints are divided into categories, each with a default [lint
 level](https://doc.rust-lang.org/rustc/lints/levels.html). You can choose how
diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md
index 9ea4c8418fd..34de9912557 100644
--- a/book/src/lint_configuration.md
+++ b/book/src/lint_configuration.md
@@ -456,7 +456,7 @@ default configuration of Clippy. By default, any configuration will replace the
 * `doc-valid-idents = ["ClipPy"]` would replace the default list with `["ClipPy"]`.
 * `doc-valid-idents = ["ClipPy", ".."]` would append `ClipPy` to the default list.
 
-**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
+**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "MHz", "GHz", "THz", "AccessKit", "CoAP", "CoreFoundation", "CoreGraphics", "CoreText", "DevOps", "Direct2D", "Direct3D", "DirectWrite", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PostScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenAL", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "OpenType", "WebGL", "WebGL2", "WebGPU", "WebRTC", "WebSocket", "WebTransport", "WebP", "OpenExr", "YCbCr", "sRGB", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "NetBSD", "OpenBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
 
 ---
 **Affected lints:**
@@ -710,6 +710,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold)
 * [`map_clone`](https://rust-lang.github.io/rust-clippy/master/index.html#map_clone)
 * [`map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#map_unwrap_or)
+* [`map_with_unused_argument_over_ranges`](https://rust-lang.github.io/rust-clippy/master/index.html#map_with_unused_argument_over_ranges)
 * [`match_like_matches_macro`](https://rust-lang.github.io/rust-clippy/master/index.html#match_like_matches_macro)
 * [`mem_replace_with_default`](https://rust-lang.github.io/rust-clippy/master/index.html#mem_replace_with_default)
 * [`missing_const_for_fn`](https://rust-lang.github.io/rust-clippy/master/index.html#missing_const_for_fn)
diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs
index 550a6310d57..5f0ccba7406 100644
--- a/clippy_config/src/conf.rs
+++ b/clippy_config/src/conf.rs
@@ -19,7 +19,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
     "KiB", "MiB", "GiB", "TiB", "PiB", "EiB",
     "MHz", "GHz", "THz",
     "AccessKit",
-    "CoreFoundation", "CoreGraphics", "CoreText",
+    "CoAP", "CoreFoundation", "CoreGraphics", "CoreText",
     "DevOps",
     "Direct2D", "Direct3D", "DirectWrite", "DirectX",
     "ECMAScript",
@@ -103,7 +103,9 @@ pub fn sanitize_explanation(raw_docs: &str) -> String {
     // Remove tags and hidden code:
     let mut explanation = String::with_capacity(128);
     let mut in_code = false;
-    for line in raw_docs.lines().map(str::trim) {
+    for line in raw_docs.lines() {
+        let line = line.strip_prefix(' ').unwrap_or(line);
+
         if let Some(lang) = line.strip_prefix("```") {
             let tag = lang.split_once(',').map_or(lang, |(left, _)| left);
             if !in_code && matches!(tag, "" | "rust" | "ignore" | "should_panic" | "no_run" | "compile_fail") {
@@ -571,6 +573,7 @@ define_Conf! {
         manual_try_fold,
         map_clone,
         map_unwrap_or,
+        map_with_unused_argument_over_ranges,
         match_like_matches_macro,
         mem_replace_with_default,
         missing_const_for_fn,
diff --git a/clippy_config/src/lib.rs b/clippy_config/src/lib.rs
index 42651521f8d..1c3f32c2514 100644
--- a/clippy_config/src/lib.rs
+++ b/clippy_config/src/lib.rs
@@ -20,6 +20,7 @@ extern crate rustc_driver;
 extern crate rustc_errors;
 extern crate rustc_session;
 extern crate rustc_span;
+extern crate smallvec;
 
 mod conf;
 mod metadata;
diff --git a/clippy_config/src/msrvs.rs b/clippy_config/src/msrvs.rs
index 2f4da4cba3d..764ca8fb50a 100644
--- a/clippy_config/src/msrvs.rs
+++ b/clippy_config/src/msrvs.rs
@@ -3,6 +3,7 @@ use rustc_attr::parse_version;
 use rustc_session::{RustcVersion, Session};
 use rustc_span::{Symbol, sym};
 use serde::Deserialize;
+use smallvec::{SmallVec, smallvec};
 use std::fmt;
 
 macro_rules! msrv_aliases {
@@ -18,7 +19,7 @@ macro_rules! msrv_aliases {
 // names may refer to stabilized feature flags or library items
 msrv_aliases! {
     1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY }
-    1,82,0 { IS_NONE_OR }
+    1,82,0 { IS_NONE_OR, REPEAT_N }
     1,81,0 { LINT_REASONS_STABILIZATION }
     1,80,0 { BOX_INTO_ITER}
     1,77,0 { C_STR_LITERALS }
@@ -54,7 +55,7 @@ msrv_aliases! {
     1,33,0 { UNDERSCORE_IMPORTS }
     1,30,0 { ITERATOR_FIND_MAP, TOOL_ATTRIBUTES }
     1,29,0 { ITER_FLATTEN }
-    1,28,0 { FROM_BOOL }
+    1,28,0 { FROM_BOOL, REPEAT_WITH }
     1,27,0 { ITERATOR_TRY_FOLD }
     1,26,0 { RANGE_INCLUSIVE, STRING_RETAIN }
     1,24,0 { IS_ASCII_DIGIT }
@@ -67,7 +68,7 @@ msrv_aliases! {
 /// Tracks the current MSRV from `clippy.toml`, `Cargo.toml` or set via `#[clippy::msrv]`
 #[derive(Debug, Clone)]
 pub struct Msrv {
-    stack: Vec<RustcVersion>,
+    stack: SmallVec<[RustcVersion; 2]>,
 }
 
 impl fmt::Display for Msrv {
@@ -87,14 +88,14 @@ impl<'de> Deserialize<'de> for Msrv {
     {
         let v = String::deserialize(deserializer)?;
         parse_version(Symbol::intern(&v))
-            .map(|v| Msrv { stack: vec![v] })
+            .map(|v| Msrv { stack: smallvec![v] })
             .ok_or_else(|| serde::de::Error::custom("not a valid Rust version"))
     }
 }
 
 impl Msrv {
     pub fn empty() -> Msrv {
-        Msrv { stack: Vec::new() }
+        Msrv { stack: SmallVec::new() }
     }
 
     pub fn read_cargo(&mut self, sess: &Session) {
@@ -103,7 +104,7 @@ impl Msrv {
             .and_then(|v| parse_version(Symbol::intern(&v)));
 
         match (self.current(), cargo_msrv) {
-            (None, Some(cargo_msrv)) => self.stack = vec![cargo_msrv],
+            (None, Some(cargo_msrv)) => self.stack = smallvec![cargo_msrv],
             (Some(clippy_msrv), Some(cargo_msrv)) => {
                 if clippy_msrv != cargo_msrv {
                     sess.dcx().warn(format!(
diff --git a/clippy_lints/src/booleans.rs b/clippy_lints/src/booleans.rs
index 26888f7e3a0..26a20bc99a0 100644
--- a/clippy_lints/src/booleans.rs
+++ b/clippy_lints/src/booleans.rs
@@ -203,6 +203,21 @@ fn check_simplify_not(cx: &LateContext<'_>, msrv: &Msrv, expr: &Expr<'_>) {
         && let Some(suggestion) = simplify_not(cx, msrv, inner)
         && cx.tcx.lint_level_at_node(NONMINIMAL_BOOL, expr.hir_id).0 != Level::Allow
     {
+        use clippy_utils::sugg::{Sugg, has_enclosing_paren};
+        let maybe_par = if let Some(sug) = Sugg::hir_opt(cx, inner) {
+            match sug {
+                Sugg::BinOp(..) => true,
+                Sugg::MaybeParen(sug) if !has_enclosing_paren(&sug) => true,
+                _ => false,
+            }
+        } else {
+            false
+        };
+        let suggestion = if maybe_par {
+            format!("({suggestion})")
+        } else {
+            suggestion
+        };
         span_lint_and_sugg(
             cx,
             NONMINIMAL_BOOL,
diff --git a/clippy_lints/src/borrow_deref_ref.rs b/clippy_lints/src/borrow_deref_ref.rs
index cba8224b84c..f2551a05b1a 100644
--- a/clippy_lints/src/borrow_deref_ref.rs
+++ b/clippy_lints/src/borrow_deref_ref.rs
@@ -4,7 +4,7 @@ use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::implements_trait;
 use clippy_utils::{get_parent_expr, is_from_proc_macro, is_lint_allowed};
 use rustc_errors::Applicability;
-use rustc_hir::{ExprKind, UnOp};
+use rustc_hir::{BorrowKind, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty;
@@ -49,7 +49,7 @@ declare_lint_pass!(BorrowDerefRef => [BORROW_DEREF_REF]);
 
 impl<'tcx> LateLintPass<'tcx> for BorrowDerefRef {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &rustc_hir::Expr<'tcx>) {
-        if let ExprKind::AddrOf(_, Mutability::Not, addrof_target) = e.kind
+        if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Not, addrof_target) = e.kind
             && let ExprKind::Unary(UnOp::Deref, deref_target) = addrof_target.kind
             && !matches!(deref_target.kind, ExprKind::Unary(UnOp::Deref, ..))
             && !e.span.from_expansion()
diff --git a/clippy_lints/src/casts/unnecessary_cast.rs b/clippy_lints/src/casts/unnecessary_cast.rs
index 811d33c8bde..abd80abffe6 100644
--- a/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/clippy_lints/src/casts/unnecessary_cast.rs
@@ -268,8 +268,7 @@ fn is_cast_from_ty_alias<'tcx>(cx: &LateContext<'tcx>, expr: impl Visitable<'tcx
                 if !snippet
                     .split("->")
                     .skip(1)
-                    .map(|s| snippet_eq_ty(s, cast_from) || s.split("where").any(|ty| snippet_eq_ty(ty, cast_from)))
-                    .any(|a| a)
+                    .any(|s| snippet_eq_ty(s, cast_from) || s.split("where").any(|ty| snippet_eq_ty(ty, cast_from)))
                 {
                     return ControlFlow::Break(());
                 }
diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs
index d8918d37afa..f065f6115dc 100644
--- a/clippy_lints/src/declared_lints.rs
+++ b/clippy_lints/src/declared_lints.rs
@@ -416,14 +416,17 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::methods::MANUAL_SPLIT_ONCE_INFO,
     crate::methods::MANUAL_STR_REPEAT_INFO,
     crate::methods::MANUAL_TRY_FOLD_INFO,
+    crate::methods::MAP_ALL_ANY_IDENTITY_INFO,
     crate::methods::MAP_CLONE_INFO,
     crate::methods::MAP_COLLECT_RESULT_UNIT_INFO,
     crate::methods::MAP_ERR_IGNORE_INFO,
     crate::methods::MAP_FLATTEN_INFO,
     crate::methods::MAP_IDENTITY_INFO,
     crate::methods::MAP_UNWRAP_OR_INFO,
+    crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES_INFO,
     crate::methods::MUT_MUTEX_LOCK_INFO,
     crate::methods::NAIVE_BYTECOUNT_INFO,
+    crate::methods::NEEDLESS_AS_BYTES_INFO,
     crate::methods::NEEDLESS_CHARACTER_ITERATION_INFO,
     crate::methods::NEEDLESS_COLLECT_INFO,
     crate::methods::NEEDLESS_OPTION_AS_DEREF_INFO,
diff --git a/clippy_lints/src/functions/ref_option.rs b/clippy_lints/src/functions/ref_option.rs
index 373ecd74cb3..aba0fbcb9fe 100644
--- a/clippy_lints/src/functions/ref_option.rs
+++ b/clippy_lints/src/functions/ref_option.rs
@@ -15,9 +15,9 @@ use rustc_span::{Span, sym};
 fn check_ty<'a>(cx: &LateContext<'a>, param: &rustc_hir::Ty<'a>, param_ty: Ty<'a>, fixes: &mut Vec<(Span, String)>) {
     if let ty::Ref(_, opt_ty, Mutability::Not) = param_ty.kind()
         && is_type_diagnostic_item(cx, *opt_ty, sym::Option)
-        && let ty::Adt(_, opt_gen) = opt_ty.kind()
-        && let [gen] = opt_gen.as_slice()
-        && let GenericArgKind::Type(gen_ty) = gen.unpack()
+        && let ty::Adt(_, opt_gen_args) = opt_ty.kind()
+        && let [gen_arg] = opt_gen_args.as_slice()
+        && let GenericArgKind::Type(gen_ty) = gen_arg.unpack()
         && !gen_ty.is_ref()
         // Need to gen the original spans, so first parsing mid, and hir parsing afterward
         && let hir::TyKind::Ref(lifetime, hir::MutTy { ty, .. }) = param.kind
diff --git a/clippy_lints/src/iter_without_into_iter.rs b/clippy_lints/src/iter_without_into_iter.rs
index 36e94593e6f..314d0dfa26c 100644
--- a/clippy_lints/src/iter_without_into_iter.rs
+++ b/clippy_lints/src/iter_without_into_iter.rs
@@ -247,8 +247,8 @@ impl {self_ty_without_ref} {{
                     let sugg = format!(
                         "
 impl IntoIterator for {self_ty_snippet} {{
-    type IntoIter = {ret_ty};
     type Item = {iter_ty};
+    type IntoIter = {ret_ty};
     fn into_iter(self) -> Self::IntoIter {{
         self.iter()
     }}
diff --git a/clippy_lints/src/large_const_arrays.rs b/clippy_lints/src/large_const_arrays.rs
index 5d2b521b250..eaaf7be72ab 100644
--- a/clippy_lints/src/large_const_arrays.rs
+++ b/clippy_lints/src/large_const_arrays.rs
@@ -4,7 +4,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_middle::ty::{self, ConstKind};
+use rustc_middle::ty::{self, ParamEnv};
 use rustc_session::impl_lint_pass;
 use rustc_span::{BytePos, Pos, Span};
 
@@ -56,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
             && !item.span.from_expansion()
             && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
             && let ty::Array(element_type, cst) = ty.kind()
-            && let ConstKind::Value(_, ty::ValTree::Leaf(element_count)) = cst.kind()
+            && let Ok((_, ty::ValTree::Leaf(element_count))) = cst.eval(cx.tcx, ParamEnv::empty(), item.span)
             && let element_count = element_count.to_target_usize(cx.tcx)
             && let Ok(element_size) = cx.layout_of(*element_type).map(|l| l.size.bytes())
             && u128::from(self.maximum_allowed_size) < u128::from(element_count) * u128::from(element_size)
diff --git a/clippy_lints/src/large_include_file.rs b/clippy_lints/src/large_include_file.rs
index f2f841dcec3..ab3d19f89c3 100644
--- a/clippy_lints/src/large_include_file.rs
+++ b/clippy_lints/src/large_include_file.rs
@@ -1,11 +1,12 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::root_macro_call_first_node;
-use rustc_ast::LitKind;
+use clippy_utils::source::snippet_opt;
+use rustc_ast::{AttrArgs, AttrArgsEq, AttrKind, Attribute, LitKind};
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::sym;
+use rustc_span::{Span, sym};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -51,6 +52,24 @@ impl LargeIncludeFile {
 
 impl_lint_pass!(LargeIncludeFile => [LARGE_INCLUDE_FILE]);
 
+impl LargeIncludeFile {
+    fn emit_lint(&self, cx: &LateContext<'_>, span: Span) {
+        #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
+        span_lint_and_then(
+            cx,
+            LARGE_INCLUDE_FILE,
+            span,
+            "attempted to include a large file",
+            |diag| {
+                diag.note(format!(
+                    "the configuration allows a maximum size of {} bytes",
+                    self.max_file_size
+                ));
+            },
+        );
+    }
+}
+
 impl LateLintPass<'_> for LargeIncludeFile {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ Expr<'_>) {
         if let ExprKind::Lit(lit) = &expr.kind
@@ -66,19 +85,33 @@ impl LateLintPass<'_> for LargeIncludeFile {
             && (cx.tcx.is_diagnostic_item(sym::include_bytes_macro, macro_call.def_id)
                 || cx.tcx.is_diagnostic_item(sym::include_str_macro, macro_call.def_id))
         {
-            #[expect(clippy::collapsible_span_lint_calls, reason = "rust-clippy#7797")]
-            span_lint_and_then(
-                cx,
-                LARGE_INCLUDE_FILE,
-                expr.span.source_callsite(),
-                "attempted to include a large file",
-                |diag| {
-                    diag.note(format!(
-                        "the configuration allows a maximum size of {} bytes",
-                        self.max_file_size
-                    ));
-                },
-            );
+            self.emit_lint(cx, expr.span.source_callsite());
+        }
+    }
+
+    fn check_attribute(&mut self, cx: &LateContext<'_>, attr: &Attribute) {
+        if !attr.span.from_expansion()
+            // Currently, rustc limits the usage of macro at the top-level of attributes,
+            // so we don't need to recurse into each level.
+            && let AttrKind::Normal(ref normal) = attr.kind
+            && let AttrArgs::Eq(_, AttrArgsEq::Hir(ref meta)) = normal.item.args
+            && !attr.span.contains(meta.span)
+            // Since the `include_str` is already expanded at this point, we can only take the
+            // whole attribute snippet and then modify for our suggestion.
+            && let Some(snippet) = snippet_opt(cx, attr.span)
+            // We cannot remove this because a `#[doc = include_str!("...")]` attribute can
+            // occupy several lines.
+            && let Some(start) = snippet.find('[')
+            && let Some(end) = snippet.rfind(']')
+            && let snippet = &snippet[start + 1..end]
+            // We check that the expansion actually comes from `include_str!` and not just from
+            // another macro.
+            && let Some(sub_snippet) = snippet.trim().strip_prefix("doc")
+            && let Some(sub_snippet) = sub_snippet.trim().strip_prefix("=")
+            && let sub_snippet = sub_snippet.trim()
+            && (sub_snippet.starts_with("include_str!") || sub_snippet.starts_with("include_bytes!"))
+        {
+            self.emit_lint(cx, attr.span);
         }
     }
 }
diff --git a/clippy_lints/src/matches/single_match.rs b/clippy_lints/src/matches/single_match.rs
index 2eda238ae8c..337622873a1 100644
--- a/clippy_lints/src/matches/single_match.rs
+++ b/clippy_lints/src/matches/single_match.rs
@@ -249,7 +249,10 @@ impl<'a> PatState<'a> {
         let states = match self {
             Self::Wild => return None,
             Self::Other => {
-                *self = Self::StdEnum(cx.arena.alloc_from_iter((0..adt.variants().len()).map(|_| Self::Other)));
+                *self = Self::StdEnum(
+                    cx.arena
+                        .alloc_from_iter(std::iter::repeat_with(|| Self::Other).take(adt.variants().len())),
+                );
                 let Self::StdEnum(x) = self else {
                     unreachable!();
                 };
diff --git a/clippy_lints/src/methods/map_all_any_identity.rs b/clippy_lints/src/methods/map_all_any_identity.rs
new file mode 100644
index 00000000000..ac11baa2d54
--- /dev/null
+++ b/clippy_lints/src/methods/map_all_any_identity.rs
@@ -0,0 +1,43 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::SpanRangeExt;
+use clippy_utils::{is_expr_identity_function, is_trait_method};
+use rustc_errors::Applicability;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_span::{Span, sym};
+
+use super::MAP_ALL_ANY_IDENTITY;
+
+#[allow(clippy::too_many_arguments)]
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    expr: &Expr<'_>,
+    recv: &Expr<'_>,
+    map_call_span: Span,
+    map_arg: &Expr<'_>,
+    any_call_span: Span,
+    any_arg: &Expr<'_>,
+    method: &str,
+) {
+    if is_trait_method(cx, expr, sym::Iterator)
+        && is_trait_method(cx, recv, sym::Iterator)
+        && is_expr_identity_function(cx, any_arg)
+        && let map_any_call_span = map_call_span.with_hi(any_call_span.hi())
+        && let Some(map_arg) = map_arg.span.get_source_text(cx)
+    {
+        span_lint_and_then(
+            cx,
+            MAP_ALL_ANY_IDENTITY,
+            map_any_call_span,
+            format!("usage of `.map(...).{method}(identity)`"),
+            |diag| {
+                diag.span_suggestion_verbose(
+                    map_any_call_span,
+                    format!("use `.{method}(...)` instead"),
+                    format!("{method}({map_arg})"),
+                    Applicability::MachineApplicable,
+                );
+            },
+        );
+    }
+}
diff --git a/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs b/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
new file mode 100644
index 00000000000..fc656fd78ba
--- /dev/null
+++ b/clippy_lints/src/methods/map_with_unused_argument_over_ranges.rs
@@ -0,0 +1,134 @@
+use crate::methods::MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES;
+use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::{eager_or_lazy, higher, usage};
+use rustc_ast::LitKind;
+use rustc_ast::ast::RangeLimits;
+use rustc_data_structures::packed::Pu128;
+use rustc_errors::Applicability;
+use rustc_hir::{Body, Closure, Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::Span;
+
+fn extract_count_with_applicability(
+    cx: &LateContext<'_>,
+    range: higher::Range<'_>,
+    applicability: &mut Applicability,
+) -> Option<String> {
+    let start = range.start?;
+    let end = range.end?;
+    // TODO: This doens't handle if either the start or end are negative literals, or if the start is
+    // not a literal. In the first case, we need to be careful about how we handle computing the
+    // count to avoid overflows. In the second, we may need to add parenthesis to make the
+    // suggestion correct.
+    if let ExprKind::Lit(lit) = start.kind
+        && let LitKind::Int(Pu128(lower_bound), _) = lit.node
+    {
+        if let ExprKind::Lit(lit) = end.kind
+            && let LitKind::Int(Pu128(upper_bound), _) = lit.node
+        {
+            // Here we can explicitly calculate the number of iterations
+            let count = if upper_bound >= lower_bound {
+                match range.limits {
+                    RangeLimits::HalfOpen => upper_bound - lower_bound,
+                    RangeLimits::Closed => (upper_bound - lower_bound).checked_add(1)?,
+                }
+            } else {
+                0
+            };
+            return Some(format!("{count}"));
+        }
+        let end_snippet = Sugg::hir_with_applicability(cx, end, "...", applicability)
+            .maybe_par()
+            .into_string();
+        if lower_bound == 0 {
+            if range.limits == RangeLimits::Closed {
+                return Some(format!("{end_snippet} + 1"));
+            }
+            return Some(end_snippet);
+        }
+        if range.limits == RangeLimits::Closed {
+            return Some(format!("{end_snippet} - {}", lower_bound - 1));
+        }
+        return Some(format!("{end_snippet} - {lower_bound}"));
+    }
+    None
+}
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    ex: &Expr<'_>,
+    receiver: &Expr<'_>,
+    arg: &Expr<'_>,
+    msrv: &Msrv,
+    method_call_span: Span,
+) {
+    let mut applicability = Applicability::MaybeIncorrect;
+    if let Some(range) = higher::Range::hir(receiver)
+        && let ExprKind::Closure(Closure { body, .. }) = arg.kind
+        && let body_hir = cx.tcx.hir().body(*body)
+        && let Body {
+            params: [param],
+            value: body_expr,
+        } = body_hir
+        && !usage::BindingUsageFinder::are_params_used(cx, body_hir)
+        && let Some(count) = extract_count_with_applicability(cx, range, &mut applicability)
+    {
+        let method_to_use_name;
+        let new_span;
+        let use_take;
+
+        if eager_or_lazy::switch_to_eager_eval(cx, body_expr) {
+            if msrv.meets(msrvs::REPEAT_N) {
+                method_to_use_name = "repeat_n";
+                let body_snippet = snippet_with_applicability(cx, body_expr.span, "..", &mut applicability);
+                new_span = (arg.span, format!("{body_snippet}, {count}"));
+                use_take = false;
+            } else {
+                method_to_use_name = "repeat";
+                let body_snippet = snippet_with_applicability(cx, body_expr.span, "..", &mut applicability);
+                new_span = (arg.span, body_snippet.to_string());
+                use_take = true;
+            }
+        } else if msrv.meets(msrvs::REPEAT_WITH) {
+            method_to_use_name = "repeat_with";
+            new_span = (param.span, String::new());
+            use_take = true;
+        } else {
+            return;
+        }
+
+        // We need to provide nonempty parts to diag.multipart_suggestion so we
+        // collate all our parts here and then remove those that are empty.
+        let mut parts = vec![
+            (
+                receiver.span.to(method_call_span),
+                format!("std::iter::{method_to_use_name}"),
+            ),
+            new_span,
+        ];
+        if use_take {
+            parts.push((ex.span.shrink_to_hi(), format!(".take({count})")));
+        }
+
+        span_lint_and_then(
+            cx,
+            MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
+            ex.span,
+            "map of a closure that does not depend on its parameter over a range",
+            |diag| {
+                diag.multipart_suggestion(
+                    if use_take {
+                        format!("remove the explicit range and use `{method_to_use_name}` and `take`")
+                    } else {
+                        format!("remove the explicit range and use `{method_to_use_name}`")
+                    },
+                    parts,
+                    applicability,
+                );
+            },
+        );
+    }
+}
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 722290fb68e..f8578ecaf9a 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -60,13 +60,16 @@ mod manual_ok_or;
 mod manual_saturating_arithmetic;
 mod manual_str_repeat;
 mod manual_try_fold;
+mod map_all_any_identity;
 mod map_clone;
 mod map_collect_result_unit;
 mod map_err_ignore;
 mod map_flatten;
 mod map_identity;
 mod map_unwrap_or;
+mod map_with_unused_argument_over_ranges;
 mod mut_mutex_lock;
+mod needless_as_bytes;
 mod needless_character_iteration;
 mod needless_collect;
 mod needless_option_as_deref;
@@ -4166,6 +4169,90 @@ declare_clippy_lint! {
     "calling `.first().is_some()` or `.first().is_none()` instead of `.is_empty()`"
 }
 
+declare_clippy_lint! {
+   /// ### What it does
+   /// It detects useless calls to `str::as_bytes()` before calling `len()` or `is_empty()`.
+   ///
+   /// ### Why is this bad?
+   /// The `len()` and `is_empty()` methods are also directly available on strings, and they
+   /// return identical results. In particular, `len()` on a string returns the number of
+   /// bytes.
+   ///
+   /// ### Example
+   /// ```
+   /// let len = "some string".as_bytes().len();
+   /// let b = "some string".as_bytes().is_empty();
+   /// ```
+   /// Use instead:
+   /// ```
+   /// let len = "some string".len();
+   /// let b = "some string".is_empty();
+   /// ```
+   #[clippy::version = "1.84.0"]
+   pub NEEDLESS_AS_BYTES,
+   complexity,
+   "detect useless calls to `as_bytes()`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for usage of `.map(…)`, followed by `.all(identity)` or `.any(identity)`.
+    ///
+    /// ### Why is this bad?
+    /// The `.all(…)` or `.any(…)` methods can be called directly in place of `.map(…)`.
+    ///
+    /// ### Example
+    /// ```
+    /// # let mut v = [""];
+    /// let e1 = v.iter().map(|s| s.is_empty()).all(|a| a);
+    /// let e2 = v.iter().map(|s| s.is_empty()).any(std::convert::identity);
+    /// ```
+    /// Use instead:
+    /// ```
+    /// # let mut v = [""];
+    /// let e1 = v.iter().all(|s| s.is_empty());
+    /// let e2 = v.iter().any(|s| s.is_empty());
+    /// ```
+    #[clippy::version = "1.84.0"]
+    pub MAP_ALL_ANY_IDENTITY,
+    complexity,
+    "combine `.map(_)` followed by `.all(identity)`/`.any(identity)` into a single call"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    ///
+    /// Checks for `Iterator::map` over ranges without using the parameter which
+    /// could be more clearly expressed using `std::iter::repeat(...).take(...)`
+    /// or `std::iter::repeat_n`.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// It expresses the intent more clearly to `take` the correct number of times
+    /// from a generating function than to apply a closure to each number in a
+    /// range only to discard them.
+    ///
+    /// ### Example
+    ///
+    /// ```no_run
+    /// let random_numbers : Vec<_> = (0..10).map(|_| { 3 + 1 }).collect();
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// let f : Vec<_> = std::iter::repeat( 3 + 1 ).take(10).collect();
+    /// ```
+    ///
+    /// ### Known Issues
+    ///
+    /// This lint may suggest replacing a `Map<Range>` with a `Take<RepeatWith>`.
+    /// The former implements some traits that the latter does not, such as
+    /// `DoubleEndedIterator`.
+    #[clippy::version = "1.84.0"]
+    pub MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
+    restriction,
+    "map of a trivial closure (not dependent on parameter) over a range"
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Msrv,
@@ -4327,6 +4414,9 @@ impl_lint_pass!(Methods => [
     NEEDLESS_CHARACTER_ITERATION,
     MANUAL_INSPECT,
     UNNECESSARY_MIN_OR_MAX,
+    NEEDLESS_AS_BYTES,
+    MAP_ALL_ANY_IDENTITY,
+    MAP_WITH_UNUSED_ARGUMENT_OVER_RANGES,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -4534,15 +4624,21 @@ impl Methods {
                 ("all", [arg]) => {
                     unused_enumerate_index::check(cx, expr, recv, arg);
                     needless_character_iteration::check(cx, expr, recv, arg, true);
-                    if let Some(("cloned", recv2, [], _, _)) = method_call(recv) {
-                        iter_overeager_cloned::check(
-                            cx,
-                            expr,
-                            recv,
-                            recv2,
-                            iter_overeager_cloned::Op::NeedlessMove(arg),
-                            false,
-                        );
+                    match method_call(recv) {
+                        Some(("cloned", recv2, [], _, _)) => {
+                            iter_overeager_cloned::check(
+                                cx,
+                                expr,
+                                recv,
+                                recv2,
+                                iter_overeager_cloned::Op::NeedlessMove(arg),
+                                false,
+                            );
+                        },
+                        Some(("map", _, [map_arg], _, map_call_span)) => {
+                            map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, "all");
+                        },
+                        _ => {},
                     }
                 },
                 ("and_then", [arg]) => {
@@ -4571,6 +4667,9 @@ impl Methods {
                         {
                             string_lit_chars_any::check(cx, expr, recv, param, peel_blocks(body.value), &self.msrv);
                         },
+                        Some(("map", _, [map_arg], _, map_call_span)) => {
+                            map_all_any_identity::check(cx, expr, recv, map_call_span, map_arg, call_span, arg, "any");
+                        },
                         _ => {},
                     }
                 },
@@ -4764,8 +4863,14 @@ impl Methods {
                     unit_hash::check(cx, expr, recv, arg);
                 },
                 ("is_empty", []) => {
-                    if let Some(("as_str", recv, [], as_str_span, _)) = method_call(recv) {
-                        redundant_as_str::check(cx, expr, recv, as_str_span, span);
+                    match method_call(recv) {
+                        Some(("as_bytes", prev_recv, [], _, _)) => {
+                            needless_as_bytes::check(cx, "is_empty", recv, prev_recv, expr.span);
+                        },
+                        Some(("as_str", recv, [], as_str_span, _)) => {
+                            redundant_as_str::check(cx, expr, recv, as_str_span, span);
+                        },
+                        _ => {},
                     }
                     is_empty::check(cx, expr, recv);
                 },
@@ -4795,6 +4900,11 @@ impl Methods {
                         );
                     }
                 },
+                ("len", []) => {
+                    if let Some(("as_bytes", prev_recv, [], _, _)) = method_call(recv) {
+                        needless_as_bytes::check(cx, "len", recv, prev_recv, expr.span);
+                    }
+                },
                 ("lock", []) => {
                     mut_mutex_lock::check(cx, expr, recv, span);
                 },
@@ -4802,6 +4912,7 @@ impl Methods {
                     if name == "map" {
                         unused_enumerate_index::check(cx, expr, recv, m_arg);
                         map_clone::check(cx, expr, recv, m_arg, &self.msrv);
+                        map_with_unused_argument_over_ranges::check(cx, expr, recv, m_arg, &self.msrv, span);
                         match method_call(recv) {
                             Some((map_name @ ("iter" | "into_iter"), recv2, _, _, _)) => {
                                 iter_kv_map::check(cx, map_name, expr, recv2, m_arg, &self.msrv);
diff --git a/clippy_lints/src/methods/needless_as_bytes.rs b/clippy_lints/src/methods/needless_as_bytes.rs
new file mode 100644
index 00000000000..75e9f317230
--- /dev/null
+++ b/clippy_lints/src/methods/needless_as_bytes.rs
@@ -0,0 +1,28 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::sugg::Sugg;
+use clippy_utils::ty::is_type_lang_item;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, LangItem};
+use rustc_lint::LateContext;
+use rustc_span::Span;
+
+use super::NEEDLESS_AS_BYTES;
+
+pub fn check(cx: &LateContext<'_>, method: &str, recv: &Expr<'_>, prev_recv: &Expr<'_>, span: Span) {
+    if cx.typeck_results().expr_ty_adjusted(recv).peel_refs().is_slice()
+        && let ty1 = cx.typeck_results().expr_ty_adjusted(prev_recv).peel_refs()
+        && (is_type_lang_item(cx, ty1, LangItem::String) || ty1.is_str())
+    {
+        let mut app = Applicability::MachineApplicable;
+        let sugg = Sugg::hir_with_context(cx, prev_recv, span.ctxt(), "..", &mut app);
+        span_lint_and_sugg(
+            cx,
+            NEEDLESS_AS_BYTES,
+            span,
+            "needless call to `as_bytes()`",
+            format!("`{method}()` can be called directly on strings"),
+            format!("{sugg}.{method}()"),
+            app,
+        );
+    }
+}
diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs
index 1cbb1bcc663..bab439015c5 100644
--- a/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -1,13 +1,15 @@
 use super::utils::clone_or_copy_needed;
-use clippy_utils::diagnostics::span_lint;
+use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::ty::is_copy;
 use clippy_utils::usage::mutated_variables;
 use clippy_utils::visitors::{Descend, for_each_expr_without_closures};
-use clippy_utils::{is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
+use clippy_utils::{MaybePath, is_res_lang_ctor, is_trait_method, path_res, path_to_local_id};
 use core::ops::ControlFlow;
+use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
 use rustc_lint::LateContext;
+use rustc_middle::query::Key;
 use rustc_middle::ty;
 use rustc_span::sym;
 
@@ -36,9 +38,25 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
                 ControlFlow::Continue(Descend::Yes)
             }
         });
-
         let in_ty = cx.typeck_results().node_type(body.params[0].hir_id);
         let sugg = if !found_filtering {
+            // Check if the closure is .filter_map(|x| Some(x))
+            if name == "filter_map"
+                && let hir::ExprKind::Call(expr, args) = body.value.kind
+                && is_res_lang_ctor(cx, path_res(cx, expr), OptionSome)
+                && arg_id.ty_def_id() == args[0].hir_id().ty_def_id()
+                && let hir::ExprKind::Path(_) = args[0].kind
+            {
+                span_lint_and_sugg(
+                    cx,
+                    UNNECESSARY_FILTER_MAP,
+                    expr.span,
+                    format!("{name} is unnecessary"),
+                    "try removing the filter_map",
+                    String::new(),
+                    Applicability::MaybeIncorrect,
+                );
+            }
             if name == "filter_map" { "map" } else { "map(..).next()" }
         } else if !found_mapping && !mutates_arg && (!clone_or_copy_needed || is_copy(cx, in_ty)) {
             match cx.typeck_results().expr_ty(body.value).kind() {
@@ -52,7 +70,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
         } else {
             return;
         };
-        span_lint(
+        span_lint_and_sugg(
             cx,
             if name == "filter_map" {
                 UNNECESSARY_FILTER_MAP
@@ -60,7 +78,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
                 UNNECESSARY_FIND_MAP
             },
             expr.span,
-            format!("this `.{name}` can be written more simply using `.{sugg}`"),
+            format!("this `.{name}` can be written more simply"),
+            "try instead",
+            sugg.to_string(),
+            Applicability::MaybeIncorrect,
         );
     }
 }
diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs
index cf406b817da..a8cc14d269a 100644
--- a/clippy_lints/src/unused_io_amount.rs
+++ b/clippy_lints/src/unused_io_amount.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::macros::{is_panic, root_macro_call_first_node};
-use clippy_utils::{is_res_lang_ctor, is_trait_method, match_trait_method, paths, peel_blocks};
+use clippy_utils::{is_res_lang_ctor, is_trait_method, match_def_path, match_trait_method, paths, peel_blocks};
 use hir::{ExprKind, HirId, PatKind};
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
@@ -83,6 +83,28 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
     /// to consider the arms, and we want to avoid breaking the logic for situations where things
     /// get desugared to match.
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx hir::Block<'tcx>) {
+        let fn_def_id = block.hir_id.owner.to_def_id();
+        if let Some(impl_id) = cx.tcx.impl_of_method(fn_def_id)
+            && let Some(trait_id) = cx.tcx.trait_id_of_impl(impl_id)
+        {
+            // We don't want to lint inside io::Read or io::Write implementations, as the author has more
+            // information about their trait implementation than our lint, see https://github.com/rust-lang/rust-clippy/issues/4836
+            if cx.tcx.is_diagnostic_item(sym::IoRead, trait_id) || cx.tcx.is_diagnostic_item(sym::IoWrite, trait_id) {
+                return;
+            }
+
+            let async_paths: [&[&str]; 4] = [
+                &paths::TOKIO_IO_ASYNCREADEXT,
+                &paths::TOKIO_IO_ASYNCWRITEEXT,
+                &paths::FUTURES_IO_ASYNCREADEXT,
+                &paths::FUTURES_IO_ASYNCWRITEEXT,
+            ];
+
+            if async_paths.into_iter().any(|path| match_def_path(cx, trait_id, path)) {
+                return;
+            }
+        }
+
         for stmt in block.stmts {
             if let hir::StmtKind::Semi(exp) = stmt.kind {
                 check_expr(cx, exp);
diff --git a/clippy_utils/src/check_proc_macro.rs b/clippy_utils/src/check_proc_macro.rs
index bfb3a76ad25..91954eebdc0 100644
--- a/clippy_utils/src/check_proc_macro.rs
+++ b/clippy_utils/src/check_proc_macro.rs
@@ -63,8 +63,8 @@ fn span_matches_pat(sess: &Session, span: Span, start_pat: Pat, end_pat: Pat) ->
             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::MultiStr(texts) => texts.iter().any(|s| start_str.ends_with(s)),
-            Pat::OwnedMultiStr(texts) => texts.iter().any(|s| start_str.starts_with(s)),
+            Pat::MultiStr(texts) => texts.iter().any(|s| end_str.ends_with(s)),
+            Pat::OwnedMultiStr(texts) => texts.iter().any(|s| end_str.ends_with(s)),
             Pat::Sym(sym) => end_str.ends_with(sym.as_str()),
             Pat::Num => end_str.as_bytes().last().map_or(false, u8::is_ascii_hexdigit),
         })
@@ -333,26 +333,32 @@ fn attr_search_pat(attr: &Attribute) -> (Pat, Pat) {
     match attr.kind {
         AttrKind::Normal(..) => {
             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::OwnedMultiStr(vec![ident.to_string(), "#".to_owned()]),
-                    Pat::Str(""),
-                )
+                let ident_string = ident.to_string();
+                if attr.style == AttrStyle::Outer {
+                    (
+                        Pat::OwnedMultiStr(vec!["#[".to_owned() + &ident_string, ident_string]),
+                        Pat::Str(""),
+                    )
+                } else {
+                    (
+                        Pat::OwnedMultiStr(vec!["#![".to_owned() + &ident_string, ident_string]),
+                        Pat::Str(""),
+                    )
+                }
             } else {
                 (Pat::Str("#"), Pat::Str("]"))
             }
         },
         AttrKind::DocComment(_kind @ CommentKind::Line, ..) => {
-            if matches!(attr.style, AttrStyle::Outer) {
+            if attr.style == AttrStyle::Outer {
                 (Pat::Str("///"), Pat::Str(""))
             } else {
                 (Pat::Str("//!"), Pat::Str(""))
             }
         },
         AttrKind::DocComment(_kind @ CommentKind::Block, ..) => {
-            if matches!(attr.style, AttrStyle::Outer) {
+            if attr.style == AttrStyle::Outer {
                 (Pat::Str("/**"), Pat::Str("*/"))
             } else {
                 (Pat::Str("/*!"), Pat::Str("*/"))
diff --git a/clippy_utils/src/consts.rs b/clippy_utils/src/consts.rs
index a1cfb7be647..0dbc7972fe9 100644
--- a/clippy_utils/src/consts.rs
+++ b/clippy_utils/src/consts.rs
@@ -1,3 +1,7 @@
+//! A simple const eval API, for use on arbitrary HIR expressions.
+//!
+//! This cannot use rustc's const eval, aka miri, as arbitrary HIR expressions cannot be lowered to
+//! executable MIR bodies, so we have to do this instead.
 #![allow(clippy::float_cmp)]
 
 use crate::macros::HirNode;
@@ -379,6 +383,8 @@ impl Ord for FullInt {
 /// The context required to evaluate a constant expression.
 ///
 /// This is currently limited to constant folding and reading the value of named constants.
+///
+/// See the module level documentation for some context.
 pub struct ConstEvalCtxt<'tcx> {
     tcx: TyCtxt<'tcx>,
     param_env: ParamEnv<'tcx>,
diff --git a/tests/ui-toml/large_include_file/large_include_file.rs b/tests/ui-toml/large_include_file/large_include_file.rs
index f3dbb6ad1cf..dc9349f75a0 100644
--- a/tests/ui-toml/large_include_file/large_include_file.rs
+++ b/tests/ui-toml/large_include_file/large_include_file.rs
@@ -1,8 +1,8 @@
 #![warn(clippy::large_include_file)]
 
 // Good
-const GOOD_INCLUDE_BYTES: &[u8; 581] = include_bytes!("large_include_file.rs");
-const GOOD_INCLUDE_STR: &str = include_str!("large_include_file.rs");
+const GOOD_INCLUDE_BYTES: &[u8; 68] = include_bytes!("../../ui/author.rs");
+const GOOD_INCLUDE_STR: &str = include_str!("../../ui/author.rs");
 
 #[allow(clippy::large_include_file)]
 const ALLOWED_TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
@@ -11,6 +11,9 @@ const ALLOWED_TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
 
 // Bad
 const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
+//~^ large_include_file
 const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
+//~^ large_include_file
 
+#[doc = include_str!("too_big.txt")] //~ large_include_file
 fn main() {}
diff --git a/tests/ui-toml/large_include_file/large_include_file.stderr b/tests/ui-toml/large_include_file/large_include_file.stderr
index 34224065f07..9e1494a47bb 100644
--- a/tests/ui-toml/large_include_file/large_include_file.stderr
+++ b/tests/ui-toml/large_include_file/large_include_file.stderr
@@ -9,12 +9,20 @@ LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
    = help: to override `-D warnings` add `#[allow(clippy::large_include_file)]`
 
 error: attempted to include a large file
-  --> tests/ui-toml/large_include_file/large_include_file.rs:14:35
+  --> tests/ui-toml/large_include_file/large_include_file.rs:15:35
    |
 LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the configuration allows a maximum size of 600 bytes
 
-error: aborting due to 2 previous errors
+error: attempted to include a large file
+  --> tests/ui-toml/large_include_file/large_include_file.rs:18:1
+   |
+LL | #[doc = include_str!("too_big.txt")]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the configuration allows a maximum size of 600 bytes
+
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui-toml/private-doc-errors/doc_lints.rs b/tests/ui-toml/private-doc-errors/doc_lints.rs
index 79c8751468d..c5d00c91b05 100644
--- a/tests/ui-toml/private-doc-errors/doc_lints.rs
+++ b/tests/ui-toml/private-doc-errors/doc_lints.rs
@@ -51,4 +51,10 @@ pub mod __macro {
     }
 }
 
+#[warn(clippy::missing_errors_doc)]
+#[test]
+fn test() -> Result<(), ()> {
+    Ok(())
+}
+
 fn main() {}
diff --git a/tests/ui/allow_attributes.fixed b/tests/ui/allow_attributes.fixed
index 058dbb77a32..8f6c962e2f5 100644
--- a/tests/ui/allow_attributes.fixed
+++ b/tests/ui/allow_attributes.fixed
@@ -1,4 +1,5 @@
 //@aux-build:proc_macros.rs
+//@aux-build:proc_macro_derive.rs
 #![allow(unused)]
 #![warn(clippy::allow_attributes)]
 #![no_main]
@@ -65,3 +66,9 @@ fn deny_allow_attributes() -> Option<u8> {
     allow?;
     Some(42)
 }
+
+// Edge case where the generated tokens spans match on #[repr(transparent)] which tricks the proc
+// macro check
+#[repr(transparent)]
+#[derive(proc_macro_derive::AllowLintSameSpan)] // This macro generates tokens with the same span as the whole struct and repr
+struct IgnoreDerived;
diff --git a/tests/ui/allow_attributes.rs b/tests/ui/allow_attributes.rs
index 6d94ce50e4c..cb6c4dcf715 100644
--- a/tests/ui/allow_attributes.rs
+++ b/tests/ui/allow_attributes.rs
@@ -1,4 +1,5 @@
 //@aux-build:proc_macros.rs
+//@aux-build:proc_macro_derive.rs
 #![allow(unused)]
 #![warn(clippy::allow_attributes)]
 #![no_main]
@@ -65,3 +66,9 @@ fn deny_allow_attributes() -> Option<u8> {
     allow?;
     Some(42)
 }
+
+// Edge case where the generated tokens spans match on #[repr(transparent)] which tricks the proc
+// macro check
+#[repr(transparent)]
+#[derive(proc_macro_derive::AllowLintSameSpan)] // This macro generates tokens with the same span as the whole struct and repr
+struct IgnoreDerived;
diff --git a/tests/ui/allow_attributes.stderr b/tests/ui/allow_attributes.stderr
index 10dac0bc808..ae1c440da73 100644
--- a/tests/ui/allow_attributes.stderr
+++ b/tests/ui/allow_attributes.stderr
@@ -1,5 +1,5 @@
 error: #[allow] attribute found
-  --> tests/ui/allow_attributes.rs:12:3
+  --> tests/ui/allow_attributes.rs:13:3
    |
 LL | #[allow(dead_code)]
    |   ^^^^^ help: replace it with: `expect`
@@ -8,19 +8,19 @@ LL | #[allow(dead_code)]
    = help: to override `-D warnings` add `#[allow(clippy::allow_attributes)]`
 
 error: #[allow] attribute found
-  --> tests/ui/allow_attributes.rs:21:30
+  --> tests/ui/allow_attributes.rs:22:30
    |
 LL | #[cfg_attr(panic = "unwind", allow(dead_code))]
    |                              ^^^^^ help: replace it with: `expect`
 
 error: #[allow] attribute found
-  --> tests/ui/allow_attributes.rs:52:7
+  --> tests/ui/allow_attributes.rs:53:7
    |
 LL |     #[allow(unused)]
    |       ^^^^^ help: replace it with: `expect`
 
 error: #[allow] attribute found
-  --> tests/ui/allow_attributes.rs:52:7
+  --> tests/ui/allow_attributes.rs:53:7
    |
 LL |     #[allow(unused)]
    |       ^^^^^ help: replace it with: `expect`
diff --git a/tests/ui/auxiliary/proc_macro_derive.rs b/tests/ui/auxiliary/proc_macro_derive.rs
index bd90042c1da..fbf84337382 100644
--- a/tests/ui/auxiliary/proc_macro_derive.rs
+++ b/tests/ui/auxiliary/proc_macro_derive.rs
@@ -1,4 +1,4 @@
-#![feature(repr128, proc_macro_quote)]
+#![feature(repr128, proc_macro_quote, proc_macro_span)]
 #![allow(incomplete_features)]
 #![allow(clippy::field_reassign_with_default)]
 #![allow(clippy::eq_op)]
@@ -182,3 +182,51 @@ pub fn non_canonical_clone_derive(_: TokenStream) -> TokenStream {
         impl Copy for NonCanonicalClone {}
     }
 }
+
+// Derive macro that generates the following but where all generated spans are set to the entire
+// input span.
+//
+// ```
+// #[allow(clippy::missing_const_for_fn)]
+// fn check() {}
+// ```
+#[proc_macro_derive(AllowLintSameSpan)]
+pub fn allow_lint_same_span_derive(input: TokenStream) -> TokenStream {
+    let mut iter = input.into_iter();
+    let first = iter.next().unwrap();
+    let last = iter.last().unwrap();
+    let span = first.span().join(last.span()).unwrap();
+    let span_help = |mut t: TokenTree| -> TokenTree {
+        t.set_span(span);
+        t
+    };
+    // Generate the TokenStream but setting all the spans to the entire input span
+    <TokenStream as FromIterator<TokenTree>>::from_iter([
+        span_help(Punct::new('#', Spacing::Alone).into()),
+        span_help(
+            Group::new(
+                Delimiter::Bracket,
+                <TokenStream as FromIterator<TokenTree>>::from_iter([
+                    Ident::new("allow", span).into(),
+                    span_help(
+                        Group::new(
+                            Delimiter::Parenthesis,
+                            <TokenStream as FromIterator<TokenTree>>::from_iter([
+                                Ident::new("clippy", span).into(),
+                                span_help(Punct::new(':', Spacing::Joint).into()),
+                                span_help(Punct::new(':', Spacing::Alone).into()),
+                                Ident::new("missing_const_for_fn", span).into(),
+                            ]),
+                        )
+                        .into(),
+                    ),
+                ]),
+            )
+            .into(),
+        ),
+        Ident::new("fn", span).into(),
+        Ident::new("check", span).into(),
+        span_help(Group::new(Delimiter::Parenthesis, TokenStream::new()).into()),
+        span_help(Group::new(Delimiter::Brace, TokenStream::new()).into()),
+    ])
+}
diff --git a/tests/ui/borrow_deref_ref.fixed b/tests/ui/borrow_deref_ref.fixed
index ea5e983de3b..22e984c46d2 100644
--- a/tests/ui/borrow_deref_ref.fixed
+++ b/tests/ui/borrow_deref_ref.fixed
@@ -71,3 +71,9 @@ mod false_negative {
         assert_ne!(addr_x, addr_y);
     }
 }
+
+fn issue_13584() {
+    let s = "Hello, world!\n";
+    let p = &raw const *s;
+    let _ = p as *const i8;
+}
diff --git a/tests/ui/borrow_deref_ref.rs b/tests/ui/borrow_deref_ref.rs
index 8c8905b150e..61d89193f42 100644
--- a/tests/ui/borrow_deref_ref.rs
+++ b/tests/ui/borrow_deref_ref.rs
@@ -71,3 +71,9 @@ mod false_negative {
         assert_ne!(addr_x, addr_y);
     }
 }
+
+fn issue_13584() {
+    let s = "Hello, world!\n";
+    let p = &raw const *s;
+    let _ = p as *const i8;
+}
diff --git a/tests/ui/doc/doc-fixable.fixed b/tests/ui/doc/doc-fixable.fixed
index 8a379330c48..5cf5c608a85 100644
--- a/tests/ui/doc/doc-fixable.fixed
+++ b/tests/ui/doc/doc-fixable.fixed
@@ -56,7 +56,7 @@ fn test_units() {
 /// KiB MiB GiB TiB PiB EiB
 /// MHz GHz THz
 /// AccessKit
-/// CoreFoundation CoreGraphics CoreText
+/// CoAP CoreFoundation CoreGraphics CoreText
 /// Direct2D Direct3D DirectWrite DirectX
 /// ECMAScript
 /// GPLv2 GPLv3
diff --git a/tests/ui/doc/doc-fixable.rs b/tests/ui/doc/doc-fixable.rs
index 35f43d98e79..420211c6539 100644
--- a/tests/ui/doc/doc-fixable.rs
+++ b/tests/ui/doc/doc-fixable.rs
@@ -56,7 +56,7 @@ fn test_units() {
 /// KiB MiB GiB TiB PiB EiB
 /// MHz GHz THz
 /// AccessKit
-/// CoreFoundation CoreGraphics CoreText
+/// CoAP CoreFoundation CoreGraphics CoreText
 /// Direct2D Direct3D DirectWrite DirectX
 /// ECMAScript
 /// GPLv2 GPLv3
diff --git a/tests/ui/iter_without_into_iter.stderr b/tests/ui/iter_without_into_iter.stderr
index 7c42fa1dd89..d748c85003b 100644
--- a/tests/ui/iter_without_into_iter.stderr
+++ b/tests/ui/iter_without_into_iter.stderr
@@ -13,8 +13,8 @@ help: consider implementing `IntoIterator` for `&S1`
    |
 LL + 
 LL + impl IntoIterator for &S1 {
-LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     type Item = &u8;
+LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -34,8 +34,8 @@ help: consider implementing `IntoIterator` for `&mut S1`
    |
 LL + 
 LL + impl IntoIterator for &mut S1 {
-LL +     type IntoIter = std::slice::IterMut<'_, u8>;
 LL +     type Item = &mut u8;
+LL +     type IntoIter = std::slice::IterMut<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -55,8 +55,8 @@ help: consider implementing `IntoIterator` for `&S3<'a>`
    |
 LL + 
 LL + impl IntoIterator for &S3<'a> {
-LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     type Item = &u8;
+LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -76,8 +76,8 @@ help: consider implementing `IntoIterator` for `&mut S3<'a>`
    |
 LL + 
 LL + impl IntoIterator for &mut S3<'a> {
-LL +     type IntoIter = std::slice::IterMut<'_, u8>;
 LL +     type Item = &mut u8;
+LL +     type IntoIter = std::slice::IterMut<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -96,8 +96,8 @@ help: consider implementing `IntoIterator` for `&S8<T>`
    |
 LL + 
 LL + impl IntoIterator for &S8<T> {
-LL +     type IntoIter = std::slice::Iter<'static, T>;
 LL +     type Item = &T;
+LL +     type IntoIter = std::slice::Iter<'static, T>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -117,8 +117,8 @@ help: consider implementing `IntoIterator` for `&S9<T>`
    |
 LL + 
 LL + impl IntoIterator for &S9<T> {
-LL +     type IntoIter = std::slice::Iter<'_, T>;
 LL +     type Item = &T;
+LL +     type IntoIter = std::slice::Iter<'_, T>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -138,8 +138,8 @@ help: consider implementing `IntoIterator` for `&mut S9<T>`
    |
 LL + 
 LL + impl IntoIterator for &mut S9<T> {
-LL +     type IntoIter = std::slice::IterMut<'_, T>;
 LL +     type Item = &mut T;
+LL +     type IntoIter = std::slice::IterMut<'_, T>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
@@ -162,8 +162,8 @@ help: consider implementing `IntoIterator` for `&Issue12037`
    |
 LL ~         
 LL + impl IntoIterator for &Issue12037 {
-LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     type Item = &u8;
+LL +     type IntoIter = std::slice::Iter<'_, u8>;
 LL +     fn into_iter(self) -> Self::IntoIter {
 LL +         self.iter()
 LL +     }
diff --git a/tests/ui/large_const_arrays.fixed b/tests/ui/large_const_arrays.fixed
index 543ce460e7b..e5b28cb6a9d 100644
--- a/tests/ui/large_const_arrays.fixed
+++ b/tests/ui/large_const_arrays.fixed
@@ -9,11 +9,13 @@ pub struct S {
 // Should lint
 pub(crate) static FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000];
 pub static FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
+static FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100];
 static FOO: [u32; 1_000_000] = [0u32; 1_000_000];
 
 // Good
 pub(crate) const G_FOO_PUB_CRATE: [u32; 250] = [0u32; 250];
 pub const G_FOO_PUB: [u32; 250] = [0u32; 250];
+const G_FOO_COMPUTED: [u32; 25 * 10] = [0u32; 25 * 10];
 const G_FOO: [u32; 250] = [0u32; 250];
 
 fn main() {
diff --git a/tests/ui/large_const_arrays.rs b/tests/ui/large_const_arrays.rs
index e23a8081171..b9593225da2 100644
--- a/tests/ui/large_const_arrays.rs
+++ b/tests/ui/large_const_arrays.rs
@@ -9,11 +9,13 @@ pub struct S {
 // Should lint
 pub(crate) const FOO_PUB_CRATE: [u32; 1_000_000] = [0u32; 1_000_000];
 pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
+const FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100];
 const FOO: [u32; 1_000_000] = [0u32; 1_000_000];
 
 // Good
 pub(crate) const G_FOO_PUB_CRATE: [u32; 250] = [0u32; 250];
 pub const G_FOO_PUB: [u32; 250] = [0u32; 250];
+const G_FOO_COMPUTED: [u32; 25 * 10] = [0u32; 25 * 10];
 const G_FOO: [u32; 250] = [0u32; 250];
 
 fn main() {
diff --git a/tests/ui/large_const_arrays.stderr b/tests/ui/large_const_arrays.stderr
index 88f921b81f7..27112205390 100644
--- a/tests/ui/large_const_arrays.stderr
+++ b/tests/ui/large_const_arrays.stderr
@@ -20,13 +20,21 @@ LL | pub const FOO_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
 error: large array defined as const
   --> tests/ui/large_const_arrays.rs:12:1
    |
+LL | const FOO_COMPUTED: [u32; 1_000 * 100] = [0u32; 1_000 * 100];
+   | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | help: make this a static item: `static`
+
+error: large array defined as const
+  --> tests/ui/large_const_arrays.rs:13:1
+   |
 LL | const FOO: [u32; 1_000_000] = [0u32; 1_000_000];
    | -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    | |
    | help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:21:5
+  --> tests/ui/large_const_arrays.rs:23:5
    |
 LL |     pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
    |     ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -34,7 +42,7 @@ LL |     pub const BAR_PUB: [u32; 1_000_000] = [0u32; 1_000_000];
    |         help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:22:5
+  --> tests/ui/large_const_arrays.rs:24:5
    |
 LL |     const BAR: [u32; 1_000_000] = [0u32; 1_000_000];
    |     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -42,7 +50,7 @@ LL |     const BAR: [u32; 1_000_000] = [0u32; 1_000_000];
    |     help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:23:5
+  --> tests/ui/large_const_arrays.rs:25:5
    |
 LL |     pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000];
    |     ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +58,7 @@ LL |     pub const BAR_STRUCT_PUB: [S; 5_000] = [S { data: [0; 32] }; 5_000];
    |         help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:24:5
+  --> tests/ui/large_const_arrays.rs:26:5
    |
 LL |     const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000];
    |     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -58,7 +66,7 @@ LL |     const BAR_STRUCT: [S; 5_000] = [S { data: [0; 32] }; 5_000];
    |     help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:25:5
+  --> tests/ui/large_const_arrays.rs:27:5
    |
 LL |     pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000];
    |     ^^^^-----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -66,12 +74,12 @@ LL |     pub const BAR_S_PUB: [Option<&str>; 200_000] = [Some("str"); 200_000];
    |         help: make this a static item: `static`
 
 error: large array defined as const
-  --> tests/ui/large_const_arrays.rs:26:5
+  --> tests/ui/large_const_arrays.rs:28:5
    |
 LL |     const BAR_S: [Option<&str>; 200_000] = [Some("str"); 200_000];
    |     -----^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     |
    |     help: make this a static item: `static`
 
-error: aborting due to 9 previous errors
+error: aborting due to 10 previous errors
 
diff --git a/tests/ui/map_all_any_identity.fixed b/tests/ui/map_all_any_identity.fixed
new file mode 100644
index 00000000000..c92462ab9c2
--- /dev/null
+++ b/tests/ui/map_all_any_identity.fixed
@@ -0,0 +1,21 @@
+#![warn(clippy::map_all_any_identity)]
+
+fn main() {
+    let _ = ["foo"].into_iter().any(|s| s == "foo");
+    //~^ map_all_any_identity
+    let _ = ["foo"].into_iter().all(|s| s == "foo");
+    //~^ map_all_any_identity
+
+    //
+    // Do not lint
+    //
+    // Not identity
+    let _ = ["foo"].into_iter().map(|s| s.len()).any(|n| n > 0);
+    // Macro
+    macro_rules! map {
+        ($x:expr) => {
+            $x.into_iter().map(|s| s == "foo")
+        };
+    }
+    map!(["foo"]).any(|a| a);
+}
diff --git a/tests/ui/map_all_any_identity.rs b/tests/ui/map_all_any_identity.rs
new file mode 100644
index 00000000000..0e4a564ca04
--- /dev/null
+++ b/tests/ui/map_all_any_identity.rs
@@ -0,0 +1,21 @@
+#![warn(clippy::map_all_any_identity)]
+
+fn main() {
+    let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a);
+    //~^ map_all_any_identity
+    let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity);
+    //~^ map_all_any_identity
+
+    //
+    // Do not lint
+    //
+    // Not identity
+    let _ = ["foo"].into_iter().map(|s| s.len()).any(|n| n > 0);
+    // Macro
+    macro_rules! map {
+        ($x:expr) => {
+            $x.into_iter().map(|s| s == "foo")
+        };
+    }
+    map!(["foo"]).any(|a| a);
+}
diff --git a/tests/ui/map_all_any_identity.stderr b/tests/ui/map_all_any_identity.stderr
new file mode 100644
index 00000000000..98fdcc2a939
--- /dev/null
+++ b/tests/ui/map_all_any_identity.stderr
@@ -0,0 +1,26 @@
+error: usage of `.map(...).any(identity)`
+  --> tests/ui/map_all_any_identity.rs:4:33
+   |
+LL |     let _ = ["foo"].into_iter().map(|s| s == "foo").any(|a| a);
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::map-all-any-identity` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::map_all_any_identity)]`
+help: use `.any(...)` instead
+   |
+LL |     let _ = ["foo"].into_iter().any(|s| s == "foo");
+   |                                 ~~~~~~~~~~~~~~~~~~~
+
+error: usage of `.map(...).all(identity)`
+  --> tests/ui/map_all_any_identity.rs:6:33
+   |
+LL |     let _ = ["foo"].into_iter().map(|s| s == "foo").all(std::convert::identity);
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `.all(...)` instead
+   |
+LL |     let _ = ["foo"].into_iter().all(|s| s == "foo");
+   |                                 ~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/map_with_unused_argument_over_ranges.fixed b/tests/ui/map_with_unused_argument_over_ranges.fixed
new file mode 100644
index 00000000000..cf520e71a64
--- /dev/null
+++ b/tests/ui/map_with_unused_argument_over_ranges.fixed
@@ -0,0 +1,73 @@
+#![allow(
+    unused,
+    clippy::redundant_closure,
+    clippy::reversed_empty_ranges,
+    clippy::identity_op
+)]
+#![warn(clippy::map_with_unused_argument_over_ranges)]
+
+fn do_something() -> usize {
+    todo!()
+}
+
+fn do_something_interesting(x: usize, y: usize) -> usize {
+    todo!()
+}
+
+macro_rules! gen {
+    () => {
+        (0..10).map(|_| do_something());
+    };
+}
+
+fn main() {
+    // These should be raised
+    std::iter::repeat_with(|| do_something()).take(10);
+    std::iter::repeat_with(|| do_something()).take(10);
+    std::iter::repeat_with(|| do_something()).take(11);
+    std::iter::repeat_with(|| do_something()).take(7);
+    std::iter::repeat_with(|| do_something()).take(8);
+    std::iter::repeat_n(3, 10);
+    std::iter::repeat_with(|| {
+        let x = 3;
+        x + 2
+    }).take(10);
+    std::iter::repeat_with(|| do_something()).take(10).collect::<Vec<_>>();
+    let upper = 4;
+    std::iter::repeat_with(|| do_something()).take(upper);
+    let upper_fn = || 4;
+    std::iter::repeat_with(|| do_something()).take(upper_fn());
+    std::iter::repeat_with(|| do_something()).take(upper_fn() + 1);
+    std::iter::repeat_with(|| do_something()).take(upper_fn() - 2);
+    std::iter::repeat_with(|| do_something()).take(upper_fn() - 1);
+    (-3..9).map(|_| do_something());
+    std::iter::repeat_with(|| do_something()).take(0);
+    std::iter::repeat_with(|| do_something()).take(1);
+    std::iter::repeat_with(|| do_something()).take((1 << 4) - 0);
+    // These should not be raised
+    gen!();
+    let lower = 2;
+    let lower_fn = || 2;
+    (lower..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (lower_fn()..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (lower_fn()..=upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (0..10).map(|x| do_something_interesting(x, 4)); // Actual map over range
+    "Foobar".chars().map(|_| do_something()); // Not a map over range
+    // i128::MAX == 340282366920938463463374607431768211455
+    (0..=340282366920938463463374607431768211455).map(|_: u128| do_something()); // Can't be replaced due to overflow
+}
+
+#[clippy::msrv = "1.27"]
+fn msrv_1_27() {
+    (0..10).map(|_| do_something());
+}
+
+#[clippy::msrv = "1.28"]
+fn msrv_1_28() {
+    std::iter::repeat_with(|| do_something()).take(10);
+}
+
+#[clippy::msrv = "1.81"]
+fn msrv_1_82() {
+    std::iter::repeat(3).take(10);
+}
diff --git a/tests/ui/map_with_unused_argument_over_ranges.rs b/tests/ui/map_with_unused_argument_over_ranges.rs
new file mode 100644
index 00000000000..298eee9ca3f
--- /dev/null
+++ b/tests/ui/map_with_unused_argument_over_ranges.rs
@@ -0,0 +1,73 @@
+#![allow(
+    unused,
+    clippy::redundant_closure,
+    clippy::reversed_empty_ranges,
+    clippy::identity_op
+)]
+#![warn(clippy::map_with_unused_argument_over_ranges)]
+
+fn do_something() -> usize {
+    todo!()
+}
+
+fn do_something_interesting(x: usize, y: usize) -> usize {
+    todo!()
+}
+
+macro_rules! gen {
+    () => {
+        (0..10).map(|_| do_something());
+    };
+}
+
+fn main() {
+    // These should be raised
+    (0..10).map(|_| do_something());
+    (0..10).map(|_foo| do_something());
+    (0..=10).map(|_| do_something());
+    (3..10).map(|_| do_something());
+    (3..=10).map(|_| do_something());
+    (0..10).map(|_| 3);
+    (0..10).map(|_| {
+        let x = 3;
+        x + 2
+    });
+    (0..10).map(|_| do_something()).collect::<Vec<_>>();
+    let upper = 4;
+    (0..upper).map(|_| do_something());
+    let upper_fn = || 4;
+    (0..upper_fn()).map(|_| do_something());
+    (0..=upper_fn()).map(|_| do_something());
+    (2..upper_fn()).map(|_| do_something());
+    (2..=upper_fn()).map(|_| do_something());
+    (-3..9).map(|_| do_something());
+    (9..3).map(|_| do_something());
+    (9..=9).map(|_| do_something());
+    (1..=1 << 4).map(|_| do_something());
+    // These should not be raised
+    gen!();
+    let lower = 2;
+    let lower_fn = || 2;
+    (lower..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (lower_fn()..upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (lower_fn()..=upper_fn()).map(|_| do_something()); // Ranges not starting at zero not yet handled
+    (0..10).map(|x| do_something_interesting(x, 4)); // Actual map over range
+    "Foobar".chars().map(|_| do_something()); // Not a map over range
+    // i128::MAX == 340282366920938463463374607431768211455
+    (0..=340282366920938463463374607431768211455).map(|_: u128| do_something()); // Can't be replaced due to overflow
+}
+
+#[clippy::msrv = "1.27"]
+fn msrv_1_27() {
+    (0..10).map(|_| do_something());
+}
+
+#[clippy::msrv = "1.28"]
+fn msrv_1_28() {
+    (0..10).map(|_| do_something());
+}
+
+#[clippy::msrv = "1.81"]
+fn msrv_1_82() {
+    (0..10).map(|_| 3);
+}
diff --git a/tests/ui/map_with_unused_argument_over_ranges.stderr b/tests/ui/map_with_unused_argument_over_ranges.stderr
new file mode 100644
index 00000000000..0b56c6d9521
--- /dev/null
+++ b/tests/ui/map_with_unused_argument_over_ranges.stderr
@@ -0,0 +1,223 @@
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:25:5
+   |
+LL |     (0..10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::map-with-unused-argument-over-ranges` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::map_with_unused_argument_over_ranges)]`
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(10);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:26:5
+   |
+LL |     (0..10).map(|_foo| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..10).map(|_foo| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(10);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:27:5
+   |
+LL |     (0..=10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..=10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(11);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:28:5
+   |
+LL |     (3..10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (3..10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(7);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:29:5
+   |
+LL |     (3..=10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (3..=10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(8);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:30:5
+   |
+LL |     (0..10).map(|_| 3);
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_n`
+   |
+LL |     std::iter::repeat_n(3, 10);
+   |     ~~~~~~~~~~~~~~~~~~~ ~~~~~
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:31:5
+   |
+LL | /     (0..10).map(|_| {
+LL | |         let x = 3;
+LL | |         x + 2
+LL | |     });
+   | |______^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL ~     std::iter::repeat_with(|| {
+LL |         let x = 3;
+LL |         x + 2
+LL ~     }).take(10);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:35:5
+   |
+LL |     (0..10).map(|_| do_something()).collect::<Vec<_>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..10).map(|_| do_something()).collect::<Vec<_>>();
+LL +     std::iter::repeat_with(|| do_something()).take(10).collect::<Vec<_>>();
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:37:5
+   |
+LL |     (0..upper).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..upper).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:39:5
+   |
+LL |     (0..upper_fn()).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..upper_fn()).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper_fn());
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:40:5
+   |
+LL |     (0..=upper_fn()).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..=upper_fn()).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper_fn() + 1);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:41:5
+   |
+LL |     (2..upper_fn()).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (2..upper_fn()).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper_fn() - 2);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:42:5
+   |
+LL |     (2..=upper_fn()).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (2..=upper_fn()).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(upper_fn() - 1);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:44:5
+   |
+LL |     (9..3).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (9..3).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(0);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:45:5
+   |
+LL |     (9..=9).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (9..=9).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(1);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:46:5
+   |
+LL |     (1..=1 << 4).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (1..=1 << 4).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take((1 << 4) - 0);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:67:5
+   |
+LL |     (0..10).map(|_| do_something());
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat_with` and `take`
+   |
+LL -     (0..10).map(|_| do_something());
+LL +     std::iter::repeat_with(|| do_something()).take(10);
+   |
+
+error: map of a closure that does not depend on its parameter over a range
+  --> tests/ui/map_with_unused_argument_over_ranges.rs:72:5
+   |
+LL |     (0..10).map(|_| 3);
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+help: remove the explicit range and use `repeat` and `take`
+   |
+LL |     std::iter::repeat(3).take(10);
+   |     ~~~~~~~~~~~~~~~~~ ~ +++++++++
+
+error: aborting due to 18 previous errors
+
diff --git a/tests/ui/needless_as_bytes.fixed b/tests/ui/needless_as_bytes.fixed
new file mode 100644
index 00000000000..042342311fd
--- /dev/null
+++ b/tests/ui/needless_as_bytes.fixed
@@ -0,0 +1,50 @@
+#![warn(clippy::needless_as_bytes)]
+#![allow(clippy::const_is_empty)]
+
+struct S;
+
+impl S {
+    fn as_bytes(&self) -> &[u8] {
+        &[]
+    }
+}
+
+fn main() {
+    if "some string".is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", "some string".len());
+        //~^ needless_as_bytes
+    }
+
+    let s = String::from("yet another string");
+    if s.is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", s.len());
+        //~^ needless_as_bytes
+    }
+
+    // Do not lint
+    let _ = S.as_bytes().is_empty();
+    let _ = S.as_bytes().len();
+    let _ = (&String::new() as &dyn AsBytes).as_bytes().len();
+    macro_rules! m {
+        (1) => {
+            ""
+        };
+        (2) => {
+            "".as_bytes()
+        };
+    }
+    m!(1).as_bytes().len();
+    m!(2).len();
+}
+
+pub trait AsBytes {
+    fn as_bytes(&self) -> &[u8];
+}
+
+impl AsBytes for String {
+    fn as_bytes(&self) -> &[u8] {
+        &[]
+    }
+}
diff --git a/tests/ui/needless_as_bytes.rs b/tests/ui/needless_as_bytes.rs
new file mode 100644
index 00000000000..c481e041e0a
--- /dev/null
+++ b/tests/ui/needless_as_bytes.rs
@@ -0,0 +1,50 @@
+#![warn(clippy::needless_as_bytes)]
+#![allow(clippy::const_is_empty)]
+
+struct S;
+
+impl S {
+    fn as_bytes(&self) -> &[u8] {
+        &[]
+    }
+}
+
+fn main() {
+    if "some string".as_bytes().is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", "some string".as_bytes().len());
+        //~^ needless_as_bytes
+    }
+
+    let s = String::from("yet another string");
+    if s.as_bytes().is_empty() {
+        //~^ needless_as_bytes
+        println!("len = {}", s.as_bytes().len());
+        //~^ needless_as_bytes
+    }
+
+    // Do not lint
+    let _ = S.as_bytes().is_empty();
+    let _ = S.as_bytes().len();
+    let _ = (&String::new() as &dyn AsBytes).as_bytes().len();
+    macro_rules! m {
+        (1) => {
+            ""
+        };
+        (2) => {
+            "".as_bytes()
+        };
+    }
+    m!(1).as_bytes().len();
+    m!(2).len();
+}
+
+pub trait AsBytes {
+    fn as_bytes(&self) -> &[u8];
+}
+
+impl AsBytes for String {
+    fn as_bytes(&self) -> &[u8] {
+        &[]
+    }
+}
diff --git a/tests/ui/needless_as_bytes.stderr b/tests/ui/needless_as_bytes.stderr
new file mode 100644
index 00000000000..3391238a142
--- /dev/null
+++ b/tests/ui/needless_as_bytes.stderr
@@ -0,0 +1,29 @@
+error: needless call to `as_bytes()`
+  --> tests/ui/needless_as_bytes.rs:13:8
+   |
+LL |     if "some string".as_bytes().is_empty() {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `"some string".is_empty()`
+   |
+   = note: `-D clippy::needless-as-bytes` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::needless_as_bytes)]`
+
+error: needless call to `as_bytes()`
+  --> tests/ui/needless_as_bytes.rs:15:30
+   |
+LL |         println!("len = {}", "some string".as_bytes().len());
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `"some string".len()`
+
+error: needless call to `as_bytes()`
+  --> tests/ui/needless_as_bytes.rs:20:8
+   |
+LL |     if s.as_bytes().is_empty() {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^ help: `is_empty()` can be called directly on strings: `s.is_empty()`
+
+error: needless call to `as_bytes()`
+  --> tests/ui/needless_as_bytes.rs:22:30
+   |
+LL |         println!("len = {}", s.as_bytes().len());
+   |                              ^^^^^^^^^^^^^^^^^^ help: `len()` can be called directly on strings: `s.len()`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui/nonminimal_bool.stderr b/tests/ui/nonminimal_bool.stderr
index eafffdaf8a6..578f918f013 100644
--- a/tests/ui/nonminimal_bool.stderr
+++ b/tests/ui/nonminimal_bool.stderr
@@ -118,25 +118,25 @@ error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:161:8
    |
 LL |     if !(12 == a) {}
-   |        ^^^^^^^^^^ help: try: `12 != a`
+   |        ^^^^^^^^^^ help: try: `(12 != a)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:162:8
    |
 LL |     if !(a == 12) {}
-   |        ^^^^^^^^^^ help: try: `a != 12`
+   |        ^^^^^^^^^^ help: try: `(a != 12)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:163:8
    |
 LL |     if !(12 != a) {}
-   |        ^^^^^^^^^^ help: try: `12 == a`
+   |        ^^^^^^^^^^ help: try: `(12 == a)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:164:8
    |
 LL |     if !(a != 12) {}
-   |        ^^^^^^^^^^ help: try: `a == 12`
+   |        ^^^^^^^^^^ help: try: `(a == 12)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool.rs:168:8
diff --git a/tests/ui/nonminimal_bool_methods.fixed b/tests/ui/nonminimal_bool_methods.fixed
index a23310c1ad9..65ccaaca891 100644
--- a/tests/ui/nonminimal_bool_methods.fixed
+++ b/tests/ui/nonminimal_bool_methods.fixed
@@ -110,9 +110,33 @@ fn dont_warn_for_negated_partial_ord_comparison() {
 fn issue_12625() {
     let a = 0;
     let b = 0;
-    if (a as u64) < b {} //~ ERROR: this boolean expression can be simplified
-    if (a as u64) < b {} //~ ERROR: this boolean expression can be simplified
-    if a as u64 > b {} //~ ERROR: this boolean expression can be simplified
+    if ((a as u64) < b) {} //~ ERROR: this boolean expression can be simplified
+    if ((a as u64) < b) {} //~ ERROR: this boolean expression can be simplified
+    if (a as u64 > b) {} //~ ERROR: this boolean expression can be simplified
+}
+
+fn issue_12761() {
+    let a = 0;
+    let b = 0;
+    let c = 0;
+    if (a < b) as i32 == c {} //~ ERROR: this boolean expression can be simplified
+    if (a < b) | (a > c) {} //~ ERROR: this boolean expression can be simplified
+    let opt: Option<usize> = Some(1);
+    let res: Result<usize, usize> = Ok(1);
+    if res.is_err() as i32 == c {} //~ ERROR: this boolean expression can be simplified
+    if res.is_err() | opt.is_some() {} //~ ERROR: this boolean expression can be simplified
+
+    fn a(a: bool) -> bool {
+        (4 <= 3).b() //~ ERROR: this boolean expression can be simplified
+    }
+
+    trait B {
+        fn b(&self) -> bool {
+            true
+        }
+    }
+
+    impl B for bool {}
 }
 
 fn issue_13436() {
diff --git a/tests/ui/nonminimal_bool_methods.rs b/tests/ui/nonminimal_bool_methods.rs
index 6c844373af7..06db3a1d4a5 100644
--- a/tests/ui/nonminimal_bool_methods.rs
+++ b/tests/ui/nonminimal_bool_methods.rs
@@ -115,6 +115,30 @@ fn issue_12625() {
     if !(a as u64 <= b) {} //~ ERROR: this boolean expression can be simplified
 }
 
+fn issue_12761() {
+    let a = 0;
+    let b = 0;
+    let c = 0;
+    if !(a >= b) as i32 == c {} //~ ERROR: this boolean expression can be simplified
+    if !(a >= b) | !(a <= c) {} //~ ERROR: this boolean expression can be simplified
+    let opt: Option<usize> = Some(1);
+    let res: Result<usize, usize> = Ok(1);
+    if !res.is_ok() as i32 == c {} //~ ERROR: this boolean expression can be simplified
+    if !res.is_ok() | !opt.is_none() {} //~ ERROR: this boolean expression can be simplified
+
+    fn a(a: bool) -> bool {
+        (!(4 > 3)).b() //~ ERROR: this boolean expression can be simplified
+    }
+
+    trait B {
+        fn b(&self) -> bool {
+            true
+        }
+    }
+
+    impl B for bool {}
+}
+
 fn issue_13436() {
     fn not_zero(x: i32) -> bool {
         x != 0
diff --git a/tests/ui/nonminimal_bool_methods.stderr b/tests/ui/nonminimal_bool_methods.stderr
index 52803e828ae..66c50f9ff1e 100644
--- a/tests/ui/nonminimal_bool_methods.stderr
+++ b/tests/ui/nonminimal_bool_methods.stderr
@@ -83,127 +83,169 @@ error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool_methods.rs:113:8
    |
 LL |     if !(a as u64 >= b) {}
-   |        ^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b`
+   |        ^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool_methods.rs:114:8
    |
 LL |     if !((a as u64) >= b) {}
-   |        ^^^^^^^^^^^^^^^^^^ help: try: `(a as u64) < b`
+   |        ^^^^^^^^^^^^^^^^^^ help: try: `((a as u64) < b)`
 
 error: this boolean expression can be simplified
   --> tests/ui/nonminimal_bool_methods.rs:115:8
    |
 LL |     if !(a as u64 <= b) {}
-   |        ^^^^^^^^^^^^^^^^ help: try: `a as u64 > b`
+   |        ^^^^^^^^^^^^^^^^ help: try: `(a as u64 > b)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:131:9
+  --> tests/ui/nonminimal_bool_methods.rs:122:8
+   |
+LL |     if !(a >= b) as i32 == c {}
+   |        ^^^^^^^^^ help: try: `(a < b)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:123:8
+   |
+LL |     if !(a >= b) | !(a <= c) {}
+   |        ^^^^^^^^^ help: try: `(a < b)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:123:20
+   |
+LL |     if !(a >= b) | !(a <= c) {}
+   |                    ^^^^^^^^^ help: try: `(a > c)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:126:8
+   |
+LL |     if !res.is_ok() as i32 == c {}
+   |        ^^^^^^^^^^^^ help: try: `res.is_err()`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:127:8
+   |
+LL |     if !res.is_ok() | !opt.is_none() {}
+   |        ^^^^^^^^^^^^ help: try: `res.is_err()`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:127:23
+   |
+LL |     if !res.is_ok() | !opt.is_none() {}
+   |                       ^^^^^^^^^^^^^^ help: try: `opt.is_some()`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:130:9
+   |
+LL |         (!(4 > 3)).b()
+   |         ^^^^^^^^^^ help: try: `(4 <= 3)`
+
+error: this boolean expression can be simplified
+  --> tests/ui/nonminimal_bool_methods.rs:155:9
    |
 LL |     _ = !opt.is_some_and(|x| x < 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x >= 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:132:9
+  --> tests/ui/nonminimal_bool_methods.rs:156:9
    |
 LL |     _ = !opt.is_some_and(|x| x <= 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x > 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:133:9
+  --> tests/ui/nonminimal_bool_methods.rs:157:9
    |
 LL |     _ = !opt.is_some_and(|x| x > 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x <= 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:134:9
+  --> tests/ui/nonminimal_bool_methods.rs:158:9
    |
 LL |     _ = !opt.is_some_and(|x| x >= 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x < 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:135:9
+  --> tests/ui/nonminimal_bool_methods.rs:159:9
    |
 LL |     _ = !opt.is_some_and(|x| x == 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x != 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:136:9
+  --> tests/ui/nonminimal_bool_methods.rs:160:9
    |
 LL |     _ = !opt.is_some_and(|x| x != 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x == 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:145:9
+  --> tests/ui/nonminimal_bool_methods.rs:169:9
    |
 LL |     _ = !opt.is_none_or(|x| x < 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x >= 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:146:9
+  --> tests/ui/nonminimal_bool_methods.rs:170:9
    |
 LL |     _ = !opt.is_none_or(|x| x <= 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x > 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:147:9
+  --> tests/ui/nonminimal_bool_methods.rs:171:9
    |
 LL |     _ = !opt.is_none_or(|x| x > 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x <= 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:148:9
+  --> tests/ui/nonminimal_bool_methods.rs:172:9
    |
 LL |     _ = !opt.is_none_or(|x| x >= 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x < 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:149:9
+  --> tests/ui/nonminimal_bool_methods.rs:173:9
    |
 LL |     _ = !opt.is_none_or(|x| x == 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x != 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:150:9
+  --> tests/ui/nonminimal_bool_methods.rs:174:9
    |
 LL |     _ = !opt.is_none_or(|x| x != 1000);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x == 1000)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:157:9
+  --> tests/ui/nonminimal_bool_methods.rs:181:9
    |
 LL |     _ = !opt.is_some_and(|x| !x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:161:9
+  --> tests/ui/nonminimal_bool_methods.rs:185:9
    |
 LL |     _ = !opt.is_none_or(|x| !x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x)`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:168:9
+  --> tests/ui/nonminimal_bool_methods.rs:192:9
    |
 LL |     _ = !opt.is_some_and(|x| x.is_ok());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_err())`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:169:9
+  --> tests/ui/nonminimal_bool_methods.rs:193:9
    |
 LL |     _ = !opt.is_some_and(|x| x.is_err());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_none_or(|x| x.is_ok())`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:170:9
+  --> tests/ui/nonminimal_bool_methods.rs:194:9
    |
 LL |     _ = !opt.is_none_or(|x| x.is_ok());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_err())`
 
 error: this boolean expression can be simplified
-  --> tests/ui/nonminimal_bool_methods.rs:171:9
+  --> tests/ui/nonminimal_bool_methods.rs:195:9
    |
 LL |     _ = !opt.is_none_or(|x| x.is_err());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `opt.is_some_and(|x| x.is_ok())`
 
-error: aborting due to 34 previous errors
+error: aborting due to 41 previous errors
 
diff --git a/tests/ui/repeat_vec_with_capacity.fixed b/tests/ui/repeat_vec_with_capacity.fixed
index 2afe2f43325..f72b61b5f6c 100644
--- a/tests/ui/repeat_vec_with_capacity.fixed
+++ b/tests/ui/repeat_vec_with_capacity.fixed
@@ -1,3 +1,4 @@
+#![allow(clippy::map_with_unused_argument_over_ranges)]
 #![warn(clippy::repeat_vec_with_capacity)]
 
 fn main() {
diff --git a/tests/ui/repeat_vec_with_capacity.rs b/tests/ui/repeat_vec_with_capacity.rs
index 659f2a3953d..c0cc81f7843 100644
--- a/tests/ui/repeat_vec_with_capacity.rs
+++ b/tests/ui/repeat_vec_with_capacity.rs
@@ -1,3 +1,4 @@
+#![allow(clippy::map_with_unused_argument_over_ranges)]
 #![warn(clippy::repeat_vec_with_capacity)]
 
 fn main() {
diff --git a/tests/ui/repeat_vec_with_capacity.stderr b/tests/ui/repeat_vec_with_capacity.stderr
index cec9c6ea84a..43027c9cb89 100644
--- a/tests/ui/repeat_vec_with_capacity.stderr
+++ b/tests/ui/repeat_vec_with_capacity.stderr
@@ -1,5 +1,5 @@
 error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
-  --> tests/ui/repeat_vec_with_capacity.rs:5:9
+  --> tests/ui/repeat_vec_with_capacity.rs:6:9
    |
 LL |         vec![Vec::<()>::with_capacity(42); 123];
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL |         (0..123).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
    |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: repeating `Vec::with_capacity` using `vec![x; n]`, which does not retain capacity
-  --> tests/ui/repeat_vec_with_capacity.rs:11:9
+  --> tests/ui/repeat_vec_with_capacity.rs:12:9
    |
 LL |         vec![Vec::<()>::with_capacity(42); n];
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |         (0..n).map(|_| Vec::<()>::with_capacity(42)).collect::<Vec<_>>();
    |         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: repeating `Vec::with_capacity` using `iter::repeat`, which does not retain capacity
-  --> tests/ui/repeat_vec_with_capacity.rs:26:9
+  --> tests/ui/repeat_vec_with_capacity.rs:27:9
    |
 LL |         std::iter::repeat(Vec::<()>::with_capacity(42));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/suspicious_map.rs b/tests/ui/suspicious_map.rs
index d4247fcd926..d4a52cb110f 100644
--- a/tests/ui/suspicious_map.rs
+++ b/tests/ui/suspicious_map.rs
@@ -1,3 +1,4 @@
+#![allow(clippy::map_with_unused_argument_over_ranges)]
 #![warn(clippy::suspicious_map)]
 
 fn main() {
diff --git a/tests/ui/suspicious_map.stderr b/tests/ui/suspicious_map.stderr
index 2a5e2bf2a34..769adebaede 100644
--- a/tests/ui/suspicious_map.stderr
+++ b/tests/ui/suspicious_map.stderr
@@ -1,5 +1,5 @@
 error: this call to `map()` won't have an effect on the call to `count()`
-  --> tests/ui/suspicious_map.rs:4:13
+  --> tests/ui/suspicious_map.rs:5:13
    |
 LL |     let _ = (0..3).map(|x| x + 2).count();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     let _ = (0..3).map(|x| x + 2).count();
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_map)]`
 
 error: this call to `map()` won't have an effect on the call to `count()`
-  --> tests/ui/suspicious_map.rs:8:13
+  --> tests/ui/suspicious_map.rs:9:13
    |
 LL |     let _ = (0..3).map(f).count();
    |             ^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/unnecessary_filter_map.rs b/tests/ui/unnecessary_filter_map.rs
index 1e0d7d12965..8cf102ab0a5 100644
--- a/tests/ui/unnecessary_filter_map.rs
+++ b/tests/ui/unnecessary_filter_map.rs
@@ -1,26 +1,31 @@
+//@no-rustfix
 #![allow(dead_code)]
 
 fn main() {
     let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None });
-    //~^ ERROR: this `.filter_map` can be written more simply using `.filter`
+    //~^ ERROR: this `.filter_map` can be written more simply
     //~| NOTE: `-D clippy::unnecessary-filter-map` implied by `-D warnings`
     let _ = (0..4).filter_map(|x| {
-        //~^ ERROR: this `.filter_map` can be written more simply using `.filter`
+        //~^ ERROR: this `.filter_map` can be written more simply
         if x > 1 {
             return Some(x);
         };
         None
     });
     let _ = (0..4).filter_map(|x| match x {
-        //~^ ERROR: this `.filter_map` can be written more simply using `.filter`
+        //~^ ERROR: this `.filter_map` can be written more simply
         0 | 1 => None,
         _ => Some(x),
     });
 
     let _ = (0..4).filter_map(|x| Some(x + 1));
-    //~^ ERROR: this `.filter_map` can be written more simply using `.map`
+    //~^ ERROR: this `.filter_map` can be written more simply
 
     let _ = (0..4).filter_map(i32::checked_abs);
+
+    let _ = (0..4).filter_map(Some);
+
+    let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));
 }
 
 fn filter_map_none_changes_item_type() -> impl Iterator<Item = bool> {
diff --git a/tests/ui/unnecessary_filter_map.stderr b/tests/ui/unnecessary_filter_map.stderr
index f32d444ba9e..b21589c5f84 100644
--- a/tests/ui/unnecessary_filter_map.stderr
+++ b/tests/ui/unnecessary_filter_map.stderr
@@ -1,14 +1,14 @@
-error: this `.filter_map` can be written more simply using `.filter`
-  --> tests/ui/unnecessary_filter_map.rs:4:13
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:5:13
    |
 LL |     let _ = (0..4).filter_map(|x| if x > 1 { Some(x) } else { None });
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `filter`
    |
    = note: `-D clippy::unnecessary-filter-map` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_filter_map)]`
 
-error: this `.filter_map` can be written more simply using `.filter`
-  --> tests/ui/unnecessary_filter_map.rs:7:13
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:8:13
    |
 LL |       let _ = (0..4).filter_map(|x| {
    |  _____________^
@@ -18,10 +18,10 @@ LL | |             return Some(x);
 LL | |         };
 LL | |         None
 LL | |     });
-   | |______^
+   | |______^ help: try instead: `filter`
 
-error: this `.filter_map` can be written more simply using `.filter`
-  --> tests/ui/unnecessary_filter_map.rs:14:13
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:15:13
    |
 LL |       let _ = (0..4).filter_map(|x| match x {
    |  _____________^
@@ -29,19 +29,40 @@ LL | |
 LL | |         0 | 1 => None,
 LL | |         _ => Some(x),
 LL | |     });
-   | |______^
+   | |______^ help: try instead: `filter`
 
-error: this `.filter_map` can be written more simply using `.map`
-  --> tests/ui/unnecessary_filter_map.rs:20:13
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:21:13
    |
 LL |     let _ = (0..4).filter_map(|x| Some(x + 1));
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map`
 
-error: this `.filter_map` can be written more simply using `.filter`
-  --> tests/ui/unnecessary_filter_map.rs:160:14
+error: redundant closure
+  --> tests/ui/unnecessary_filter_map.rs:28:57
+   |
+LL |     let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));
+   |                                                         ^^^^^^^^^^^ help: replace the closure with the function itself: `Some`
+   |
+   = note: `-D clippy::redundant-closure` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
+
+error: filter_map is unnecessary
+  --> tests/ui/unnecessary_filter_map.rs:28:61
+   |
+LL |     let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));
+   |                                                             ^^^^ help: try removing the filter_map
+
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:28:13
+   |
+LL |     let _ = vec![Some(10), None].into_iter().filter_map(|x| Some(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map`
+
+error: this `.filter_map` can be written more simply
+  --> tests/ui/unnecessary_filter_map.rs:165:14
    |
 LL |     let _x = std::iter::once(1).filter_map(|n| (n > 1).then_some(n));
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `filter`
 
-error: aborting due to 5 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/tests/ui/unnecessary_find_map.rs b/tests/ui/unnecessary_find_map.rs
index 9972b68092a..c357d853248 100644
--- a/tests/ui/unnecessary_find_map.rs
+++ b/tests/ui/unnecessary_find_map.rs
@@ -1,24 +1,25 @@
+//@no-rustfix
 #![allow(dead_code)]
 
 fn main() {
     let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None });
-    //~^ ERROR: this `.find_map` can be written more simply using `.find`
+    //~^ ERROR: this `.find_map` can be written more simply
     //~| NOTE: `-D clippy::unnecessary-find-map` implied by `-D warnings`
     let _ = (0..4).find_map(|x| {
-        //~^ ERROR: this `.find_map` can be written more simply using `.find`
+        //~^ ERROR: this `.find_map` can be written more simply
         if x > 1 {
             return Some(x);
         };
         None
     });
     let _ = (0..4).find_map(|x| match x {
-        //~^ ERROR: this `.find_map` can be written more simply using `.find`
+        //~^ ERROR: this `.find_map` can be written more simply
         0 | 1 => None,
         _ => Some(x),
     });
 
     let _ = (0..4).find_map(|x| Some(x + 1));
-    //~^ ERROR: this `.find_map` can be written more simply using `.map(..).next()`
+    //~^ ERROR: this `.find_map` can be written more simply
 
     let _ = (0..4).find_map(i32::checked_abs);
 }
diff --git a/tests/ui/unnecessary_find_map.stderr b/tests/ui/unnecessary_find_map.stderr
index bb939a99214..98a6c3d164a 100644
--- a/tests/ui/unnecessary_find_map.stderr
+++ b/tests/ui/unnecessary_find_map.stderr
@@ -1,14 +1,14 @@
-error: this `.find_map` can be written more simply using `.find`
-  --> tests/ui/unnecessary_find_map.rs:4:13
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:5:13
    |
 LL |     let _ = (0..4).find_map(|x| if x > 1 { Some(x) } else { None });
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `find`
    |
    = note: `-D clippy::unnecessary-find-map` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_find_map)]`
 
-error: this `.find_map` can be written more simply using `.find`
-  --> tests/ui/unnecessary_find_map.rs:7:13
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:8:13
    |
 LL |       let _ = (0..4).find_map(|x| {
    |  _____________^
@@ -18,10 +18,10 @@ LL | |             return Some(x);
 LL | |         };
 LL | |         None
 LL | |     });
-   | |______^
+   | |______^ help: try instead: `find`
 
-error: this `.find_map` can be written more simply using `.find`
-  --> tests/ui/unnecessary_find_map.rs:14:13
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:15:13
    |
 LL |       let _ = (0..4).find_map(|x| match x {
    |  _____________^
@@ -29,19 +29,19 @@ LL | |
 LL | |         0 | 1 => None,
 LL | |         _ => Some(x),
 LL | |     });
-   | |______^
+   | |______^ help: try instead: `find`
 
-error: this `.find_map` can be written more simply using `.map(..).next()`
-  --> tests/ui/unnecessary_find_map.rs:20:13
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:21:13
    |
 LL |     let _ = (0..4).find_map(|x| Some(x + 1));
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `map(..).next()`
 
-error: this `.find_map` can be written more simply using `.find`
-  --> tests/ui/unnecessary_find_map.rs:32:14
+error: this `.find_map` can be written more simply
+  --> tests/ui/unnecessary_find_map.rs:33:14
    |
 LL |     let _x = std::iter::once(1).find_map(|n| (n > 1).then_some(n));
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try instead: `find`
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/unused_io_amount.rs b/tests/ui/unused_io_amount.rs
index f5b200d5ffe..175c4ca7689 100644
--- a/tests/ui/unused_io_amount.rs
+++ b/tests/ui/unused_io_amount.rs
@@ -277,4 +277,18 @@ fn allow_works<F: std::io::Read>(mut f: F) {
     f.read(&mut data).unwrap();
 }
 
+struct Reader {}
+
+impl Read for Reader {
+    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+        todo!()
+    }
+
+    fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
+        // We shouldn't recommend using Read::read_exact inside Read::read_exact!
+        self.read(buf).unwrap();
+        Ok(())
+    }
+}
+
 fn main() {}
diff --git a/triagebot.toml b/triagebot.toml
index cd9641eedd8..eadfd7107c7 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -21,13 +21,11 @@ new_pr = true
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
 users_on_vacation = [
     "matthiaskrgr",
-    "giraffate",
 ]
 
 [assign.owners]
 "/.github" = ["@flip1995"]
 "/book" = ["@flip1995"]
-"/util/gh-pages" = ["@xFrednet"]
 "*" = [
     "@Manishearth",
     "@llogiq",