about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2024-01-25 19:17:36 +0100
committerPhilipp Krones <hello@philkrones.com>2024-01-25 19:17:36 +0100
commit798865c593b8ad255ed1e19ee2502c8d91f16c65 (patch)
tree45a86a528d2ea8bed8b4c82f4a6d0ad108e67f5e
parent0b6cf3b78c9602798b132ea4a420ea51fe3aa795 (diff)
downloadrust-798865c593b8ad255ed1e19ee2502c8d91f16c65.tar.gz
rust-798865c593b8ad255ed1e19ee2502c8d91f16c65.zip
Merge commit '66c29b973b3b10278bd39f4e26b08522a379c2c9' into clippy-subtree-update
-rw-r--r--CHANGELOG.md2
-rw-r--r--book/src/lint_configuration.md21
-rw-r--r--clippy_config/src/conf.rs80
-rw-r--r--clippy_config/src/lib.rs1
-rw-r--r--clippy_config/src/types.rs2
-rw-r--r--clippy_dev/Cargo.toml4
-rw-r--r--clippy_dev/src/update_lints.rs3
-rw-r--r--clippy_lints/Cargo.toml2
-rw-r--r--clippy_lints/src/arc_with_non_send_sync.rs8
-rw-r--r--clippy_lints/src/blocks_in_conditions.rs5
-rw-r--r--clippy_lints/src/cargo/mod.rs6
-rw-r--r--clippy_lints/src/cargo/multiple_crate_versions.rs19
-rw-r--r--clippy_lints/src/declared_lints.rs1
-rw-r--r--clippy_lints/src/default_instead_of_iter_empty.rs13
-rw-r--r--clippy_lints/src/default_numeric_fallback.rs14
-rw-r--r--clippy_lints/src/derive.rs3
-rw-r--r--clippy_lints/src/doc/needless_doctest_main.rs4
-rw-r--r--clippy_lints/src/from_over_into.rs9
-rw-r--r--clippy_lints/src/inherent_impl.rs4
-rw-r--r--clippy_lints/src/lib.rs4
-rw-r--r--clippy_lints/src/loops/same_item_push.rs2
-rw-r--r--clippy_lints/src/mem_replace.rs15
-rw-r--r--clippy_lints/src/methods/iter_on_single_or_empty_collections.rs12
-rw-r--r--clippy_lints/src/methods/join_absolute_paths.rs2
-rw-r--r--clippy_lints/src/methods/manual_saturating_arithmetic.rs2
-rw-r--r--clippy_lints/src/methods/map_clone.rs20
-rw-r--r--clippy_lints/src/methods/mod.rs39
-rw-r--r--clippy_lints/src/methods/open_options.rs230
-rw-r--r--clippy_lints/src/methods/option_as_ref_deref.rs2
-rw-r--r--clippy_lints/src/methods/option_map_or_err_ok.rs2
-rw-r--r--clippy_lints/src/methods/option_map_or_none.rs6
-rw-r--r--clippy_lints/src/methods/result_map_or_else_none.rs2
-rw-r--r--clippy_lints/src/methods/search_is_some.rs8
-rw-r--r--clippy_lints/src/methods/single_char_pattern.rs2
-rw-r--r--clippy_lints/src/methods/unnecessary_join.rs2
-rw-r--r--clippy_lints/src/methods/unnecessary_sort_by.rs4
-rw-r--r--clippy_lints/src/methods/useless_asref.rs18
-rw-r--r--clippy_lints/src/needless_pass_by_ref_mut.rs77
-rw-r--r--clippy_lints/src/no_effect.rs179
-rw-r--r--clippy_lints/src/operators/ptr_eq.rs8
-rw-r--r--clippy_lints/src/pub_underscore_fields.rs2
-rw-r--r--clippy_lints/src/read_zero_byte_vec.rs118
-rw-r--r--clippy_lints/src/semicolon_if_nothing_returned.rs6
-rw-r--r--clippy_lints/src/single_call_fn.rs12
-rw-r--r--clippy_lints/src/trait_bounds.rs14
-rw-r--r--clippy_lints/src/transmute/transmute_int_to_char.rs5
-rw-r--r--clippy_lints/src/transmute/transmute_ref_to_ref.rs8
-rw-r--r--clippy_lints/src/unconditional_recursion.rs10
-rw-r--r--clippy_lints/src/unused_io_amount.rs292
-rw-r--r--clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs2
-rw-r--r--clippy_lints/src/utils/internal_lints/invalid_paths.rs4
-rw-r--r--clippy_utils/src/attrs.rs12
-rw-r--r--clippy_utils/src/hir_utils.rs6
-rw-r--r--clippy_utils/src/lib.rs10
-rw-r--r--clippy_utils/src/paths.rs8
-rw-r--r--clippy_utils/src/ty.rs3
-rw-r--r--rust-toolchain2
-rw-r--r--tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.stderr6
-rw-r--r--tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.toml14
-rw-r--r--tests/ui-cargo/multiple_crate_versions/12145_with_dashes/src/main.rs3
-rw-r--r--tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml10
-rw-r--r--tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml1
-rw-r--r--tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs3
-rw-r--r--tests/ui-internal/check_formulation.stderr4
-rw-r--r--tests/ui-internal/disallow_span_lint.stderr6
-rw-r--r--tests/ui-toml/pub_underscore_fields/exported/clippy.toml2
-rw-r--r--tests/ui-toml/toml_unknown_key/clippy.toml3
-rw-r--r--tests/ui-toml/toml_unknown_key/conf_unknown_key.rs1
-rw-r--r--tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr81
-rw-r--r--tests/ui/auxiliary/proc_macro_attr.rs34
-rw-r--r--tests/ui/blocks_in_conditions.fixed14
-rw-r--r--tests/ui/blocks_in_conditions.rs14
-rw-r--r--tests/ui/branches_sharing_code/shared_at_top.rs8
-rw-r--r--tests/ui/branches_sharing_code/shared_at_top.stderr6
-rw-r--r--tests/ui/branches_sharing_code/valid_if_blocks.rs12
-rw-r--r--tests/ui/branches_sharing_code/valid_if_blocks.stderr18
-rw-r--r--tests/ui/crashes/ice-9041.stderr2
-rw-r--r--tests/ui/default_instead_of_iter_empty_no_std.fixed28
-rw-r--r--tests/ui/default_instead_of_iter_empty_no_std.rs28
-rw-r--r--tests/ui/default_instead_of_iter_empty_no_std.stderr17
-rw-r--r--tests/ui/default_numeric_fallback_i32.fixed40
-rw-r--r--tests/ui/default_numeric_fallback_i32.rs40
-rw-r--r--tests/ui/derive_partial_eq_without_eq.fixed32
-rw-r--r--tests/ui/derive_partial_eq_without_eq.rs32
-rw-r--r--tests/ui/doc/doc-fixable.fixed2
-rw-r--r--tests/ui/doc/doc-fixable.rs2
-rw-r--r--tests/ui/from_over_into.fixed8
-rw-r--r--tests/ui/from_over_into.rs8
-rw-r--r--tests/ui/from_over_into.stderr16
-rw-r--r--tests/ui/if_same_then_else.rs28
-rw-r--r--tests/ui/if_same_then_else.stderr69
-rw-r--r--tests/ui/if_same_then_else2.rs18
-rw-r--r--tests/ui/if_same_then_else2.stderr37
-rw-r--r--tests/ui/ineffective_open_options.fixed9
-rw-r--r--tests/ui/ineffective_open_options.rs9
-rw-r--r--tests/ui/join_absolute_paths.stderr8
-rw-r--r--tests/ui/manual_ok_or.stderr2
-rw-r--r--tests/ui/manual_saturating_arithmetic.stderr48
-rw-r--r--tests/ui/map_clone.fixed33
-rw-r--r--tests/ui/map_clone.rs35
-rw-r--r--tests/ui/map_clone.stderr36
-rw-r--r--tests/ui/match_same_arms2.rs4
-rw-r--r--tests/ui/match_same_arms2.stderr5
-rw-r--r--tests/ui/mem_replace_no_std.fixed82
-rw-r--r--tests/ui/mem_replace_no_std.rs82
-rw-r--r--tests/ui/mem_replace_no_std.stderr50
-rw-r--r--tests/ui/no_effect.rs2
-rw-r--r--tests/ui/no_effect.stderr16
-rw-r--r--tests/ui/open_options.rs38
-rw-r--r--tests/ui/open_options.stderr34
-rw-r--r--tests/ui/open_options_fixable.fixed7
-rw-r--r--tests/ui/open_options_fixable.rs7
-rw-r--r--tests/ui/open_options_fixable.stderr14
-rw-r--r--tests/ui/option_as_ref_deref.stderr36
-rw-r--r--tests/ui/option_map_or_err_ok.stderr2
-rw-r--r--tests/ui/option_map_or_none.stderr10
-rw-r--r--tests/ui/ptr_eq_no_std.fixed49
-rw-r--r--tests/ui/ptr_eq_no_std.rs49
-rw-r--r--tests/ui/ptr_eq_no_std.stderr17
-rw-r--r--tests/ui/read_zero_byte_vec.rs29
-rw-r--r--tests/ui/read_zero_byte_vec.stderr34
-rw-r--r--tests/ui/result_map_or_into_option.stderr6
-rw-r--r--tests/ui/same_item_push.stderr10
-rw-r--r--tests/ui/search_is_some.stderr4
-rw-r--r--tests/ui/search_is_some_fixable_none.stderr86
-rw-r--r--tests/ui/search_is_some_fixable_some.stderr94
-rw-r--r--tests/ui/seek_to_start_instead_of_rewind.fixed3
-rw-r--r--tests/ui/seek_to_start_instead_of_rewind.rs3
-rw-r--r--tests/ui/seek_to_start_instead_of_rewind.stderr2
-rw-r--r--tests/ui/semicolon_if_nothing_returned.fixed34
-rw-r--r--tests/ui/semicolon_if_nothing_returned.rs34
-rw-r--r--tests/ui/semicolon_if_nothing_returned.stderr10
-rw-r--r--tests/ui/single_call_fn.rs11
-rw-r--r--tests/ui/single_char_pattern.stderr80
-rw-r--r--tests/ui/trait_duplication_in_bounds.fixed31
-rw-r--r--tests/ui/trait_duplication_in_bounds.rs31
-rw-r--r--tests/ui/transmute.rs13
-rw-r--r--tests/ui/transmute.stderr61
-rw-r--r--tests/ui/transmute_int_to_char.fixed15
-rw-r--r--tests/ui/transmute_int_to_char.rs15
-rw-r--r--tests/ui/transmute_int_to_char.stderr17
-rw-r--r--tests/ui/transmute_int_to_char_no_std.fixed27
-rw-r--r--tests/ui/transmute_int_to_char_no_std.rs27
-rw-r--r--tests/ui/transmute_int_to_char_no_std.stderr17
-rw-r--r--tests/ui/transmute_ref_to_ref.rs2
-rw-r--r--tests/ui/transmute_ref_to_ref.stderr4
-rw-r--r--tests/ui/transmute_ref_to_ref_no_std.rs30
-rw-r--r--tests/ui/transmute_ref_to_ref_no_std.stderr26
-rw-r--r--tests/ui/unconditional_recursion.rs26
-rw-r--r--tests/ui/unconditional_recursion.stderr19
-rw-r--r--tests/ui/unnecessary_join.stderr4
-rw-r--r--tests/ui/unnecessary_sort_by.stderr24
-rw-r--r--tests/ui/unused_io_amount.rs87
-rw-r--r--tests/ui/unused_io_amount.stderr141
-rw-r--r--tests/ui/useless_asref.fixed36
-rw-r--r--tests/ui/useless_asref.rs36
-rw-r--r--tests/ui/useless_asref.stderr26
-rw-r--r--triagebot.toml1
158 files changed, 2839 insertions, 999 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4d32bbec914..5fa45ceeb39 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5606,6 +5606,7 @@ Released 2018-09-13
 [`suspicious_else_formatting`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_else_formatting
 [`suspicious_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_map
 [`suspicious_op_assign_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_op_assign_impl
+[`suspicious_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_open_options
 [`suspicious_operation_groupings`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_operation_groupings
 [`suspicious_splitn`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_splitn
 [`suspicious_to_owned`]: https://rust-lang.github.io/rust-clippy/master/index.html#suspicious_to_owned
@@ -5814,6 +5815,7 @@ Released 2018-09-13
 [`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
 [`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
 [`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
+[`allowed-duplicate-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-duplicate-crates
 [`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
 [`check-private-items`]: https://doc.rust-lang.org/clippy/lint_configuration.html#check-private-items
 [`pub-underscore-fields-behavior`]: https://doc.rust-lang.org/clippy/lint_configuration.html#pub-underscore-fields-behavior
diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md
index 3b62ae0524a..7f7aff92bf1 100644
--- a/book/src/lint_configuration.md
+++ b/book/src/lint_configuration.md
@@ -212,7 +212,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", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
+**Default Value:** `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "WebAssembly", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry", "WebGL", "WebGL2", "WebGPU", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]`
 
 ---
 **Affected lints:**
@@ -768,7 +768,19 @@ Additional dotfiles (files or directories starting with a dot) to allow
 * [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
 
 
+## `allowed-duplicate-crates`
+A list of crate names to allow duplicates of
+
+**Default Value:** `[]`
+
+---
+**Affected lints:**
+* [`multiple_crate_versions`](https://rust-lang.github.io/rust-clippy/master/index.html#multiple_crate_versions)
+
+
 ## `enforce-iter-loop-reborrow`
+Whether to recommend using implicit into iter for reborrowed values.
+
 #### Example
 ```no_run
 let mut vec = vec![1, 2, 3];
@@ -793,7 +805,7 @@ for _ in &mut *rmvec {}
 
 
 ## `check-private-items`
-
+Whether to also run the listed lints on private items.
 
 **Default Value:** `false`
 
@@ -806,9 +818,10 @@ for _ in &mut *rmvec {}
 
 
 ## `pub-underscore-fields-behavior`
+Lint "public" fields in a struct that are prefixed with an underscore based on their
+exported visibility, or whether they are marked as "pub".
 
-
-**Default Value:** `"PublicallyExported"`
+**Default Value:** `"PubliclyExported"`
 
 ---
 **Affected lints:**
diff --git a/clippy_config/src/conf.rs b/clippy_config/src/conf.rs
index 5477d9b83a7..4e9ddbf8259 100644
--- a/clippy_config/src/conf.rs
+++ b/clippy_config/src/conf.rs
@@ -2,7 +2,9 @@ use crate::msrvs::Msrv;
 use crate::types::{DisallowedPath, MacroMatcher, MatchLintBehaviour, PubUnderscoreFieldsBehaviour, Rename};
 use crate::ClippyConfiguration;
 use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Applicability;
 use rustc_session::Session;
+use rustc_span::edit_distance::edit_distance;
 use rustc_span::{BytePos, Pos, SourceFile, Span, SyntaxContext};
 use serde::de::{IgnoredAny, IntoDeserializer, MapAccess, Visitor};
 use serde::{Deserialize, Deserializer, Serialize};
@@ -26,7 +28,7 @@ const DEFAULT_DOC_VALID_IDENTS: &[&str] = &[
     "NaN", "NaNs",
     "OAuth", "GraphQL",
     "OCaml",
-    "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS",
+    "OpenDNS", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenTelemetry",
     "WebGL", "WebGL2", "WebGPU",
     "TensorFlow",
     "TrueType",
@@ -59,18 +61,25 @@ impl TryConf {
 #[derive(Debug)]
 struct ConfError {
     message: String,
+    suggestion: Option<Suggestion>,
     span: Span,
 }
 
 impl ConfError {
     fn from_toml(file: &SourceFile, error: &toml::de::Error) -> Self {
         let span = error.span().unwrap_or(0..file.source_len.0 as usize);
-        Self::spanned(file, error.message(), span)
+        Self::spanned(file, error.message(), None, span)
     }
 
-    fn spanned(file: &SourceFile, message: impl Into<String>, span: Range<usize>) -> Self {
+    fn spanned(
+        file: &SourceFile,
+        message: impl Into<String>,
+        suggestion: Option<Suggestion>,
+        span: Range<usize>,
+    ) -> Self {
         Self {
             message: message.into(),
+            suggestion,
             span: Span::new(
                 file.start_pos + BytePos::from_usize(span.start),
                 file.start_pos + BytePos::from_usize(span.end),
@@ -147,16 +156,18 @@ macro_rules! define_Conf {
                     match Field::deserialize(name.get_ref().as_str().into_deserializer()) {
                         Err(e) => {
                             let e: FieldError = e;
-                            errors.push(ConfError::spanned(self.0, e.0, name.span()));
+                            errors.push(ConfError::spanned(self.0, e.error, e.suggestion, name.span()));
                         }
                         $(Ok(Field::$name) => {
-                            $(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), name.span()));)?
+                            $(warnings.push(ConfError::spanned(self.0, format!("deprecated field `{}`. {}", name.get_ref(), $dep), None, name.span()));)?
                             let raw_value = map.next_value::<toml::Spanned<toml::Value>>()?;
                             let value_span = raw_value.span();
                             match <$ty>::deserialize(raw_value.into_inner()) {
-                                Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), value_span)),
+                                Err(e) => errors.push(ConfError::spanned(self.0, e.to_string().replace('\n', " ").trim(), None, value_span)),
                                 Ok(value) => match $name {
-                                    Some(_) => errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), name.span())),
+                                    Some(_) => {
+                                        errors.push(ConfError::spanned(self.0, format!("duplicate field `{}`", name.get_ref()), None, name.span()));
+                                    }
                                     None => {
                                         $name = Some(value);
                                         // $new_conf is the same as one of the defined `$name`s, so
@@ -165,7 +176,7 @@ macro_rules! define_Conf {
                                             Some(_) => errors.push(ConfError::spanned(self.0, concat!(
                                                 "duplicate field `", stringify!($new_conf),
                                                 "` (provided as `", stringify!($name), "`)"
-                                            ), name.span())),
+                                            ), None, name.span())),
                                             None => $new_conf = $name.clone(),
                                         })?
                                     },
@@ -523,7 +534,11 @@ define_Conf! {
     ///
     /// Additional dotfiles (files or directories starting with a dot) to allow
     (allowed_dotfiles: FxHashSet<String> = FxHashSet::default()),
-    /// Lint: EXPLICIT_ITER_LOOP
+    /// Lint: MULTIPLE_CRATE_VERSIONS.
+    ///
+    /// A list of crate names to allow duplicates of
+    (allowed_duplicate_crates: FxHashSet<String> = FxHashSet::default()),
+    /// Lint: EXPLICIT_ITER_LOOP.
     ///
     /// Whether to recommend using implicit into iter for reborrowed values.
     ///
@@ -543,15 +558,15 @@ define_Conf! {
     /// for _ in &mut *rmvec {}
     /// ```
     (enforce_iter_loop_reborrow: bool = false),
-    /// Lint: MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC, MISSING_PANICS_DOC, MISSING_ERRORS_DOC
+    /// Lint: MISSING_SAFETY_DOC, UNNECESSARY_SAFETY_DOC, MISSING_PANICS_DOC, MISSING_ERRORS_DOC.
     ///
     /// Whether to also run the listed lints on private items.
     (check_private_items: bool = false),
-    /// Lint: PUB_UNDERSCORE_FIELDS
+    /// Lint: PUB_UNDERSCORE_FIELDS.
     ///
     /// Lint "public" fields in a struct that are prefixed with an underscore based on their
     /// exported visibility, or whether they are marked as "pub".
-    (pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PublicallyExported),
+    (pub_underscore_fields_behavior: PubUnderscoreFieldsBehaviour = PubUnderscoreFieldsBehaviour::PubliclyExported),
 }
 
 /// Search for the configuration file.
@@ -669,10 +684,16 @@ impl Conf {
 
         // all conf errors are non-fatal, we just use the default conf in case of error
         for error in errors {
-            sess.dcx().span_err(
+            let mut diag = sess.dcx().struct_span_err(
                 error.span,
                 format!("error reading Clippy's configuration file: {}", error.message),
             );
+
+            if let Some(sugg) = error.suggestion {
+                diag.span_suggestion(error.span, sugg.message, sugg.suggestion, Applicability::MaybeIncorrect);
+            }
+
+            diag.emit();
         }
 
         for warning in warnings {
@@ -689,19 +710,31 @@ impl Conf {
 const SEPARATOR_WIDTH: usize = 4;
 
 #[derive(Debug)]
-struct FieldError(String);
+struct FieldError {
+    error: String,
+    suggestion: Option<Suggestion>,
+}
+
+#[derive(Debug)]
+struct Suggestion {
+    message: &'static str,
+    suggestion: &'static str,
+}
 
 impl std::error::Error for FieldError {}
 
 impl Display for FieldError {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        f.pad(&self.0)
+        f.pad(&self.error)
     }
 }
 
 impl serde::de::Error for FieldError {
     fn custom<T: Display>(msg: T) -> Self {
-        Self(msg.to_string())
+        Self {
+            error: msg.to_string(),
+            suggestion: None,
+        }
     }
 
     fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
@@ -723,7 +756,20 @@ impl serde::de::Error for FieldError {
                 write!(msg, "{:SEPARATOR_WIDTH$}{field:column_width$}", " ").unwrap();
             }
         }
-        Self(msg)
+
+        let suggestion = expected
+            .iter()
+            .filter_map(|expected| {
+                let dist = edit_distance(field, expected, 4)?;
+                Some((dist, expected))
+            })
+            .min_by_key(|&(dist, _)| dist)
+            .map(|(_, suggestion)| Suggestion {
+                message: "perhaps you meant",
+                suggestion,
+            });
+
+        Self { error: msg, suggestion }
     }
 }
 
diff --git a/clippy_config/src/lib.rs b/clippy_config/src/lib.rs
index f5dcb16d670..533e375a310 100644
--- a/clippy_config/src/lib.rs
+++ b/clippy_config/src/lib.rs
@@ -11,6 +11,7 @@ extern crate rustc_ast;
 extern crate rustc_data_structures;
 #[allow(unused_extern_crates)]
 extern crate rustc_driver;
+extern crate rustc_errors;
 extern crate rustc_session;
 extern crate rustc_span;
 
diff --git a/clippy_config/src/types.rs b/clippy_config/src/types.rs
index baee09629ac..435aa9244c5 100644
--- a/clippy_config/src/types.rs
+++ b/clippy_config/src/types.rs
@@ -129,6 +129,6 @@ unimplemented_serialize! {
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Deserialize, Serialize)]
 pub enum PubUnderscoreFieldsBehaviour {
-    PublicallyExported,
+    PubliclyExported,
     AllPubFields,
 }
diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml
index ce738e3f4ec..5ec67554e7d 100644
--- a/clippy_dev/Cargo.toml
+++ b/clippy_dev/Cargo.toml
@@ -4,11 +4,11 @@ version = "0.0.1"
 edition = "2021"
 
 [dependencies]
-aho-corasick = "0.7"
+aho-corasick = "1.0"
 clap = "4.1.4"
 indoc = "1.0"
 itertools = "0.11"
-opener = "0.5"
+opener = "0.6"
 shell-escape = "0.1"
 walkdir = "2.3"
 
diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs
index 6b76a44debf..9a357466923 100644
--- a/clippy_dev/src/update_lints.rs
+++ b/clippy_dev/src/update_lints.rs
@@ -504,9 +504,8 @@ fn replace_ident_like(contents: &str, replacements: &[(&str, &str)]) -> Option<S
     }
 
     let searcher = AhoCorasickBuilder::new()
-        .dfa(true)
         .match_kind(aho_corasick::MatchKind::LeftmostLongest)
-        .build_with_size::<u16, _, _>(replacements.iter().map(|&(x, _)| x.as_bytes()))
+        .build(replacements.iter().map(|&(x, _)| x.as_bytes()))
         .unwrap();
 
     let mut result = String::with_capacity(contents.len() + 1024);
diff --git a/clippy_lints/Cargo.toml b/clippy_lints/Cargo.toml
index 8cba35f3d87..416e9a680dd 100644
--- a/clippy_lints/Cargo.toml
+++ b/clippy_lints/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2021"
 
 [dependencies]
 arrayvec = { version = "0.7", default-features = false }
-cargo_metadata = "0.15.3"
+cargo_metadata = "0.18"
 clippy_config = { path = "../clippy_config" }
 clippy_utils = { path = "../clippy_utils" }
 declare_clippy_lint = { path = "../declare_clippy_lint" }
diff --git a/clippy_lints/src/arc_with_non_send_sync.rs b/clippy_lints/src/arc_with_non_send_sync.rs
index 657d52d0e9e..1102c7fb236 100644
--- a/clippy_lints/src/arc_with_non_send_sync.rs
+++ b/clippy_lints/src/arc_with_non_send_sync.rs
@@ -14,10 +14,10 @@ declare_clippy_lint! {
     /// This lint warns when you use `Arc` with a type that does not implement `Send` or `Sync`.
     ///
     /// ### Why is this bad?
-    /// `Arc<T>` is an Atomic `RC<T>` and guarantees that updates to the reference counter are
-    /// Atomic. This is useful in multiprocessing scenarios. To send an `Arc<T>` across processes
-    /// and make use of the atomic ref counter, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-Send-for-Arc%3CT%3E),
-    /// either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
+    /// `Arc<T>` is a thread-safe `Rc<T>` and guarantees that updates to the reference counter
+    /// use atomic operations. To send an `Arc<T>` across thread boundaries and
+    /// share ownership between multiple threads, `T` must be [both `Send` and `Sync`](https://doc.rust-lang.org/std/sync/struct.Arc.html#thread-safety),
+    /// so either `T` should be made `Send + Sync` or an `Rc` should be used instead of an `Arc`
     ///
     /// ### Example
     /// ```no_run
diff --git a/clippy_lints/src/blocks_in_conditions.rs b/clippy_lints/src/blocks_in_conditions.rs
index 1417e230aee..ff4dffd0607 100644
--- a/clippy_lints/src/blocks_in_conditions.rs
+++ b/clippy_lints/src/blocks_in_conditions.rs
@@ -67,6 +67,11 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
         );
 
         if let ExprKind::Block(block, _) = &cond.kind {
+            if !block.span.eq_ctxt(expr.span) {
+                // If the block comes from a macro, or as an argument to a macro,
+                // do not lint.
+                return;
+            }
             if block.rules == BlockCheckMode::DefaultBlock {
                 if block.stmts.is_empty() {
                     if let Some(ex) = &block.expr {
diff --git a/clippy_lints/src/cargo/mod.rs b/clippy_lints/src/cargo/mod.rs
index fea6924d89e..d8107f61f37 100644
--- a/clippy_lints/src/cargo/mod.rs
+++ b/clippy_lints/src/cargo/mod.rs
@@ -6,6 +6,7 @@ mod wildcard_dependencies;
 use cargo_metadata::MetadataCommand;
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::is_lint_allowed;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_lint::{LateContext, LateLintPass, Lint};
 use rustc_session::impl_lint_pass;
@@ -128,6 +129,8 @@ declare_clippy_lint! {
     /// ### Known problems
     /// Because this can be caused purely by the dependencies
     /// themselves, it's not always possible to fix this issue.
+    /// In those cases, you can allow that specific crate using
+    /// the `allowed_duplicate_crates` configuration option.
     ///
     /// ### Example
     /// ```toml
@@ -163,6 +166,7 @@ declare_clippy_lint! {
 }
 
 pub struct Cargo {
+    pub allowed_duplicate_crates: FxHashSet<String>,
     pub ignore_publish: bool,
 }
 
@@ -208,7 +212,7 @@ impl LateLintPass<'_> for Cargo {
         {
             match MetadataCommand::new().exec() {
                 Ok(metadata) => {
-                    multiple_crate_versions::check(cx, &metadata);
+                    multiple_crate_versions::check(cx, &metadata, &self.allowed_duplicate_crates);
                 },
                 Err(e) => {
                     for lint in WITH_DEPS_LINTS {
diff --git a/clippy_lints/src/cargo/multiple_crate_versions.rs b/clippy_lints/src/cargo/multiple_crate_versions.rs
index ec681adb7ae..3f30a77fcfe 100644
--- a/clippy_lints/src/cargo/multiple_crate_versions.rs
+++ b/clippy_lints/src/cargo/multiple_crate_versions.rs
@@ -3,27 +3,40 @@
 use cargo_metadata::{DependencyKind, Metadata, Node, Package, PackageId};
 use clippy_utils::diagnostics::span_lint;
 use itertools::Itertools;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_lint::LateContext;
 use rustc_span::DUMMY_SP;
 
 use super::MULTIPLE_CRATE_VERSIONS;
 
-pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata) {
+pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, allowed_duplicate_crates: &FxHashSet<String>) {
     let local_name = cx.tcx.crate_name(LOCAL_CRATE);
     let mut packages = metadata.packages.clone();
     packages.sort_by(|a, b| a.name.cmp(&b.name));
 
     if let Some(resolve) = &metadata.resolve
         && let Some(local_id) = packages.iter().find_map(|p| {
-            if p.name == local_name.as_str() {
+            // p.name contains the original crate names with dashes intact
+            // local_name contains the crate name as a namespace, with the dashes converted to underscores
+            // the code below temporarily rectifies this discrepancy
+            if p.name
+                .as_bytes()
+                .iter()
+                .map(|b| if b == &b'-' { &b'_' } else { b })
+                .eq(local_name.as_str().as_bytes())
+            {
                 Some(&p.id)
             } else {
                 None
             }
         })
     {
-        for (name, group) in &packages.iter().group_by(|p| p.name.clone()) {
+        for (name, group) in &packages
+            .iter()
+            .filter(|p| !allowed_duplicate_crates.contains(&p.name))
+            .group_by(|p| &p.name)
+        {
             let group: Vec<&Package> = group.collect();
 
             if group.len() <= 1 {
diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs
index 20230106d53..639edd8da30 100644
--- a/clippy_lints/src/declared_lints.rs
+++ b/clippy_lints/src/declared_lints.rs
@@ -439,6 +439,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::methods::STR_SPLIT_AT_NEWLINE_INFO,
     crate::methods::SUSPICIOUS_COMMAND_ARG_SPACE_INFO,
     crate::methods::SUSPICIOUS_MAP_INFO,
+    crate::methods::SUSPICIOUS_OPEN_OPTIONS_INFO,
     crate::methods::SUSPICIOUS_SPLITN_INFO,
     crate::methods::SUSPICIOUS_TO_OWNED_INFO,
     crate::methods::TYPE_ID_ON_BOX_INFO,
diff --git a/clippy_lints/src/default_instead_of_iter_empty.rs b/clippy_lints/src/default_instead_of_iter_empty.rs
index 2472e2ee76f..e617c19eff0 100644
--- a/clippy_lints/src/default_instead_of_iter_empty.rs
+++ b/clippy_lints/src/default_instead_of_iter_empty.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::last_path_segment;
 use clippy_utils::source::snippet_with_context;
+use clippy_utils::{last_path_segment, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::{def, Expr, ExprKind, GenericArg, QPath, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -42,12 +42,14 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty {
             && ty.span.ctxt() == ctxt
         {
             let mut applicability = Applicability::MachineApplicable;
-            let sugg = make_sugg(cx, ty_path, ctxt, &mut applicability);
+            let Some(path) = std_or_core(cx) else { return };
+            let path = format!("{path}::iter::empty");
+            let sugg = make_sugg(cx, ty_path, ctxt, &mut applicability, &path);
             span_lint_and_sugg(
                 cx,
                 DEFAULT_INSTEAD_OF_ITER_EMPTY,
                 expr.span,
-                "`std::iter::empty()` is the more idiomatic way",
+                &format!("`{path}()` is the more idiomatic way"),
                 "try",
                 sugg,
                 applicability,
@@ -61,6 +63,7 @@ fn make_sugg(
     ty_path: &rustc_hir::QPath<'_>,
     ctxt: SyntaxContext,
     applicability: &mut Applicability,
+    path: &str,
 ) -> String {
     if let Some(last) = last_path_segment(ty_path).args
         && let Some(iter_ty) = last.args.iter().find_map(|arg| match arg {
@@ -69,10 +72,10 @@ fn make_sugg(
         })
     {
         format!(
-            "std::iter::empty::<{}>()",
+            "{path}::<{}>()",
             snippet_with_context(cx, iter_ty.span, ctxt, "..", applicability).0
         )
     } else {
-        "std::iter::empty()".to_owned()
+        format!("{path}()")
     }
 }
diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs
index 712bc075650..c4437a3c4b3 100644
--- a/clippy_lints/src/default_numeric_fallback.rs
+++ b/clippy_lints/src/default_numeric_fallback.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_hir_and_then;
+use clippy_utils::numeric_literal;
 use clippy_utils::source::snippet_opt;
-use clippy_utils::{get_parent_node, numeric_literal};
 use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, walk_stmt, Visitor};
-use rustc_hir::{Block, Body, Expr, ExprKind, FnRetTy, HirId, ItemKind, Lit, Node, Stmt, StmtKind};
+use rustc_hir::{Block, Body, ConstContext, Expr, ExprKind, FnRetTy, HirId, Lit, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, FloatTy, IntTy, PolyFnSig, Ty};
@@ -50,11 +50,11 @@ declare_lint_pass!(DefaultNumericFallback => [DEFAULT_NUMERIC_FALLBACK]);
 
 impl<'tcx> LateLintPass<'tcx> for DefaultNumericFallback {
     fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
-        let is_parent_const = if let Some(Node::Item(item)) = get_parent_node(cx.tcx, body.id().hir_id) {
-            matches!(item.kind, ItemKind::Const(..))
-        } else {
-            false
-        };
+        let hir = cx.tcx.hir();
+        let is_parent_const = matches!(
+            hir.body_const_context(hir.body_owner_def_id(body.id())),
+            Some(ConstContext::Const { inline: false } | ConstContext::Static(_))
+        );
         let mut visitor = NumericFallbackVisitor::new(cx, is_parent_const);
         visitor.visit_body(body);
     }
diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs
index df596338b95..6144ec7b3ca 100644
--- a/clippy_lints/src/derive.rs
+++ b/clippy_lints/src/derive.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_note, span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::ty::{implements_trait, implements_trait_with_env, is_copy};
-use clippy_utils::{is_lint_allowed, match_def_path, paths};
+use clippy_utils::{has_non_exhaustive_attr, is_lint_allowed, match_def_path, paths};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
@@ -450,6 +450,7 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r
         && let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq)
         && let Some(def_id) = trait_ref.trait_def_id()
         && cx.tcx.is_diagnostic_item(sym::PartialEq, def_id)
+        && !has_non_exhaustive_attr(cx.tcx, *adt)
         && let param_env = param_env_for_derived_eq(cx.tcx, adt.did(), eq_trait_def_id)
         && !implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, None, &[])
         // If all of our fields implement `Eq`, we can implement `Eq` too
diff --git a/clippy_lints/src/doc/needless_doctest_main.rs b/clippy_lints/src/doc/needless_doctest_main.rs
index 8b018220c17..8dde4f227ed 100644
--- a/clippy_lints/src/doc/needless_doctest_main.rs
+++ b/clippy_lints/src/doc/needless_doctest_main.rs
@@ -6,7 +6,7 @@ use clippy_utils::diagnostics::span_lint;
 use rustc_ast::{CoroutineKind, Fn, FnRetTy, Item, ItemKind};
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::emitter::HumanEmitter;
-use rustc_errors::DiagCtxt;
+use rustc_errors::{DiagCtxt, DiagnosticBuilder};
 use rustc_lint::LateContext;
 use rustc_parse::maybe_new_parser_from_source_str;
 use rustc_parse::parser::ForceCollect;
@@ -53,7 +53,7 @@ pub fn check(
                 let mut parser = match maybe_new_parser_from_source_str(&sess, filename, code) {
                     Ok(p) => p,
                     Err(errs) => {
-                        errs.into_iter().for_each(|err| err.cancel());
+                        errs.into_iter().for_each(DiagnosticBuilder::cancel);
                         return (false, test_attr_spans);
                     },
                 };
diff --git a/clippy_lints/src/from_over_into.rs b/clippy_lints/src/from_over_into.rs
index fa1f98ba013..93527bcdf5c 100644
--- a/clippy_lints/src/from_over_into.rs
+++ b/clippy_lints/src/from_over_into.rs
@@ -6,8 +6,8 @@ use clippy_utils::source::snippet_opt;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_path, Visitor};
 use rustc_hir::{
-    GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path, PathSegment, Ty,
-    TyKind,
+    FnRetTy, GenericArg, GenericArgs, HirId, Impl, ImplItemKind, ImplItemRef, Item, ItemKind, PatKind, Path,
+    PathSegment, Ty, TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter::OnlyBodies;
@@ -181,6 +181,9 @@ fn convert_to_from(
     let from = snippet_opt(cx, self_ty.span)?;
     let into = snippet_opt(cx, target_ty.span)?;
 
+    let return_type = matches!(sig.decl.output, FnRetTy::Return(_))
+        .then_some(String::from("Self"))
+        .unwrap_or_default();
     let mut suggestions = vec![
         // impl Into<T> for U  ->  impl From<T> for U
         //      ~~~~                    ~~~~
@@ -199,7 +202,7 @@ fn convert_to_from(
         (self_ident.span, format!("val: {from}")),
         // fn into(self) -> T  ->  fn into(self) -> Self
         //                  ~                       ~~~~
-        (sig.decl.output.span(), String::from("Self")),
+        (sig.decl.output.span(), return_type),
     ];
 
     let mut finder = SelfFinder {
diff --git a/clippy_lints/src/inherent_impl.rs b/clippy_lints/src/inherent_impl.rs
index fb7b82ec304..1127f00abde 100644
--- a/clippy_lints/src/inherent_impl.rs
+++ b/clippy_lints/src/inherent_impl.rs
@@ -53,7 +53,9 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl {
         // List of spans to lint. (lint_span, first_span)
         let mut lint_spans = Vec::new();
 
-        let Ok(impls) = cx.tcx.crate_inherent_impls(()) else { return };
+        let Ok(impls) = cx.tcx.crate_inherent_impls(()) else {
+            return;
+        };
         let inherent_impls = cx
             .tcx
             .with_stable_hashing_context(|hcx| impls.inherent_impls.to_sorted(&hcx, true));
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index efdd3925949..feb4d188f39 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -574,6 +574,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
         warn_on_all_wildcard_imports,
         check_private_items,
         pub_underscore_fields_behavior,
+        ref allowed_duplicate_crates,
 
         blacklisted_names: _,
         cyclomatic_complexity_threshold: _,
@@ -719,7 +720,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(|_| Box::new(needless_update::NeedlessUpdate));
     store.register_late_pass(|_| Box::new(needless_borrowed_ref::NeedlessBorrowedRef));
     store.register_late_pass(|_| Box::new(borrow_deref_ref::BorrowDerefRef));
-    store.register_late_pass(|_| Box::new(no_effect::NoEffect));
+    store.register_late_pass(|_| Box::<no_effect::NoEffect>::default());
     store.register_late_pass(|_| Box::new(temporary_assignment::TemporaryAssignment));
     store.register_late_pass(move |_| Box::new(transmute::Transmute::new(msrv())));
     store.register_late_pass(move |_| {
@@ -947,6 +948,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
     store.register_late_pass(move |_| {
         Box::new(cargo::Cargo {
             ignore_publish: cargo_ignore_publish,
+            allowed_duplicate_crates: allowed_duplicate_crates.clone(),
         })
     });
     store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef));
diff --git a/clippy_lints/src/loops/same_item_push.rs b/clippy_lints/src/loops/same_item_push.rs
index c245eaf1ab4..920a887a6fd 100644
--- a/clippy_lints/src/loops/same_item_push.rs
+++ b/clippy_lints/src/loops/same_item_push.rs
@@ -31,7 +31,7 @@ pub(super) fn check<'tcx>(
             vec.span,
             "it looks like the same item is being pushed into this Vec",
             None,
-            &format!("try using vec![{item_str};SIZE] or {vec_str}.resize(NEW_SIZE, {item_str})"),
+            &format!("consider using vec![{item_str};SIZE] or {vec_str}.resize(NEW_SIZE, {item_str})"),
         );
     }
 
diff --git a/clippy_lints/src/mem_replace.rs b/clippy_lints/src/mem_replace.rs
index c22f76484d0..fa4f4a47e38 100644
--- a/clippy_lints/src/mem_replace.rs
+++ b/clippy_lints/src/mem_replace.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_sugg, span_lin
 use clippy_utils::source::{snippet, snippet_with_applicability};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_non_aggregate_primitive_type;
-use clippy_utils::{is_default_equivalent, is_res_lang_ctor, path_res, peel_ref_operators};
+use clippy_utils::{is_default_equivalent, is_res_lang_ctor, path_res, peel_ref_operators, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::OptionNone;
 use rustc_hir::{Expr, ExprKind};
@@ -128,6 +128,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
         // check if replacement is mem::MaybeUninit::uninit().assume_init()
         && cx.tcx.is_diagnostic_item(sym::assume_init, method_def_id)
     {
+        let Some(top_crate) = std_or_core(cx) else { return };
         let mut applicability = Applicability::MachineApplicable;
         span_lint_and_sugg(
             cx,
@@ -136,7 +137,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
             "replacing with `mem::MaybeUninit::uninit().assume_init()`",
             "consider using",
             format!(
-                "std::ptr::read({})",
+                "{top_crate}::ptr::read({})",
                 snippet_with_applicability(cx, dest.span, "", &mut applicability)
             ),
             applicability,
@@ -149,6 +150,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
         && let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id()
     {
         if cx.tcx.is_diagnostic_item(sym::mem_uninitialized, repl_def_id) {
+            let Some(top_crate) = std_or_core(cx) else { return };
             let mut applicability = Applicability::MachineApplicable;
             span_lint_and_sugg(
                 cx,
@@ -157,7 +159,7 @@ fn check_replace_with_uninit(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<'
                 "replacing with `mem::uninitialized()`",
                 "consider using",
                 format!(
-                    "std::ptr::read({})",
+                    "{top_crate}::ptr::read({})",
                     snippet_with_applicability(cx, dest.span, "", &mut applicability)
                 ),
                 applicability,
@@ -184,14 +186,17 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
         return;
     }
     if is_default_equivalent(cx, src) && !in_external_macro(cx.tcx.sess, expr_span) {
+        let Some(top_crate) = std_or_core(cx) else { return };
         span_lint_and_then(
             cx,
             MEM_REPLACE_WITH_DEFAULT,
             expr_span,
-            "replacing a value of type `T` with `T::default()` is better expressed using `std::mem::take`",
+            &format!(
+                "replacing a value of type `T` with `T::default()` is better expressed using `{top_crate}::mem::take`"
+            ),
             |diag| {
                 if !expr_span.from_expansion() {
-                    let suggestion = format!("std::mem::take({})", snippet(cx, dest.span, ""));
+                    let suggestion = format!("{top_crate}::mem::take({})", snippet(cx, dest.span, ""));
 
                     diag.span_suggestion(
                         expr_span,
diff --git a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
index 70abe4891d9..4c7c56e7174 100644
--- a/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
+++ b/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
-use clippy_utils::{get_expr_use_or_unification_node, is_no_std_crate, is_res_lang_ctor, path_res};
+use clippy_utils::{get_expr_use_or_unification_node, is_res_lang_ctor, path_res, std_or_core};
 
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::{OptionNone, OptionSome};
@@ -58,10 +58,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
         return;
     }
 
+    let Some(top_crate) = std_or_core(cx) else { return };
     if let Some(i) = item {
         let sugg = format!(
-            "{}::iter::once({}{})",
-            if is_no_std_crate(cx) { "core" } else { "std" },
+            "{top_crate}::iter::once({}{})",
             iter_type.ref_prefix(),
             snippet(cx, i.span, "...")
         );
@@ -81,11 +81,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
             expr.span,
             &format!("`{method_name}` call on an empty collection"),
             "try",
-            if is_no_std_crate(cx) {
-                "core::iter::empty()".to_string()
-            } else {
-                "std::iter::empty()".to_string()
-            },
+            format!("{top_crate}::iter::empty()"),
             Applicability::MaybeIncorrect,
         );
     }
diff --git a/clippy_lints/src/methods/join_absolute_paths.rs b/clippy_lints/src/methods/join_absolute_paths.rs
index 02f28779cf6..aa1ec60d434 100644
--- a/clippy_lints/src/methods/join_absolute_paths.rs
+++ b/clippy_lints/src/methods/join_absolute_paths.rs
@@ -42,7 +42,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx Expr<'tcx>, join_a
                     )
                     .span_suggestion(
                         expr_span,
-                        "if this is intentional, try using `Path::new` instead",
+                        "if this is intentional, consider using `Path::new`",
                         format!("PathBuf::from({arg_str})"),
                         Applicability::Unspecified,
                     );
diff --git a/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/clippy_lints/src/methods/manual_saturating_arithmetic.rs
index 04bdbc1ea25..bf437db7e72 100644
--- a/clippy_lints/src/methods/manual_saturating_arithmetic.rs
+++ b/clippy_lints/src/methods/manual_saturating_arithmetic.rs
@@ -50,7 +50,7 @@ pub fn check(
         super::MANUAL_SATURATING_ARITHMETIC,
         expr.span,
         "manual saturating arithmetic",
-        &format!("try using `saturating_{arith}`"),
+        &format!("consider using `saturating_{arith}`"),
         format!(
             "{}.saturating_{arith}({})",
             snippet_with_applicability(cx, arith_lhs.span, "..", &mut applicability),
diff --git a/clippy_lints/src/methods/map_clone.rs b/clippy_lints/src/methods/map_clone.rs
index f9f636bbbf7..27e17b43b01 100644
--- a/clippy_lints/src/methods/map_clone.rs
+++ b/clippy_lints/src/methods/map_clone.rs
@@ -113,9 +113,15 @@ fn handle_path(
     if let Some(path_def_id) = cx.qpath_res(qpath, arg.hir_id).opt_def_id()
         && match_def_path(cx, path_def_id, &paths::CLONE_TRAIT_METHOD)
     {
-        // FIXME: It would be better to infer the type to check if it's copyable or not
-        // to suggest to use `.copied()` instead of `.cloned()` where applicable.
-        lint_path(cx, e.span, recv.span);
+        // The `copied` and `cloned` methods are only available on `&T` and `&mut T` in `Option`
+        // and `Result`.
+        if let ty::Adt(_, args) = cx.typeck_results().expr_ty(recv).kind()
+            && let args = args.as_slice()
+            && let Some(ty) = args.iter().find_map(|generic_arg| generic_arg.as_type())
+            && ty.is_ref()
+        {
+            lint_path(cx, e.span, recv.span, is_copy(cx, ty.peel_refs()));
+        }
     }
 }
 
@@ -139,17 +145,19 @@ fn lint_needless_cloning(cx: &LateContext<'_>, root: Span, receiver: Span) {
     );
 }
 
-fn lint_path(cx: &LateContext<'_>, replace: Span, root: Span) {
+fn lint_path(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool) {
     let mut applicability = Applicability::MachineApplicable;
 
+    let replacement = if is_copy { "copied" } else { "cloned" };
+
     span_lint_and_sugg(
         cx,
         MAP_CLONE,
         replace,
         "you are explicitly cloning with `.map()`",
-        "consider calling the dedicated `cloned` method",
+        &format!("consider calling the dedicated `{replacement}` method"),
         format!(
-            "{}.cloned()",
+            "{}.{replacement}()",
             snippet_with_applicability(cx, root, "..", &mut applicability),
         ),
         applicability,
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 89ea3597dc0..03bcf108914 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -2829,6 +2829,44 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
+    /// Checks for the suspicious use of `OpenOptions::create()`
+    /// without an explicit `OpenOptions::truncate()`.
+    ///
+    /// ### Why is this bad?
+    /// `create()` alone will either create a new file or open an
+    /// existing file. If the file already exists, it will be
+    /// overwritten when written to, but the file will not be
+    /// truncated by default.
+    /// If less data is written to the file
+    /// than it already contains, the remainder of the file will
+    /// remain unchanged, and the end of the file will contain old
+    /// data.
+    /// In most cases, one should either use `create_new` to ensure
+    /// the file is created from scratch, or ensure `truncate` is
+    /// called so that the truncation behaviour is explicit. `truncate(true)`
+    /// will ensure the file is entirely overwritten with new data, whereas
+    /// `truncate(false)` will explicitely keep the default behavior.
+    ///
+    /// ### Example
+    /// ```rust,no_run
+    /// use std::fs::OpenOptions;
+    ///
+    /// OpenOptions::new().create(true);
+    /// ```
+    /// Use instead:
+    /// ```rust,no_run
+    /// use std::fs::OpenOptions;
+    ///
+    /// OpenOptions::new().create(true).truncate(true);
+    /// ```
+    #[clippy::version = "1.75.0"]
+    pub SUSPICIOUS_OPEN_OPTIONS,
+    suspicious,
+    "suspicious combination of options for opening a file"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
     ///* Checks for [push](https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.push)
     /// calls on `PathBuf` that can cause overwrites.
     ///
@@ -4033,6 +4071,7 @@ impl_lint_pass!(Methods => [
     MAP_ERR_IGNORE,
     MUT_MUTEX_LOCK,
     NONSENSICAL_OPEN_OPTIONS,
+    SUSPICIOUS_OPEN_OPTIONS,
     PATH_BUF_PUSH_OVERWRITE,
     RANGE_ZIP_WITH_LEN,
     REPEAT_ONCE,
diff --git a/clippy_lints/src/methods/open_options.rs b/clippy_lints/src/methods/open_options.rs
index 65c986dcacc..77484ab91a9 100644
--- a/clippy_lints/src/methods/open_options.rs
+++ b/clippy_lints/src/methods/open_options.rs
@@ -1,46 +1,74 @@
-use clippy_utils::diagnostics::span_lint;
-use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_data_structures::fx::FxHashMap;
+
+use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
+use clippy_utils::ty::{is_type_diagnostic_item, match_type};
+use clippy_utils::{match_any_def_paths, paths};
 use rustc_ast::ast::LitKind;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
+use rustc_middle::ty::Ty;
 use rustc_span::source_map::Spanned;
 use rustc_span::{sym, Span};
 
-use super::NONSENSICAL_OPEN_OPTIONS;
+use super::{NONSENSICAL_OPEN_OPTIONS, SUSPICIOUS_OPEN_OPTIONS};
+
+fn is_open_options(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
+    is_type_diagnostic_item(cx, ty, sym::FsOpenOptions) || match_type(cx, ty, &paths::TOKIO_IO_OPEN_OPTIONS)
+}
 
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) {
     if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
         && let Some(impl_id) = cx.tcx.impl_of_method(method_id)
-        && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::FsOpenOptions)
+        && is_open_options(cx, cx.tcx.type_of(impl_id).instantiate_identity())
     {
         let mut options = Vec::new();
-        get_open_options(cx, recv, &mut options);
-        check_open_options(cx, &options, e.span);
+        if get_open_options(cx, recv, &mut options) {
+            check_open_options(cx, &options, e.span);
+        }
     }
 }
 
-#[derive(Debug, PartialEq, Eq, Clone, Copy)]
+#[derive(Eq, PartialEq, Clone, Debug)]
 enum Argument {
-    True,
-    False,
+    Set(bool),
     Unknown,
 }
 
-#[derive(Debug)]
+#[derive(Debug, Eq, PartialEq, Hash, Clone)]
 enum OpenOption {
-    Write,
+    Append,
+    Create,
+    CreateNew,
     Read,
     Truncate,
-    Create,
-    Append,
+    Write,
+}
+impl std::fmt::Display for OpenOption {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            OpenOption::Append => write!(f, "append"),
+            OpenOption::Create => write!(f, "create"),
+            OpenOption::CreateNew => write!(f, "create_new"),
+            OpenOption::Read => write!(f, "read"),
+            OpenOption::Truncate => write!(f, "truncate"),
+            OpenOption::Write => write!(f, "write"),
+        }
+    }
 }
 
-fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec<(OpenOption, Argument)>) {
-    if let ExprKind::MethodCall(path, receiver, arguments, _) = argument.kind {
+/// Collects information about a method call chain on `OpenOptions`.
+/// Returns false if an unexpected expression kind was found "on the way",
+/// and linting should then be avoided.
+fn get_open_options(
+    cx: &LateContext<'_>,
+    argument: &Expr<'_>,
+    options: &mut Vec<(OpenOption, Argument, Span)>,
+) -> bool {
+    if let ExprKind::MethodCall(path, receiver, arguments, span) = argument.kind {
         let obj_ty = cx.typeck_results().expr_ty(receiver).peel_refs();
 
         // Only proceed if this is a call on some object of type std::fs::OpenOptions
-        if is_type_diagnostic_item(cx, obj_ty, sym::FsOpenOptions) && !arguments.is_empty() {
+        if !arguments.is_empty() && is_open_options(cx, obj_ty) {
             let argument_option = match arguments[0].kind {
                 ExprKind::Lit(span) => {
                     if let Spanned {
@@ -48,11 +76,12 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec
                         ..
                     } = span
                     {
-                        if *lit { Argument::True } else { Argument::False }
+                        Argument::Set(*lit)
                     } else {
                         // The function is called with a literal which is not a boolean literal.
                         // This is theoretically possible, but not very likely.
-                        return;
+                        // We'll ignore it for now
+                        return get_open_options(cx, receiver, options);
                     }
                 },
                 _ => Argument::Unknown,
@@ -60,106 +89,77 @@ fn get_open_options(cx: &LateContext<'_>, argument: &Expr<'_>, options: &mut Vec
 
             match path.ident.as_str() {
                 "create" => {
-                    options.push((OpenOption::Create, argument_option));
+                    options.push((OpenOption::Create, argument_option, span));
+                },
+                "create_new" => {
+                    options.push((OpenOption::CreateNew, argument_option, span));
                 },
                 "append" => {
-                    options.push((OpenOption::Append, argument_option));
+                    options.push((OpenOption::Append, argument_option, span));
                 },
                 "truncate" => {
-                    options.push((OpenOption::Truncate, argument_option));
+                    options.push((OpenOption::Truncate, argument_option, span));
                 },
                 "read" => {
-                    options.push((OpenOption::Read, argument_option));
+                    options.push((OpenOption::Read, argument_option, span));
                 },
                 "write" => {
-                    options.push((OpenOption::Write, argument_option));
+                    options.push((OpenOption::Write, argument_option, span));
+                },
+                _ => {
+                    // Avoid linting altogether if this method is from a trait.
+                    // This might be a user defined extension trait with a method like `truncate_write`
+                    // which would be a false positive
+                    if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(argument.hir_id)
+                        && cx.tcx.trait_of_item(method_def_id).is_some()
+                    {
+                        return false;
+                    }
                 },
-                _ => (),
             }
 
-            get_open_options(cx, receiver, options);
+            get_open_options(cx, receiver, options)
+        } else {
+            false
         }
+    } else if let ExprKind::Call(callee, _) = argument.kind
+        && let ExprKind::Path(path) = callee.kind
+        && let Some(did) = cx.qpath_res(&path, callee.hir_id).opt_def_id()
+    {
+        match_any_def_paths(
+            cx,
+            did,
+            &[
+                &paths::TOKIO_IO_OPEN_OPTIONS_NEW,
+                &paths::OPEN_OPTIONS_NEW,
+                &paths::FILE_OPTIONS,
+                &paths::TOKIO_FILE_OPTIONS,
+            ],
+        )
+        .is_some()
+    } else {
+        false
     }
 }
 
-fn check_open_options(cx: &LateContext<'_>, options: &[(OpenOption, Argument)], span: Span) {
-    let (mut create, mut append, mut truncate, mut read, mut write) = (false, false, false, false, false);
-    let (mut create_arg, mut append_arg, mut truncate_arg, mut read_arg, mut write_arg) =
-        (false, false, false, false, false);
-    // This code is almost duplicated (oh, the irony), but I haven't found a way to
-    // unify it.
-
-    for option in options {
-        match *option {
-            (OpenOption::Create, arg) => {
-                if create {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `create` is called more than once",
-                    );
-                } else {
-                    create = true;
-                }
-                create_arg = create_arg || (arg == Argument::True);
-            },
-            (OpenOption::Append, arg) => {
-                if append {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `append` is called more than once",
-                    );
-                } else {
-                    append = true;
-                }
-                append_arg = append_arg || (arg == Argument::True);
-            },
-            (OpenOption::Truncate, arg) => {
-                if truncate {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `truncate` is called more than once",
-                    );
-                } else {
-                    truncate = true;
-                }
-                truncate_arg = truncate_arg || (arg == Argument::True);
-            },
-            (OpenOption::Read, arg) => {
-                if read {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `read` is called more than once",
-                    );
-                } else {
-                    read = true;
-                }
-                read_arg = read_arg || (arg == Argument::True);
-            },
-            (OpenOption::Write, arg) => {
-                if write {
-                    span_lint(
-                        cx,
-                        NONSENSICAL_OPEN_OPTIONS,
-                        span,
-                        "the method `write` is called more than once",
-                    );
-                } else {
-                    write = true;
-                }
-                write_arg = write_arg || (arg == Argument::True);
-            },
+fn check_open_options(cx: &LateContext<'_>, settings: &[(OpenOption, Argument, Span)], span: Span) {
+    // The args passed to these methods, if they have been called
+    let mut options = FxHashMap::default();
+    for (option, arg, sp) in settings {
+        if let Some((_, prev_span)) = options.insert(option.clone(), (arg.clone(), *sp)) {
+            span_lint(
+                cx,
+                NONSENSICAL_OPEN_OPTIONS,
+                prev_span,
+                &format!("the method `{}` is called more than once", &option),
+            );
         }
     }
 
-    if read && truncate && read_arg && truncate_arg && !(write && write_arg) {
+    if let Some((Argument::Set(true), _)) = options.get(&OpenOption::Read)
+        && let Some((Argument::Set(true), _)) = options.get(&OpenOption::Truncate)
+        && let None | Some((Argument::Set(false), _)) = options.get(&OpenOption::Write)
+    {
         span_lint(
             cx,
             NONSENSICAL_OPEN_OPTIONS,
@@ -167,7 +167,10 @@ fn check_open_options(cx: &LateContext<'_>, options: &[(OpenOption, Argument)],
             "file opened with `truncate` and `read`",
         );
     }
-    if append && truncate && append_arg && truncate_arg {
+
+    if let Some((Argument::Set(true), _)) = options.get(&OpenOption::Append)
+        && let Some((Argument::Set(true), _)) = options.get(&OpenOption::Truncate)
+    {
         span_lint(
             cx,
             NONSENSICAL_OPEN_OPTIONS,
@@ -175,4 +178,29 @@ fn check_open_options(cx: &LateContext<'_>, options: &[(OpenOption, Argument)],
             "file opened with `append` and `truncate`",
         );
     }
+
+    if let Some((Argument::Set(true), create_span)) = options.get(&OpenOption::Create)
+        && let None = options.get(&OpenOption::Truncate)
+        && let None | Some((Argument::Set(false), _)) = options.get(&OpenOption::Append)
+    {
+        span_lint_and_then(
+            cx,
+            SUSPICIOUS_OPEN_OPTIONS,
+            *create_span,
+            "file opened with `create`, but `truncate` behavior not defined",
+            |diag| {
+                diag.span_suggestion(
+                    create_span.shrink_to_hi(),
+                    "add",
+                    ".truncate(true)".to_string(),
+                    rustc_errors::Applicability::MaybeIncorrect,
+                )
+                .help("if you intend to overwrite an existing file entirely, call `.truncate(true)`")
+                .help(
+                    "if you instead know that you may want to keep some parts of the old file, call `.truncate(false)`",
+                )
+                .help("alternatively, use `.append(true)` to append to the file instead of overwriting it");
+            },
+        );
+    }
 }
diff --git a/clippy_lints/src/methods/option_as_ref_deref.rs b/clippy_lints/src/methods/option_as_ref_deref.rs
index 756dbe62d84..88e2af15658 100644
--- a/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -97,7 +97,7 @@ pub(super) fn check(
         };
         let method_hint = if is_mut { "as_deref_mut" } else { "as_deref" };
         let hint = format!("{}.{method_hint}()", snippet(cx, as_ref_recv.span, ".."));
-        let suggestion = format!("try using {method_hint} instead");
+        let suggestion = format!("consider using {method_hint}");
 
         let msg = format!("called `{current_method}` on an `Option` value");
         span_lint_and_sugg(
diff --git a/clippy_lints/src/methods/option_map_or_err_ok.rs b/clippy_lints/src/methods/option_map_or_err_ok.rs
index 91e39d5a1cd..4e424d4c066 100644
--- a/clippy_lints/src/methods/option_map_or_err_ok.rs
+++ b/clippy_lints/src/methods/option_map_or_err_ok.rs
@@ -33,7 +33,7 @@ pub(super) fn check<'tcx>(
             OPTION_MAP_OR_ERR_OK,
             expr.span,
             msg,
-            "try using `ok_or` instead",
+            "consider using `ok_or`",
             format!("{self_snippet}.ok_or({err_snippet})"),
             Applicability::MachineApplicable,
         );
diff --git a/clippy_lints/src/methods/option_map_or_none.rs b/clippy_lints/src/methods/option_map_or_none.rs
index ff4d8cc9e3e..193deafccf6 100644
--- a/clippy_lints/src/methods/option_map_or_none.rs
+++ b/clippy_lints/src/methods/option_map_or_none.rs
@@ -72,7 +72,7 @@ pub(super) fn check<'tcx>(
                 OPTION_MAP_OR_NONE,
                 expr.span,
                 msg,
-                "try using `map` instead",
+                "consider using `map`",
                 format!("{self_snippet}.map({arg_snippet} {func_snippet})"),
                 Applicability::MachineApplicable,
             );
@@ -85,7 +85,7 @@ pub(super) fn check<'tcx>(
             OPTION_MAP_OR_NONE,
             expr.span,
             msg,
-            "try using `and_then` instead",
+            "consider using `and_then`",
             format!("{self_snippet}.and_then({func_snippet})"),
             Applicability::MachineApplicable,
         );
@@ -97,7 +97,7 @@ pub(super) fn check<'tcx>(
             RESULT_MAP_OR_INTO_OPTION,
             expr.span,
             msg,
-            "try using `ok` instead",
+            "consider using `ok`",
             format!("{self_snippet}.ok()"),
             Applicability::MachineApplicable,
         );
diff --git a/clippy_lints/src/methods/result_map_or_else_none.rs b/clippy_lints/src/methods/result_map_or_else_none.rs
index bc16a112816..3b0dc506305 100644
--- a/clippy_lints/src/methods/result_map_or_else_none.rs
+++ b/clippy_lints/src/methods/result_map_or_else_none.rs
@@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(
             RESULT_MAP_OR_INTO_OPTION,
             expr.span,
             msg,
-            "try using `ok` instead",
+            "consider using `ok`",
             format!("{self_snippet}.ok()"),
             Applicability::MachineApplicable,
         );
diff --git a/clippy_lints/src/methods/search_is_some.rs b/clippy_lints/src/methods/search_is_some.rs
index 6339011c92f..ef1baa6c988 100644
--- a/clippy_lints/src/methods/search_is_some.rs
+++ b/clippy_lints/src/methods/search_is_some.rs
@@ -63,7 +63,7 @@ pub(super) fn check<'tcx>(
                     SEARCH_IS_SOME,
                     method_span.with_hi(expr.span.hi()),
                     &msg,
-                    "use `any()` instead",
+                    "consider using",
                     format!(
                         "any({})",
                         any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)
@@ -77,7 +77,7 @@ pub(super) fn check<'tcx>(
                     SEARCH_IS_SOME,
                     expr.span,
                     &msg,
-                    "use `!_.any()` instead",
+                    "consider using",
                     format!(
                         "!{iter}.any({})",
                         any_search_snippet.as_ref().map_or(&*search_snippet, String::as_str)
@@ -118,7 +118,7 @@ pub(super) fn check<'tcx>(
                         SEARCH_IS_SOME,
                         method_span.with_hi(expr.span.hi()),
                         &msg,
-                        "use `contains()` instead",
+                        "consider using",
                         format!("contains({find_arg})"),
                         applicability,
                     );
@@ -132,7 +132,7 @@ pub(super) fn check<'tcx>(
                         SEARCH_IS_SOME,
                         expr.span,
                         &msg,
-                        "use `!_.contains()` instead",
+                        "consider using",
                         format!("!{string}.contains({find_arg})"),
                         applicability,
                     );
diff --git a/clippy_lints/src/methods/single_char_pattern.rs b/clippy_lints/src/methods/single_char_pattern.rs
index 3983f0c0cab..363b1f2b812 100644
--- a/clippy_lints/src/methods/single_char_pattern.rs
+++ b/clippy_lints/src/methods/single_char_pattern.rs
@@ -57,7 +57,7 @@ pub(super) fn check(
                 SINGLE_CHAR_PATTERN,
                 arg.span,
                 "single-character string constant used as pattern",
-                "try using a `char` instead",
+                "consider using a `char`",
                 hint,
                 applicability,
             );
diff --git a/clippy_lints/src/methods/unnecessary_join.rs b/clippy_lints/src/methods/unnecessary_join.rs
index e2b389e96da..c3ad4db3875 100644
--- a/clippy_lints/src/methods/unnecessary_join.rs
+++ b/clippy_lints/src/methods/unnecessary_join.rs
@@ -32,7 +32,7 @@ pub(super) fn check<'tcx>(
             UNNECESSARY_JOIN,
             span.with_hi(expr.span.hi()),
             r#"called `.collect::<Vec<String>>().join("")` on an iterator"#,
-            "try using",
+            "consider using",
             "collect::<String>()".to_owned(),
             applicability,
         );
diff --git a/clippy_lints/src/methods/unnecessary_sort_by.rs b/clippy_lints/src/methods/unnecessary_sort_by.rs
index 696e5e74d60..6911da69b94 100644
--- a/clippy_lints/src/methods/unnecessary_sort_by.rs
+++ b/clippy_lints/src/methods/unnecessary_sort_by.rs
@@ -203,7 +203,7 @@ pub(super) fn check<'tcx>(
             cx,
             UNNECESSARY_SORT_BY,
             expr.span,
-            "use Vec::sort_by_key here instead",
+            "consider using `sort_by_key`",
             "try",
             format!(
                 "{}.sort{}_by_key(|{}| {})",
@@ -226,7 +226,7 @@ pub(super) fn check<'tcx>(
             cx,
             UNNECESSARY_SORT_BY,
             expr.span,
-            "use Vec::sort here instead",
+            "consider using `sort`",
             "try",
             format!(
                 "{}.sort{}()",
diff --git a/clippy_lints/src/methods/useless_asref.rs b/clippy_lints/src/methods/useless_asref.rs
index 66727e5a29d..514015af045 100644
--- a/clippy_lints/src/methods/useless_asref.rs
+++ b/clippy_lints/src/methods/useless_asref.rs
@@ -1,7 +1,9 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::walk_ptrs_ty_depth;
-use clippy_utils::{get_parent_expr, is_diag_trait_item, match_def_path, paths, peel_blocks};
+use clippy_utils::{
+    get_parent_expr, is_diag_trait_item, match_def_path, path_to_local_id, paths, peel_blocks, strip_pat_refs,
+};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -108,9 +110,12 @@ fn check_qpath(cx: &LateContext<'_>, qpath: hir::QPath<'_>, hir_id: hir::HirId)
 
 fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
     match arg.kind {
-        hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
+        hir::ExprKind::Closure(&hir::Closure { body, .. })
             // If it's a closure, we need to check what is called.
-            let closure_body = cx.tcx.hir().body(body);
+            if let closure_body = cx.tcx.hir().body(body)
+                && let [param] = closure_body.params
+                && let hir::PatKind::Binding(_, local_id, ..) = strip_pat_refs(param.pat).kind =>
+        {
             let closure_expr = peel_blocks(closure_body.value);
             match closure_expr.kind {
                 hir::ExprKind::MethodCall(method, obj, [], _) => {
@@ -122,14 +127,17 @@ fn is_calling_clone(cx: &LateContext<'_>, arg: &hir::Expr<'_>) -> bool {
                         // no autoderefs
                         && !cx.typeck_results().expr_adjustments(obj).iter()
                             .any(|a| matches!(a.kind, Adjust::Deref(Some(..))))
+                        && path_to_local_id(obj, local_id)
                     {
                         true
                     } else {
                         false
                     }
                 },
-                hir::ExprKind::Call(call, [_]) => {
-                    if let hir::ExprKind::Path(qpath) = call.kind {
+                hir::ExprKind::Call(call, [recv]) => {
+                    if let hir::ExprKind::Path(qpath) = call.kind
+                        && path_to_local_id(recv, local_id)
+                    {
                         check_qpath(cx, qpath, call.hir_id)
                     } else {
                         false
diff --git a/clippy_lints/src/needless_pass_by_ref_mut.rs b/clippy_lints/src/needless_pass_by_ref_mut.rs
index 64ef709e2fa..d2eef6ae433 100644
--- a/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -5,16 +5,15 @@ use clippy_utils::visitors::for_each_expr_with_closures;
 use clippy_utils::{get_parent_node, inherits_cfg, is_from_proc_macro, is_self};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_errors::Applicability;
-use rustc_hir::intravisit::{walk_qpath, FnKind, Visitor};
+use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
     BlockCheckMode, Body, Closure, Expr, ExprKind, FnDecl, HirId, HirIdMap, HirIdSet, Impl, ItemKind, Mutability, Node,
-    PatKind, QPath,
+    PatKind,
 };
 use rustc_hir_typeck::expr_use_visitor as euv;
 use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::map::associated_body;
-use rustc_middle::hir::nested_filter::OnlyBodies;
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::ty::{self, Ty, TyCtxt, UpvarId, UpvarPath};
 use rustc_session::impl_lint_pass;
@@ -234,12 +233,29 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
         }
     }
 
-    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
-        cx.tcx.hir().visit_all_item_likes_in_crate(&mut FnNeedsMutVisitor {
-            cx,
-            used_fn_def_ids: &mut self.used_fn_def_ids,
-        });
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        // #11182; do not lint if mutability is required elsewhere
+        if let ExprKind::Path(..) = expr.kind
+            && let Some(parent) = get_parent_node(cx.tcx, expr.hir_id)
+            && let ty::FnDef(def_id, _) = cx.typeck_results().expr_ty(expr).kind()
+            && let Some(def_id) = def_id.as_local()
+        {
+            if let Node::Expr(e) = parent
+                && let ExprKind::Call(call, _) = e.kind
+                && call.hir_id == expr.hir_id
+            {
+                return;
+            }
 
+            // We don't need to check each argument individually as you cannot coerce a function
+            // taking `&mut` -> `&`, for some reason, so if we've gotten this far we know it's
+            // passed as a `fn`-like argument (or is unified) and should ignore every "unused"
+            // argument entirely
+            self.used_fn_def_ids.insert(def_id);
+        }
+    }
+
+    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
         for (fn_def_id, unused) in self
             .fn_def_ids_to_maybe_unused_mut
             .iter()
@@ -501,48 +517,3 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> {
         }
     }
 }
-
-/// A final pass to check for paths referencing this function that require the argument to be
-/// `&mut`, basically if the function is ever used as a `fn`-like argument.
-struct FnNeedsMutVisitor<'a, 'tcx> {
-    cx: &'a LateContext<'tcx>,
-    used_fn_def_ids: &'a mut FxHashSet<LocalDefId>,
-}
-
-impl<'tcx> Visitor<'tcx> for FnNeedsMutVisitor<'_, 'tcx> {
-    type NestedFilter = OnlyBodies;
-
-    fn nested_visit_map(&mut self) -> Self::Map {
-        self.cx.tcx.hir()
-    }
-
-    fn visit_qpath(&mut self, qpath: &'tcx QPath<'tcx>, hir_id: HirId, _: Span) {
-        walk_qpath(self, qpath, hir_id);
-
-        let Self { cx, used_fn_def_ids } = self;
-
-        // #11182; do not lint if mutability is required elsewhere
-        if let Node::Expr(expr) = cx.tcx.hir_node(hir_id)
-            && let Some(parent) = get_parent_node(cx.tcx, expr.hir_id)
-            && let ty::FnDef(def_id, _) = cx
-                .tcx
-                .typeck(cx.tcx.hir().enclosing_body_owner(hir_id))
-                .expr_ty(expr)
-                .kind()
-            && let Some(def_id) = def_id.as_local()
-        {
-            if let Node::Expr(e) = parent
-                && let ExprKind::Call(call, _) = e.kind
-                && call.hir_id == expr.hir_id
-            {
-                return;
-            }
-
-            // We don't need to check each argument individually as you cannot coerce a function
-            // taking `&mut` -> `&`, for some reason, so if we've gotten this far we know it's
-            // passed as a `fn`-like argument (or is unified) and should ignore every "unused"
-            // argument entirely
-            used_fn_def_ids.insert(def_id);
-        }
-    }
-}
diff --git a/clippy_lints/src/no_effect.rs b/clippy_lints/src/no_effect.rs
index 6bbe427ea29..0d234f7f9b5 100644
--- a/clippy_lints/src/no_effect.rs
+++ b/clippy_lints/src/no_effect.rs
@@ -1,16 +1,18 @@
 use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::has_drop;
-use clippy_utils::{get_parent_node, is_lint_allowed, peel_blocks};
+use clippy_utils::{any_parent_is_automatically_derived, get_parent_node, is_lint_allowed, path_to_local, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
-    is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, ItemKind, Node, PatKind, Stmt, StmtKind, UnsafeSource,
+    is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, HirId, HirIdMap, ItemKind, Node, PatKind, Stmt,
+    StmtKind, UnsafeSource,
 };
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_session::declare_lint_pass;
+use rustc_session::impl_lint_pass;
+use rustc_span::Span;
 use std::ops::Deref;
 
 declare_clippy_lint! {
@@ -74,94 +76,125 @@ declare_clippy_lint! {
     "outer expressions with no effect"
 }
 
-declare_lint_pass!(NoEffect => [NO_EFFECT, UNNECESSARY_OPERATION, NO_EFFECT_UNDERSCORE_BINDING]);
+#[derive(Default)]
+pub struct NoEffect {
+    underscore_bindings: HirIdMap<Span>,
+    local_bindings: Vec<Vec<HirId>>,
+}
+
+impl_lint_pass!(NoEffect => [NO_EFFECT, UNNECESSARY_OPERATION, NO_EFFECT_UNDERSCORE_BINDING]);
 
 impl<'tcx> LateLintPass<'tcx> for NoEffect {
     fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
-        if check_no_effect(cx, stmt) {
+        if self.check_no_effect(cx, stmt) {
             return;
         }
         check_unnecessary_operation(cx, stmt);
     }
-}
 
-fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
-    if let StmtKind::Semi(expr) = stmt.kind {
-        // move `expr.span.from_expansion()` ahead
-        if expr.span.from_expansion() {
-            return false;
+    fn check_block(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Block<'tcx>) {
+        self.local_bindings.push(Vec::default());
+    }
+
+    fn check_block_post(&mut self, cx: &LateContext<'tcx>, _: &'tcx rustc_hir::Block<'tcx>) {
+        for hir_id in self.local_bindings.pop().unwrap() {
+            if let Some(span) = self.underscore_bindings.remove(&hir_id) {
+                span_lint_hir(
+                    cx,
+                    NO_EFFECT_UNDERSCORE_BINDING,
+                    hir_id,
+                    span,
+                    "binding to `_` prefixed variable with no side-effect",
+                );
+            }
         }
-        let expr = peel_blocks(expr);
+    }
 
-        if is_operator_overridden(cx, expr) {
-            // Return `true`, to prevent `check_unnecessary_operation` from
-            // linting on this statement as well.
-            return true;
+    fn check_expr(&mut self, _: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+        if let Some(def_id) = path_to_local(expr) {
+            self.underscore_bindings.remove(&def_id);
         }
-        if has_no_effect(cx, expr) {
-            span_lint_hir_and_then(
-                cx,
-                NO_EFFECT,
-                expr.hir_id,
-                stmt.span,
-                "statement with no effect",
-                |diag| {
-                    for parent in cx.tcx.hir().parent_iter(stmt.hir_id) {
-                        if let Node::Item(item) = parent.1
-                            && let ItemKind::Fn(..) = item.kind
-                            && let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id)
-                            && let [.., final_stmt] = block.stmts
-                            && final_stmt.hir_id == stmt.hir_id
-                        {
-                            let expr_ty = cx.typeck_results().expr_ty(expr);
-                            let mut ret_ty = cx
-                                .tcx
-                                .fn_sig(item.owner_id)
-                                .instantiate_identity()
-                                .output()
-                                .skip_binder();
+    }
+}
+
+impl NoEffect {
+    fn check_no_effect(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
+        if let StmtKind::Semi(expr) = stmt.kind {
+            // move `expr.span.from_expansion()` ahead
+            if expr.span.from_expansion() {
+                return false;
+            }
+            let expr = peel_blocks(expr);
 
-                            // Remove `impl Future<Output = T>` to get `T`
-                            if cx.tcx.ty_is_opaque_future(ret_ty)
-                                && let Some(true_ret_ty) = cx.tcx.infer_ctxt().build().get_impl_future_output_ty(ret_ty)
+            if is_operator_overridden(cx, expr) {
+                // Return `true`, to prevent `check_unnecessary_operation` from
+                // linting on this statement as well.
+                return true;
+            }
+            if has_no_effect(cx, expr) {
+                span_lint_hir_and_then(
+                    cx,
+                    NO_EFFECT,
+                    expr.hir_id,
+                    stmt.span,
+                    "statement with no effect",
+                    |diag| {
+                        for parent in cx.tcx.hir().parent_iter(stmt.hir_id) {
+                            if let Node::Item(item) = parent.1
+                                && let ItemKind::Fn(..) = item.kind
+                                && let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id)
+                                && let [.., final_stmt] = block.stmts
+                                && final_stmt.hir_id == stmt.hir_id
                             {
-                                ret_ty = true_ret_ty;
-                            }
+                                let expr_ty = cx.typeck_results().expr_ty(expr);
+                                let mut ret_ty = cx
+                                    .tcx
+                                    .fn_sig(item.owner_id)
+                                    .instantiate_identity()
+                                    .output()
+                                    .skip_binder();
+
+                                // Remove `impl Future<Output = T>` to get `T`
+                                if cx.tcx.ty_is_opaque_future(ret_ty)
+                                    && let Some(true_ret_ty) =
+                                        cx.tcx.infer_ctxt().build().get_impl_future_output_ty(ret_ty)
+                                {
+                                    ret_ty = true_ret_ty;
+                                }
 
-                            if !ret_ty.is_unit() && ret_ty == expr_ty {
-                                diag.span_suggestion(
-                                    stmt.span.shrink_to_lo(),
-                                    "did you mean to return it?",
-                                    "return ",
-                                    Applicability::MaybeIncorrect,
-                                );
+                                if !ret_ty.is_unit() && ret_ty == expr_ty {
+                                    diag.span_suggestion(
+                                        stmt.span.shrink_to_lo(),
+                                        "did you mean to return it?",
+                                        "return ",
+                                        Applicability::MaybeIncorrect,
+                                    );
+                                }
                             }
                         }
-                    }
-                },
-            );
-            return true;
-        }
-    } else if let StmtKind::Local(local) = stmt.kind {
-        if !is_lint_allowed(cx, NO_EFFECT_UNDERSCORE_BINDING, local.hir_id)
-            && let Some(init) = local.init
-            && local.els.is_none()
-            && !local.pat.span.from_expansion()
-            && has_no_effect(cx, init)
-            && let PatKind::Binding(_, _, ident, _) = local.pat.kind
-            && ident.name.to_ident_string().starts_with('_')
-        {
-            span_lint_hir(
-                cx,
-                NO_EFFECT_UNDERSCORE_BINDING,
-                init.hir_id,
-                stmt.span,
-                "binding to `_` prefixed variable with no side-effect",
-            );
-            return true;
+                    },
+                );
+                return true;
+            }
+        } else if let StmtKind::Local(local) = stmt.kind {
+            if !is_lint_allowed(cx, NO_EFFECT_UNDERSCORE_BINDING, local.hir_id)
+                && let Some(init) = local.init
+                && local.els.is_none()
+                && !local.pat.span.from_expansion()
+                && has_no_effect(cx, init)
+                && let PatKind::Binding(_, hir_id, ident, _) = local.pat.kind
+                && ident.name.to_ident_string().starts_with('_')
+                && !any_parent_is_automatically_derived(cx.tcx, local.hir_id)
+            {
+                if let Some(l) = self.local_bindings.last_mut() {
+                    l.push(hir_id);
+                    self.underscore_bindings.insert(hir_id, ident.span);
+                }
+                return true;
+            }
         }
+        false
     }
-    false
 }
 
 fn is_operator_overridden(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
diff --git a/clippy_lints/src/operators/ptr_eq.rs b/clippy_lints/src/operators/ptr_eq.rs
index 9db2e24630a..a69989e400b 100644
--- a/clippy_lints/src/operators/ptr_eq.rs
+++ b/clippy_lints/src/operators/ptr_eq.rs
@@ -1,13 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_opt;
+use clippy_utils::std_or_core;
 use rustc_errors::Applicability;
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 
 use super::PTR_EQ;
 
-static LINT_MSG: &str = "use `std::ptr::eq` when comparing raw pointers";
-
 pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
     expr: &'tcx Expr<'_>,
@@ -26,13 +25,14 @@ pub(super) fn check<'tcx>(
             && let Some(left_snip) = snippet_opt(cx, left_var.span)
             && let Some(right_snip) = snippet_opt(cx, right_var.span)
         {
+            let Some(top_crate) = std_or_core(cx) else { return };
             span_lint_and_sugg(
                 cx,
                 PTR_EQ,
                 expr.span,
-                LINT_MSG,
+                &format!("use `{top_crate}::ptr::eq` when comparing raw pointers"),
                 "try",
-                format!("std::ptr::eq({left_snip}, {right_snip})"),
+                format!("{top_crate}::ptr::eq({left_snip}, {right_snip})"),
                 Applicability::MachineApplicable,
             );
         }
diff --git a/clippy_lints/src/pub_underscore_fields.rs b/clippy_lints/src/pub_underscore_fields.rs
index 00465ce4381..88b5a6cfe2a 100644
--- a/clippy_lints/src/pub_underscore_fields.rs
+++ b/clippy_lints/src/pub_underscore_fields.rs
@@ -54,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for PubUnderscoreFields {
         };
 
         let is_visible = |field: &FieldDef<'_>| match self.behavior {
-            PubUnderscoreFieldsBehaviour::PublicallyExported => cx.effective_visibilities.is_reachable(field.def_id),
+            PubUnderscoreFieldsBehaviour::PubliclyExported => cx.effective_visibilities.is_reachable(field.def_id),
             PubUnderscoreFieldsBehaviour::AllPubFields => {
                 // If there is a visibility span then the field is marked pub in some way.
                 !field.vis_span.is_empty()
diff --git a/clippy_lints/src/read_zero_byte_vec.rs b/clippy_lints/src/read_zero_byte_vec.rs
index 62f3c09aa7e..650324d4249 100644
--- a/clippy_lints/src/read_zero_byte_vec.rs
+++ b/clippy_lints/src/read_zero_byte_vec.rs
@@ -1,11 +1,13 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
+use clippy_utils::get_enclosing_block;
 use clippy_utils::higher::{get_vec_init_kind, VecInitKind};
 use clippy_utils::source::snippet;
-use clippy_utils::visitors::for_each_expr;
-use core::ops::ControlFlow;
-use hir::{Expr, ExprKind, Local, PatKind, PathSegment, QPath, StmtKind};
+
+use hir::{Expr, ExprKind, HirId, Local, PatKind, PathSegment, QPath, StmtKind};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
+use rustc_hir::def::Res;
+use rustc_hir::intravisit::{walk_expr, Visitor};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 
@@ -49,57 +51,40 @@ declare_lint_pass!(ReadZeroByteVec => [READ_ZERO_BYTE_VEC]);
 
 impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &hir::Block<'tcx>) {
-        for (idx, stmt) in block.stmts.iter().enumerate() {
-            if !stmt.span.from_expansion()
-                // matches `let v = Vec::new();`
-                && let StmtKind::Local(local) = stmt.kind
-                && let Local { pat, init: Some(init), .. } = local
-                && let PatKind::Binding(_, _, ident, _) = pat.kind
+        for stmt in block.stmts {
+            if stmt.span.from_expansion() {
+                return;
+            }
+
+            if let StmtKind::Local(local) = stmt.kind
+                && let Local {
+                    pat, init: Some(init), ..
+                } = local
+                && let PatKind::Binding(_, id, ident, _) = pat.kind
                 && let Some(vec_init_kind) = get_vec_init_kind(cx, init)
             {
-                let visitor = |expr: &Expr<'_>| {
-                    if let ExprKind::MethodCall(path, _, [arg], _) = expr.kind
-                        && let PathSegment {
-                            ident: read_or_read_exact,
-                            ..
-                        } = *path
-                        && matches!(read_or_read_exact.as_str(), "read" | "read_exact")
-                        && let ExprKind::AddrOf(_, hir::Mutability::Mut, inner) = arg.kind
-                        && let ExprKind::Path(QPath::Resolved(None, inner_path)) = inner.kind
-                        && let [inner_seg] = inner_path.segments
-                        && ident.name == inner_seg.ident.name
-                    {
-                        ControlFlow::Break(())
-                    } else {
-                        ControlFlow::Continue(())
-                    }
+                let mut visitor = ReadVecVisitor {
+                    local_id: id,
+                    read_zero_expr: None,
+                    has_resize: false,
                 };
 
-                let (read_found, next_stmt_span) = if let Some(next_stmt) = block.stmts.get(idx + 1) {
-                    // case { .. stmt; stmt; .. }
-                    (for_each_expr(next_stmt, visitor).is_some(), next_stmt.span)
-                } else if let Some(e) = block.expr {
-                    // case { .. stmt; expr }
-                    (for_each_expr(e, visitor).is_some(), e.span)
-                } else {
+                let Some(enclosing_block) = get_enclosing_block(cx, id) else {
                     return;
                 };
+                visitor.visit_block(enclosing_block);
 
-                if read_found && !next_stmt_span.from_expansion() {
+                if let Some(expr) = visitor.read_zero_expr {
                     let applicability = Applicability::MaybeIncorrect;
                     match vec_init_kind {
                         VecInitKind::WithConstCapacity(len) => {
                             span_lint_and_sugg(
                                 cx,
                                 READ_ZERO_BYTE_VEC,
-                                next_stmt_span,
+                                expr.span,
                                 "reading zero byte data to `Vec`",
                                 "try",
-                                format!(
-                                    "{}.resize({len}, 0); {}",
-                                    ident.as_str(),
-                                    snippet(cx, next_stmt_span, "..")
-                                ),
+                                format!("{}.resize({len}, 0); {}", ident.as_str(), snippet(cx, expr.span, "..")),
                                 applicability,
                             );
                         },
@@ -108,25 +93,20 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
                             span_lint_and_sugg(
                                 cx,
                                 READ_ZERO_BYTE_VEC,
-                                next_stmt_span,
+                                expr.span,
                                 "reading zero byte data to `Vec`",
                                 "try",
                                 format!(
                                     "{}.resize({}, 0); {}",
                                     ident.as_str(),
                                     snippet(cx, e.span, ".."),
-                                    snippet(cx, next_stmt_span, "..")
+                                    snippet(cx, expr.span, "..")
                                 ),
                                 applicability,
                             );
                         },
                         _ => {
-                            span_lint(
-                                cx,
-                                READ_ZERO_BYTE_VEC,
-                                next_stmt_span,
-                                "reading zero byte data to `Vec`",
-                            );
+                            span_lint(cx, READ_ZERO_BYTE_VEC, expr.span, "reading zero byte data to `Vec`");
                         },
                     }
                 }
@@ -134,3 +114,47 @@ impl<'tcx> LateLintPass<'tcx> for ReadZeroByteVec {
         }
     }
 }
+
+struct ReadVecVisitor<'tcx> {
+    local_id: HirId,
+    read_zero_expr: Option<&'tcx Expr<'tcx>>,
+    has_resize: bool,
+}
+
+impl<'tcx> Visitor<'tcx> for ReadVecVisitor<'tcx> {
+    fn visit_expr(&mut self, e: &'tcx Expr<'tcx>) {
+        if let ExprKind::MethodCall(path, receiver, args, _) = e.kind {
+            let PathSegment { ident, .. } = *path;
+
+            match ident.as_str() {
+                "read" | "read_exact" => {
+                    let [arg] = args else { return };
+                    if let ExprKind::AddrOf(_, hir::Mutability::Mut, inner) = arg.kind
+                        && let ExprKind::Path(QPath::Resolved(None, inner_path)) = inner.kind
+                        && let [inner_seg] = inner_path.segments
+                        && let Res::Local(res_id) = inner_seg.res
+                        && self.local_id == res_id
+                    {
+                        self.read_zero_expr = Some(e);
+                        return;
+                    }
+                },
+                "resize" => {
+                    // If the Vec is resized, then it's a valid read
+                    if let ExprKind::Path(QPath::Resolved(_, inner_path)) = receiver.kind
+                        && let Res::Local(res_id) = inner_path.res
+                        && self.local_id == res_id
+                    {
+                        self.has_resize = true;
+                        return;
+                    }
+                },
+                _ => {},
+            }
+        }
+
+        if !self.has_resize && self.read_zero_expr.is_none() {
+            walk_expr(self, e);
+        }
+    }
+}
diff --git a/clippy_lints/src/semicolon_if_nothing_returned.rs b/clippy_lints/src/semicolon_if_nothing_returned.rs
index 2cd3e57f885..6540626f7d5 100644
--- a/clippy_lints/src/semicolon_if_nothing_returned.rs
+++ b/clippy_lints/src/semicolon_if_nothing_returned.rs
@@ -5,6 +5,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Block, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
+use rustc_span::{ExpnKind, MacroKind, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -39,6 +40,7 @@ impl<'tcx> LateLintPass<'tcx> for SemicolonIfNothingReturned {
     fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
         if !block.span.from_expansion()
             && let Some(expr) = block.expr
+            && !from_attr_macro(expr.span)
             && let t_expr = cx.typeck_results().expr_ty(expr)
             && t_expr.is_unit()
             && let mut app = Applicability::MachineApplicable
@@ -63,3 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for SemicolonIfNothingReturned {
         }
     }
 }
+
+fn from_attr_macro(span: Span) -> bool {
+    matches!(span.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Attr, _))
+}
diff --git a/clippy_lints/src/single_call_fn.rs b/clippy_lints/src/single_call_fn.rs
index 8e181c3ccc7..03877420774 100644
--- a/clippy_lints/src/single_call_fn.rs
+++ b/clippy_lints/src/single_call_fn.rs
@@ -1,4 +1,4 @@
-use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::{is_from_proc_macro, is_in_test_function};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::LocalDefId;
@@ -88,16 +88,18 @@ impl<'tcx> LateLintPass<'tcx> for SingleCallFn {
         };
         cx.tcx.hir().visit_all_item_likes_in_crate(&mut v);
 
-        for usage in self.def_id_to_usage.values() {
+        for (&def_id, usage) in &self.def_id_to_usage {
             let single_call_fn_span = usage.0;
             if let [caller_span] = *usage.1 {
-                span_lint_and_help(
+                span_lint_hir_and_then(
                     cx,
                     SINGLE_CALL_FN,
+                    cx.tcx.local_def_id_to_hir_id(def_id),
                     single_call_fn_span,
                     "this function is only used once",
-                    Some(caller_span),
-                    "used here",
+                    |diag| {
+                        diag.span_help(caller_span, "used here");
+                    },
                 );
             }
         }
diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs
index e4054393d0a..768623b5d03 100644
--- a/clippy_lints/src/trait_bounds.rs
+++ b/clippy_lints/src/trait_bounds.rs
@@ -390,6 +390,14 @@ fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'
     }
 }
 
+fn get_ty_res(ty: Ty<'_>) -> Option<Res> {
+    match ty.kind {
+        TyKind::Path(QPath::Resolved(_, path)) => Some(path.res),
+        TyKind::Path(QPath::TypeRelative(ty, _)) => get_ty_res(*ty),
+        _ => None,
+    }
+}
+
 // FIXME: ComparableTraitRef does not support nested bounds needed for associated_type_bounds
 fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
     ComparableTraitRef(
@@ -401,10 +409,8 @@ fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
             .filter_map(|segment| {
                 // get trait bound type arguments
                 Some(segment.args?.args.iter().filter_map(|arg| {
-                    if let GenericArg::Type(ty) = arg
-                        && let TyKind::Path(QPath::Resolved(_, path)) = ty.kind
-                    {
-                        return Some(path.res);
+                    if let GenericArg::Type(ty) = arg {
+                        return get_ty_res(**ty);
                     }
                     None
                 }))
diff --git a/clippy_lints/src/transmute/transmute_int_to_char.rs b/clippy_lints/src/transmute/transmute_int_to_char.rs
index 7d31c375f8c..2a6c2481254 100644
--- a/clippy_lints/src/transmute/transmute_int_to_char.rs
+++ b/clippy_lints/src/transmute/transmute_int_to_char.rs
@@ -1,6 +1,6 @@
 use super::TRANSMUTE_INT_TO_CHAR;
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::sugg;
+use clippy_utils::{std_or_core, sugg};
 use rustc_ast as ast;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
@@ -25,6 +25,7 @@ pub(super) fn check<'tcx>(
                 e.span,
                 &format!("transmute from a `{from_ty}` to a `char`"),
                 |diag| {
+                    let Some(top_crate) = std_or_core(cx) else { return };
                     let arg = sugg::Sugg::hir(cx, arg, "..");
                     let arg = if let ty::Int(_) = from_ty.kind() {
                         arg.as_ty(ast::UintTy::U32.name_str())
@@ -34,7 +35,7 @@ pub(super) fn check<'tcx>(
                     diag.span_suggestion(
                         e.span,
                         "consider using",
-                        format!("std::char::from_u32({arg}).unwrap()"),
+                        format!("{top_crate}::char::from_u32({arg}).unwrap()"),
                         Applicability::Unspecified,
                     );
                 },
diff --git a/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/clippy_lints/src/transmute/transmute_ref_to_ref.rs
index 98e9ea2d775..6c885ebdea1 100644
--- a/clippy_lints/src/transmute/transmute_ref_to_ref.rs
+++ b/clippy_lints/src/transmute/transmute_ref_to_ref.rs
@@ -1,7 +1,7 @@
 use super::{TRANSMUTE_BYTES_TO_STR, TRANSMUTE_PTR_TO_PTR};
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
 use clippy_utils::source::snippet;
-use clippy_utils::sugg;
+use clippy_utils::{std_or_core, sugg};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability};
 use rustc_lint::LateContext;
@@ -25,6 +25,8 @@ pub(super) fn check<'tcx>(
             && let ty::Uint(ty::UintTy::U8) = slice_ty.kind()
             && from_mutbl == to_mutbl
         {
+            let Some(top_crate) = std_or_core(cx) else { return true };
+
             let postfix = if *from_mutbl == Mutability::Mut { "_mut" } else { "" };
 
             let snippet = snippet(cx, arg.span, "..");
@@ -36,9 +38,9 @@ pub(super) fn check<'tcx>(
                 &format!("transmute from a `{from_ty}` to a `{to_ty}`"),
                 "consider using",
                 if const_context {
-                    format!("std::str::from_utf8_unchecked{postfix}({snippet})")
+                    format!("{top_crate}::str::from_utf8_unchecked{postfix}({snippet})")
                 } else {
-                    format!("std::str::from_utf8{postfix}({snippet}).unwrap()")
+                    format!("{top_crate}::str::from_utf8{postfix}({snippet}).unwrap()")
                 },
                 Applicability::MaybeIncorrect,
             );
diff --git a/clippy_lints/src/unconditional_recursion.rs b/clippy_lints/src/unconditional_recursion.rs
index b418db53ea4..209035804e4 100644
--- a/clippy_lints/src/unconditional_recursion.rs
+++ b/clippy_lints/src/unconditional_recursion.rs
@@ -167,7 +167,15 @@ fn check_partial_eq(cx: &LateContext<'_>, method_span: Span, method_def_id: Loca
                     false
                 }
             },
-            ExprKind::MethodCall(segment, _receiver, &[_arg], _) if segment.ident.name == name.name => {
+            ExprKind::MethodCall(segment, receiver, &[_arg], _) if segment.ident.name == name.name => {
+                if let Some(ty) = cx.typeck_results().expr_ty_opt(receiver)
+                    && let Some(ty_id) = get_ty_def_id(ty)
+                    && self_arg != ty_id
+                {
+                    // Since this called on a different type, the lint should not be
+                    // triggered here.
+                    return;
+                }
                 if let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
                     && let Some(trait_id) = cx.tcx.trait_of_item(fn_id)
                     && trait_id == trait_def_id
diff --git a/clippy_lints/src/unused_io_amount.rs b/clippy_lints/src/unused_io_amount.rs
index 1de9adfcb96..adc66e15ff5 100644
--- a/clippy_lints/src/unused_io_amount.rs
+++ b/clippy_lints/src/unused_io_amount.rs
@@ -1,9 +1,10 @@
-use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
-use clippy_utils::{is_trait_method, is_try, match_trait_method, paths};
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::{is_res_lang_ctor, is_trait_method, match_trait_method, paths};
+use hir::{ExprKind, PatKind};
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::sym;
+use rustc_span::{sym, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -45,126 +46,219 @@ declare_clippy_lint! {
 
 declare_lint_pass!(UnusedIoAmount => [UNUSED_IO_AMOUNT]);
 
+#[derive(Copy, Clone)]
+enum IoOp {
+    AsyncWrite(bool),
+    AsyncRead(bool),
+    SyncRead(bool),
+    SyncWrite(bool),
+}
+
 impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
-    fn check_stmt(&mut self, cx: &LateContext<'_>, s: &hir::Stmt<'_>) {
-        let (hir::StmtKind::Semi(expr) | hir::StmtKind::Expr(expr)) = s.kind else {
-            return;
-        };
+    /// We perform the check on the block level.
+    /// If we want to catch match and if expressions that act as returns of the block
+    ///   we need to check them at `check_expr` or `check_block` as they are not stmts
+    ///   but we can't check them at `check_expr` because we need the broader context
+    ///   because we should do this only for the final expression of the block, and not for
+    ///   `StmtKind::Local` which binds values => the io amount is used.
+    ///
+    /// To check for unused io amount in stmts, we only consider `StmtKind::Semi`.
+    /// `StmtKind::Local` is not considered because it binds values => the io amount is used.
+    /// `StmtKind::Expr` is not considered because requires unit type => the io amount is used.
+    /// `StmtKind::Item` is not considered because it's not an expression.
+    ///
+    /// We then check the individual expressions via `check_expr`. We use the same logic for
+    /// semi expressions and the final expression as we need to check match and if expressions
+    /// for binding of the io amount to `Ok(_)`.
+    ///
+    /// We explicitly check for the match source to be Normal as it needs special logic
+    /// 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>) {
+        for stmt in block.stmts {
+            if let hir::StmtKind::Semi(exp) = stmt.kind {
+                check_expr(cx, exp);
+            }
+        }
 
-        match expr.kind {
-            hir::ExprKind::Match(res, _, _) if is_try(cx, expr).is_some() => {
-                if let hir::ExprKind::Call(func, [ref arg_0, ..]) = res.kind {
-                    if matches!(
-                        func.kind,
-                        hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..))
-                    ) {
-                        check_map_error(cx, arg_0, expr);
+        if let Some(exp) = block.expr
+            && matches!(exp.kind, hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, _))
+        {
+            check_expr(cx, exp);
+        }
+    }
+}
+
+fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
+    match expr.kind {
+        hir::ExprKind::If(cond, _, _)
+            if let ExprKind::Let(hir::Let { pat, init, .. }) = cond.kind
+                && pattern_is_ignored_ok(cx, pat)
+                && let Some(op) = should_lint(cx, init) =>
+        {
+            emit_lint(cx, cond.span, op, &[pat.span]);
+        },
+        hir::ExprKind::Match(expr, arms, hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => {
+            let found_arms: Vec<_> = arms
+                .iter()
+                .filter_map(|arm| {
+                    if pattern_is_ignored_ok(cx, arm.pat) {
+                        Some(arm.span)
+                    } else {
+                        None
                     }
-                } else {
-                    check_map_error(cx, res, expr);
-                }
-            },
-            hir::ExprKind::MethodCall(path, arg_0, ..) => match path.ident.as_str() {
-                "expect" | "unwrap" | "unwrap_or" | "unwrap_or_else" | "is_ok" | "is_err" => {
-                    check_map_error(cx, arg_0, expr);
-                },
-                _ => (),
-            },
-            _ => (),
+                })
+                .collect();
+            if !found_arms.is_empty() {
+                emit_lint(cx, expr.span, op, found_arms.as_slice());
+            }
+        },
+        _ if let Some(op) = should_lint(cx, expr) => {
+            emit_lint(cx, expr.span, op, &[]);
+        },
+        _ => {},
+    };
+}
+
+fn should_lint<'a>(cx: &LateContext<'a>, mut inner: &'a hir::Expr<'a>) -> Option<IoOp> {
+    inner = unpack_match(inner);
+    inner = unpack_try(inner);
+    inner = unpack_call_chain(inner);
+    inner = unpack_await(inner);
+    // we type-check it to get whether it's a read/write or their vectorized forms
+    // and keep only the ones that are produce io amount
+    check_io_mode(cx, inner)
+}
+
+fn pattern_is_ignored_ok(cx: &LateContext<'_>, pat: &hir::Pat<'_>) -> bool {
+    // the if checks whether we are in a result Ok( ) pattern
+    // and the return checks whether it is unhandled
+
+    if let PatKind::TupleStruct(ref path, inner_pat, ddp) = pat.kind
+        // we check against Result::Ok to avoid linting on Err(_) or something else.
+        && is_res_lang_ctor(cx, cx.qpath_res(path, pat.hir_id), hir::LangItem::ResultOk)
+    {
+        return match (inner_pat, ddp.as_opt_usize()) {
+            // Ok(_) pattern
+            ([inner_pat], None) if matches!(inner_pat.kind, PatKind::Wild) => true,
+            // Ok(..) pattern
+            ([], Some(0)) => true,
+            _ => false,
+        };
+    }
+    false
+}
+
+fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
+    while let hir::ExprKind::MethodCall(path, receiver, ..) = expr.kind {
+        if matches!(
+            path.ident.as_str(),
+            "unwrap" | "expect" | "unwrap_or" | "unwrap_or_else" | "ok" | "is_ok" | "is_err" | "or_else" | "or"
+        ) {
+            expr = receiver;
+        } else {
+            break;
         }
     }
+    expr
+}
+
+fn unpack_try<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
+    while let hir::ExprKind::Call(func, [ref arg_0, ..]) = expr.kind
+        && matches!(
+            func.kind,
+            hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..))
+        )
+    {
+        expr = arg_0;
+    }
+    expr
+}
+
+fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
+    while let hir::ExprKind::Match(res, _, _) = expr.kind {
+        expr = res;
+    }
+    expr
 }
 
 /// If `expr` is an (e).await, return the inner expression "e" that's being
 /// waited on.  Otherwise return None.
-fn try_remove_await<'a>(expr: &'a hir::Expr<'a>) -> Option<&hir::Expr<'a>> {
+fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &hir::Expr<'a> {
     if let hir::ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind {
         if let hir::ExprKind::Call(func, [ref arg_0, ..]) = expr.kind {
             if matches!(
                 func.kind,
                 hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoFutureIntoFuture, ..))
             ) {
-                return Some(arg_0);
+                return arg_0;
             }
         }
     }
-
-    None
+    expr
 }
 
-fn check_map_error(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>) {
-    let mut call = call;
-    while let hir::ExprKind::MethodCall(path, receiver, ..) = call.kind {
-        if matches!(path.ident.as_str(), "or" | "or_else" | "ok") {
-            call = receiver;
-        } else {
-            break;
-        }
-    }
+/// Check whether the current expr is a function call for an IO operation
+fn check_io_mode(cx: &LateContext<'_>, call: &hir::Expr<'_>) -> Option<IoOp> {
+    let hir::ExprKind::MethodCall(path, ..) = call.kind else {
+        return None;
+    };
 
-    if let Some(call) = try_remove_await(call) {
-        check_method_call(cx, call, expr, true);
-    } else {
-        check_method_call(cx, call, expr, false);
+    let vectorized = match path.ident.as_str() {
+        "write_vectored" | "read_vectored" => true,
+        "write" | "read" => false,
+        _ => {
+            return None;
+        },
+    };
+
+    match (
+        is_trait_method(cx, call, sym::IoRead),
+        is_trait_method(cx, call, sym::IoWrite),
+        match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCREADEXT)
+            || match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCREADEXT),
+        match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCWRITEEXT)
+            || match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCWRITEEXT),
+    ) {
+        (true, _, _, _) => Some(IoOp::SyncRead(vectorized)),
+        (_, true, _, _) => Some(IoOp::SyncWrite(vectorized)),
+        (_, _, true, _) => Some(IoOp::AsyncRead(vectorized)),
+        (_, _, _, true) => Some(IoOp::AsyncWrite(vectorized)),
+        _ => None,
     }
 }
 
-fn check_method_call(cx: &LateContext<'_>, call: &hir::Expr<'_>, expr: &hir::Expr<'_>, is_await: bool) {
-    if let hir::ExprKind::MethodCall(path, ..) = call.kind {
-        let symbol = path.ident.as_str();
-        let read_trait = if is_await {
-            match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCREADEXT)
-                || match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCREADEXT)
-        } else {
-            is_trait_method(cx, call, sym::IoRead)
-        };
-        let write_trait = if is_await {
-            match_trait_method(cx, call, &paths::FUTURES_IO_ASYNCWRITEEXT)
-                || match_trait_method(cx, call, &paths::TOKIO_IO_ASYNCWRITEEXT)
-        } else {
-            is_trait_method(cx, call, sym::IoWrite)
-        };
+fn emit_lint(cx: &LateContext<'_>, span: Span, op: IoOp, wild_cards: &[Span]) {
+    let (msg, help) = match op {
+        IoOp::AsyncRead(false) => (
+            "read amount is not handled",
+            Some("use `AsyncReadExt::read_exact` instead, or handle partial reads"),
+        ),
+        IoOp::SyncRead(false) => (
+            "read amount is not handled",
+            Some("use `Read::read_exact` instead, or handle partial reads"),
+        ),
+        IoOp::SyncWrite(false) => (
+            "written amount is not handled",
+            Some("use `Write::write_all` instead, or handle partial writes"),
+        ),
+        IoOp::AsyncWrite(false) => (
+            "written amount is not handled",
+            Some("use `AsyncWriteExt::write_all` instead, or handle partial writes"),
+        ),
+        IoOp::SyncRead(true) | IoOp::AsyncRead(true) => ("read amount is not handled", None),
+        IoOp::SyncWrite(true) | IoOp::AsyncWrite(true) => ("written amount is not handled", None),
+    };
 
-        match (read_trait, write_trait, symbol, is_await) {
-            (true, _, "read", false) => span_lint_and_help(
-                cx,
-                UNUSED_IO_AMOUNT,
-                expr.span,
-                "read amount is not handled",
-                None,
-                "use `Read::read_exact` instead, or handle partial reads",
-            ),
-            (true, _, "read", true) => span_lint_and_help(
-                cx,
-                UNUSED_IO_AMOUNT,
-                expr.span,
-                "read amount is not handled",
-                None,
-                "use `AsyncReadExt::read_exact` instead, or handle partial reads",
-            ),
-            (true, _, "read_vectored", _) => {
-                span_lint(cx, UNUSED_IO_AMOUNT, expr.span, "read amount is not handled");
-            },
-            (_, true, "write", false) => span_lint_and_help(
-                cx,
-                UNUSED_IO_AMOUNT,
-                expr.span,
-                "written amount is not handled",
-                None,
-                "use `Write::write_all` instead, or handle partial writes",
-            ),
-            (_, true, "write", true) => span_lint_and_help(
-                cx,
-                UNUSED_IO_AMOUNT,
-                expr.span,
-                "written amount is not handled",
-                None,
-                "use `AsyncWriteExt::write_all` instead, or handle partial writes",
-            ),
-            (_, true, "write_vectored", _) => {
-                span_lint(cx, UNUSED_IO_AMOUNT, expr.span, "written amount is not handled");
-            },
-            _ => (),
+    span_lint_and_then(cx, UNUSED_IO_AMOUNT, span, msg, |diag| {
+        if let Some(help_str) = help {
+            diag.help(help_str);
         }
-    }
+        for span in wild_cards {
+            diag.span_note(
+                *span,
+                "the result is consumed here, but the amount of I/O bytes remains unhandled",
+            );
+        }
+    });
 }
diff --git a/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
index 5ddedb24b15..4822970e47e 100644
--- a/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
+++ b/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
@@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation {
                                         ident.span,
                                         "non-standard lint formulation",
                                         None,
-                                        &format!("try using `{}` instead", formulation.correction),
+                                        &format!("consider using `{}`", formulation.correction),
                                     );
                                 }
                                 return;
diff --git a/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index 4fb615e1d57..c62ae8d718d 100644
--- a/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -71,7 +71,9 @@ pub fn check_path(cx: &LateContext<'_>, path: &[&str]) -> bool {
         SimplifiedType::Str,
     ]
     .iter()
-    .flat_map(|&ty| cx.tcx.incoherent_impls(ty).iter().copied());
+    .flat_map(|&ty| cx.tcx.incoherent_impls(ty).into_iter())
+    .flatten()
+    .copied();
     for item_def_id in lang_items.iter().map(|(_, def_id)| def_id).chain(incoherent_impls) {
         let lang_item_path = cx.get_def_path(item_def_id);
         if path_syms.starts_with(&lang_item_path) {
diff --git a/clippy_utils/src/attrs.rs b/clippy_utils/src/attrs.rs
index ad8619f0d3d..2d0c2cf1253 100644
--- a/clippy_utils/src/attrs.rs
+++ b/clippy_utils/src/attrs.rs
@@ -1,5 +1,6 @@
 use rustc_ast::{ast, attr};
 use rustc_errors::Applicability;
+use rustc_middle::ty::{AdtDef, TyCtxt};
 use rustc_session::Session;
 use rustc_span::sym;
 use std::str::FromStr;
@@ -159,3 +160,14 @@ pub fn is_doc_hidden(attrs: &[ast::Attribute]) -> bool {
         .filter_map(ast::Attribute::meta_item_list)
         .any(|l| attr::list_contains_name(&l, sym::hidden))
 }
+
+pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
+    adt.is_variant_list_non_exhaustive()
+        || tcx.has_attr(adt.did(), sym::non_exhaustive)
+        || adt.variants().iter().any(|variant_def| {
+            variant_def.is_field_list_non_exhaustive() || tcx.has_attr(variant_def.def_id, sym::non_exhaustive)
+        })
+        || adt
+            .all_fields()
+            .any(|field_def| tcx.has_attr(field_def.did, sym::non_exhaustive))
+}
diff --git a/clippy_utils/src/hir_utils.rs b/clippy_utils/src/hir_utils.rs
index 979b117db25..4fa93ad23c3 100644
--- a/clippy_utils/src/hir_utils.rs
+++ b/clippy_utils/src/hir_utils.rs
@@ -134,7 +134,7 @@ impl HirEqInterExpr<'_, '_, '_> {
     /// Checks whether two blocks are the same.
     #[expect(clippy::similar_names)]
     fn eq_block(&mut self, left: &Block<'_>, right: &Block<'_>) -> bool {
-        use TokenKind::{BlockComment, LineComment, Semi, Whitespace};
+        use TokenKind::{Semi, Whitespace};
         if left.stmts.len() != right.stmts.len() {
             return false;
         }
@@ -177,7 +177,7 @@ impl HirEqInterExpr<'_, '_, '_> {
                 return false;
             }
             if !eq_span_tokens(self.inner.cx, lstart..lstmt_span.lo, rstart..rstmt_span.lo, |t| {
-                !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)
+                !matches!(t, Whitespace | Semi)
             }) {
                 return false;
             }
@@ -212,7 +212,7 @@ impl HirEqInterExpr<'_, '_, '_> {
             return false;
         }
         eq_span_tokens(self.inner.cx, lstart..lend, rstart..rend, |t| {
-            !matches!(t, Whitespace | LineComment { .. } | BlockComment { .. } | Semi)
+            !matches!(t, Whitespace | Semi)
         })
     }
 
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index ebe520b27eb..4e499ff4cc6 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -536,7 +536,12 @@ fn find_primitive_impls<'tcx>(tcx: TyCtxt<'tcx>, name: &str) -> impl Iterator<It
         "f32" => SimplifiedType::Float(FloatTy::F32),
         "f64" => SimplifiedType::Float(FloatTy::F64),
         #[allow(trivial_casts)]
-        _ => return Result::<_, rustc_errors::ErrorGuaranteed>::Ok(&[] as &[_]).into_iter().flatten().copied(),
+        _ => {
+            return Result::<_, rustc_errors::ErrorGuaranteed>::Ok(&[] as &[_])
+                .into_iter()
+                .flatten()
+                .copied();
+        },
     };
 
     tcx.incoherent_impls(ty).into_iter().flatten().copied()
@@ -1712,7 +1717,6 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
         PatKind::Wild | PatKind::Never => false, // If `!` typechecked then the type is empty, so not refutable.
         PatKind::Binding(_, _, _, pat) => pat.map_or(false, |pat| is_refutable(cx, pat)),
         PatKind::Box(pat) | PatKind::Ref(pat, _) => is_refutable(cx, pat),
-        PatKind::Lit(..) | PatKind::Range(..) => true,
         PatKind::Path(ref qpath) => is_enum_variant(cx, qpath, pat.hir_id),
         PatKind::Or(pats) => {
             // TODO: should be the honest check, that pats is exhaustive set
@@ -1736,7 +1740,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
                 },
             }
         },
-        PatKind::Err(_) => true,
+        PatKind::Lit(..) | PatKind::Range(..) | PatKind::Err(_) => true,
     }
 }
 
diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs
index 0a820a1754c..0051f784514 100644
--- a/clippy_utils/src/paths.rs
+++ b/clippy_utils/src/paths.rs
@@ -26,6 +26,7 @@ pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"];
 pub const EARLY_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "EarlyLintPass"];
 pub const F32_EPSILON: [&str; 4] = ["core", "f32", "<impl f32>", "EPSILON"];
 pub const F64_EPSILON: [&str; 4] = ["core", "f64", "<impl f64>", "EPSILON"];
+pub const FILE_OPTIONS: [&str; 4] = ["std", "fs", "File", "options"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncReadExt"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
@@ -50,6 +51,7 @@ pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
 pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
 pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
 pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"];
+pub const OPEN_OPTIONS_NEW: [&str; 4] = ["std", "fs", "OpenOptions", "new"];
 pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
 pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
 pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"];
@@ -89,9 +91,15 @@ pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol",
 pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
 pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
+pub const TOKIO_FILE_OPTIONS: [&str; 5] = ["tokio", "fs", "file", "File", "options"];
+#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const TOKIO_IO_ASYNCREADEXT: [&str; 5] = ["tokio", "io", "util", "async_read_ext", "AsyncReadExt"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const TOKIO_IO_ASYNCWRITEEXT: [&str; 5] = ["tokio", "io", "util", "async_write_ext", "AsyncWriteExt"];
+#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
+pub const TOKIO_IO_OPEN_OPTIONS: [&str; 4] = ["tokio", "fs", "open_options", "OpenOptions"];
+#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
+pub const TOKIO_IO_OPEN_OPTIONS_NEW: [&str; 5] = ["tokio", "fs", "open_options", "OpenOptions", "new"];
 pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
 pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"];
 pub const VEC_DEQUE_ITER: [&str; 5] = ["alloc", "collections", "vec_deque", "VecDeque", "iter"];
diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs
index 59ebe685c11..11bb16ff6c5 100644
--- a/clippy_utils/src/ty.rs
+++ b/clippy_utils/src/ty.rs
@@ -219,7 +219,8 @@ pub fn implements_trait<'tcx>(
 
 /// Same as `implements_trait` but allows using a `ParamEnv` different from the lint context.
 ///
-/// The `callee_id` argument is used to determine whether this is a function call in a `const fn` environment, used for checking const traits.
+/// The `callee_id` argument is used to determine whether this is a function call in a `const fn`
+/// environment, used for checking const traits.
 pub fn implements_trait_with_env<'tcx>(
     tcx: TyCtxt<'tcx>,
     param_env: ParamEnv<'tcx>,
diff --git a/rust-toolchain b/rust-toolchain
index 2589d46e7da..d2d56e59ee3 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-01-11"
+channel = "nightly-2024-01-25"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.stderr b/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.stderr
new file mode 100644
index 00000000000..8f0ca764924
--- /dev/null
+++ b/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.stderr
@@ -0,0 +1,6 @@
+error: multiple versions for dependency `winapi`: 0.2.8, 0.3.9
+  |
+  = note: `-D clippy::multiple-crate-versions` implied by `-D warnings`
+  = help: to override `-D warnings` add `#[allow(clippy::multiple_crate_versions)]`
+
+error: could not compile `multiple-crate-versions` (bin "multiple-crate-versions") due to 1 previous error
diff --git a/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.toml b/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.toml
new file mode 100644
index 00000000000..d39ad6c909a
--- /dev/null
+++ b/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/Cargo.toml
@@ -0,0 +1,14 @@
+# Should not lint for dev or build dependencies. See issue 5041.
+
+[package]
+# purposefully separated by - instead of _
+name = "multiple-crate-versions"
+version = "0.1.0"
+publish = false
+
+[workspace]
+
+# One of the versions of winapi is only a dev dependency: allowed
+[dependencies]
+winapi = "0.2"
+ansi_term = "=0.11.0"
diff --git a/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/src/main.rs b/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/src/main.rs
new file mode 100644
index 00000000000..4bc61dd6299
--- /dev/null
+++ b/tests/ui-cargo/multiple_crate_versions/12145_with_dashes/src/main.rs
@@ -0,0 +1,3 @@
+#![warn(clippy::multiple_crate_versions)]
+
+fn main() {}
diff --git a/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml
new file mode 100644
index 00000000000..79317659ac0
--- /dev/null
+++ b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "multiple_crate_versions"
+version = "0.1.0"
+publish = false
+
+[workspace]
+
+[dependencies]
+winapi = "0.2"
+ansi_term = "=0.11.0"
diff --git a/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml
new file mode 100644
index 00000000000..121361de2fe
--- /dev/null
+++ b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/clippy.toml
@@ -0,0 +1 @@
+allowed-duplicate-crates = ["winapi"]
diff --git a/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs
new file mode 100644
index 00000000000..4bc61dd6299
--- /dev/null
+++ b/tests/ui-cargo/multiple_crate_versions/12176_allow_duplicate_crates/src/main.rs
@@ -0,0 +1,3 @@
+#![warn(clippy::multiple_crate_versions)]
+
+fn main() {}
diff --git a/tests/ui-internal/check_formulation.stderr b/tests/ui-internal/check_formulation.stderr
index 96fa617601f..42a872d9a83 100644
--- a/tests/ui-internal/check_formulation.stderr
+++ b/tests/ui-internal/check_formulation.stderr
@@ -4,7 +4,7 @@ error: non-standard lint formulation
 LL |     /// Check for lint formulations that are correct
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try using `Checks for` instead
+   = help: consider using `Checks for`
    = note: `-D clippy::almost-standard-lint-formulation` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::almost_standard_lint_formulation)]`
 
@@ -14,7 +14,7 @@ error: non-standard lint formulation
 LL |     /// Detects uses of incorrect formulations
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: try using `Checks for` instead
+   = help: consider using `Checks for`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui-internal/disallow_span_lint.stderr b/tests/ui-internal/disallow_span_lint.stderr
index 03556823a8f..5ca183d41a9 100644
--- a/tests/ui-internal/disallow_span_lint.stderr
+++ b/tests/ui-internal/disallow_span_lint.stderr
@@ -1,5 +1,5 @@
 error: use of a disallowed method `rustc_lint::context::LintContext::span_lint`
-  --> $DIR/disallow_struct_span_lint.rs:14:5
+  --> $DIR/disallow_span_lint.rs:14:5
    |
 LL |     cx.span_lint(lint, span, msg, |_| {});
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,10 +8,10 @@ LL |     cx.span_lint(lint, span, msg, |_| {});
    = help: to override `-D warnings` add `#[allow(clippy::disallowed_methods)]`
 
 error: use of a disallowed method `rustc_middle::ty::context::TyCtxt::node_span_lint`
-  --> $DIR/disallow_struct_span_lint.rs:24:5
+  --> $DIR/disallow_span_lint.rs:24:5
    |
 LL |     tcx.node_span_lint(lint, hir_id, span, msg, |_| {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui-toml/pub_underscore_fields/exported/clippy.toml b/tests/ui-toml/pub_underscore_fields/exported/clippy.toml
index 94a0d3554bc..9e472bd14ba 100644
--- a/tests/ui-toml/pub_underscore_fields/exported/clippy.toml
+++ b/tests/ui-toml/pub_underscore_fields/exported/clippy.toml
@@ -1 +1 @@
-pub-underscore-fields-behavior = "PublicallyExported"
\ No newline at end of file
+pub-underscore-fields-behavior = "PubliclyExported"
diff --git a/tests/ui-toml/toml_unknown_key/clippy.toml b/tests/ui-toml/toml_unknown_key/clippy.toml
index b77b4580051..2b63f6e5c26 100644
--- a/tests/ui-toml/toml_unknown_key/clippy.toml
+++ b/tests/ui-toml/toml_unknown_key/clippy.toml
@@ -3,6 +3,9 @@ foobar = 42
 # so is this one
 barfoo = 53
 
+# when using underscores instead of dashes, suggest the correct one
+allow_mixed_uninlined_format_args = true
+
 # that one is ignored
 [third-party]
 clippy-feature = "nightly"
diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs b/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs
index 38009627757..49139b60a9f 100644
--- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs
+++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.rs
@@ -1,3 +1,4 @@
+//@no-rustfix
 //@error-in-other-file: unknown field `foobar`, expected one of
 
 fn main() {}
diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index ed4fb84df1a..fc683e514ba 100644
--- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -11,6 +11,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            allow-private-module-inception
            allow-unwrap-in-tests
            allowed-dotfiles
+           allowed-duplicate-crates
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed
@@ -87,6 +88,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            allow-private-module-inception
            allow-unwrap-in-tests
            allowed-dotfiles
+           allowed-duplicate-crates
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed
@@ -150,5 +152,82 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
 LL | barfoo = 53
    | ^^^^^^
 
-error: aborting due to 2 previous errors
+error: error reading Clippy's configuration file: unknown field `allow_mixed_uninlined_format_args`, expected one of
+           absolute-paths-allowed-crates
+           absolute-paths-max-segments
+           accept-comment-above-attributes
+           accept-comment-above-statement
+           allow-dbg-in-tests
+           allow-expect-in-tests
+           allow-mixed-uninlined-format-args
+           allow-one-hash-in-raw-strings
+           allow-print-in-tests
+           allow-private-module-inception
+           allow-unwrap-in-tests
+           allowed-dotfiles
+           allowed-duplicate-crates
+           allowed-idents-below-min-chars
+           allowed-scripts
+           arithmetic-side-effects-allowed
+           arithmetic-side-effects-allowed-binary
+           arithmetic-side-effects-allowed-unary
+           array-size-threshold
+           avoid-breaking-exported-api
+           await-holding-invalid-types
+           blacklisted-names
+           cargo-ignore-publish
+           check-private-items
+           cognitive-complexity-threshold
+           cyclomatic-complexity-threshold
+           disallowed-macros
+           disallowed-methods
+           disallowed-names
+           disallowed-types
+           doc-valid-idents
+           enable-raw-pointer-heuristic-for-send
+           enforce-iter-loop-reborrow
+           enforced-import-renames
+           enum-variant-name-threshold
+           enum-variant-size-threshold
+           excessive-nesting-threshold
+           future-size-threshold
+           ignore-interior-mutability
+           large-error-threshold
+           literal-representation-threshold
+           matches-for-let-else
+           max-fn-params-bools
+           max-include-file-size
+           max-struct-bools
+           max-suggested-slice-pattern-length
+           max-trait-bounds
+           min-ident-chars-threshold
+           missing-docs-in-crate-items
+           msrv
+           pass-by-value-size-limit
+           pub-underscore-fields-behavior
+           semicolon-inside-block-ignore-singleline
+           semicolon-outside-block-ignore-multiline
+           single-char-binding-names-threshold
+           stack-size-threshold
+           standard-macro-braces
+           struct-field-name-threshold
+           suppress-restriction-lint-in-const
+           third-party
+           too-large-for-stack
+           too-many-arguments-threshold
+           too-many-lines-threshold
+           trivial-copy-size-limit
+           type-complexity-threshold
+           unnecessary-box-size
+           unreadable-literal-lint-fractions
+           upper-case-acronyms-aggressive
+           vec-box-size-threshold
+           verbose-bit-mask-threshold
+           warn-on-all-wildcard-imports
+  --> $DIR/$DIR/clippy.toml:7:1
+   |
+LL | allow_mixed_uninlined_format_args = true
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: perhaps you meant: `allow-mixed-uninlined-format-args`
+
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/auxiliary/proc_macro_attr.rs b/tests/ui/auxiliary/proc_macro_attr.rs
index c5879557516..ac544737099 100644
--- a/tests/ui/auxiliary/proc_macro_attr.rs
+++ b/tests/ui/auxiliary/proc_macro_attr.rs
@@ -11,8 +11,8 @@ use quote::{quote, quote_spanned};
 use syn::spanned::Spanned;
 use syn::token::Star;
 use syn::{
-    parse_macro_input, parse_quote, FnArg, ImplItem, ItemImpl, ItemTrait, Lifetime, Pat, PatIdent, PatType, Signature,
-    TraitItem, Type,
+    parse_macro_input, parse_quote, FnArg, ImplItem, ItemFn, ItemImpl, ItemTrait, Lifetime, Pat, PatIdent, PatType,
+    Signature, TraitItem, Type,
 };
 
 #[proc_macro_attribute]
@@ -95,3 +95,33 @@ pub fn rename_my_lifetimes(_args: TokenStream, input: TokenStream) -> TokenStrea
 
     TokenStream::from(quote!(#item))
 }
+
+#[proc_macro_attribute]
+pub fn fake_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    let mut item = parse_macro_input!(item as ItemFn);
+    let span = item.block.brace_token.span;
+
+    if item.sig.asyncness.is_some() {
+        item.sig.asyncness = None;
+    }
+
+    let crate_name = quote! { fake_crate };
+    let block = item.block;
+    item.block = syn::parse_quote_spanned! {
+        span =>
+        {
+            #crate_name::block_on(async {
+                #block
+            })
+        }
+    };
+
+    quote! {
+        mod #crate_name {
+            pub fn block_on<F: ::std::future::Future>(_fut: F) {}
+        }
+
+        #item
+    }
+    .into()
+}
diff --git a/tests/ui/blocks_in_conditions.fixed b/tests/ui/blocks_in_conditions.fixed
index 2ab441bbd0c..efef60567a9 100644
--- a/tests/ui/blocks_in_conditions.fixed
+++ b/tests/ui/blocks_in_conditions.fixed
@@ -85,4 +85,18 @@ fn block_in_match_expr(num: i32) -> i32 {
     }
 }
 
+// issue #12162
+macro_rules! timed {
+    ($name:expr, $body:expr $(,)?) => {{
+        let __scope = ();
+        $body
+    }};
+}
+
+fn issue_12162() {
+    if timed!("check this!", false) {
+        println!();
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/blocks_in_conditions.rs b/tests/ui/blocks_in_conditions.rs
index dd5ae4fb486..8bd8a939eb1 100644
--- a/tests/ui/blocks_in_conditions.rs
+++ b/tests/ui/blocks_in_conditions.rs
@@ -85,4 +85,18 @@ fn block_in_match_expr(num: i32) -> i32 {
     }
 }
 
+// issue #12162
+macro_rules! timed {
+    ($name:expr, $body:expr $(,)?) => {{
+        let __scope = ();
+        $body
+    }};
+}
+
+fn issue_12162() {
+    if timed!("check this!", false) {
+        println!();
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/branches_sharing_code/shared_at_top.rs b/tests/ui/branches_sharing_code/shared_at_top.rs
index 44f8b2eabce..9af81f6f7cd 100644
--- a/tests/ui/branches_sharing_code/shared_at_top.rs
+++ b/tests/ui/branches_sharing_code/shared_at_top.rs
@@ -9,17 +9,16 @@ fn simple_examples() {
 
     // Simple
     if true {
-        //~^ ERROR: all if blocks contain the same code at the start
         println!("Hello World!");
         println!("I'm branch nr: 1");
     } else {
         println!("Hello World!");
         println!("I'm branch nr: 2");
     }
+    //~^^^^^^^ ERROR: all if blocks contain the same code at the start
 
     // Else if
     if x == 0 {
-        //~^ ERROR: all if blocks contain the same code at the start
         let y = 9;
         println!("The value y was set to: `{}`", y);
         let _z = y;
@@ -38,6 +37,7 @@ fn simple_examples() {
 
         println!("Ha, Pascal allows you to start the array where you want")
     }
+    //~^^^^^^^^^^^^^^^^^^^ ERROR: all if blocks contain the same code at the start
 
     // Return a value
     let _ = if x == 7 {
@@ -60,7 +60,6 @@ fn simple_but_suggestion_is_invalid() {
     // Can't be automatically moved because used_value_name is getting used again
     let used_value_name = 19;
     if x == 10 {
-        //~^ ERROR: all if blocks contain the same code at the start
         let used_value_name = "Different type";
         println!("Str: {}", used_value_name);
         let _ = 1;
@@ -69,6 +68,7 @@ fn simple_but_suggestion_is_invalid() {
         println!("Str: {}", used_value_name);
         let _ = 2;
     }
+    //~^^^^^^^^^ ERROR: all if blocks contain the same code at the start
     let _ = used_value_name;
 
     // This can be automatically moved as `can_be_overridden` is not used again
@@ -101,11 +101,11 @@ fn check_if_same_than_else_mask() {
     }
 
     if x == 2019 {
-        //~^ ERROR: this `if` has identical blocks
         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
     } else {
         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 }
 
 #[allow(clippy::vec_init_then_push)]
diff --git a/tests/ui/branches_sharing_code/shared_at_top.stderr b/tests/ui/branches_sharing_code/shared_at_top.stderr
index 9d4d42fb689..317d1577226 100644
--- a/tests/ui/branches_sharing_code/shared_at_top.stderr
+++ b/tests/ui/branches_sharing_code/shared_at_top.stderr
@@ -2,7 +2,6 @@ error: all if blocks contain the same code at the start
   --> $DIR/shared_at_top.rs:11:5
    |
 LL | /     if true {
-LL | |
 LL | |         println!("Hello World!");
    | |_________________________________^
    |
@@ -21,7 +20,6 @@ error: all if blocks contain the same code at the start
   --> $DIR/shared_at_top.rs:21:5
    |
 LL | /     if x == 0 {
-LL | |
 LL | |         let y = 9;
 LL | |         println!("The value y was set to: `{}`", y);
 LL | |         let _z = y;
@@ -54,7 +52,6 @@ error: all if blocks contain the same code at the start
   --> $DIR/shared_at_top.rs:62:5
    |
 LL | /     if x == 10 {
-LL | |
 LL | |         let used_value_name = "Different type";
 LL | |         println!("Str: {}", used_value_name);
    | |_____________________________________________^
@@ -105,13 +102,12 @@ error: this `if` has identical blocks
    |
 LL |       if x == 2019 {
    |  __________________^
-LL | |
 LL | |         println!("This should trigger `IS_SAME_THAN_ELSE` as usual");
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/shared_at_top.rs:106:12
+  --> $DIR/shared_at_top.rs:105:12
    |
 LL |       } else {
    |  ____________^
diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.rs b/tests/ui/branches_sharing_code/valid_if_blocks.rs
index 2aeacb89c0c..b63819d7c39 100644
--- a/tests/ui/branches_sharing_code/valid_if_blocks.rs
+++ b/tests/ui/branches_sharing_code/valid_if_blocks.rs
@@ -107,9 +107,9 @@ fn valid_examples() {
 
     // Let's test empty blocks
     if false {
-        //~^ ERROR: this `if` has identical blocks
     } else {
     }
+    //~^^^ ERROR: this `if` has identical blocks
 }
 
 /// This makes sure that the `if_same_then_else` masks the `shared_code_in_if_blocks` lint
@@ -119,7 +119,6 @@ fn trigger_other_lint() {
 
     // Same block
     if x == 0 {
-        //~^ ERROR: this `if` has identical blocks
         let u = 19;
         println!("How are u today?");
         let _ = "This is a string";
@@ -128,6 +127,7 @@ fn trigger_other_lint() {
         println!("How are u today?");
         let _ = "This is a string";
     }
+    //~^^^^^^^^^ ERROR: this `if` has identical blocks
 
     // Only same expression
     let _ = if x == 6 { 7 } else { 7 };
@@ -138,28 +138,24 @@ fn trigger_other_lint() {
         println!("Well I'm the most important block");
         "I'm a pretty string"
     } else if x == 68 {
-        //~^ ERROR: this `if` has identical blocks
         println!("I'm a doppelgänger");
-        // Don't listen to my clone below
 
         if y == 90 { "=^.^=" } else { ":D" }
     } else {
-        // Don't listen to my clone above
         println!("I'm a doppelgänger");
 
         if y == 90 { "=^.^=" } else { ":D" }
     };
+    //~^^^^^^^^^ ERROR: this `if` has identical blocks
 
     if x == 0 {
         println!("I'm single");
     } else if x == 68 {
-        //~^ ERROR: this `if` has identical blocks
         println!("I'm a doppelgänger");
-        // Don't listen to my clone below
     } else {
-        // Don't listen to my clone above
         println!("I'm a doppelgänger");
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 }
 
 fn main() {}
diff --git a/tests/ui/branches_sharing_code/valid_if_blocks.stderr b/tests/ui/branches_sharing_code/valid_if_blocks.stderr
index fcbf12235aa..0daf2ff6967 100644
--- a/tests/ui/branches_sharing_code/valid_if_blocks.stderr
+++ b/tests/ui/branches_sharing_code/valid_if_blocks.stderr
@@ -3,12 +3,11 @@ error: this `if` has identical blocks
    |
 LL |       if false {
    |  ______________^
-LL | |
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/valid_if_blocks.rs:111:12
+  --> $DIR/valid_if_blocks.rs:110:12
    |
 LL |       } else {
    |  ____________^
@@ -25,7 +24,6 @@ error: this `if` has identical blocks
    |
 LL |       if x == 0 {
    |  _______________^
-LL | |
 LL | |         let u = 19;
 LL | |         println!("How are u today?");
 LL | |         let _ = "This is a string";
@@ -33,7 +31,7 @@ LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/valid_if_blocks.rs:126:12
+  --> $DIR/valid_if_blocks.rs:125:12
    |
 LL |       } else {
    |  ____________^
@@ -60,20 +58,17 @@ error: this `if` has identical blocks
    |
 LL |       } else if x == 68 {
    |  _______________________^
-LL | |
 LL | |         println!("I'm a doppelgänger");
-LL | |         // Don't listen to my clone below
 LL | |
 LL | |         if y == 90 { "=^.^=" } else { ":D" }
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/valid_if_blocks.rs:146:12
+  --> $DIR/valid_if_blocks.rs:144:12
    |
 LL |       } else {
    |  ____________^
-LL | |         // Don't listen to my clone above
 LL | |         println!("I'm a doppelgänger");
 LL | |
 LL | |         if y == 90 { "=^.^=" } else { ":D" }
@@ -81,22 +76,19 @@ LL | |     };
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/valid_if_blocks.rs:155:23
+  --> $DIR/valid_if_blocks.rs:153:23
    |
 LL |       } else if x == 68 {
    |  _______________________^
-LL | |
 LL | |         println!("I'm a doppelgänger");
-LL | |         // Don't listen to my clone below
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/valid_if_blocks.rs:159:12
+  --> $DIR/valid_if_blocks.rs:155:12
    |
 LL |       } else {
    |  ____________^
-LL | |         // Don't listen to my clone above
 LL | |         println!("I'm a doppelgänger");
 LL | |     }
    | |_____^
diff --git a/tests/ui/crashes/ice-9041.stderr b/tests/ui/crashes/ice-9041.stderr
index 00b65f00d78..67589d1a8ab 100644
--- a/tests/ui/crashes/ice-9041.stderr
+++ b/tests/ui/crashes/ice-9041.stderr
@@ -2,7 +2,7 @@ error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/ice-9041.rs:5:19
    |
 LL |     things.iter().find(|p| is_thing_ready(p)).is_some()
-   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|p| is_thing_ready(&p))`
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|p| is_thing_ready(&p))`
    |
    = note: `-D clippy::search-is-some` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
diff --git a/tests/ui/default_instead_of_iter_empty_no_std.fixed b/tests/ui/default_instead_of_iter_empty_no_std.fixed
new file mode 100644
index 00000000000..7300bd9bd2a
--- /dev/null
+++ b/tests/ui/default_instead_of_iter_empty_no_std.fixed
@@ -0,0 +1,28 @@
+#![warn(clippy::default_instead_of_iter_empty)]
+#![allow(dead_code)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+#[derive(Default)]
+struct Iter {
+    iter: core::iter::Empty<usize>,
+}
+
+fn main() {
+    // Do lint.
+    let _ = core::iter::empty::<usize>();
+    let _foo: core::iter::Empty<usize> = core::iter::empty();
+
+    // Do not lint.
+    let _ = Iter::default();
+}
diff --git a/tests/ui/default_instead_of_iter_empty_no_std.rs b/tests/ui/default_instead_of_iter_empty_no_std.rs
new file mode 100644
index 00000000000..0bc5c7169d1
--- /dev/null
+++ b/tests/ui/default_instead_of_iter_empty_no_std.rs
@@ -0,0 +1,28 @@
+#![warn(clippy::default_instead_of_iter_empty)]
+#![allow(dead_code)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+#[derive(Default)]
+struct Iter {
+    iter: core::iter::Empty<usize>,
+}
+
+fn main() {
+    // Do lint.
+    let _ = core::iter::Empty::<usize>::default();
+    let _foo: core::iter::Empty<usize> = core::iter::Empty::default();
+
+    // Do not lint.
+    let _ = Iter::default();
+}
diff --git a/tests/ui/default_instead_of_iter_empty_no_std.stderr b/tests/ui/default_instead_of_iter_empty_no_std.stderr
new file mode 100644
index 00000000000..747a31ecbf3
--- /dev/null
+++ b/tests/ui/default_instead_of_iter_empty_no_std.stderr
@@ -0,0 +1,17 @@
+error: `core::iter::empty()` is the more idiomatic way
+  --> $DIR/default_instead_of_iter_empty_no_std.rs:23:13
+   |
+LL |     let _ = core::iter::Empty::<usize>::default();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::iter::empty::<usize>()`
+   |
+   = note: `-D clippy::default-instead-of-iter-empty` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::default_instead_of_iter_empty)]`
+
+error: `core::iter::empty()` is the more idiomatic way
+  --> $DIR/default_instead_of_iter_empty_no_std.rs:24:42
+   |
+LL |     let _foo: core::iter::Empty<usize> = core::iter::Empty::default();
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::iter::empty()`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed
index c364c683057..e7038082c08 100644
--- a/tests/ui/default_numeric_fallback_i32.fixed
+++ b/tests/ui/default_numeric_fallback_i32.fixed
@@ -216,4 +216,44 @@ mod type_already_inferred {
     }
 }
 
+mod issue12159 {
+    #![allow(non_upper_case_globals, clippy::exhaustive_structs)]
+    pub struct Foo;
+
+    static F: i32 = 1;
+    impl Foo {
+        const LIFE_u8: u8 = 42;
+        const LIFE_i8: i8 = 42;
+        const LIFE_u16: u16 = 42;
+        const LIFE_i16: i16 = 42;
+        const LIFE_u32: u32 = 42;
+        const LIFE_i32: i32 = 42;
+        const LIFE_u64: u64 = 42;
+        const LIFE_i64: i64 = 42;
+        const LIFE_u128: u128 = 42;
+        const LIFE_i128: i128 = 42;
+        const LIFE_usize: usize = 42;
+        const LIFE_isize: isize = 42;
+        const LIFE_f32: f32 = 42.;
+        const LIFE_f64: f64 = 42.;
+
+        const fn consts() {
+            const LIFE_u8: u8 = 42;
+            const LIFE_i8: i8 = 42;
+            const LIFE_u16: u16 = 42;
+            const LIFE_i16: i16 = 42;
+            const LIFE_u32: u32 = 42;
+            const LIFE_i32: i32 = 42;
+            const LIFE_u64: u64 = 42;
+            const LIFE_i64: i64 = 42;
+            const LIFE_u128: u128 = 42;
+            const LIFE_i128: i128 = 42;
+            const LIFE_usize: usize = 42;
+            const LIFE_isize: isize = 42;
+            const LIFE_f32: f32 = 42.;
+            const LIFE_f64: f64 = 42.;
+        }
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/default_numeric_fallback_i32.rs b/tests/ui/default_numeric_fallback_i32.rs
index ffa7b961d1c..d8eeda70491 100644
--- a/tests/ui/default_numeric_fallback_i32.rs
+++ b/tests/ui/default_numeric_fallback_i32.rs
@@ -216,4 +216,44 @@ mod type_already_inferred {
     }
 }
 
+mod issue12159 {
+    #![allow(non_upper_case_globals, clippy::exhaustive_structs)]
+    pub struct Foo;
+
+    static F: i32 = 1;
+    impl Foo {
+        const LIFE_u8: u8 = 42;
+        const LIFE_i8: i8 = 42;
+        const LIFE_u16: u16 = 42;
+        const LIFE_i16: i16 = 42;
+        const LIFE_u32: u32 = 42;
+        const LIFE_i32: i32 = 42;
+        const LIFE_u64: u64 = 42;
+        const LIFE_i64: i64 = 42;
+        const LIFE_u128: u128 = 42;
+        const LIFE_i128: i128 = 42;
+        const LIFE_usize: usize = 42;
+        const LIFE_isize: isize = 42;
+        const LIFE_f32: f32 = 42.;
+        const LIFE_f64: f64 = 42.;
+
+        const fn consts() {
+            const LIFE_u8: u8 = 42;
+            const LIFE_i8: i8 = 42;
+            const LIFE_u16: u16 = 42;
+            const LIFE_i16: i16 = 42;
+            const LIFE_u32: u32 = 42;
+            const LIFE_i32: i32 = 42;
+            const LIFE_u64: u64 = 42;
+            const LIFE_i64: i64 = 42;
+            const LIFE_u128: u128 = 42;
+            const LIFE_i128: i128 = 42;
+            const LIFE_usize: usize = 42;
+            const LIFE_isize: isize = 42;
+            const LIFE_f32: f32 = 42.;
+            const LIFE_f64: f64 = 42.;
+        }
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/derive_partial_eq_without_eq.fixed b/tests/ui/derive_partial_eq_without_eq.fixed
index a7f5d3ec7cd..aa7a95405e0 100644
--- a/tests/ui/derive_partial_eq_without_eq.fixed
+++ b/tests/ui/derive_partial_eq_without_eq.fixed
@@ -121,4 +121,36 @@ pub fn _from_mod() -> _hidden::InPubFn {
 #[derive(PartialEq)]
 struct InternalTy;
 
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+#[non_exhaustive]
+pub struct MissingEqNonExhaustive {
+    foo: u32,
+    bar: String,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+pub struct MissingEqNonExhaustive1 {
+    foo: u32,
+    #[non_exhaustive]
+    bar: String,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+#[non_exhaustive]
+pub enum MissingEqNonExhaustive2 {
+    Foo,
+    Bar,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+pub enum MissingEqNonExhaustive3 {
+    Foo,
+    #[non_exhaustive]
+    Bar,
+}
+
 fn main() {}
diff --git a/tests/ui/derive_partial_eq_without_eq.rs b/tests/ui/derive_partial_eq_without_eq.rs
index 476d2aee23a..90ac7a7989e 100644
--- a/tests/ui/derive_partial_eq_without_eq.rs
+++ b/tests/ui/derive_partial_eq_without_eq.rs
@@ -121,4 +121,36 @@ pub fn _from_mod() -> _hidden::InPubFn {
 #[derive(PartialEq)]
 struct InternalTy;
 
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+#[non_exhaustive]
+pub struct MissingEqNonExhaustive {
+    foo: u32,
+    bar: String,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+pub struct MissingEqNonExhaustive1 {
+    foo: u32,
+    #[non_exhaustive]
+    bar: String,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+#[non_exhaustive]
+pub enum MissingEqNonExhaustive2 {
+    Foo,
+    Bar,
+}
+
+// This is a `non_exhaustive` type so should not warn.
+#[derive(Debug, PartialEq)]
+pub enum MissingEqNonExhaustive3 {
+    Foo,
+    #[non_exhaustive]
+    Bar,
+}
+
 fn main() {}
diff --git a/tests/ui/doc/doc-fixable.fixed b/tests/ui/doc/doc-fixable.fixed
index bff46e55722..16f7bafd44b 100644
--- a/tests/ui/doc/doc-fixable.fixed
+++ b/tests/ui/doc/doc-fixable.fixed
@@ -64,7 +64,7 @@ fn test_units() {
 /// NaN NaNs
 /// OAuth GraphQL
 /// OCaml
-/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS
+/// OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry
 /// WebGL WebGL2 WebGPU
 /// TensorFlow
 /// TrueType
diff --git a/tests/ui/doc/doc-fixable.rs b/tests/ui/doc/doc-fixable.rs
index 4e162a97dee..4058b2bad74 100644
--- a/tests/ui/doc/doc-fixable.rs
+++ b/tests/ui/doc/doc-fixable.rs
@@ -64,7 +64,7 @@ fn test_units() {
 /// NaN NaNs
 /// OAuth GraphQL
 /// OCaml
-/// OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenDNS
+/// OpenDNS OpenGL OpenMP OpenSSH OpenSSL OpenStreetMap OpenTelemetry
 /// WebGL WebGL2 WebGPU
 /// TensorFlow
 /// TrueType
diff --git a/tests/ui/from_over_into.fixed b/tests/ui/from_over_into.fixed
index 18d285693e6..4a68505ee0b 100644
--- a/tests/ui/from_over_into.fixed
+++ b/tests/ui/from_over_into.fixed
@@ -89,4 +89,12 @@ fn msrv_1_41() {
     }
 }
 
+fn issue_12138() {
+    struct Hello;
+
+    impl From<Hello> for () {
+        fn from(val: Hello) {}
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/from_over_into.rs b/tests/ui/from_over_into.rs
index 779ef709e92..bf3ed0c2b64 100644
--- a/tests/ui/from_over_into.rs
+++ b/tests/ui/from_over_into.rs
@@ -89,4 +89,12 @@ fn msrv_1_41() {
     }
 }
 
+fn issue_12138() {
+    struct Hello;
+
+    impl Into<()> for Hello {
+        fn into(self) {}
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/from_over_into.stderr b/tests/ui/from_over_into.stderr
index 784843ce5fd..f1370ed844f 100644
--- a/tests/ui/from_over_into.stderr
+++ b/tests/ui/from_over_into.stderr
@@ -86,5 +86,19 @@ LL ~         fn from(val: Vec<T>) -> Self {
 LL ~             FromOverInto(val)
    |
 
-error: aborting due to 6 previous errors
+error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
+  --> $DIR/from_over_into.rs:95:5
+   |
+LL |     impl Into<()> for Hello {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: `impl From<Local> for Foreign` is allowed by the orphan rules, for more information see
+           https://doc.rust-lang.org/reference/items/implementations.html#trait-implementation-coherence
+help: replace the `Into` implementation with `From<issue_12138::Hello>`
+   |
+LL ~     impl From<Hello> for () {
+LL ~         fn from(val: Hello) {}
+   |
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/if_same_then_else.rs b/tests/ui/if_same_then_else.rs
index e84b20e9fef..d53e1383d84 100644
--- a/tests/ui/if_same_then_else.rs
+++ b/tests/ui/if_same_then_else.rs
@@ -21,7 +21,6 @@ fn foo() -> bool {
 
 fn if_same_then_else() {
     if true {
-        //~^ ERROR: this `if` has identical blocks
         Foo { bar: 42 };
         0..10;
         ..;
@@ -38,6 +37,7 @@ fn if_same_then_else() {
         0..=10;
         foo();
     }
+    //~^^^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks
 
     if true {
         Foo { bar: 42 };
@@ -64,19 +64,11 @@ fn if_same_then_else() {
         foo();
     }
 
-    let _ = if true {
-        //~^ ERROR: this `if` has identical blocks
-        0.0
-    } else {
-        0.0
-    };
+    let _ = if true { 0.0 } else { 0.0 };
+    //~^ ERROR: this `if` has identical blocks
 
-    let _ = if true {
-        //~^ ERROR: this `if` has identical blocks
-        -0.0
-    } else {
-        -0.0
-    };
+    let _ = if true { -0.0 } else { -0.0 };
+    //~^ ERROR: this `if` has identical blocks
 
     let _ = if true { 0.0 } else { -0.0 };
 
@@ -87,15 +79,10 @@ fn if_same_then_else() {
         foo();
     }
 
-    let _ = if true {
-        //~^ ERROR: this `if` has identical blocks
-        42
-    } else {
-        42
-    };
+    let _ = if true { 42 } else { 42 };
+    //~^ ERROR: this `if` has identical blocks
 
     if true {
-        //~^ ERROR: this `if` has identical blocks
         let bar = if true { 42 } else { 43 };
 
         while foo() {
@@ -110,6 +97,7 @@ fn if_same_then_else() {
         }
         bar + 1;
     }
+    //~^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks
 
     if true {
         let _ = match 42 {
diff --git a/tests/ui/if_same_then_else.stderr b/tests/ui/if_same_then_else.stderr
index fb33e94e6c3..281f30f88b4 100644
--- a/tests/ui/if_same_then_else.stderr
+++ b/tests/ui/if_same_then_else.stderr
@@ -3,16 +3,16 @@ error: this `if` has identical blocks
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         Foo { bar: 42 };
 LL | |         0..10;
+LL | |         ..;
 ...  |
 LL | |         foo();
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:32:12
+  --> $DIR/if_same_then_else.rs:31:12
    |
 LL |       } else {
    |  ____________^
@@ -29,75 +29,54 @@ LL | |     }
 error: this `if` has identical blocks
   --> $DIR/if_same_then_else.rs:67:21
    |
-LL |       let _ = if true {
-   |  _____________________^
-LL | |
-LL | |         0.0
-LL | |     } else {
-   | |_____^
+LL |     let _ = if true { 0.0 } else { 0.0 };
+   |                     ^^^^^^^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:70:12
+  --> $DIR/if_same_then_else.rs:67:34
    |
-LL |       } else {
-   |  ____________^
-LL | |         0.0
-LL | |     };
-   | |_____^
+LL |     let _ = if true { 0.0 } else { 0.0 };
+   |                                  ^^^^^^^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else.rs:74:21
+  --> $DIR/if_same_then_else.rs:70:21
    |
-LL |       let _ = if true {
-   |  _____________________^
-LL | |
-LL | |         -0.0
-LL | |     } else {
-   | |_____^
+LL |     let _ = if true { -0.0 } else { -0.0 };
+   |                     ^^^^^^^^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:77:12
+  --> $DIR/if_same_then_else.rs:70:35
    |
-LL |       } else {
-   |  ____________^
-LL | |         -0.0
-LL | |     };
-   | |_____^
+LL |     let _ = if true { -0.0 } else { -0.0 };
+   |                                   ^^^^^^^^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else.rs:90:21
+  --> $DIR/if_same_then_else.rs:82:21
    |
-LL |       let _ = if true {
-   |  _____________________^
-LL | |
-LL | |         42
-LL | |     } else {
-   | |_____^
+LL |     let _ = if true { 42 } else { 42 };
+   |                     ^^^^^^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:93:12
+  --> $DIR/if_same_then_else.rs:82:33
    |
-LL |       } else {
-   |  ____________^
-LL | |         42
-LL | |     };
-   | |_____^
+LL |     let _ = if true { 42 } else { 42 };
+   |                                 ^^^^^^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else.rs:97:13
+  --> $DIR/if_same_then_else.rs:85:13
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         let bar = if true { 42 } else { 43 };
 LL | |
+LL | |         while foo() {
 ...  |
 LL | |         bar + 1;
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:105:12
+  --> $DIR/if_same_then_else.rs:92:12
    |
 LL |       } else {
    |  ____________^
@@ -110,7 +89,7 @@ LL | |     }
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else.rs:250:14
+  --> $DIR/if_same_then_else.rs:238:14
    |
 LL |           if x {
    |  ______________^
@@ -119,7 +98,7 @@ LL | |         } else {
    | |_________^
    |
 note: same as this
-  --> $DIR/if_same_then_else.rs:252:16
+  --> $DIR/if_same_then_else.rs:240:16
    |
 LL |           } else {
    |  ________________^
diff --git a/tests/ui/if_same_then_else2.rs b/tests/ui/if_same_then_else2.rs
index 0b171f21d0c..e23c77b0827 100644
--- a/tests/ui/if_same_then_else2.rs
+++ b/tests/ui/if_same_then_else2.rs
@@ -13,7 +13,6 @@
 
 fn if_same_then_else2() -> Result<&'static str, ()> {
     if true {
-        //~^ ERROR: this `if` has identical blocks
         for _ in &[42] {
             let foo: &Option<_> = &Some::<u8>(42);
             if foo.is_some() {
@@ -32,20 +31,21 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
             }
         }
     }
+    //~^^^^^^^^^^^^^^^^^^^ ERROR: this `if` has identical blocks
 
     if true {
-        //~^ ERROR: this `if` has identical blocks
         if let Some(a) = Some(42) {}
     } else {
         if let Some(a) = Some(42) {}
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 
     if true {
-        //~^ ERROR: this `if` has identical blocks
         if let (1, .., 3) = (1, 2, 3) {}
     } else {
         if let (1, .., 3) = (1, 2, 3) {}
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 
     if true {
         if let (1, .., 3) = (1, 2, 3) {}
@@ -90,19 +90,15 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
     }
 
     // Same NaNs
-    let _ = if true {
-        //~^ ERROR: this `if` has identical blocks
-        f32::NAN
-    } else {
-        f32::NAN
-    };
+    let _ = if true { f32::NAN } else { f32::NAN };
+    //~^ ERROR: this `if` has identical blocks
 
     if true {
-        //~^ ERROR: this `if` has identical blocks
         Ok("foo")?;
     } else {
         Ok("foo")?;
     }
+    //~^^^^^ ERROR: this `if` has identical blocks
 
     if true {
         let foo = "";
@@ -122,13 +118,13 @@ fn if_same_then_else2() -> Result<&'static str, ()> {
         let foo = "bar";
         return Ok(&foo[0..]);
     } else if true {
-        //~^ ERROR: this `if` has identical blocks
         let foo = "";
         return Ok(&foo[0..]);
     } else {
         let foo = "";
         return Ok(&foo[0..]);
     }
+    //~^^^^^^^ ERROR: this `if` has identical blocks
 
     // False positive `if_same_then_else`: `let (x, y)` vs. `let (y, x)`; see issue #3559.
     if true {
diff --git a/tests/ui/if_same_then_else2.stderr b/tests/ui/if_same_then_else2.stderr
index fe68ef2711b..4e7a7c87dc5 100644
--- a/tests/ui/if_same_then_else2.stderr
+++ b/tests/ui/if_same_then_else2.stderr
@@ -3,16 +3,16 @@ error: this `if` has identical blocks
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         for _ in &[42] {
 LL | |             let foo: &Option<_> = &Some::<u8>(42);
+LL | |             if foo.is_some() {
 ...  |
 LL | |         }
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:25:12
+  --> $DIR/if_same_then_else2.rs:24:12
    |
 LL |       } else {
    |  ____________^
@@ -31,13 +31,12 @@ error: this `if` has identical blocks
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         if let Some(a) = Some(42) {}
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:39:12
+  --> $DIR/if_same_then_else2.rs:38:12
    |
 LL |       } else {
    |  ____________^
@@ -50,13 +49,12 @@ error: this `if` has identical blocks
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         if let (1, .., 3) = (1, 2, 3) {}
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:46:12
+  --> $DIR/if_same_then_else2.rs:45:12
    |
 LL |       } else {
    |  ____________^
@@ -67,34 +65,26 @@ LL | |     }
 error: this `if` has identical blocks
   --> $DIR/if_same_then_else2.rs:93:21
    |
-LL |       let _ = if true {
-   |  _____________________^
-LL | |
-LL | |         f32::NAN
-LL | |     } else {
-   | |_____^
+LL |     let _ = if true { f32::NAN } else { f32::NAN };
+   |                     ^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:96:12
+  --> $DIR/if_same_then_else2.rs:93:39
    |
-LL |       } else {
-   |  ____________^
-LL | |         f32::NAN
-LL | |     };
-   | |_____^
+LL |     let _ = if true { f32::NAN } else { f32::NAN };
+   |                                       ^^^^^^^^^^^^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:100:13
+  --> $DIR/if_same_then_else2.rs:96:13
    |
 LL |       if true {
    |  _____________^
-LL | |
 LL | |         Ok("foo")?;
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:103:12
+  --> $DIR/if_same_then_else2.rs:98:12
    |
 LL |       } else {
    |  ____________^
@@ -103,18 +93,17 @@ LL | |     }
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:124:20
+  --> $DIR/if_same_then_else2.rs:120:20
    |
 LL |       } else if true {
    |  ____________________^
-LL | |
 LL | |         let foo = "";
 LL | |         return Ok(&foo[0..]);
 LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:128:12
+  --> $DIR/if_same_then_else2.rs:123:12
    |
 LL |       } else {
    |  ____________^
diff --git a/tests/ui/ineffective_open_options.fixed b/tests/ui/ineffective_open_options.fixed
index 3af8f3c5aaa..88489dc46bb 100644
--- a/tests/ui/ineffective_open_options.fixed
+++ b/tests/ui/ineffective_open_options.fixed
@@ -26,16 +26,23 @@ fn main() {
         .unwrap();
     let file = OpenOptions::new()
         .create(true)
+        .truncate(true)
         .write(true)
         .append(false)
         .open("dump.json")
         .unwrap();
     let file = OpenOptions::new()
         .create(true)
+        .truncate(true)
         .write(false)
         .append(false)
         .open("dump.json")
         .unwrap();
     let file = OpenOptions::new().create(true).append(true).open("dump.json").unwrap();
-    let file = OpenOptions::new().create(true).write(true).open("dump.json").unwrap();
+    let file = OpenOptions::new()
+        .create(true)
+        .truncate(true)
+        .write(true)
+        .open("dump.json")
+        .unwrap();
 }
diff --git a/tests/ui/ineffective_open_options.rs b/tests/ui/ineffective_open_options.rs
index 4eaf6293c40..db8bca3e2ac 100644
--- a/tests/ui/ineffective_open_options.rs
+++ b/tests/ui/ineffective_open_options.rs
@@ -26,16 +26,23 @@ fn main() {
         .unwrap();
     let file = OpenOptions::new()
         .create(true)
+        .truncate(true)
         .write(true)
         .append(false)
         .open("dump.json")
         .unwrap();
     let file = OpenOptions::new()
         .create(true)
+        .truncate(true)
         .write(false)
         .append(false)
         .open("dump.json")
         .unwrap();
     let file = OpenOptions::new().create(true).append(true).open("dump.json").unwrap();
-    let file = OpenOptions::new().create(true).write(true).open("dump.json").unwrap();
+    let file = OpenOptions::new()
+        .create(true)
+        .truncate(true)
+        .write(true)
+        .open("dump.json")
+        .unwrap();
 }
diff --git a/tests/ui/join_absolute_paths.stderr b/tests/ui/join_absolute_paths.stderr
index 0c2f89d9978..ab4d189ca3a 100644
--- a/tests/ui/join_absolute_paths.stderr
+++ b/tests/ui/join_absolute_paths.stderr
@@ -11,7 +11,7 @@ help: if this is unintentional, try removing the starting separator
    |
 LL |     path.join("sh");
    |               ~~~~
-help: if this is intentional, try using `Path::new` instead
+help: if this is intentional, consider using `Path::new`
    |
 LL |     PathBuf::from("/sh");
    |     ~~~~~~~~~~~~~~~~~~~~
@@ -27,7 +27,7 @@ help: if this is unintentional, try removing the starting separator
    |
 LL |     path.join("\user");
    |               ~~~~~~~
-help: if this is intentional, try using `Path::new` instead
+help: if this is intentional, consider using `Path::new`
    |
 LL |     PathBuf::from("\\user");
    |     ~~~~~~~~~~~~~~~~~~~~~~~
@@ -43,7 +43,7 @@ help: if this is unintentional, try removing the starting separator
    |
 LL |     path.join("sh");
    |               ~~~~
-help: if this is intentional, try using `Path::new` instead
+help: if this is intentional, consider using `Path::new`
    |
 LL |     PathBuf::from("/sh");
    |     ~~~~~~~~~~~~~~~~~~~~
@@ -59,7 +59,7 @@ help: if this is unintentional, try removing the starting separator
    |
 LL |     path.join(r#"sh"#);
    |               ~~~~~~~
-help: if this is intentional, try using `Path::new` instead
+help: if this is intentional, consider using `Path::new`
    |
 LL |     PathBuf::from(r#"/sh"#);
    |     ~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/tests/ui/manual_ok_or.stderr b/tests/ui/manual_ok_or.stderr
index b277d22e59b..89df6cdbedb 100644
--- a/tests/ui/manual_ok_or.stderr
+++ b/tests/ui/manual_ok_or.stderr
@@ -17,7 +17,7 @@ error: called `map_or(Err(_), Ok)` on an `Option` value
   --> $DIR/manual_ok_or.rs:14:5
    |
 LL |     foo.map_or(Err("error"), Ok);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok_or` instead: `foo.ok_or("error")`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok_or`: `foo.ok_or("error")`
    |
    = note: `-D clippy::option-map-or-err-ok` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]`
diff --git a/tests/ui/manual_saturating_arithmetic.stderr b/tests/ui/manual_saturating_arithmetic.stderr
index dc36a5ee7c6..3ce108b1ca8 100644
--- a/tests/ui/manual_saturating_arithmetic.stderr
+++ b/tests/ui/manual_saturating_arithmetic.stderr
@@ -2,7 +2,7 @@ error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:6:13
    |
 LL |     let _ = 1u32.checked_add(1).unwrap_or(u32::max_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1u32.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u32.saturating_add(1)`
    |
    = note: `-D clippy::manual-saturating-arithmetic` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::manual_saturating_arithmetic)]`
@@ -11,13 +11,13 @@ error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:7:13
    |
 LL |     let _ = 1u32.checked_add(1).unwrap_or(u32::MAX);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1u32.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u32.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:8:13
    |
 LL |     let _ = 1u8.checked_add(1).unwrap_or(255);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1u8.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1u8.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:9:13
@@ -26,49 +26,49 @@ LL |       let _ = 1u128
    |  _____________^
 LL | |         .checked_add(1)
 LL | |         .unwrap_or(340_282_366_920_938_463_463_374_607_431_768_211_455);
-   | |_______________________________________________________________________^ help: try using `saturating_add`: `1u128.saturating_add(1)`
+   | |_______________________________________________________________________^ help: consider using `saturating_add`: `1u128.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:14:13
    |
 LL |     let _ = 1u32.checked_mul(1).unwrap_or(u32::MAX);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_mul`: `1u32.saturating_mul(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_mul`: `1u32.saturating_mul(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:16:13
    |
 LL |     let _ = 1u32.checked_sub(1).unwrap_or(u32::min_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1u32.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:17:13
    |
 LL |     let _ = 1u32.checked_sub(1).unwrap_or(u32::MIN);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1u32.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u32.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:18:13
    |
 LL |     let _ = 1u8.checked_sub(1).unwrap_or(0);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1u8.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1u8.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:22:13
    |
 LL |     let _ = 1i32.checked_add(1).unwrap_or(i32::max_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:23:13
    |
 LL |     let _ = 1i32.checked_add(1).unwrap_or(i32::MAX);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:24:13
    |
 LL |     let _ = 1i8.checked_add(1).unwrap_or(127);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i8.saturating_add(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:25:13
@@ -77,25 +77,25 @@ LL |       let _ = 1i128
    |  _____________^
 LL | |         .checked_add(1)
 LL | |         .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);
-   | |_______________________________________________________________________^ help: try using `saturating_add`: `1i128.saturating_add(1)`
+   | |_______________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:28:13
    |
 LL |     let _ = 1i32.checked_add(-1).unwrap_or(i32::min_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:29:13
    |
 LL |     let _ = 1i32.checked_add(-1).unwrap_or(i32::MIN);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i32.saturating_add(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i32.saturating_add(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:30:13
    |
 LL |     let _ = 1i8.checked_add(-1).unwrap_or(-128);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_add`: `1i8.saturating_add(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_add`: `1i8.saturating_add(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:31:13
@@ -104,25 +104,25 @@ LL |       let _ = 1i128
    |  _____________^
 LL | |         .checked_add(-1)
 LL | |         .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);
-   | |________________________________________________________________________^ help: try using `saturating_add`: `1i128.saturating_add(-1)`
+   | |________________________________________________________________________^ help: consider using `saturating_add`: `1i128.saturating_add(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:38:13
    |
 LL |     let _ = 1i32.checked_sub(1).unwrap_or(i32::min_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:39:13
    |
 LL |     let _ = 1i32.checked_sub(1).unwrap_or(i32::MIN);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:40:13
    |
 LL |     let _ = 1i8.checked_sub(1).unwrap_or(-128);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i8.saturating_sub(1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:41:13
@@ -131,25 +131,25 @@ LL |       let _ = 1i128
    |  _____________^
 LL | |         .checked_sub(1)
 LL | |         .unwrap_or(-170_141_183_460_469_231_731_687_303_715_884_105_728);
-   | |________________________________________________________________________^ help: try using `saturating_sub`: `1i128.saturating_sub(1)`
+   | |________________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:44:13
    |
 LL |     let _ = 1i32.checked_sub(-1).unwrap_or(i32::max_value());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:45:13
    |
 LL |     let _ = 1i32.checked_sub(-1).unwrap_or(i32::MAX);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i32.saturating_sub(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i32.saturating_sub(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:46:13
    |
 LL |     let _ = 1i8.checked_sub(-1).unwrap_or(127);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `saturating_sub`: `1i8.saturating_sub(-1)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `saturating_sub`: `1i8.saturating_sub(-1)`
 
 error: manual saturating arithmetic
   --> $DIR/manual_saturating_arithmetic.rs:47:13
@@ -158,7 +158,7 @@ LL |       let _ = 1i128
    |  _____________^
 LL | |         .checked_sub(-1)
 LL | |         .unwrap_or(170_141_183_460_469_231_731_687_303_715_884_105_727);
-   | |_______________________________________________________________________^ help: try using `saturating_sub`: `1i128.saturating_sub(-1)`
+   | |_______________________________________________________________________^ help: consider using `saturating_sub`: `1i128.saturating_sub(-1)`
 
 error: aborting due to 24 previous errors
 
diff --git a/tests/ui/map_clone.fixed b/tests/ui/map_clone.fixed
index 08b155a1aea..395eea69294 100644
--- a/tests/ui/map_clone.fixed
+++ b/tests/ui/map_clone.fixed
@@ -69,15 +69,48 @@ fn main() {
     //~^ ERROR: you are explicitly cloning with `.map()`
     let y = x.cloned();
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
     let y = x.cloned();
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
+
+    let x: Option<u32> = Some(0);
+    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
+    let y = x.copied();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+    let y = x.copied();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+
+    // Should not suggest `copied` or `cloned` here since `T` is not a reference.
+    let x: Option<u32> = Some(0);
+    let y = x.map(|x| u32::clone(&x));
+    let y = x.map(|x| Clone::clone(&x));
 
     // Testing with `Result` now.
     let x: Result<String, ()> = Ok(String::new());
     let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
     let y = x.cloned();
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
     let y = x.cloned();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
+
+    let x: Result<u32, ()> = Ok(0);
+    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
+    let y = x.copied();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+    let y = x.copied();
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+
+    // Should not suggest `copied` or `cloned` here since `T` is not a reference.
+    let x: Result<u32, ()> = Ok(0);
+    let y = x.map(|x| u32::clone(&x));
+    let y = x.map(|x| Clone::clone(&x));
 
     // We ensure that no warning is emitted here because `useless_asref` is taking over.
     let x = Some(String::new());
diff --git a/tests/ui/map_clone.rs b/tests/ui/map_clone.rs
index 901d9b278b4..82a103edf5a 100644
--- a/tests/ui/map_clone.rs
+++ b/tests/ui/map_clone.rs
@@ -69,15 +69,48 @@ fn main() {
     //~^ ERROR: you are explicitly cloning with `.map()`
     let y = x.map(Clone::clone);
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
     let y = x.map(String::clone);
     //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
+
+    let x: Option<u32> = Some(0);
+    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
+    let y = x.map(|x| u32::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+    let y = x.map(|x| Clone::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+
+    // Should not suggest `copied` or `cloned` here since `T` is not a reference.
+    let x: Option<u32> = Some(0);
+    let y = x.map(|x| u32::clone(&x));
+    let y = x.map(|x| Clone::clone(&x));
 
     // Testing with `Result` now.
     let x: Result<String, ()> = Ok(String::new());
     let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
     let y = x.map(|x| String::clone(x));
     //~^ ERROR: you are explicitly cloning with `.map()`
-    let y = x.map(|x| String::clone(x));
+    //~| HELP: consider calling the dedicated `cloned` method
+    let y = x.map(|x| Clone::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `cloned` method
+
+    let x: Result<u32, ()> = Ok(0);
+    let x = x.as_ref(); // We do this to prevent triggering the `useless_asref` lint.
+    let y = x.map(|x| u32::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+    let y = x.map(|x| Clone::clone(x));
+    //~^ ERROR: you are explicitly cloning with `.map()`
+    //~| HELP: consider calling the dedicated `copied` method
+
+    // Should not suggest `copied` or `cloned` here since `T` is not a reference.
+    let x: Result<u32, ()> = Ok(0);
+    let y = x.map(|x| u32::clone(&x));
+    let y = x.map(|x| Clone::clone(&x));
 
     // We ensure that no warning is emitted here because `useless_asref` is taking over.
     let x = Some(String::new());
diff --git a/tests/ui/map_clone.stderr b/tests/ui/map_clone.stderr
index 9d7e9317b58..2c86a67fab8 100644
--- a/tests/ui/map_clone.stderr
+++ b/tests/ui/map_clone.stderr
@@ -50,22 +50,46 @@ LL |     let y = x.map(Clone::clone);
    |             ^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
 
 error: you are explicitly cloning with `.map()`
-  --> $DIR/map_clone.rs:72:13
+  --> $DIR/map_clone.rs:73:13
    |
 LL |     let y = x.map(String::clone);
    |             ^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
 
 error: you are explicitly cloning with `.map()`
-  --> $DIR/map_clone.rs:78:13
+  --> $DIR/map_clone.rs:79:13
    |
-LL |     let y = x.map(|x| String::clone(x));
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
+LL |     let y = x.map(|x| u32::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`
 
 error: you are explicitly cloning with `.map()`
-  --> $DIR/map_clone.rs:80:13
+  --> $DIR/map_clone.rs:82:13
+   |
+LL |     let y = x.map(|x| Clone::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`
+
+error: you are explicitly cloning with `.map()`
+  --> $DIR/map_clone.rs:94:13
    |
 LL |     let y = x.map(|x| String::clone(x));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
 
-error: aborting due to 11 previous errors
+error: you are explicitly cloning with `.map()`
+  --> $DIR/map_clone.rs:97:13
+   |
+LL |     let y = x.map(|x| Clone::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `cloned` method: `x.cloned()`
+
+error: you are explicitly cloning with `.map()`
+  --> $DIR/map_clone.rs:103:13
+   |
+LL |     let y = x.map(|x| u32::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`
+
+error: you are explicitly cloning with `.map()`
+  --> $DIR/map_clone.rs:106:13
+   |
+LL |     let y = x.map(|x| Clone::clone(x));
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling the dedicated `copied` method: `x.copied()`
+
+error: aborting due to 15 previous errors
 
diff --git a/tests/ui/match_same_arms2.rs b/tests/ui/match_same_arms2.rs
index 525a355f403..3428ff45906 100644
--- a/tests/ui/match_same_arms2.rs
+++ b/tests/ui/match_same_arms2.rs
@@ -13,7 +13,6 @@ fn foo() -> bool {
 fn match_same_arms() {
     let _ = match 42 {
         42 => {
-            //~^ ERROR: this match arm has an identical body to the `_` wildcard arm
             foo();
             let mut a = 42 + [23].len() as i32;
             if true {
@@ -32,6 +31,7 @@ fn match_same_arms() {
             a
         },
     };
+    //~^^^^^^^^^^^^^^^^^^^ ERROR: this match arm has an identical body to the `_` wildcard arm
 
     let _ = match 42 {
         42 => foo(),
@@ -146,13 +146,13 @@ fn match_same_arms() {
             empty!(0);
         },
         1 => {
-            //~^ ERROR: this match arm has an identical body to another arm
             empty!(0);
         },
         x => {
             empty!(x);
         },
     }
+    //~^^^^^^^ ERROR: this match arm has an identical body to another arm
 
     match_expr_like_matches_macro_priority();
 }
diff --git a/tests/ui/match_same_arms2.stderr b/tests/ui/match_same_arms2.stderr
index 40b20c7e16d..512ca7413a7 100644
--- a/tests/ui/match_same_arms2.stderr
+++ b/tests/ui/match_same_arms2.stderr
@@ -2,9 +2,9 @@ error: this match arm has an identical body to the `_` wildcard arm
   --> $DIR/match_same_arms2.rs:15:9
    |
 LL | /         42 => {
-LL | |
 LL | |             foo();
 LL | |             let mut a = 42 + [23].len() as i32;
+LL | |             if true {
 ...  |
 LL | |             a
 LL | |         },
@@ -12,7 +12,7 @@ LL | |         },
    |
    = help: or try changing either arm body
 note: `_` wildcard arm here
-  --> $DIR/match_same_arms2.rs:25:9
+  --> $DIR/match_same_arms2.rs:24:9
    |
 LL | /         _ => {
 LL | |             foo();
@@ -122,7 +122,6 @@ LL |           1 => {
    |           ^ help: try merging the arm patterns: `1 | 0`
    |  _________|
    | |
-LL | |
 LL | |             empty!(0);
 LL | |         },
    | |_________^
diff --git a/tests/ui/mem_replace_no_std.fixed b/tests/ui/mem_replace_no_std.fixed
new file mode 100644
index 00000000000..c970f2ba281
--- /dev/null
+++ b/tests/ui/mem_replace_no_std.fixed
@@ -0,0 +1,82 @@
+#![allow(unused)]
+#![warn(
+    clippy::all,
+    clippy::style,
+    clippy::mem_replace_option_with_none,
+    clippy::mem_replace_with_default
+)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::mem;
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn replace_option_with_none() {
+    let mut an_option = Some(1);
+    let _ = an_option.take();
+    let an_option = &mut Some(1);
+    let _ = an_option.take();
+}
+
+fn replace_with_default() {
+    let mut refstr = "hello";
+    let _ = core::mem::take(&mut refstr);
+
+    let mut slice: &[i32] = &[1, 2, 3];
+    let _ = core::mem::take(&mut slice);
+}
+
+// lint is disabled for primitives because in this case `take`
+// has no clear benefit over `replace` and sometimes is harder to read
+fn dont_lint_primitive() {
+    let mut pbool = true;
+    let _ = mem::replace(&mut pbool, false);
+
+    let mut pint = 5;
+    let _ = mem::replace(&mut pint, 0);
+}
+
+fn main() {
+    replace_option_with_none();
+    replace_with_default();
+    dont_lint_primitive();
+}
+
+fn issue9824() {
+    struct Foo<'a>(Option<&'a str>);
+    impl<'a> core::ops::Deref for Foo<'a> {
+        type Target = Option<&'a str>;
+
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+    impl<'a> core::ops::DerefMut for Foo<'a> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.0
+        }
+    }
+
+    struct Bar {
+        opt: Option<u8>,
+        val: u8,
+    }
+
+    let mut f = Foo(Some("foo"));
+    let mut b = Bar { opt: Some(1), val: 12 };
+
+    // replace option with none
+    let _ = f.0.take();
+    let _ = (*f).take();
+    let _ = b.opt.take();
+    // replace with default
+    let _ = mem::replace(&mut b.val, u8::default());
+}
diff --git a/tests/ui/mem_replace_no_std.rs b/tests/ui/mem_replace_no_std.rs
new file mode 100644
index 00000000000..673d5c7b4f4
--- /dev/null
+++ b/tests/ui/mem_replace_no_std.rs
@@ -0,0 +1,82 @@
+#![allow(unused)]
+#![warn(
+    clippy::all,
+    clippy::style,
+    clippy::mem_replace_option_with_none,
+    clippy::mem_replace_with_default
+)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::mem;
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn replace_option_with_none() {
+    let mut an_option = Some(1);
+    let _ = mem::replace(&mut an_option, None);
+    let an_option = &mut Some(1);
+    let _ = mem::replace(an_option, None);
+}
+
+fn replace_with_default() {
+    let mut refstr = "hello";
+    let _ = mem::replace(&mut refstr, "");
+
+    let mut slice: &[i32] = &[1, 2, 3];
+    let _ = mem::replace(&mut slice, &[]);
+}
+
+// lint is disabled for primitives because in this case `take`
+// has no clear benefit over `replace` and sometimes is harder to read
+fn dont_lint_primitive() {
+    let mut pbool = true;
+    let _ = mem::replace(&mut pbool, false);
+
+    let mut pint = 5;
+    let _ = mem::replace(&mut pint, 0);
+}
+
+fn main() {
+    replace_option_with_none();
+    replace_with_default();
+    dont_lint_primitive();
+}
+
+fn issue9824() {
+    struct Foo<'a>(Option<&'a str>);
+    impl<'a> core::ops::Deref for Foo<'a> {
+        type Target = Option<&'a str>;
+
+        fn deref(&self) -> &Self::Target {
+            &self.0
+        }
+    }
+    impl<'a> core::ops::DerefMut for Foo<'a> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.0
+        }
+    }
+
+    struct Bar {
+        opt: Option<u8>,
+        val: u8,
+    }
+
+    let mut f = Foo(Some("foo"));
+    let mut b = Bar { opt: Some(1), val: 12 };
+
+    // replace option with none
+    let _ = mem::replace(&mut f.0, None);
+    let _ = mem::replace(&mut *f, None);
+    let _ = mem::replace(&mut b.opt, None);
+    // replace with default
+    let _ = mem::replace(&mut b.val, u8::default());
+}
diff --git a/tests/ui/mem_replace_no_std.stderr b/tests/ui/mem_replace_no_std.stderr
new file mode 100644
index 00000000000..744fb5a1587
--- /dev/null
+++ b/tests/ui/mem_replace_no_std.stderr
@@ -0,0 +1,50 @@
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:24:13
+   |
+LL |     let _ = mem::replace(&mut an_option, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
+   |
+   = note: `-D clippy::mem-replace-option-with-none` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_option_with_none)]`
+
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:26:13
+   |
+LL |     let _ = mem::replace(an_option, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `an_option.take()`
+
+error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
+  --> $DIR/mem_replace_no_std.rs:31:13
+   |
+LL |     let _ = mem::replace(&mut refstr, "");
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut refstr)`
+   |
+   = note: `-D clippy::mem-replace-with-default` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::mem_replace_with_default)]`
+
+error: replacing a value of type `T` with `T::default()` is better expressed using `core::mem::take`
+  --> $DIR/mem_replace_no_std.rs:34:13
+   |
+LL |     let _ = mem::replace(&mut slice, &[]);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::mem::take(&mut slice)`
+
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:77:13
+   |
+LL |     let _ = mem::replace(&mut f.0, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `f.0.take()`
+
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:78:13
+   |
+LL |     let _ = mem::replace(&mut *f, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `(*f).take()`
+
+error: replacing an `Option` with `None`
+  --> $DIR/mem_replace_no_std.rs:79:13
+   |
+LL |     let _ = mem::replace(&mut b.opt, None);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider `Option::take()` instead: `b.opt.take()`
+
+error: aborting due to 7 previous errors
+
diff --git a/tests/ui/no_effect.rs b/tests/ui/no_effect.rs
index 777b1e52c2d..dabeda72f0c 100644
--- a/tests/ui/no_effect.rs
+++ b/tests/ui/no_effect.rs
@@ -181,6 +181,8 @@ fn main() {
     //~^ ERROR: binding to `_` prefixed variable with no side-effect
     let _cat = [2, 4, 6, 8][2];
     //~^ ERROR: binding to `_` prefixed variable with no side-effect
+    let _issue_12166 = 42;
+    let underscore_variable_above_can_be_used_dont_lint = _issue_12166;
 
     #[allow(clippy::no_effect)]
     0;
diff --git a/tests/ui/no_effect.stderr b/tests/ui/no_effect.stderr
index f5ba234b4cb..8140ba1feee 100644
--- a/tests/ui/no_effect.stderr
+++ b/tests/ui/no_effect.stderr
@@ -152,31 +152,31 @@ LL |     FooString { s: s };
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:175:5
+  --> $DIR/no_effect.rs:175:9
    |
 LL |     let _unused = 1;
-   |     ^^^^^^^^^^^^^^^^
+   |         ^^^^^^^
    |
    = note: `-D clippy::no-effect-underscore-binding` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::no_effect_underscore_binding)]`
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:178:5
+  --> $DIR/no_effect.rs:178:9
    |
 LL |     let _penguin = || println!("Some helpful closure");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:180:5
+  --> $DIR/no_effect.rs:180:9
    |
 LL |     let _duck = Struct { field: 0 };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^^
 
 error: binding to `_` prefixed variable with no side-effect
-  --> $DIR/no_effect.rs:182:5
+  --> $DIR/no_effect.rs:182:9
    |
 LL |     let _cat = [2, 4, 6, 8][2];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         ^^^^
 
 error: aborting due to 29 previous errors
 
diff --git a/tests/ui/open_options.rs b/tests/ui/open_options.rs
index 0cdc5bf2bb5..4acb3780df4 100644
--- a/tests/ui/open_options.rs
+++ b/tests/ui/open_options.rs
@@ -1,7 +1,18 @@
+#![allow(unused_must_use)]
+#![warn(clippy::nonsensical_open_options)]
+
 use std::fs::OpenOptions;
 
-#[allow(unused_must_use)]
-#[warn(clippy::nonsensical_open_options)]
+trait OpenOptionsExt {
+    fn truncate_write(&mut self, opt: bool) -> &mut Self;
+}
+
+impl OpenOptionsExt for OpenOptions {
+    fn truncate_write(&mut self, opt: bool) -> &mut Self {
+        self.truncate(opt).write(opt)
+    }
+}
+
 fn main() {
     OpenOptions::new().read(true).truncate(true).open("foo.txt");
     //~^ ERROR: file opened with `truncate` and `read`
@@ -11,12 +22,31 @@ fn main() {
 
     OpenOptions::new().read(true).read(false).open("foo.txt");
     //~^ ERROR: the method `read` is called more than once
-    OpenOptions::new().create(true).create(false).open("foo.txt");
-    //~^ ERROR: the method `create` is called more than once
+    OpenOptions::new()
+        .create(true)
+        .truncate(true) // Ensure we don't trigger suspicious open options by having create without truncate
+        .create(false)
+        //~^ ERROR: the method `create` is called more than once
+        .open("foo.txt");
     OpenOptions::new().write(true).write(false).open("foo.txt");
     //~^ ERROR: the method `write` is called more than once
     OpenOptions::new().append(true).append(false).open("foo.txt");
     //~^ ERROR: the method `append` is called more than once
     OpenOptions::new().truncate(true).truncate(false).open("foo.txt");
     //~^ ERROR: the method `truncate` is called more than once
+
+    std::fs::File::options().read(true).read(false).open("foo.txt");
+    //~^ ERROR: the method `read` is called more than once
+
+    let mut options = std::fs::OpenOptions::new();
+    options.read(true);
+    options.read(false);
+    // Possible future improvement: recognize open options method call chains across statements.
+    options.open("foo.txt");
+
+    let mut options = std::fs::OpenOptions::new();
+    options.truncate(true);
+    options.create(true).open("foo.txt");
+
+    OpenOptions::new().create(true).truncate_write(true).open("foo.txt");
 }
diff --git a/tests/ui/open_options.stderr b/tests/ui/open_options.stderr
index 7ac826f52fa..4f84d1d09f9 100644
--- a/tests/ui/open_options.stderr
+++ b/tests/ui/open_options.stderr
@@ -1,5 +1,5 @@
 error: file opened with `truncate` and `read`
-  --> $DIR/open_options.rs:6:5
+  --> $DIR/open_options.rs:17:5
    |
 LL |     OpenOptions::new().read(true).truncate(true).open("foo.txt");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,40 +8,46 @@ LL |     OpenOptions::new().read(true).truncate(true).open("foo.txt");
    = help: to override `-D warnings` add `#[allow(clippy::nonsensical_open_options)]`
 
 error: file opened with `append` and `truncate`
-  --> $DIR/open_options.rs:9:5
+  --> $DIR/open_options.rs:20:5
    |
 LL |     OpenOptions::new().append(true).truncate(true).open("foo.txt");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: the method `read` is called more than once
-  --> $DIR/open_options.rs:12:5
+  --> $DIR/open_options.rs:23:35
    |
 LL |     OpenOptions::new().read(true).read(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                   ^^^^^^^^^^^
 
 error: the method `create` is called more than once
-  --> $DIR/open_options.rs:14:5
+  --> $DIR/open_options.rs:28:10
    |
-LL |     OpenOptions::new().create(true).create(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         .create(false)
+   |          ^^^^^^^^^^^^^
 
 error: the method `write` is called more than once
-  --> $DIR/open_options.rs:16:5
+  --> $DIR/open_options.rs:31:36
    |
 LL |     OpenOptions::new().write(true).write(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                    ^^^^^^^^^^^^
 
 error: the method `append` is called more than once
-  --> $DIR/open_options.rs:18:5
+  --> $DIR/open_options.rs:33:37
    |
 LL |     OpenOptions::new().append(true).append(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                     ^^^^^^^^^^^^^
 
 error: the method `truncate` is called more than once
-  --> $DIR/open_options.rs:20:5
+  --> $DIR/open_options.rs:35:39
    |
 LL |     OpenOptions::new().truncate(true).truncate(false).open("foo.txt");
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                       ^^^^^^^^^^^^^^^
+
+error: the method `read` is called more than once
+  --> $DIR/open_options.rs:38:41
+   |
+LL |     std::fs::File::options().read(true).read(false).open("foo.txt");
+   |                                         ^^^^^^^^^^^
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/tests/ui/open_options_fixable.fixed b/tests/ui/open_options_fixable.fixed
new file mode 100644
index 00000000000..90a129a9bdf
--- /dev/null
+++ b/tests/ui/open_options_fixable.fixed
@@ -0,0 +1,7 @@
+use std::fs::OpenOptions;
+#[allow(unused_must_use)]
+#[warn(clippy::suspicious_open_options)]
+fn main() {
+    OpenOptions::new().create(true).truncate(true).open("foo.txt");
+    //~^ ERROR: file opened with `create`, but `truncate` behavior not defined
+}
diff --git a/tests/ui/open_options_fixable.rs b/tests/ui/open_options_fixable.rs
new file mode 100644
index 00000000000..3a9e522ba15
--- /dev/null
+++ b/tests/ui/open_options_fixable.rs
@@ -0,0 +1,7 @@
+use std::fs::OpenOptions;
+#[allow(unused_must_use)]
+#[warn(clippy::suspicious_open_options)]
+fn main() {
+    OpenOptions::new().create(true).open("foo.txt");
+    //~^ ERROR: file opened with `create`, but `truncate` behavior not defined
+}
diff --git a/tests/ui/open_options_fixable.stderr b/tests/ui/open_options_fixable.stderr
new file mode 100644
index 00000000000..e327661713b
--- /dev/null
+++ b/tests/ui/open_options_fixable.stderr
@@ -0,0 +1,14 @@
+error: file opened with `create`, but `truncate` behavior not defined
+  --> $DIR/open_options_fixable.rs:5:24
+   |
+LL |     OpenOptions::new().create(true).open("foo.txt");
+   |                        ^^^^^^^^^^^^- help: add: `.truncate(true)`
+   |
+   = help: if you intend to overwrite an existing file entirely, call `.truncate(true)`
+   = help: if you instead know that you may want to keep some parts of the old file, call `.truncate(false)`
+   = help: alternatively, use `.append(true)` to append to the file instead of overwriting it
+   = note: `-D clippy::suspicious-open-options` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::suspicious_open_options)]`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/option_as_ref_deref.stderr b/tests/ui/option_as_ref_deref.stderr
index 9d173e409ab..036b8c749e4 100644
--- a/tests/ui/option_as_ref_deref.stderr
+++ b/tests/ui/option_as_ref_deref.stderr
@@ -2,7 +2,7 @@ error: called `.as_ref().map(Deref::deref)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:11:13
    |
 LL |     let _ = opt.clone().as_ref().map(Deref::deref).map(str::len);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.clone().as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.clone().as_deref()`
    |
    = note: `-D clippy::option-as-ref-deref` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::option_as_ref_deref)]`
@@ -15,103 +15,103 @@ LL |       let _ = opt.clone()
 LL | |         .as_ref().map(
 LL | |             Deref::deref
 LL | |         )
-   | |_________^ help: try using as_deref instead: `opt.clone().as_deref()`
+   | |_________^ help: consider using as_deref: `opt.clone().as_deref()`
 
 error: called `.as_mut().map(DerefMut::deref_mut)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:20:13
    |
 LL |     let _ = opt.as_mut().map(DerefMut::deref_mut);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`
 
 error: called `.as_ref().map(String::as_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:22:13
    |
 LL |     let _ = opt.as_ref().map(String::as_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_ref().map(|x| x.as_str())` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:23:13
    |
 LL |     let _ = opt.as_ref().map(|x| x.as_str());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_mut().map(String::as_mut_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:24:13
    |
 LL |     let _ = opt.as_mut().map(String::as_mut_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`
 
 error: called `.as_mut().map(|x| x.as_mut_str())` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:25:13
    |
 LL |     let _ = opt.as_mut().map(|x| x.as_mut_str());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`
 
 error: called `.as_ref().map(CString::as_c_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:26:13
    |
 LL |     let _ = Some(CString::new(vec![]).unwrap()).as_ref().map(CString::as_c_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(CString::new(vec![]).unwrap()).as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(CString::new(vec![]).unwrap()).as_deref()`
 
 error: called `.as_ref().map(OsString::as_os_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:27:13
    |
 LL |     let _ = Some(OsString::new()).as_ref().map(OsString::as_os_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(OsString::new()).as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(OsString::new()).as_deref()`
 
 error: called `.as_ref().map(PathBuf::as_path)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:28:13
    |
 LL |     let _ = Some(PathBuf::new()).as_ref().map(PathBuf::as_path);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(PathBuf::new()).as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(PathBuf::new()).as_deref()`
 
 error: called `.as_ref().map(Vec::as_slice)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:29:13
    |
 LL |     let _ = Some(Vec::<()>::new()).as_ref().map(Vec::as_slice);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `Some(Vec::<()>::new()).as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `Some(Vec::<()>::new()).as_deref()`
 
 error: called `.as_mut().map(Vec::as_mut_slice)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:30:13
    |
 LL |     let _ = Some(Vec::<()>::new()).as_mut().map(Vec::as_mut_slice);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `Some(Vec::<()>::new()).as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `Some(Vec::<()>::new()).as_deref_mut()`
 
 error: called `.as_ref().map(|x| x.deref())` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:32:13
    |
 LL |     let _ = opt.as_ref().map(|x| x.deref());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_mut().map(|x| x.deref_mut())` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:33:13
    |
 LL |     let _ = opt.clone().as_mut().map(|x| x.deref_mut()).map(|x| x.len());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.clone().as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.clone().as_deref_mut()`
 
 error: called `.as_ref().map(|x| &**x)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:40:13
    |
 LL |     let _ = opt.as_ref().map(|x| &**x);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_mut().map(|x| &mut **x)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:41:13
    |
 LL |     let _ = opt.as_mut().map(|x| &mut **x);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref_mut instead: `opt.as_deref_mut()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref_mut: `opt.as_deref_mut()`
 
 error: called `.as_ref().map(std::ops::Deref::deref)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:44:13
    |
 LL |     let _ = opt.as_ref().map(std::ops::Deref::deref);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: called `.as_ref().map(String::as_str)` on an `Option` value
   --> $DIR/option_as_ref_deref.rs:56:13
    |
 LL |     let _ = opt.as_ref().map(String::as_str);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using as_deref instead: `opt.as_deref()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using as_deref: `opt.as_deref()`
 
 error: aborting due to 18 previous errors
 
diff --git a/tests/ui/option_map_or_err_ok.stderr b/tests/ui/option_map_or_err_ok.stderr
index a193e3c4c49..381601cb6b3 100644
--- a/tests/ui/option_map_or_err_ok.stderr
+++ b/tests/ui/option_map_or_err_ok.stderr
@@ -2,7 +2,7 @@ error: called `map_or(Err(_), Ok)` on an `Option` value
   --> $DIR/option_map_or_err_ok.rs:5:13
    |
 LL |     let _ = x.map_or(Err("a"), Ok);
-   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok_or` instead: `x.ok_or("a")`
+   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok_or`: `x.ok_or("a")`
    |
    = note: `-D clippy::option-map-or-err-ok` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::option_map_or_err_ok)]`
diff --git a/tests/ui/option_map_or_none.stderr b/tests/ui/option_map_or_none.stderr
index f2cfc3f9a28..d58ff83c3da 100644
--- a/tests/ui/option_map_or_none.stderr
+++ b/tests/ui/option_map_or_none.stderr
@@ -2,7 +2,7 @@ error: called `map_or(None, ..)` on an `Option` value
   --> $DIR/option_map_or_none.rs:10:26
    |
 LL |     let _: Option<i32> = opt.map_or(None, |x| Some(x + 1));
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `map` instead: `opt.map(|x| x + 1)`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `map`: `opt.map(|x| x + 1)`
    |
    = note: `-D clippy::option-map-or-none` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::option_map_or_none)]`
@@ -14,13 +14,13 @@ LL |       let _: Option<i32> = opt.map_or(None, |x| {
    |  __________________________^
 LL | |                         Some(x + 1)
 LL | |                        });
-   | |_________________________^ help: try using `map` instead: `opt.map(|x| x + 1)`
+   | |_________________________^ help: consider using `map`: `opt.map(|x| x + 1)`
 
 error: called `map_or(None, ..)` on an `Option` value
   --> $DIR/option_map_or_none.rs:17:26
    |
 LL |     let _: Option<i32> = opt.map_or(None, bar);
-   |                          ^^^^^^^^^^^^^^^^^^^^^ help: try using `and_then` instead: `opt.and_then(bar)`
+   |                          ^^^^^^^^^^^^^^^^^^^^^ help: consider using `and_then`: `opt.and_then(bar)`
 
 error: called `map_or(None, ..)` on an `Option` value
   --> $DIR/option_map_or_none.rs:18:26
@@ -33,7 +33,7 @@ LL | |         Some(offset + height)
 LL | |     });
    | |______^
    |
-help: try using `and_then` instead
+help: consider using `and_then`
    |
 LL ~     let _: Option<i32> = opt.and_then(|x| {
 LL +         let offset = 0;
@@ -46,7 +46,7 @@ error: called `map_or(None, Some)` on a `Result` value
   --> $DIR/option_map_or_none.rs:25:26
    |
 LL |     let _: Option<i32> = r.map_or(None, Some);
-   |                          ^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `r.ok()`
+   |                          ^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `r.ok()`
    |
    = note: `-D clippy::result-map-or-into-option` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]`
diff --git a/tests/ui/ptr_eq_no_std.fixed b/tests/ui/ptr_eq_no_std.fixed
new file mode 100644
index 00000000000..97c8c394c03
--- /dev/null
+++ b/tests/ui/ptr_eq_no_std.fixed
@@ -0,0 +1,49 @@
+#![warn(clippy::ptr_eq)]
+#![no_std]
+#![feature(lang_items)]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+macro_rules! mac {
+    ($a:expr, $b:expr) => {
+        $a as *const _ as usize == $b as *const _ as usize
+    };
+}
+
+macro_rules! another_mac {
+    ($a:expr, $b:expr) => {
+        $a as *const _ == $b as *const _
+    };
+}
+
+fn main() {
+    let a = &[1, 2, 3];
+    let b = &[1, 2, 3];
+
+    let _ = core::ptr::eq(a, b);
+    let _ = core::ptr::eq(a, b);
+    let _ = a.as_ptr() == b as *const _;
+    let _ = a.as_ptr() == b.as_ptr();
+
+    // Do not lint
+
+    let _ = mac!(a, b);
+    let _ = another_mac!(a, b);
+
+    let a = &mut [1, 2, 3];
+    let b = &mut [1, 2, 3];
+
+    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+    let _ = a.as_mut_ptr() == b.as_mut_ptr();
+
+    let _ = a == b;
+    let _ = core::ptr::eq(a, b);
+}
diff --git a/tests/ui/ptr_eq_no_std.rs b/tests/ui/ptr_eq_no_std.rs
new file mode 100644
index 00000000000..a7ba9b4d817
--- /dev/null
+++ b/tests/ui/ptr_eq_no_std.rs
@@ -0,0 +1,49 @@
+#![warn(clippy::ptr_eq)]
+#![no_std]
+#![feature(lang_items)]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+macro_rules! mac {
+    ($a:expr, $b:expr) => {
+        $a as *const _ as usize == $b as *const _ as usize
+    };
+}
+
+macro_rules! another_mac {
+    ($a:expr, $b:expr) => {
+        $a as *const _ == $b as *const _
+    };
+}
+
+fn main() {
+    let a = &[1, 2, 3];
+    let b = &[1, 2, 3];
+
+    let _ = a as *const _ as usize == b as *const _ as usize;
+    let _ = a as *const _ == b as *const _;
+    let _ = a.as_ptr() == b as *const _;
+    let _ = a.as_ptr() == b.as_ptr();
+
+    // Do not lint
+
+    let _ = mac!(a, b);
+    let _ = another_mac!(a, b);
+
+    let a = &mut [1, 2, 3];
+    let b = &mut [1, 2, 3];
+
+    let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+    let _ = a.as_mut_ptr() == b.as_mut_ptr();
+
+    let _ = a == b;
+    let _ = core::ptr::eq(a, b);
+}
diff --git a/tests/ui/ptr_eq_no_std.stderr b/tests/ui/ptr_eq_no_std.stderr
new file mode 100644
index 00000000000..3e289f5be61
--- /dev/null
+++ b/tests/ui/ptr_eq_no_std.stderr
@@ -0,0 +1,17 @@
+error: use `core::ptr::eq` when comparing raw pointers
+  --> $DIR/ptr_eq_no_std.rs:31:13
+   |
+LL |     let _ = a as *const _ as usize == b as *const _ as usize;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)`
+   |
+   = note: `-D clippy::ptr-eq` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ptr_eq)]`
+
+error: use `core::ptr::eq` when comparing raw pointers
+  --> $DIR/ptr_eq_no_std.rs:32:13
+   |
+LL |     let _ = a as *const _ == b as *const _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/read_zero_byte_vec.rs b/tests/ui/read_zero_byte_vec.rs
index 76b9b981851..fd5a88a37a6 100644
--- a/tests/ui/read_zero_byte_vec.rs
+++ b/tests/ui/read_zero_byte_vec.rs
@@ -56,14 +56,6 @@ fn test() -> io::Result<()> {
     f.read(&mut buf)?;
 
     // should not lint
-    let mut empty = vec![];
-    let mut data7 = vec![];
-    f.read(&mut empty);
-
-    // should not lint
-    f.read(&mut data7);
-
-    // should not lint
     let mut data8 = Vec::new();
     data8.resize(100, 0);
     f.read_exact(&mut data8)?;
@@ -75,6 +67,27 @@ fn test() -> io::Result<()> {
     Ok(())
 }
 
+fn test_nested() -> io::Result<()> {
+    let cap = 1000;
+    let mut f = File::open("foo.txt").unwrap();
+
+    // Issue #9274
+    // Should not lint
+    let mut v = Vec::new();
+    {
+        v.resize(10, 0);
+        f.read(&mut v)?;
+    }
+
+    let mut v = Vec::new();
+    {
+        f.read(&mut v)?;
+        //~^ ERROR: reading zero byte data to `Vec`
+    }
+
+    Ok(())
+}
+
 async fn test_futures<R: AsyncRead + Unpin>(r: &mut R) {
     // should lint
     let mut data = Vec::new();
diff --git a/tests/ui/read_zero_byte_vec.stderr b/tests/ui/read_zero_byte_vec.stderr
index 523ecb2948d..e85aa051c34 100644
--- a/tests/ui/read_zero_byte_vec.stderr
+++ b/tests/ui/read_zero_byte_vec.stderr
@@ -2,7 +2,7 @@ error: reading zero byte data to `Vec`
   --> $DIR/read_zero_byte_vec.rs:21:5
    |
 LL |     f.read_exact(&mut data).unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data.resize(20, 0); f.read_exact(&mut data).unwrap();`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data.resize(20, 0); f.read_exact(&mut data)`
    |
    = note: `-D clippy::read-zero-byte-vec` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::read_zero_byte_vec)]`
@@ -11,19 +11,19 @@ error: reading zero byte data to `Vec`
   --> $DIR/read_zero_byte_vec.rs:27:5
    |
 LL |     f.read_exact(&mut data2)?;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data2.resize(cap, 0); f.read_exact(&mut data2)?;`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `data2.resize(cap, 0); f.read_exact(&mut data2)`
 
 error: reading zero byte data to `Vec`
   --> $DIR/read_zero_byte_vec.rs:32:5
    |
 LL |     f.read_exact(&mut data3)?;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:37:5
+  --> $DIR/read_zero_byte_vec.rs:37:13
    |
 LL |     let _ = f.read(&mut data4)?;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |             ^^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
   --> $DIR/read_zero_byte_vec.rs:43:9
@@ -38,28 +38,34 @@ LL |         f.read(&mut data6)
    |         ^^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:81:5
+  --> $DIR/read_zero_byte_vec.rs:84:9
+   |
+LL |         f.read(&mut v)?;
+   |         ^^^^^^^^^^^^^^
+
+error: reading zero byte data to `Vec`
+  --> $DIR/read_zero_byte_vec.rs:94:5
    |
 LL |     r.read(&mut data).await.unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:86:5
+  --> $DIR/read_zero_byte_vec.rs:99:5
    |
 LL |     r.read_exact(&mut data2).await.unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:93:5
+  --> $DIR/read_zero_byte_vec.rs:106:5
    |
 LL |     r.read(&mut data).await.unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^
 
 error: reading zero byte data to `Vec`
-  --> $DIR/read_zero_byte_vec.rs:98:5
+  --> $DIR/read_zero_byte_vec.rs:111:5
    |
 LL |     r.read_exact(&mut data2).await.unwrap();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 10 previous errors
+error: aborting due to 11 previous errors
 
diff --git a/tests/ui/result_map_or_into_option.stderr b/tests/ui/result_map_or_into_option.stderr
index 3d6bfef48ec..201868f09ef 100644
--- a/tests/ui/result_map_or_into_option.stderr
+++ b/tests/ui/result_map_or_into_option.stderr
@@ -2,7 +2,7 @@ error: called `map_or(None, Some)` on a `Result` value
   --> $DIR/result_map_or_into_option.rs:5:13
    |
 LL |     let _ = opt.map_or(None, Some);
-   |             ^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `opt.ok()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()`
    |
    = note: `-D clippy::result-map-or-into-option` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::result_map_or_into_option)]`
@@ -11,13 +11,13 @@ error: called `map_or_else(|_| None, Some)` on a `Result` value
   --> $DIR/result_map_or_into_option.rs:7:13
    |
 LL |     let _ = opt.map_or_else(|_| None, Some);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `opt.ok()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()`
 
 error: called `map_or_else(|_| None, Some)` on a `Result` value
   --> $DIR/result_map_or_into_option.rs:10:13
    |
 LL |     let _ = opt.map_or_else(|_| { None }, Some);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try using `ok` instead: `opt.ok()`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `ok`: `opt.ok()`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/same_item_push.stderr b/tests/ui/same_item_push.stderr
index f519be46369..f569aab6490 100644
--- a/tests/ui/same_item_push.stderr
+++ b/tests/ui/same_item_push.stderr
@@ -4,7 +4,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(item);
    |         ^^^
    |
-   = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = help: consider using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
    = note: `-D clippy::same-item-push` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::same_item_push)]`
 
@@ -14,7 +14,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(item);
    |         ^^^
    |
-   = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = help: consider using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
 
 error: it looks like the same item is being pushed into this Vec
   --> $DIR/same_item_push.rs:36:9
@@ -22,7 +22,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(13);
    |         ^^^
    |
-   = help: try using vec![13;SIZE] or vec.resize(NEW_SIZE, 13)
+   = help: consider using vec![13;SIZE] or vec.resize(NEW_SIZE, 13)
 
 error: it looks like the same item is being pushed into this Vec
   --> $DIR/same_item_push.rs:42:9
@@ -30,7 +30,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(VALUE);
    |         ^^^
    |
-   = help: try using vec![VALUE;SIZE] or vec.resize(NEW_SIZE, VALUE)
+   = help: consider using vec![VALUE;SIZE] or vec.resize(NEW_SIZE, VALUE)
 
 error: it looks like the same item is being pushed into this Vec
   --> $DIR/same_item_push.rs:49:9
@@ -38,7 +38,7 @@ error: it looks like the same item is being pushed into this Vec
 LL |         vec.push(item);
    |         ^^^
    |
-   = help: try using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
+   = help: consider using vec![item;SIZE] or vec.resize(NEW_SIZE, item)
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/search_is_some.stderr b/tests/ui/search_is_some.stderr
index a7a47447f61..9dec8c9caf2 100644
--- a/tests/ui/search_is_some.stderr
+++ b/tests/ui/search_is_some.stderr
@@ -40,7 +40,7 @@ error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some.rs:42:20
    |
 LL |     let _ = (0..1).find(some_closure).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(some_closure)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(some_closure)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some.rs:52:13
@@ -82,7 +82,7 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some.rs:79:13
    |
 LL |     let _ = (0..1).find(some_closure).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(some_closure)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(some_closure)`
 
 error: aborting due to 8 previous errors
 
diff --git a/tests/ui/search_is_some_fixable_none.stderr b/tests/ui/search_is_some_fixable_none.stderr
index f33b0430912..107f59a97d2 100644
--- a/tests/ui/search_is_some_fixable_none.stderr
+++ b/tests/ui/search_is_some_fixable_none.stderr
@@ -2,7 +2,7 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:9:13
    |
 LL |     let _ = v.iter().find(|&x| *x < 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| *x < 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x < 0)`
    |
    = note: `-D clippy::search-is-some` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
@@ -11,43 +11,43 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:10:13
    |
 LL |     let _ = (0..1).find(|x| **y == *x).is_none(); // one dereference less
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(|x| **y == x)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| **y == x)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:11:13
    |
 LL |     let _ = (0..1).find(|x| *x == 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(0..1).any(|x| x == 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(0..1).any(|x| x == 0)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:12:13
    |
 LL |     let _ = v.iter().find(|x| **x == 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| *x == 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| *x == 0)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:13:13
    |
 LL |     let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(4..5).any(|x| x == 1 || x == 3 || x == 5)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(4..5).any(|x| x == 1 || x == 3 || x == 5)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:14:13
    |
 LL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:15:13
    |
 LL |     let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| x == 0 || [1, 2, 3].contains(&x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:16:13
    |
 LL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:17:13
@@ -56,91 +56,91 @@ LL |       let _ = (1..3)
    |  _____________^
 LL | |         .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1)
 LL | |         .is_none();
-   | |__________________^ help: use `!_.any()` instead: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
+   | |__________________^ help: consider using: `!(1..3).any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
 
 error: called `is_none()` after searching an `Iterator` with `position`
   --> $DIR/search_is_some_fixable_none.rs:22:13
    |
 LL |     let _ = v.iter().position(|&x| x < 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|&x| x < 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)`
 
 error: called `is_none()` after searching an `Iterator` with `rposition`
   --> $DIR/search_is_some_fixable_none.rs:25:13
    |
 LL |     let _ = v.iter().rposition(|&x| x < 0).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|&x| x < 0)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|&x| x < 0)`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:31:13
    |
 LL |     let _ = "hello world".find("world").is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains("world")`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains("world")`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:32:13
    |
 LL |     let _ = "hello world".find(&s2).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains(&s2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains(&s2)`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:33:13
    |
 LL |     let _ = "hello world".find(&s2[2..]).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!"hello world".contains(&s2[2..])`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!"hello world".contains(&s2[2..])`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:35:13
    |
 LL |     let _ = s1.find("world").is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains("world")`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains("world")`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:36:13
    |
 LL |     let _ = s1.find(&s2).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains(&s2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2)`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:37:13
    |
 LL |     let _ = s1.find(&s2[2..]).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1.contains(&s2[2..])`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1.contains(&s2[2..])`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:39:13
    |
 LL |     let _ = s1[2..].find("world").is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains("world")`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains("world")`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:40:13
    |
 LL |     let _ = s1[2..].find(&s2).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains(&s2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2)`
 
 error: called `is_none()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_none.rs:41:13
    |
 LL |     let _ = s1[2..].find(&s2[2..]).is_none();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.contains()` instead: `!s1[2..].contains(&s2[2..])`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!s1[2..].contains(&s2[2..])`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:57:25
    |
 LL |             .filter(|c| filter_hand.iter().find(|cc| c == cc).is_none())
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == &cc)`
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == &cc)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:73:30
    |
 LL |             .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_none())
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!filter_hand.iter().any(|cc| c == cc)`
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!filter_hand.iter().any(|cc| c == cc)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:84:17
    |
 LL |         let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.foo == 1 && v.bar == 2)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.foo == 1 && v.bar == 2)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:87:17
@@ -152,7 +152,7 @@ LL | |             .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)
 LL | |             .is_none();
    | |______________________^
    |
-help: use `!_.any()` instead
+help: consider using
    |
 LL ~         let _ = !vfoo
 LL ~             .iter().any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2);
@@ -162,49 +162,49 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:95:17
    |
 LL |         let _ = vfoo.iter().find(|a| a[0] == 42).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|a| a[0] == 42)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|a| a[0] == 42)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:101:17
    |
 LL |         let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|sub| sub[1..4].len() == 3)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:119:17
    |
 LL |         let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![ppx].iter().any(|ppp_x: &&u32| please(ppp_x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:120:17
    |
 LL |         let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![String::from("Hey hey")].iter().any(|s| s.len() == 2)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![String::from("Hey hey")].iter().any(|s| s.len() == 2)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:123:17
    |
 LL |         let _ = v.iter().find(|x| deref_enough(**x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| deref_enough(*x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| deref_enough(*x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:124:17
    |
 LL |         let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x: &u32| deref_enough(*x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| deref_enough(*x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:127:17
    |
 LL |         let _ = v.iter().find(|x| arg_no_deref(x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x| arg_no_deref(&x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x| arg_no_deref(&x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:129:17
    |
 LL |         let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|x: &u32| arg_no_deref(&x))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|x: &u32| arg_no_deref(&x))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:149:17
@@ -216,7 +216,7 @@ LL | |             .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] ==
 LL | |             .is_none();
    | |______________________^
    |
-help: use `!_.any()` instead
+help: consider using
    |
 LL ~         let _ = !vfoo
 LL ~             .iter().any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2);
@@ -226,61 +226,61 @@ error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:165:17
    |
 LL |         let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.inner[0].bar == 2)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.inner[0].bar == 2)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:170:17
    |
 LL |         let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|x| (**x)[0] == 9)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|x| (**x)[0] == 9)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:183:17
    |
 LL |         let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!vfoo.iter().any(|v| v.by_ref(&v.bar))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!vfoo.iter().any(|v| v.by_ref(&v.bar))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:187:17
    |
 LL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:188:17
    |
 LL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `![&(&1, 2), &(&3, 4), &(&5, 4)].iter().any(|(&x, y)| x == *y)`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:207:17
    |
 LL |         let _ = v.iter().find(|s| s[0].is_empty()).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|s| s[0].is_empty())`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| s[0].is_empty())`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:208:17
    |
 LL |         let _ = v.iter().find(|s| test_string_1(&s[0])).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|s| test_string_1(&s[0]))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|s| test_string_1(&s[0]))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:217:17
    |
 LL |         let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| fp.field.is_power_of_two())`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| fp.field.is_power_of_two())`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:218:17
    |
 LL |         let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| test_u32_1(fp.field))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_1(fp.field))`
 
 error: called `is_none()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_none.rs:219:17
    |
 LL |         let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_none();
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `!_.any()` instead: `!v.iter().any(|fp| test_u32_2(*fp.field))`
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `!v.iter().any(|fp| test_u32_2(*fp.field))`
 
 error: aborting due to 43 previous errors
 
diff --git a/tests/ui/search_is_some_fixable_some.stderr b/tests/ui/search_is_some_fixable_some.stderr
index e878e62de07..e706ce64692 100644
--- a/tests/ui/search_is_some_fixable_some.stderr
+++ b/tests/ui/search_is_some_fixable_some.stderr
@@ -2,7 +2,7 @@ error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:9:22
    |
 LL |     let _ = v.iter().find(|&x| *x < 0).is_some();
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| *x < 0)`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| *x < 0)`
    |
    = note: `-D clippy::search-is-some` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::search_is_some)]`
@@ -11,43 +11,43 @@ error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:10:20
    |
 LL |     let _ = (0..1).find(|x| **y == *x).is_some(); // one dereference less
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| **y == x)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| **y == x)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:11:20
    |
 LL |     let _ = (0..1).find(|x| *x == 0).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 0)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:12:22
    |
 LL |     let _ = v.iter().find(|x| **x == 0).is_some();
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| *x == 0)`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| *x == 0)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:13:20
    |
 LL |     let _ = (4..5).find(|x| *x == 1 || *x == 3 || *x == 5).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 1 || x == 3 || x == 5)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 1 || x == 3 || x == 5)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:14:20
    |
 LL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x)).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x))`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:15:20
    |
 LL |     let _ = (1..3).find(|x| *x == 0 || [1, 2, 3].contains(x)).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| x == 0 || [1, 2, 3].contains(&x))`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| x == 0 || [1, 2, 3].contains(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:16:20
    |
 LL |     let _ = (1..3).find(|x| [1, 2, 3].contains(x) || *x == 0).is_some();
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x) || x == 0)`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:18:10
@@ -55,91 +55,91 @@ error: called `is_some()` after searching an `Iterator` with `find`
 LL |           .find(|x| [1, 2, 3].contains(x) || *x == 0 || [4, 5, 6].contains(x) || *x == -1)
    |  __________^
 LL | |         .is_some();
-   | |__________________^ help: use `any()` instead: `any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
+   | |__________________^ help: consider using: `any(|x| [1, 2, 3].contains(&x) || x == 0 || [4, 5, 6].contains(&x) || x == -1)`
 
 error: called `is_some()` after searching an `Iterator` with `position`
   --> $DIR/search_is_some_fixable_some.rs:22:22
    |
 LL |     let _ = v.iter().position(|&x| x < 0).is_some();
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|&x| x < 0)`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)`
 
 error: called `is_some()` after searching an `Iterator` with `rposition`
   --> $DIR/search_is_some_fixable_some.rs:25:22
    |
 LL |     let _ = v.iter().rposition(|&x| x < 0).is_some();
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|&x| x < 0)`
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|&x| x < 0)`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:30:27
    |
 LL |     let _ = "hello world".find("world").is_some();
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:31:27
    |
 LL |     let _ = "hello world".find(&s2).is_some();
-   |                           ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)`
+   |                           ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:32:27
    |
 LL |     let _ = "hello world".find(&s2[2..]).is_some();
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:34:16
    |
 LL |     let _ = s1.find("world").is_some();
-   |                ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")`
+   |                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:35:16
    |
 LL |     let _ = s1.find(&s2).is_some();
-   |                ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)`
+   |                ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:36:16
    |
 LL |     let _ = s1.find(&s2[2..]).is_some();
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])`
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:38:21
    |
 LL |     let _ = s1[2..].find("world").is_some();
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains("world")`
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains("world")`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:39:21
    |
 LL |     let _ = s1[2..].find(&s2).is_some();
-   |                     ^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2)`
+   |                     ^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2)`
 
 error: called `is_some()` after calling `find()` on a string
   --> $DIR/search_is_some_fixable_some.rs:40:21
    |
 LL |     let _ = s1[2..].find(&s2[2..]).is_some();
-   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: use `contains()` instead: `contains(&s2[2..])`
+   |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `contains(&s2[2..])`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:56:44
    |
 LL |             .filter(|c| filter_hand.iter().find(|cc| c == cc).is_some())
-   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|cc| c == &cc)`
+   |                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == &cc)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:72:49
    |
 LL |             .filter(|(c, _)| filter_hand.iter().find(|cc| c == *cc).is_some())
-   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|cc| c == cc)`
+   |                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|cc| c == cc)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:83:29
    |
 LL |         let _ = vfoo.iter().find(|v| v.foo == 1 && v.bar == 2).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.foo == 1 && v.bar == 2)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.foo == 1 && v.bar == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:88:14
@@ -147,55 +147,55 @@ error: called `is_some()` after searching an `Iterator` with `find`
 LL |               .find(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)
    |  ______________^
 LL | |             .is_some();
-   | |______________________^ help: use `any()` instead: `any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)`
+   | |______________________^ help: consider using: `any(|(i, v)| *i == 42 && v.foo == 1 && v.bar == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:94:29
    |
 LL |         let _ = vfoo.iter().find(|a| a[0] == 42).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|a| a[0] == 42)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|a| a[0] == 42)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:100:29
    |
 LL |         let _ = vfoo.iter().find(|sub| sub[1..4].len() == 3).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|sub| sub[1..4].len() == 3)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|sub| sub[1..4].len() == 3)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:118:30
    |
 LL |         let _ = [ppx].iter().find(|ppp_x: &&&u32| please(**ppp_x)).is_some();
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|ppp_x: &&u32| please(ppp_x))`
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|ppp_x: &&u32| please(ppp_x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:119:50
    |
 LL |         let _ = [String::from("Hey hey")].iter().find(|s| s.len() == 2).is_some();
-   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| s.len() == 2)`
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s.len() == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:122:26
    |
 LL |         let _ = v.iter().find(|x| deref_enough(**x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| deref_enough(*x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| deref_enough(*x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:123:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| deref_enough(**x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| deref_enough(*x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| deref_enough(*x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:126:26
    |
 LL |         let _ = v.iter().find(|x| arg_no_deref(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| arg_no_deref(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| arg_no_deref(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:128:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| arg_no_deref(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:150:14
@@ -203,91 +203,91 @@ error: called `is_some()` after searching an `Iterator` with `find`
 LL |               .find(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)
    |  ______________^
 LL | |             .is_some();
-   | |______________________^ help: use `any()` instead: `any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)`
+   | |______________________^ help: consider using: `any(|v| v.inner_double.bar[0][0] == 2 && v.inner.bar[0] == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:164:29
    |
 LL |         let _ = vfoo.iter().find(|v| v.inner[0].bar == 2).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.inner[0].bar == 2)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.inner[0].bar == 2)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:169:29
    |
 LL |         let _ = vfoo.iter().find(|x| (**x)[0] == 9).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x| (**x)[0] == 9)`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x| (**x)[0] == 9)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:182:29
    |
 LL |         let _ = vfoo.iter().find(|v| v.by_ref(&v.bar)).is_some();
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|v| v.by_ref(&v.bar))`
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|v| v.by_ref(&v.bar))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:186:55
    |
 LL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|(&x, y)| x == *y).is_some();
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|(&x, y)| x == *y)`
+   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:187:55
    |
 LL |         let _ = [&(&1, 2), &(&3, 4), &(&5, 4)].iter().find(|&(&x, y)| x == *y).is_some();
-   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|(&x, y)| x == *y)`
+   |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|(&x, y)| x == *y)`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:206:26
    |
 LL |         let _ = v.iter().find(|s| s[0].is_empty()).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| s[0].is_empty())`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| s[0].is_empty())`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:207:26
    |
 LL |         let _ = v.iter().find(|s| test_string_1(&s[0])).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|s| test_string_1(&s[0]))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|s| test_string_1(&s[0]))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:216:26
    |
 LL |         let _ = v.iter().find(|fp| fp.field.is_power_of_two()).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| fp.field.is_power_of_two())`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| fp.field.is_power_of_two())`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:217:26
    |
 LL |         let _ = v.iter().find(|fp| test_u32_1(fp.field)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| test_u32_1(fp.field))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_1(fp.field))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:218:26
    |
 LL |         let _ = v.iter().find(|fp| test_u32_2(*fp.field)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|fp| test_u32_2(*fp.field))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|fp| test_u32_2(*fp.field))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:233:18
    |
 LL |         v.iter().find(|x: &&u32| func(x)).is_some()
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| func(&x))`
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| func(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:242:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| arg_no_deref_impl(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref_impl(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_impl(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:245:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| arg_no_deref_dyn(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| arg_no_deref_dyn(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| arg_no_deref_dyn(&x))`
 
 error: called `is_some()` after searching an `Iterator` with `find`
   --> $DIR/search_is_some_fixable_some.rs:248:26
    |
 LL |         let _ = v.iter().find(|x: &&u32| (*arg_no_deref_dyn)(x)).is_some();
-   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `any()` instead: `any(|x: &u32| (*arg_no_deref_dyn)(&x))`
+   |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `any(|x: &u32| (*arg_no_deref_dyn)(&x))`
 
 error: aborting due to 47 previous errors
 
diff --git a/tests/ui/seek_to_start_instead_of_rewind.fixed b/tests/ui/seek_to_start_instead_of_rewind.fixed
index 15cc8d54faa..8859a68320f 100644
--- a/tests/ui/seek_to_start_instead_of_rewind.fixed
+++ b/tests/ui/seek_to_start_instead_of_rewind.fixed
@@ -80,6 +80,7 @@ fn main() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
@@ -104,6 +105,7 @@ fn msrv_1_54() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
@@ -124,6 +126,7 @@ fn msrv_1_55() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
diff --git a/tests/ui/seek_to_start_instead_of_rewind.rs b/tests/ui/seek_to_start_instead_of_rewind.rs
index 197225ffbd5..7b72efb34ff 100644
--- a/tests/ui/seek_to_start_instead_of_rewind.rs
+++ b/tests/ui/seek_to_start_instead_of_rewind.rs
@@ -80,6 +80,7 @@ fn main() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
@@ -104,6 +105,7 @@ fn msrv_1_54() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
@@ -124,6 +126,7 @@ fn msrv_1_55() {
         .write(true)
         .read(true)
         .create(true)
+        .truncate(true)
         .open("foo.txt")
         .unwrap();
 
diff --git a/tests/ui/seek_to_start_instead_of_rewind.stderr b/tests/ui/seek_to_start_instead_of_rewind.stderr
index 05c11cf7f8c..b6b0d2effa8 100644
--- a/tests/ui/seek_to_start_instead_of_rewind.stderr
+++ b/tests/ui/seek_to_start_instead_of_rewind.stderr
@@ -14,7 +14,7 @@ LL |     t.seek(SeekFrom::Start(0));
    |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`
 
 error: used `seek` to go to the start of the stream
-  --> $DIR/seek_to_start_instead_of_rewind.rs:133:7
+  --> $DIR/seek_to_start_instead_of_rewind.rs:136:7
    |
 LL |     f.seek(SeekFrom::Start(0));
    |       ^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with: `rewind()`
diff --git a/tests/ui/semicolon_if_nothing_returned.fixed b/tests/ui/semicolon_if_nothing_returned.fixed
index bbcc0de27d1..cdfa5d9cc78 100644
--- a/tests/ui/semicolon_if_nothing_returned.fixed
+++ b/tests/ui/semicolon_if_nothing_returned.fixed
@@ -1,6 +1,11 @@
+//@aux-build:proc_macro_attr.rs
+
 #![warn(clippy::semicolon_if_nothing_returned)]
 #![allow(clippy::redundant_closure, clippy::uninlined_format_args, clippy::needless_late_init)]
 
+#[macro_use]
+extern crate proc_macro_attr;
+
 fn get_unit() {}
 
 // the functions below trigger the lint
@@ -120,3 +125,32 @@ fn let_else_stmts() {
         return;
     };
 }
+
+mod issue12123 {
+    #[rustfmt::skip]
+    mod this_triggers {
+        #[fake_main]
+        async fn main() {
+
+        }
+    }
+
+    mod and_this {
+        #[fake_main]
+        async fn main() {
+            println!("hello");
+        }
+    }
+
+    #[rustfmt::skip]
+    mod maybe_this {
+        /** */ #[fake_main]
+        async fn main() {
+        }
+    }
+
+    mod but_this_does_not {
+        #[fake_main]
+        async fn main() {}
+    }
+}
diff --git a/tests/ui/semicolon_if_nothing_returned.rs b/tests/ui/semicolon_if_nothing_returned.rs
index fdc9c0c33f5..315b7e4f383 100644
--- a/tests/ui/semicolon_if_nothing_returned.rs
+++ b/tests/ui/semicolon_if_nothing_returned.rs
@@ -1,6 +1,11 @@
+//@aux-build:proc_macro_attr.rs
+
 #![warn(clippy::semicolon_if_nothing_returned)]
 #![allow(clippy::redundant_closure, clippy::uninlined_format_args, clippy::needless_late_init)]
 
+#[macro_use]
+extern crate proc_macro_attr;
+
 fn get_unit() {}
 
 // the functions below trigger the lint
@@ -120,3 +125,32 @@ fn let_else_stmts() {
         return;
     };
 }
+
+mod issue12123 {
+    #[rustfmt::skip]
+    mod this_triggers {
+        #[fake_main]
+        async fn main() {
+
+        }
+    }
+
+    mod and_this {
+        #[fake_main]
+        async fn main() {
+            println!("hello");
+        }
+    }
+
+    #[rustfmt::skip]
+    mod maybe_this {
+        /** */ #[fake_main]
+        async fn main() {
+        }
+    }
+
+    mod but_this_does_not {
+        #[fake_main]
+        async fn main() {}
+    }
+}
diff --git a/tests/ui/semicolon_if_nothing_returned.stderr b/tests/ui/semicolon_if_nothing_returned.stderr
index 66373a13c56..09c4d12f216 100644
--- a/tests/ui/semicolon_if_nothing_returned.stderr
+++ b/tests/ui/semicolon_if_nothing_returned.stderr
@@ -1,5 +1,5 @@
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:8:5
+  --> $DIR/semicolon_if_nothing_returned.rs:13:5
    |
 LL |     println!("Hello")
    |     ^^^^^^^^^^^^^^^^^ help: add a `;` here: `println!("Hello");`
@@ -8,25 +8,25 @@ LL |     println!("Hello")
    = help: to override `-D warnings` add `#[allow(clippy::semicolon_if_nothing_returned)]`
 
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:12:5
+  --> $DIR/semicolon_if_nothing_returned.rs:17:5
    |
 LL |     get_unit()
    |     ^^^^^^^^^^ help: add a `;` here: `get_unit();`
 
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:17:5
+  --> $DIR/semicolon_if_nothing_returned.rs:22:5
    |
 LL |     y = x + 1
    |     ^^^^^^^^^ help: add a `;` here: `y = x + 1;`
 
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:23:9
+  --> $DIR/semicolon_if_nothing_returned.rs:28:9
    |
 LL |         hello()
    |         ^^^^^^^ help: add a `;` here: `hello();`
 
 error: consider adding a `;` to the last statement for consistent formatting
-  --> $DIR/semicolon_if_nothing_returned.rs:34:9
+  --> $DIR/semicolon_if_nothing_returned.rs:39:9
    |
 LL |         ptr::drop_in_place(s.as_mut_ptr())
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`
diff --git a/tests/ui/single_call_fn.rs b/tests/ui/single_call_fn.rs
index 3cc8061647d..c20214feccc 100644
--- a/tests/ui/single_call_fn.rs
+++ b/tests/ui/single_call_fn.rs
@@ -69,6 +69,17 @@ fn e() {
 #[test]
 fn k() {}
 
+mod issue12182 {
+    #[allow(clippy::single_call_fn)]
+    fn print_foo(text: &str) {
+        println!("{text}");
+    }
+
+    fn use_print_foo() {
+        print_foo("foo");
+    }
+}
+
 #[test]
 fn l() {
     k();
diff --git a/tests/ui/single_char_pattern.stderr b/tests/ui/single_char_pattern.stderr
index 781ab316d9d..664d6b5a1e9 100644
--- a/tests/ui/single_char_pattern.stderr
+++ b/tests/ui/single_char_pattern.stderr
@@ -2,7 +2,7 @@ error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:7:13
    |
 LL |     x.split("x");
-   |             ^^^ help: try using a `char` instead: `'x'`
+   |             ^^^ help: consider using a `char`: `'x'`
    |
    = note: `-D clippy::single-char-pattern` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::single_char_pattern)]`
@@ -11,235 +11,235 @@ error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:13:13
    |
 LL |     x.split("ß");
-   |             ^^^ help: try using a `char` instead: `'ß'`
+   |             ^^^ help: consider using a `char`: `'ß'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:14:13
    |
 LL |     x.split("ℝ");
-   |             ^^^ help: try using a `char` instead: `'ℝ'`
+   |             ^^^ help: consider using a `char`: `'ℝ'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:15:13
    |
 LL |     x.split("💣");
-   |             ^^^^ help: try using a `char` instead: `'💣'`
+   |             ^^^^ help: consider using a `char`: `'💣'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:18:23
    |
 LL |     x.split_inclusive("x");
-   |                       ^^^ help: try using a `char` instead: `'x'`
+   |                       ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:19:16
    |
 LL |     x.contains("x");
-   |                ^^^ help: try using a `char` instead: `'x'`
+   |                ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:20:19
    |
 LL |     x.starts_with("x");
-   |                   ^^^ help: try using a `char` instead: `'x'`
+   |                   ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:21:17
    |
 LL |     x.ends_with("x");
-   |                 ^^^ help: try using a `char` instead: `'x'`
+   |                 ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:22:12
    |
 LL |     x.find("x");
-   |            ^^^ help: try using a `char` instead: `'x'`
+   |            ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:23:13
    |
 LL |     x.rfind("x");
-   |             ^^^ help: try using a `char` instead: `'x'`
+   |             ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:24:14
    |
 LL |     x.rsplit("x");
-   |              ^^^ help: try using a `char` instead: `'x'`
+   |              ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:25:24
    |
 LL |     x.split_terminator("x");
-   |                        ^^^ help: try using a `char` instead: `'x'`
+   |                        ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:26:25
    |
 LL |     x.rsplit_terminator("x");
-   |                         ^^^ help: try using a `char` instead: `'x'`
+   |                         ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:27:17
    |
 LL |     x.splitn(2, "x");
-   |                 ^^^ help: try using a `char` instead: `'x'`
+   |                 ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:28:18
    |
 LL |     x.rsplitn(2, "x");
-   |                  ^^^ help: try using a `char` instead: `'x'`
+   |                  ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:29:18
    |
 LL |     x.split_once("x");
-   |                  ^^^ help: try using a `char` instead: `'x'`
+   |                  ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:30:19
    |
 LL |     x.rsplit_once("x");
-   |                   ^^^ help: try using a `char` instead: `'x'`
+   |                   ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:31:15
    |
 LL |     x.matches("x");
-   |               ^^^ help: try using a `char` instead: `'x'`
+   |               ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:32:16
    |
 LL |     x.rmatches("x");
-   |                ^^^ help: try using a `char` instead: `'x'`
+   |                ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:33:21
    |
 LL |     x.match_indices("x");
-   |                     ^^^ help: try using a `char` instead: `'x'`
+   |                     ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:34:22
    |
 LL |     x.rmatch_indices("x");
-   |                      ^^^ help: try using a `char` instead: `'x'`
+   |                      ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:35:26
    |
 LL |     x.trim_start_matches("x");
-   |                          ^^^ help: try using a `char` instead: `'x'`
+   |                          ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:36:24
    |
 LL |     x.trim_end_matches("x");
-   |                        ^^^ help: try using a `char` instead: `'x'`
+   |                        ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:37:20
    |
 LL |     x.strip_prefix("x");
-   |                    ^^^ help: try using a `char` instead: `'x'`
+   |                    ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:38:20
    |
 LL |     x.strip_suffix("x");
-   |                    ^^^ help: try using a `char` instead: `'x'`
+   |                    ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:39:15
    |
 LL |     x.replace("x", "y");
-   |               ^^^ help: try using a `char` instead: `'x'`
+   |               ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:40:16
    |
 LL |     x.replacen("x", "y", 3);
-   |                ^^^ help: try using a `char` instead: `'x'`
+   |                ^^^ help: consider using a `char`: `'x'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:42:13
    |
 LL |     x.split("\n");
-   |             ^^^^ help: try using a `char` instead: `'\n'`
+   |             ^^^^ help: consider using a `char`: `'\n'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:43:13
    |
 LL |     x.split("'");
-   |             ^^^ help: try using a `char` instead: `'\''`
+   |             ^^^ help: consider using a `char`: `'\''`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:44:13
    |
 LL |     x.split("\'");
-   |             ^^^^ help: try using a `char` instead: `'\''`
+   |             ^^^^ help: consider using a `char`: `'\''`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:46:13
    |
 LL |     x.split("\"");
-   |             ^^^^ help: try using a `char` instead: `'"'`
+   |             ^^^^ help: consider using a `char`: `'"'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:51:31
    |
 LL |     x.replace(';', ",").split(","); // issue #2978
-   |                               ^^^ help: try using a `char` instead: `','`
+   |                               ^^^ help: consider using a `char`: `','`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:52:19
    |
 LL |     x.starts_with("\x03"); // issue #2996
-   |                   ^^^^^^ help: try using a `char` instead: `'\x03'`
+   |                   ^^^^^^ help: consider using a `char`: `'\x03'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:59:13
    |
 LL |     x.split(r"a");
-   |             ^^^^ help: try using a `char` instead: `'a'`
+   |             ^^^^ help: consider using a `char`: `'a'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:60:13
    |
 LL |     x.split(r#"a"#);
-   |             ^^^^^^ help: try using a `char` instead: `'a'`
+   |             ^^^^^^ help: consider using a `char`: `'a'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:61:13
    |
 LL |     x.split(r###"a"###);
-   |             ^^^^^^^^^^ help: try using a `char` instead: `'a'`
+   |             ^^^^^^^^^^ help: consider using a `char`: `'a'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:62:13
    |
 LL |     x.split(r###"'"###);
-   |             ^^^^^^^^^^ help: try using a `char` instead: `'\''`
+   |             ^^^^^^^^^^ help: consider using a `char`: `'\''`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:63:13
    |
 LL |     x.split(r###"#"###);
-   |             ^^^^^^^^^^ help: try using a `char` instead: `'#'`
+   |             ^^^^^^^^^^ help: consider using a `char`: `'#'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:65:13
    |
 LL |     x.split(r#"\"#);
-   |             ^^^^^^ help: try using a `char` instead: `'\\'`
+   |             ^^^^^^ help: consider using a `char`: `'\\'`
 
 error: single-character string constant used as pattern
   --> $DIR/single_char_pattern.rs:66:13
    |
 LL |     x.split(r"\");
-   |             ^^^^ help: try using a `char` instead: `'\\'`
+   |             ^^^^ help: consider using a `char`: `'\\'`
 
 error: aborting due to 40 previous errors
 
diff --git a/tests/ui/trait_duplication_in_bounds.fixed b/tests/ui/trait_duplication_in_bounds.fixed
index 4fca29698e0..7e2663d734f 100644
--- a/tests/ui/trait_duplication_in_bounds.fixed
+++ b/tests/ui/trait_duplication_in_bounds.fixed
@@ -118,4 +118,33 @@ fn bad_trait_object(arg0: &(dyn Any + Send)) {
     unimplemented!();
 }
 
-fn main() {}
+trait Proj {
+    type S;
+}
+
+impl Proj for () {
+    type S = ();
+}
+
+impl Proj for i32 {
+    type S = i32;
+}
+
+trait Base<T> {
+    fn is_base(&self);
+}
+
+trait Derived<B: Proj>: Base<B::S> + Base<()> {
+    fn is_derived(&self);
+}
+
+fn f<P: Proj>(obj: &dyn Derived<P>) {
+    obj.is_derived();
+    Base::<P::S>::is_base(obj);
+    Base::<()>::is_base(obj);
+}
+
+fn main() {
+    let _x: fn(_) = f::<()>;
+    let _x: fn(_) = f::<i32>;
+}
diff --git a/tests/ui/trait_duplication_in_bounds.rs b/tests/ui/trait_duplication_in_bounds.rs
index f67c8e35ed4..fede1671a43 100644
--- a/tests/ui/trait_duplication_in_bounds.rs
+++ b/tests/ui/trait_duplication_in_bounds.rs
@@ -118,4 +118,33 @@ fn bad_trait_object(arg0: &(dyn Any + Send + Send)) {
     unimplemented!();
 }
 
-fn main() {}
+trait Proj {
+    type S;
+}
+
+impl Proj for () {
+    type S = ();
+}
+
+impl Proj for i32 {
+    type S = i32;
+}
+
+trait Base<T> {
+    fn is_base(&self);
+}
+
+trait Derived<B: Proj>: Base<B::S> + Base<()> {
+    fn is_derived(&self);
+}
+
+fn f<P: Proj>(obj: &dyn Derived<P>) {
+    obj.is_derived();
+    Base::<P::S>::is_base(obj);
+    Base::<()>::is_base(obj);
+}
+
+fn main() {
+    let _x: fn(_) = f::<()>;
+    let _x: fn(_) = f::<i32>;
+}
diff --git a/tests/ui/transmute.rs b/tests/ui/transmute.rs
index 32f6027e991..1796ccaf28e 100644
--- a/tests/ui/transmute.rs
+++ b/tests/ui/transmute.rs
@@ -102,19 +102,6 @@ fn crosspointer() {
     }
 }
 
-#[warn(clippy::transmute_int_to_char)]
-fn int_to_char() {
-    let _: char = unsafe { std::mem::transmute(0_u32) };
-    //~^ ERROR: transmute from a `u32` to a `char`
-    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
-    let _: char = unsafe { std::mem::transmute(0_i32) };
-    //~^ ERROR: transmute from a `i32` to a `char`
-
-    // These shouldn't warn
-    const _: char = unsafe { std::mem::transmute(0_u32) };
-    const _: char = unsafe { std::mem::transmute(0_i32) };
-}
-
 #[warn(clippy::transmute_int_to_bool)]
 fn int_to_bool() {
     let _: bool = unsafe { std::mem::transmute(0_u8) };
diff --git a/tests/ui/transmute.stderr b/tests/ui/transmute.stderr
index cdc733b54a9..df32d478cbf 100644
--- a/tests/ui/transmute.stderr
+++ b/tests/ui/transmute.stderr
@@ -88,23 +88,8 @@ error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`)
 LL |         let _: *mut Usize = core::intrinsics::transmute(my_int());
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: transmute from a `u32` to a `char`
-  --> $DIR/transmute.rs:107:28
-   |
-LL |     let _: char = unsafe { std::mem::transmute(0_u32) };
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
-   |
-   = note: `-D clippy::transmute-int-to-char` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]`
-
-error: transmute from a `i32` to a `char`
-  --> $DIR/transmute.rs:110:28
-   |
-LL |     let _: char = unsafe { std::mem::transmute(0_i32) };
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
-
 error: transmute from a `u8` to a `bool`
-  --> $DIR/transmute.rs:120:28
+  --> $DIR/transmute.rs:107:28
    |
 LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
@@ -113,7 +98,7 @@ LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]`
 
 error: transmute from a `u32` to a `f32`
-  --> $DIR/transmute.rs:128:31
+  --> $DIR/transmute.rs:115:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
@@ -122,25 +107,25 @@ LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_float)]`
 
 error: transmute from a `i32` to a `f32`
-  --> $DIR/transmute.rs:131:31
+  --> $DIR/transmute.rs:118:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_i32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
 
 error: transmute from a `u64` to a `f64`
-  --> $DIR/transmute.rs:133:31
+  --> $DIR/transmute.rs:120:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_u64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
 
 error: transmute from a `i64` to a `f64`
-  --> $DIR/transmute.rs:135:31
+  --> $DIR/transmute.rs:122:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_i64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:156:30
+  --> $DIR/transmute.rs:143:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
@@ -149,85 +134,85 @@ LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:159:30
+  --> $DIR/transmute.rs:146:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:161:31
+  --> $DIR/transmute.rs:148:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:163:30
+  --> $DIR/transmute.rs:150:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:165:30
+  --> $DIR/transmute.rs:152:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:167:31
+  --> $DIR/transmute.rs:154:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `f32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:169:30
+  --> $DIR/transmute.rs:156:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0.0f32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
 
 error: transmute from a `f64` to a `[u8; 8]`
-  --> $DIR/transmute.rs:171:30
+  --> $DIR/transmute.rs:158:30
    |
 LL |             let _: [u8; 8] = std::mem::transmute(0.0f64);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:177:30
+  --> $DIR/transmute.rs:164:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:179:30
+  --> $DIR/transmute.rs:166:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:181:31
+  --> $DIR/transmute.rs:168:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:183:30
+  --> $DIR/transmute.rs:170:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:185:30
+  --> $DIR/transmute.rs:172:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:187:31
+  --> $DIR/transmute.rs:174:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `&[u8]` to a `&str`
-  --> $DIR/transmute.rs:198:28
+  --> $DIR/transmute.rs:185:28
    |
 LL |     let _: &str = unsafe { std::mem::transmute(B) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
@@ -236,16 +221,16 @@ LL |     let _: &str = unsafe { std::mem::transmute(B) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]`
 
 error: transmute from a `&mut [u8]` to a `&mut str`
-  --> $DIR/transmute.rs:201:32
+  --> $DIR/transmute.rs:188:32
    |
 LL |     let _: &mut str = unsafe { std::mem::transmute(mb) };
    |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
 
 error: transmute from a `&[u8]` to a `&str`
-  --> $DIR/transmute.rs:203:30
+  --> $DIR/transmute.rs:190:30
    |
 LL |     const _: &str = unsafe { std::mem::transmute(B) };
    |                              ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
 
-error: aborting due to 38 previous errors
+error: aborting due to 36 previous errors
 
diff --git a/tests/ui/transmute_int_to_char.fixed b/tests/ui/transmute_int_to_char.fixed
new file mode 100644
index 00000000000..17080118175
--- /dev/null
+++ b/tests/ui/transmute_int_to_char.fixed
@@ -0,0 +1,15 @@
+#![warn(clippy::transmute_int_to_char)]
+
+fn int_to_char() {
+    let _: char = unsafe { std::char::from_u32(0_u32).unwrap() };
+    //~^ ERROR: transmute from a `u32` to a `char`
+    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+    let _: char = unsafe { std::char::from_u32(0_i32 as u32).unwrap() };
+    //~^ ERROR: transmute from a `i32` to a `char`
+
+    // These shouldn't warn
+    const _: char = unsafe { std::mem::transmute(0_u32) };
+    const _: char = unsafe { std::mem::transmute(0_i32) };
+}
+
+fn main() {}
diff --git a/tests/ui/transmute_int_to_char.rs b/tests/ui/transmute_int_to_char.rs
new file mode 100644
index 00000000000..5846a97e88a
--- /dev/null
+++ b/tests/ui/transmute_int_to_char.rs
@@ -0,0 +1,15 @@
+#![warn(clippy::transmute_int_to_char)]
+
+fn int_to_char() {
+    let _: char = unsafe { std::mem::transmute(0_u32) };
+    //~^ ERROR: transmute from a `u32` to a `char`
+    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+    let _: char = unsafe { std::mem::transmute(0_i32) };
+    //~^ ERROR: transmute from a `i32` to a `char`
+
+    // These shouldn't warn
+    const _: char = unsafe { std::mem::transmute(0_u32) };
+    const _: char = unsafe { std::mem::transmute(0_i32) };
+}
+
+fn main() {}
diff --git a/tests/ui/transmute_int_to_char.stderr b/tests/ui/transmute_int_to_char.stderr
new file mode 100644
index 00000000000..2297f5b4f8b
--- /dev/null
+++ b/tests/ui/transmute_int_to_char.stderr
@@ -0,0 +1,17 @@
+error: transmute from a `u32` to a `char`
+  --> $DIR/transmute_int_to_char.rs:4:28
+   |
+LL |     let _: char = unsafe { std::mem::transmute(0_u32) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
+   |
+   = note: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]`
+
+error: transmute from a `i32` to a `char`
+  --> $DIR/transmute_int_to_char.rs:7:28
+   |
+LL |     let _: char = unsafe { std::mem::transmute(0_i32) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/transmute_int_to_char_no_std.fixed b/tests/ui/transmute_int_to_char_no_std.fixed
new file mode 100644
index 00000000000..9ae4e11fb56
--- /dev/null
+++ b/tests/ui/transmute_int_to_char_no_std.fixed
@@ -0,0 +1,27 @@
+#![no_std]
+#![feature(lang_items)]
+#![warn(clippy::transmute_int_to_char)]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn int_to_char() {
+    let _: char = unsafe { core::char::from_u32(0_u32).unwrap() };
+    //~^ ERROR: transmute from a `u32` to a `char`
+    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+    let _: char = unsafe { core::char::from_u32(0_i32 as u32).unwrap() };
+    //~^ ERROR: transmute from a `i32` to a `char`
+
+    // These shouldn't warn
+    const _: char = unsafe { core::mem::transmute(0_u32) };
+    const _: char = unsafe { core::mem::transmute(0_i32) };
+}
+
+fn main() {}
diff --git a/tests/ui/transmute_int_to_char_no_std.rs b/tests/ui/transmute_int_to_char_no_std.rs
new file mode 100644
index 00000000000..9a2afd5bd2f
--- /dev/null
+++ b/tests/ui/transmute_int_to_char_no_std.rs
@@ -0,0 +1,27 @@
+#![no_std]
+#![feature(lang_items)]
+#![warn(clippy::transmute_int_to_char)]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn int_to_char() {
+    let _: char = unsafe { core::mem::transmute(0_u32) };
+    //~^ ERROR: transmute from a `u32` to a `char`
+    //~| NOTE: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+    let _: char = unsafe { core::mem::transmute(0_i32) };
+    //~^ ERROR: transmute from a `i32` to a `char`
+
+    // These shouldn't warn
+    const _: char = unsafe { core::mem::transmute(0_u32) };
+    const _: char = unsafe { core::mem::transmute(0_i32) };
+}
+
+fn main() {}
diff --git a/tests/ui/transmute_int_to_char_no_std.stderr b/tests/ui/transmute_int_to_char_no_std.stderr
new file mode 100644
index 00000000000..aace6968696
--- /dev/null
+++ b/tests/ui/transmute_int_to_char_no_std.stderr
@@ -0,0 +1,17 @@
+error: transmute from a `u32` to a `char`
+  --> $DIR/transmute_int_to_char_no_std.rs:16:28
+   |
+LL |     let _: char = unsafe { core::mem::transmute(0_u32) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::char::from_u32(0_u32).unwrap()`
+   |
+   = note: `-D clippy::transmute-int-to-char` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]`
+
+error: transmute from a `i32` to a `char`
+  --> $DIR/transmute_int_to_char_no_std.rs:19:28
+   |
+LL |     let _: char = unsafe { core::mem::transmute(0_i32) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::char::from_u32(0_i32 as u32).unwrap()`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/transmute_ref_to_ref.rs b/tests/ui/transmute_ref_to_ref.rs
index e7f35c57436..bdc7b9f6478 100644
--- a/tests/ui/transmute_ref_to_ref.rs
+++ b/tests/ui/transmute_ref_to_ref.rs
@@ -12,7 +12,7 @@ fn main() {
         let b: &[u8] = unsafe { std::mem::transmute(a) };
         //~^ ERROR: transmute from a reference to a reference
         let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
-        let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
+        let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) };
         //~^ ERROR: transmute from a reference to a reference
     }
 }
diff --git a/tests/ui/transmute_ref_to_ref.stderr b/tests/ui/transmute_ref_to_ref.stderr
index cc6b156b188..4238bc637ad 100644
--- a/tests/ui/transmute_ref_to_ref.stderr
+++ b/tests/ui/transmute_ref_to_ref.stderr
@@ -19,8 +19,8 @@ LL |         let b: &[u8] = unsafe { std::mem::transmute(a) };
 error: transmute from a reference to a reference
   --> $DIR/transmute_ref_to_ref.rs:15:42
    |
-LL |         let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`
+LL |         let alt_slice: &[u32] = unsafe { std::mem::transmute(bytes) };
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/transmute_ref_to_ref_no_std.rs b/tests/ui/transmute_ref_to_ref_no_std.rs
new file mode 100644
index 00000000000..b67386f8588
--- /dev/null
+++ b/tests/ui/transmute_ref_to_ref_no_std.rs
@@ -0,0 +1,30 @@
+//@no-rustfix
+
+#![deny(clippy::transmute_ptr_to_ptr)]
+#![allow(dead_code)]
+#![feature(lang_items)]
+#![no_std]
+
+use core::panic::PanicInfo;
+
+#[lang = "eh_personality"]
+extern "C" fn eh_personality() {}
+
+#[panic_handler]
+fn panic(info: &PanicInfo) -> ! {
+    loop {}
+}
+
+fn main() {
+    unsafe {
+        let single_u64: &[u64] = &[0xDEAD_BEEF_DEAD_BEEF];
+        let bools: &[bool] = unsafe { core::mem::transmute(single_u64) };
+        //~^ ERROR: transmute from a reference to a reference
+        let a: &[u32] = &[0x12345678, 0x90ABCDEF, 0xFEDCBA09, 0x87654321];
+        let b: &[u8] = unsafe { core::mem::transmute(a) };
+        //~^ ERROR: transmute from a reference to a reference
+        let bytes = &[1u8, 2u8, 3u8, 4u8] as &[u8];
+        let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
+        //~^ ERROR: transmute from a reference to a reference
+    }
+}
diff --git a/tests/ui/transmute_ref_to_ref_no_std.stderr b/tests/ui/transmute_ref_to_ref_no_std.stderr
new file mode 100644
index 00000000000..ca7966ffa9e
--- /dev/null
+++ b/tests/ui/transmute_ref_to_ref_no_std.stderr
@@ -0,0 +1,26 @@
+error: transmute from a reference to a reference
+  --> $DIR/transmute_ref_to_ref_no_std.rs:21:39
+   |
+LL |         let bools: &[bool] = unsafe { core::mem::transmute(single_u64) };
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(single_u64 as *const [u64] as *const [bool])`
+   |
+note: the lint level is defined here
+  --> $DIR/transmute_ref_to_ref_no_std.rs:3:9
+   |
+LL | #![deny(clippy::transmute_ptr_to_ptr)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: transmute from a reference to a reference
+  --> $DIR/transmute_ref_to_ref_no_std.rs:24:33
+   |
+LL |         let b: &[u8] = unsafe { core::mem::transmute(a) };
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const [u32] as *const [u8])`
+
+error: transmute from a reference to a reference
+  --> $DIR/transmute_ref_to_ref_no_std.rs:27:42
+   |
+LL |         let alt_slice: &[u32] = unsafe { core::mem::transmute(bytes) };
+   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(bytes as *const [u8] as *const [u32])`
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/unconditional_recursion.rs b/tests/ui/unconditional_recursion.rs
index e1a2d6a90b8..7b898a6e0e7 100644
--- a/tests/ui/unconditional_recursion.rs
+++ b/tests/ui/unconditional_recursion.rs
@@ -264,6 +264,28 @@ impl S13 {
     }
 }
 
-fn main() {
-    // test code goes here
+struct S14 {
+    field: String,
+}
+
+impl PartialEq for S14 {
+    fn eq(&self, other: &Self) -> bool {
+        // Should not warn!
+        self.field.eq(&other.field)
+    }
+}
+
+struct S15<'a> {
+    field: &'a S15<'a>,
 }
+
+impl PartialEq for S15<'_> {
+    fn eq(&self, other: &Self) -> bool {
+        //~^ ERROR: function cannot return without recursing
+        let mine = &self.field;
+        let theirs = &other.field;
+        mine.eq(theirs)
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/unconditional_recursion.stderr b/tests/ui/unconditional_recursion.stderr
index 5d82e2a9f31..094b80d4586 100644
--- a/tests/ui/unconditional_recursion.stderr
+++ b/tests/ui/unconditional_recursion.stderr
@@ -340,5 +340,22 @@ note: recursive call site
 LL |         Self::default()
    |         ^^^^^^^^^^^^^^^
 
-error: aborting due to 26 previous errors
+error: function cannot return without recursing
+  --> $DIR/unconditional_recursion.rs:283:5
+   |
+LL | /     fn eq(&self, other: &Self) -> bool {
+LL | |
+LL | |         let mine = &self.field;
+LL | |         let theirs = &other.field;
+LL | |         mine.eq(theirs)
+LL | |     }
+   | |_____^
+   |
+note: recursive call site
+  --> $DIR/unconditional_recursion.rs:287:9
+   |
+LL |         mine.eq(theirs)
+   |         ^^^^^^^^^^^^^^^
+
+error: aborting due to 27 previous errors
 
diff --git a/tests/ui/unnecessary_join.stderr b/tests/ui/unnecessary_join.stderr
index 8bf2ac5fdb1..205a714b694 100644
--- a/tests/ui/unnecessary_join.stderr
+++ b/tests/ui/unnecessary_join.stderr
@@ -4,7 +4,7 @@ error: called `.collect::<Vec<String>>().join("")` on an iterator
 LL |           .collect::<Vec<String>>()
    |  __________^
 LL | |         .join("");
-   | |_________________^ help: try using: `collect::<String>()`
+   | |_________________^ help: consider using: `collect::<String>()`
    |
    = note: `-D clippy::unnecessary-join` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_join)]`
@@ -15,7 +15,7 @@ error: called `.collect::<Vec<String>>().join("")` on an iterator
 LL |           .collect::<Vec<_>>()
    |  __________^
 LL | |         .join("");
-   | |_________________^ help: try using: `collect::<String>()`
+   | |_________________^ help: consider using: `collect::<String>()`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/unnecessary_sort_by.stderr b/tests/ui/unnecessary_sort_by.stderr
index 9d54c8d50e3..f4409113a45 100644
--- a/tests/ui/unnecessary_sort_by.stderr
+++ b/tests/ui/unnecessary_sort_by.stderr
@@ -1,4 +1,4 @@
-error: use Vec::sort here instead
+error: consider using `sort`
   --> $DIR/unnecessary_sort_by.rs:12:5
    |
 LL |     vec.sort_by(|a, b| a.cmp(b));
@@ -7,67 +7,67 @@ LL |     vec.sort_by(|a, b| a.cmp(b));
    = note: `-D clippy::unnecessary-sort-by` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_sort_by)]`
 
-error: use Vec::sort here instead
+error: consider using `sort`
   --> $DIR/unnecessary_sort_by.rs:13:5
    |
 LL |     vec.sort_unstable_by(|a, b| a.cmp(b));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable()`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:14:5
    |
 LL |     vec.sort_by(|a, b| (a + 5).abs().cmp(&(b + 5).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (a + 5).abs())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:15:5
    |
 LL |     vec.sort_unstable_by(|a, b| id(-a).cmp(&id(-b)));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| id(-a))`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:18:5
    |
 LL |     vec.sort_by(|a, b| (b + 5).abs().cmp(&(a + 5).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|b| std::cmp::Reverse((b + 5).abs()))`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:19:5
    |
 LL |     vec.sort_unstable_by(|a, b| id(-b).cmp(&id(-a)));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|b| std::cmp::Reverse(id(-b)))`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:29:5
    |
 LL |     vec.sort_by(|a, b| (***a).abs().cmp(&(***b).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_by_key(|a| (***a).abs())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:30:5
    |
 LL |     vec.sort_unstable_by(|a, b| (***a).abs().cmp(&(***b).abs()));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `vec.sort_unstable_by_key(|a| (***a).abs())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:89:9
    |
 LL |         args.sort_by(|a, b| a.name().cmp(&b.name()));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|a| a.name())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:90:9
    |
 LL |         args.sort_unstable_by(|a, b| a.name().cmp(&b.name()));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_unstable_by_key(|a| a.name())`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:92:9
    |
 LL |         args.sort_by(|a, b| b.name().cmp(&a.name()));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `args.sort_by_key(|b| std::cmp::Reverse(b.name()))`
 
-error: use Vec::sort_by_key here instead
+error: consider using `sort_by_key`
   --> $DIR/unnecessary_sort_by.rs:93:9
    |
 LL |         args.sort_unstable_by(|a, b| b.name().cmp(&a.name()));
diff --git a/tests/ui/unused_io_amount.rs b/tests/ui/unused_io_amount.rs
index 62aec6e9eaf..9974600dad5 100644
--- a/tests/ui/unused_io_amount.rs
+++ b/tests/ui/unused_io_amount.rs
@@ -1,4 +1,5 @@
 #![allow(dead_code, clippy::needless_pass_by_ref_mut)]
+#![allow(clippy::redundant_pattern_matching)]
 #![warn(clippy::unused_io_amount)]
 
 extern crate futures;
@@ -142,4 +143,90 @@ async fn undetected_bad_async_write<W: AsyncWrite + Unpin>(w: &mut W) {
     future.await.unwrap();
 }
 
+fn match_okay_underscore<T: io::Read + io::Write>(s: &mut T) {
+    match s.write(b"test") {
+        //~^ ERROR: written amount is not handled
+        Ok(_) => todo!(),
+        //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled
+        Err(_) => todo!(),
+    };
+
+    let mut buf = [0u8; 4];
+    match s.read(&mut buf) {
+        //~^ ERROR: read amount is not handled
+        Ok(_) => todo!(),
+        //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled
+        Err(_) => todo!(),
+    }
+}
+
+fn match_okay_underscore_read_expr<T: io::Read + io::Write>(s: &mut T) {
+    match s.read(&mut [0u8; 4]) {
+        //~^ ERROR: read amount is not handled
+        Ok(_) => todo!(),
+        //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled
+        Err(_) => todo!(),
+    }
+}
+
+fn match_okay_underscore_write_expr<T: io::Read + io::Write>(s: &mut T) {
+    match s.write(b"test") {
+        //~^ ERROR: written amount is not handled
+        Ok(_) => todo!(),
+        //~^ NOTE: the result is consumed here, but the amount of I/O bytes remains unhandled
+        Err(_) => todo!(),
+    }
+}
+
+fn returned_value_should_not_lint<T: io::Read + io::Write>(s: &mut T) -> Result<usize, std::io::Error> {
+    s.write(b"test")
+}
+
+fn if_okay_underscore_read_expr<T: io::Read + io::Write>(s: &mut T) {
+    if let Ok(_) = s.read(&mut [0u8; 4]) {
+        //~^ ERROR: read amount is not handled
+        todo!()
+    }
+}
+
+fn if_okay_underscore_write_expr<T: io::Read + io::Write>(s: &mut T) {
+    if let Ok(_) = s.write(b"test") {
+        //~^ ERROR: written amount is not handled
+        todo!()
+    }
+}
+
+fn if_okay_dots_write_expr<T: io::Read + io::Write>(s: &mut T) {
+    if let Ok(..) = s.write(b"test") {
+        //~^ ERROR: written amount is not handled
+        todo!()
+    }
+}
+
+fn if_okay_underscore_write_expr_true_negative<T: io::Read + io::Write>(s: &mut T) {
+    if let Ok(bound) = s.write(b"test") {
+        todo!()
+    }
+}
+
+fn match_okay_underscore_true_neg<T: io::Read + io::Write>(s: &mut T) {
+    match s.write(b"test") {
+        Ok(bound) => todo!(),
+        Err(_) => todo!(),
+    };
+}
+
+fn true_negative<T: io::Read + io::Write>(s: &mut T) {
+    let mut buf = [0u8; 4];
+    let read_amount = s.read(&mut buf).unwrap();
+}
+
+fn on_return_should_not_raise<T: io::Read + io::Write>(s: &mut T) -> io::Result<usize> {
+    /// this is bad code because it goes around the problem of handling the read amount
+    /// by returning it, which makes it impossible to know this is a resonpose from the
+    /// correct account.
+    let mut buf = [0u8; 4];
+    s.read(&mut buf)
+}
+
 fn main() {}
diff --git a/tests/ui/unused_io_amount.stderr b/tests/ui/unused_io_amount.stderr
index f9aef596a1c..4af56d264bf 100644
--- a/tests/ui/unused_io_amount.stderr
+++ b/tests/ui/unused_io_amount.stderr
@@ -1,5 +1,5 @@
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:9:5
+  --> $DIR/unused_io_amount.rs:10:5
    |
 LL |     s.write(b"test")?;
    |     ^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     s.write(b"test")?;
    = help: to override `-D warnings` add `#[allow(clippy::unused_io_amount)]`
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:12:5
+  --> $DIR/unused_io_amount.rs:13:5
    |
 LL |     s.read(&mut buf)?;
    |     ^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     s.read(&mut buf)?;
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:18:5
+  --> $DIR/unused_io_amount.rs:19:5
    |
 LL |     s.write(b"test").unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     s.write(b"test").unwrap();
    = help: use `Write::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:21:5
+  --> $DIR/unused_io_amount.rs:22:5
    |
 LL |     s.read(&mut buf).unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -33,19 +33,19 @@ LL |     s.read(&mut buf).unwrap();
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:26:5
+  --> $DIR/unused_io_amount.rs:27:5
    |
 LL |     s.read_vectored(&mut [io::IoSliceMut::new(&mut [])])?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:28:5
+  --> $DIR/unused_io_amount.rs:29:5
    |
 LL |     s.write_vectored(&[io::IoSlice::new(&[])])?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:36:5
+  --> $DIR/unused_io_amount.rs:37:5
    |
 LL |     reader.read(&mut result).ok()?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -53,7 +53,7 @@ LL |     reader.read(&mut result).ok()?;
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:46:5
+  --> $DIR/unused_io_amount.rs:47:5
    |
 LL |     reader.read(&mut result).or_else(|err| Err(err))?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL |     reader.read(&mut result).or_else(|err| Err(err))?;
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:59:5
+  --> $DIR/unused_io_amount.rs:60:5
    |
 LL |     reader.read(&mut result).or(Err(Error::Kind))?;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -69,7 +69,7 @@ LL |     reader.read(&mut result).or(Err(Error::Kind))?;
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:67:5
+  --> $DIR/unused_io_amount.rs:68:5
    |
 LL | /     reader
 LL | |
@@ -82,7 +82,7 @@ LL | |         .expect("error");
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:77:5
+  --> $DIR/unused_io_amount.rs:78:5
    |
 LL |     s.write(b"ok").is_ok();
    |     ^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     s.write(b"ok").is_ok();
    = help: use `Write::write_all` instead, or handle partial writes
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:79:5
+  --> $DIR/unused_io_amount.rs:80:5
    |
 LL |     s.write(b"err").is_err();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -98,7 +98,7 @@ LL |     s.write(b"err").is_err();
    = help: use `Write::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:82:5
+  --> $DIR/unused_io_amount.rs:83:5
    |
 LL |     s.read(&mut buf).is_ok();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -106,7 +106,7 @@ LL |     s.read(&mut buf).is_ok();
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:84:5
+  --> $DIR/unused_io_amount.rs:85:5
    |
 LL |     s.read(&mut buf).is_err();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -114,7 +114,7 @@ LL |     s.read(&mut buf).is_err();
    = help: use `Read::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:89:5
+  --> $DIR/unused_io_amount.rs:90:5
    |
 LL |     w.write(b"hello world").await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -122,7 +122,7 @@ LL |     w.write(b"hello world").await.unwrap();
    = help: use `AsyncWriteExt::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:95:5
+  --> $DIR/unused_io_amount.rs:96:5
    |
 LL |     r.read(&mut buf[..]).await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -130,7 +130,15 @@ LL |     r.read(&mut buf[..]).await.unwrap();
    = help: use `AsyncReadExt::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:109:9
+  --> $DIR/unused_io_amount.rs:104:5
+   |
+LL |     w.write(b"hello world");
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `AsyncWriteExt::write_all` instead, or handle partial writes
+
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:110:9
    |
 LL |         w.write(b"hello world").await?;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,7 +146,7 @@ LL |         w.write(b"hello world").await?;
    = help: use `AsyncWriteExt::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:118:9
+  --> $DIR/unused_io_amount.rs:119:9
    |
 LL |         r.read(&mut buf[..]).await.or(Err(Error::Kind))?;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -146,7 +154,7 @@ LL |         r.read(&mut buf[..]).await.or(Err(Error::Kind))?;
    = help: use `AsyncReadExt::read_exact` instead, or handle partial reads
 
 error: written amount is not handled
-  --> $DIR/unused_io_amount.rs:127:5
+  --> $DIR/unused_io_amount.rs:128:5
    |
 LL |     w.write(b"hello world").await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,12 +162,103 @@ LL |     w.write(b"hello world").await.unwrap();
    = help: use `AsyncWriteExt::write_all` instead, or handle partial writes
 
 error: read amount is not handled
-  --> $DIR/unused_io_amount.rs:133:5
+  --> $DIR/unused_io_amount.rs:134:5
    |
 LL |     r.read(&mut buf[..]).await.unwrap();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: use `AsyncReadExt::read_exact` instead, or handle partial reads
 
-error: aborting due to 20 previous errors
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:147:11
+   |
+LL |     match s.write(b"test") {
+   |           ^^^^^^^^^^^^^^^^
+   |
+   = help: use `Write::write_all` instead, or handle partial writes
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:149:9
+   |
+LL |         Ok(_) => todo!(),
+   |         ^^^^^^^^^^^^^^^^
+
+error: read amount is not handled
+  --> $DIR/unused_io_amount.rs:155:11
+   |
+LL |     match s.read(&mut buf) {
+   |           ^^^^^^^^^^^^^^^^
+   |
+   = help: use `Read::read_exact` instead, or handle partial reads
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:157:9
+   |
+LL |         Ok(_) => todo!(),
+   |         ^^^^^^^^^^^^^^^^
+
+error: read amount is not handled
+  --> $DIR/unused_io_amount.rs:164:11
+   |
+LL |     match s.read(&mut [0u8; 4]) {
+   |           ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `Read::read_exact` instead, or handle partial reads
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:166:9
+   |
+LL |         Ok(_) => todo!(),
+   |         ^^^^^^^^^^^^^^^^
+
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:173:11
+   |
+LL |     match s.write(b"test") {
+   |           ^^^^^^^^^^^^^^^^
+   |
+   = help: use `Write::write_all` instead, or handle partial writes
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:175:9
+   |
+LL |         Ok(_) => todo!(),
+   |         ^^^^^^^^^^^^^^^^
+
+error: read amount is not handled
+  --> $DIR/unused_io_amount.rs:186:8
+   |
+LL |     if let Ok(_) = s.read(&mut [0u8; 4]) {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `Read::read_exact` instead, or handle partial reads
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:186:12
+   |
+LL |     if let Ok(_) = s.read(&mut [0u8; 4]) {
+   |            ^^^^^
+
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:193:8
+   |
+LL |     if let Ok(_) = s.write(b"test") {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `Write::write_all` instead, or handle partial writes
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:193:12
+   |
+LL |     if let Ok(_) = s.write(b"test") {
+   |            ^^^^^
+
+error: written amount is not handled
+  --> $DIR/unused_io_amount.rs:200:8
+   |
+LL |     if let Ok(..) = s.write(b"test") {
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: use `Write::write_all` instead, or handle partial writes
+note: the result is consumed here, but the amount of I/O bytes remains unhandled
+  --> $DIR/unused_io_amount.rs:200:12
+   |
+LL |     if let Ok(..) = s.write(b"test") {
+   |            ^^^^^^
+
+error: aborting due to 28 previous errors
 
diff --git a/tests/ui/useless_asref.fixed b/tests/ui/useless_asref.fixed
index 88b95095bc0..c98f2928e03 100644
--- a/tests/ui/useless_asref.fixed
+++ b/tests/ui/useless_asref.fixed
@@ -144,6 +144,42 @@ fn foo() {
     //~^ ERROR: this call to `as_ref.map(...)` does nothing
 }
 
+mod issue12135 {
+    pub struct Struct {
+        field: Option<InnerStruct>,
+    }
+
+    #[derive(Clone)]
+    pub struct Foo;
+
+    #[derive(Clone)]
+    struct InnerStruct {
+        x: Foo,
+    }
+
+    impl InnerStruct {
+        fn method(&self) -> &Foo {
+            &self.x
+        }
+    }
+
+    pub fn f(x: &Struct) -> Option<Foo> {
+        x.field.clone();
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+        x.field.clone();
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+        x.field.clone();
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+
+        // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223
+        #[allow(clippy::clone_on_copy)]
+        Some(1).clone();
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+
+        x.field.as_ref().map(|v| v.method().clone())
+    }
+}
+
 fn main() {
     not_ok();
     ok();
diff --git a/tests/ui/useless_asref.rs b/tests/ui/useless_asref.rs
index 504dc1f5cbf..f9d603f116d 100644
--- a/tests/ui/useless_asref.rs
+++ b/tests/ui/useless_asref.rs
@@ -144,6 +144,42 @@ fn foo() {
     //~^ ERROR: this call to `as_ref.map(...)` does nothing
 }
 
+mod issue12135 {
+    pub struct Struct {
+        field: Option<InnerStruct>,
+    }
+
+    #[derive(Clone)]
+    pub struct Foo;
+
+    #[derive(Clone)]
+    struct InnerStruct {
+        x: Foo,
+    }
+
+    impl InnerStruct {
+        fn method(&self) -> &Foo {
+            &self.x
+        }
+    }
+
+    pub fn f(x: &Struct) -> Option<Foo> {
+        x.field.as_ref().map(|v| v.clone());
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+        x.field.as_ref().map(Clone::clone);
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+        x.field.as_ref().map(|v| Clone::clone(v));
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+
+        // https://github.com/rust-lang/rust-clippy/pull/12136#discussion_r1451565223
+        #[allow(clippy::clone_on_copy)]
+        Some(1).as_ref().map(|&x| x.clone());
+        //~^ ERROR: this call to `as_ref.map(...)` does nothing
+
+        x.field.as_ref().map(|v| v.method().clone())
+    }
+}
+
 fn main() {
     not_ok();
     ok();
diff --git a/tests/ui/useless_asref.stderr b/tests/ui/useless_asref.stderr
index deb5d90f2f6..e158df2664d 100644
--- a/tests/ui/useless_asref.stderr
+++ b/tests/ui/useless_asref.stderr
@@ -88,5 +88,29 @@ error: this call to `as_ref.map(...)` does nothing
 LL |     let z = x.as_ref().map(|z| String::clone(z));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()`
 
-error: aborting due to 14 previous errors
+error: this call to `as_ref.map(...)` does nothing
+  --> $DIR/useless_asref.rs:167:9
+   |
+LL |         x.field.as_ref().map(|v| v.clone());
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`
+
+error: this call to `as_ref.map(...)` does nothing
+  --> $DIR/useless_asref.rs:169:9
+   |
+LL |         x.field.as_ref().map(Clone::clone);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`
+
+error: this call to `as_ref.map(...)` does nothing
+  --> $DIR/useless_asref.rs:171:9
+   |
+LL |         x.field.as_ref().map(|v| Clone::clone(v));
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`
+
+error: this call to `as_ref.map(...)` does nothing
+  --> $DIR/useless_asref.rs:176:9
+   |
+LL |         Some(1).as_ref().map(|&x| x.clone());
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(1).clone()`
+
+error: aborting due to 18 previous errors
 
diff --git a/triagebot.toml b/triagebot.toml
index a05765b3981..3eadc66f544 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -19,7 +19,6 @@ new_pr = true
 
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
-users_on_vacation = ["blyxyas"]
 
 [assign.owners]
 "/.github" = ["@flip1995"]