about summary refs log tree commit diff
path: root/src/tools/clippy/tests/ui
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2025-03-20 22:34:29 +0100
committerPhilipp Krones <hello@philkrones.com>2025-03-20 22:34:29 +0100
commitae31f7a024dbc601b7323d95a086acd70f00a723 (patch)
tree6eb5b07deb7bdee6c25ecdd85dd344df49ed53bc /src/tools/clippy/tests/ui
parentd8e44b722a93e55cbc9a8188dfbfe3faf1226096 (diff)
parent1e5237f4a56ae958af7e5824343eacf737b67083 (diff)
downloadrust-ae31f7a024dbc601b7323d95a086acd70f00a723.tar.gz
rust-ae31f7a024dbc601b7323d95a086acd70f00a723.zip
Merge commit '1e5237f4a56ae958af7e5824343eacf737b67083' into clippy-subtree-update
Diffstat (limited to 'src/tools/clippy/tests/ui')
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.fixed7
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.rs7
-rw-r--r--src/tools/clippy/tests/ui/crashes/if_same_then_else.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr6
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.fixed98
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.rs98
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.stderr50
-rw-r--r--src/tools/clippy/tests/ui/entry_unfixable.rs94
-rw-r--r--src/tools/clippy/tests/ui/entry_unfixable.stderr41
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.fixed11
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.rs11
-rw-r--r--src/tools/clippy/tests/ui/from_over_into.stderr18
-rw-r--r--src/tools/clippy/tests/ui/ifs_same_cond.rs7
-rw-r--r--src/tools/clippy/tests/ui/ifs_same_cond.stderr16
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.fixed24
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.rs24
-rw-r--r--src/tools/clippy/tests/ui/implicit_saturating_sub.stderr20
-rw-r--r--src/tools/clippy/tests/ui/incompatible_msrv.rs39
-rw-r--r--src/tools/clippy/tests/ui/incompatible_msrv.stderr37
-rw-r--r--src/tools/clippy/tests/ui/io_other_error.fixed5
-rw-r--r--src/tools/clippy/tests/ui/io_other_error.rs5
-rw-r--r--src/tools/clippy/tests/ui/io_other_error.stderr14
-rw-r--r--src/tools/clippy/tests/ui/literals.rs4
-rw-r--r--src/tools/clippy/tests/ui/literals.stderr45
-rw-r--r--src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs9
-rw-r--r--src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr38
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.stderr58
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.rs34
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else.stderr42
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs88
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.fixed23
-rw-r--r--src/tools/clippy/tests/ui/needless_collect.rs23
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.fixed6
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.rs6
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.stderr18
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_value.rs36
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_value.stderr172
-rw-r--r--src/tools/clippy/tests/ui/needless_return.fixed12
-rw-r--r--src/tools/clippy/tests/ui/needless_return.rs12
-rw-r--r--src/tools/clippy/tests/ui/needless_return.stderr122
-rw-r--r--src/tools/clippy/tests/ui/never_loop.rs28
-rw-r--r--src/tools/clippy/tests/ui/never_loop.stderr70
-rw-r--r--src/tools/clippy/tests/ui/never_loop_fixable.fixed20
-rw-r--r--src/tools/clippy/tests/ui/never_loop_fixable.rs20
-rw-r--r--src/tools/clippy/tests/ui/never_loop_fixable.stderr35
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.fixed20
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.rs20
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq.fixed23
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq.rs15
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq.stderr44
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq_no_std.fixed12
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq_no_std.rs4
-rw-r--r--src/tools/clippy/tests/ui/ptr_eq_no_std.stderr26
-rw-r--r--src/tools/clippy/tests/ui/question_mark.fixed55
-rw-r--r--src/tools/clippy/tests/ui/question_mark.rs72
-rw-r--r--src/tools/clippy/tests/ui/question_mark.stderr62
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.rs7
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr24
-rw-r--r--src/tools/clippy/tests/ui/single_match.fixed34
-rw-r--r--src/tools/clippy/tests/ui/single_match.rs10
-rw-r--r--src/tools/clippy/tests/ui/single_match.stderr97
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.fixed8
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.rs12
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.stderr43
-rw-r--r--src/tools/clippy/tests/ui/size_of_ref.stderr12
-rw-r--r--src/tools/clippy/tests/ui/string_to_string.rs15
-rw-r--r--src/tools/clippy/tests/ui/string_to_string.stderr18
-rw-r--r--src/tools/clippy/tests/ui/string_to_string_in_map.fixed20
-rw-r--r--src/tools/clippy/tests/ui/string_to_string_in_map.rs20
-rw-r--r--src/tools/clippy/tests/ui/string_to_string_in_map.stderr38
-rw-r--r--src/tools/clippy/tests/ui/struct_fields.rs27
-rw-r--r--src/tools/clippy/tests/ui/struct_fields.stderr21
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed36
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs36
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.stderr86
76 files changed, 2130 insertions, 347 deletions
diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
index df375e37057..cd307e803d0 100644
--- a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
@@ -118,6 +118,13 @@ mod issue_12016 {
     }
 }
 
+fn issue_9911() {
+    if { return } {}
+
+    let a = 1;
+    if { if a == 1 { return } else { true } } {}
+}
+
 fn in_closure() {
     let v = vec![1, 2, 3];
     if v.into_iter()
diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.rs b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
index 1d9c9dd4246..6a211c8edfd 100644
--- a/src/tools/clippy/tests/ui/blocks_in_conditions.rs
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
@@ -118,6 +118,13 @@ mod issue_12016 {
     }
 }
 
+fn issue_9911() {
+    if { return } {}
+
+    let a = 1;
+    if { if a == 1 { return } else { true } } {}
+}
+
 fn in_closure() {
     let v = vec![1, 2, 3];
     if v.into_iter()
diff --git a/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs b/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs
index 58ee751948b..8a27b3c6d47 100644
--- a/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs
+++ b/src/tools/clippy/tests/ui/crashes/if_same_then_else.rs
@@ -1,6 +1,5 @@
 //@ check-pass
 
-#![allow(clippy::comparison_chain)]
 #![deny(clippy::if_same_then_else)]
 
 // Test for https://github.com/rust-lang/rust-clippy/issues/2426
diff --git a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
index 28479570006..b4fb1222539 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
+++ b/src/tools/clippy/tests/ui/crashes/needless_pass_by_value-w-late-bound.stderr
@@ -2,7 +2,7 @@ error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/crashes/needless_pass_by_value-w-late-bound.rs:7:12
    |
 LL | fn test(x: Foo<'_>) {}
-   |            ^^^^^^^ help: consider taking a reference instead: `&Foo<'_>`
+   |            ^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/crashes/needless_pass_by_value-w-late-bound.rs:5:1
@@ -11,6 +11,10 @@ LL | struct Foo<'a>(&'a [(); 100]);
    | ^^^^^^^^^^^^^^
    = note: `-D clippy::needless-pass-by-value` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_value)]`
+help: consider taking a reference instead
+   |
+LL | fn test(x: &Foo<'_>) {}
+   |            +
 
 error: aborting due to 1 previous error
 
diff --git a/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.fixed b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.fixed
new file mode 100644
index 00000000000..6a616b2c7e1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.fixed
@@ -0,0 +1,98 @@
+#![feature(custom_inner_attributes)]
+#![rustfmt::skip]
+
+#![warn(clippy::doc_comment_double_space_linebreaks)]
+#![allow(unused, clippy::empty_docs)]
+
+//~v doc_comment_double_space_linebreaks
+//! Should warn on double space linebreaks\
+//! in file/module doc comment
+
+/// Should not warn on single-line doc comments
+fn single_line() {}
+
+/// Should not warn on single-line doc comments
+/// split across multiple lines
+fn single_line_split() {}
+
+// Should not warn on normal comments
+
+// note: cargo fmt can remove double spaces from normal and block comments
+// Should not warn on normal comments  
+// with double spaces at the end of a line  
+
+#[doc = "This is a doc attribute, which should not be linted"]
+fn normal_comment() {
+   /*
+   Should not warn on block comments
+   */
+  
+  /*
+  Should not warn on block comments  
+  with double space at the end of a line
+  */
+}
+
+//~v doc_comment_double_space_linebreaks
+/// Should warn when doc comment uses double space\
+/// as a line-break, even when there are multiple\
+/// in a row
+fn double_space_doc_comment() {}
+
+/// Should not warn when back-slash is used \
+/// as a line-break
+fn back_slash_doc_comment() {}
+
+//~v doc_comment_double_space_linebreaks
+/// 🌹 are 🟥\
+/// 🌷 are 🟦\
+/// 📎 is 😎\
+/// and so are 🫵\
+/// (hopefully no formatting weirdness linting this)
+fn multi_byte_chars_tada() {}
+
+macro_rules! macro_that_makes_function {
+   () => {
+      /// Shouldn't lint on this!  
+      /// (hopefully)
+      fn my_macro_created_function() {}
+   }
+}
+
+macro_that_makes_function!();
+
+// dont lint when its alone on a line
+///  
+fn alone() {}
+
+/// | First column | Second column |  
+/// | ------------ | ------------- |  
+/// | Not a line   | break when    |  
+/// | after a line | in a table    |  
+fn table() {}
+
+/// ```text  
+/// It's also not a hard line break if  
+/// there's two spaces at the end of a  
+/// line in a block code.  
+/// ```  
+fn codeblock() {}
+
+/// It's also not a hard line break `if  
+/// there's` two spaces in the middle of inline code.  
+fn inline() {}
+
+/// It's also not a hard line break [when](  
+/// https://example.com) in a URL.  
+fn url() {}
+
+//~v doc_comment_double_space_linebreaks
+/// here we mix\
+/// double spaces\
+/// and also\
+/// adding backslash\
+/// to some of them\
+/// to see how that looks
+fn mixed() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.rs b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.rs
new file mode 100644
index 00000000000..e36cf7dea23
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.rs
@@ -0,0 +1,98 @@
+#![feature(custom_inner_attributes)]
+#![rustfmt::skip]
+
+#![warn(clippy::doc_comment_double_space_linebreaks)]
+#![allow(unused, clippy::empty_docs)]
+
+//~v doc_comment_double_space_linebreaks
+//! Should warn on double space linebreaks  
+//! in file/module doc comment
+
+/// Should not warn on single-line doc comments
+fn single_line() {}
+
+/// Should not warn on single-line doc comments
+/// split across multiple lines
+fn single_line_split() {}
+
+// Should not warn on normal comments
+
+// note: cargo fmt can remove double spaces from normal and block comments
+// Should not warn on normal comments  
+// with double spaces at the end of a line  
+
+#[doc = "This is a doc attribute, which should not be linted"]
+fn normal_comment() {
+   /*
+   Should not warn on block comments
+   */
+  
+  /*
+  Should not warn on block comments  
+  with double space at the end of a line
+  */
+}
+
+//~v doc_comment_double_space_linebreaks
+/// Should warn when doc comment uses double space  
+/// as a line-break, even when there are multiple  
+/// in a row
+fn double_space_doc_comment() {}
+
+/// Should not warn when back-slash is used \
+/// as a line-break
+fn back_slash_doc_comment() {}
+
+//~v doc_comment_double_space_linebreaks
+/// 🌹 are 🟥  
+/// 🌷 are 🟦  
+/// 📎 is 😎  
+/// and so are 🫵  
+/// (hopefully no formatting weirdness linting this)
+fn multi_byte_chars_tada() {}
+
+macro_rules! macro_that_makes_function {
+   () => {
+      /// Shouldn't lint on this!  
+      /// (hopefully)
+      fn my_macro_created_function() {}
+   }
+}
+
+macro_that_makes_function!();
+
+// dont lint when its alone on a line
+///  
+fn alone() {}
+
+/// | First column | Second column |  
+/// | ------------ | ------------- |  
+/// | Not a line   | break when    |  
+/// | after a line | in a table    |  
+fn table() {}
+
+/// ```text  
+/// It's also not a hard line break if  
+/// there's two spaces at the end of a  
+/// line in a block code.  
+/// ```  
+fn codeblock() {}
+
+/// It's also not a hard line break `if  
+/// there's` two spaces in the middle of inline code.  
+fn inline() {}
+
+/// It's also not a hard line break [when](  
+/// https://example.com) in a URL.  
+fn url() {}
+
+//~v doc_comment_double_space_linebreaks
+/// here we mix  
+/// double spaces\
+/// and also  
+/// adding backslash\
+/// to some of them  
+/// to see how that looks
+fn mixed() {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.stderr b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.stderr
new file mode 100644
index 00000000000..08c6956c3d0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_comment_double_space_linebreaks.stderr
@@ -0,0 +1,50 @@
+error: doc comment uses two spaces for a hard line break
+  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:8:43
+   |
+LL | //! Should warn on double space linebreaks  
+   |                                           ^^
+   |
+   = help: replace this double space with a backslash: `\`
+   = note: `-D clippy::doc-comment-double-space-linebreaks` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::doc_comment_double_space_linebreaks)]`
+
+error: doc comment uses two spaces for a hard line break
+  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:37:51
+   |
+LL | /// Should warn when doc comment uses double space  
+   |                                                   ^^
+LL | /// as a line-break, even when there are multiple  
+   |                                                  ^^
+   |
+   = help: replace this double space with a backslash: `\`
+
+error: doc comment uses two spaces for a hard line break
+  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:47:12
+   |
+LL | /// 🌹 are 🟥  
+   |              ^^
+LL | /// 🌷 are 🟦  
+   |              ^^
+LL | /// 📎 is 😎  
+   |             ^^
+LL | /// and so are 🫵  
+   |                  ^^
+   |
+   = help: replace this double space with a backslash: `\`
+
+error: doc comment uses two spaces for a hard line break
+  --> tests/ui/doc/doc_comment_double_space_linebreaks.rs:90:16
+   |
+LL | /// here we mix  
+   |                ^^
+LL | /// double spaces\
+LL | /// and also  
+   |             ^^
+LL | /// adding backslash\
+LL | /// to some of them  
+   |                    ^^
+   |
+   = help: replace this double space with a backslash: `\`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/entry_unfixable.rs b/src/tools/clippy/tests/ui/entry_unfixable.rs
new file mode 100644
index 00000000000..dbdacf95056
--- /dev/null
+++ b/src/tools/clippy/tests/ui/entry_unfixable.rs
@@ -0,0 +1,94 @@
+#![allow(unused, clippy::needless_pass_by_value, clippy::collapsible_if)]
+#![warn(clippy::map_entry)]
+//@no-rustfix
+
+use std::collections::HashMap;
+use std::hash::Hash;
+
+macro_rules! m {
+    ($e:expr) => {{ $e }};
+}
+
+macro_rules! insert {
+    ($map:expr, $key:expr, $val:expr) => {
+        $map.insert($key, $val)
+    };
+}
+
+mod issue13306 {
+    use std::collections::HashMap;
+
+    struct Env {
+        enclosing: Option<Box<Env>>,
+        values: HashMap<String, usize>,
+    }
+
+    impl Env {
+        fn assign(&mut self, name: String, value: usize) -> bool {
+            if !self.values.contains_key(&name) {
+                //~^ map_entry
+                self.values.insert(name, value);
+                true
+            } else if let Some(enclosing) = &mut self.enclosing {
+                enclosing.assign(name, value)
+            } else {
+                false
+            }
+        }
+    }
+}
+
+fn issue9925(mut hm: HashMap<String, bool>) {
+    let key = "hello".to_string();
+    if hm.contains_key(&key) {
+        //~^ map_entry
+        let bval = hm.get_mut(&key).unwrap();
+        *bval = false;
+    } else {
+        hm.insert(key, true);
+    }
+}
+
+mod issue9470 {
+    use std::collections::HashMap;
+    use std::sync::Mutex;
+
+    struct Interner(i32);
+
+    impl Interner {
+        const fn new() -> Self {
+            Interner(0)
+        }
+
+        fn resolve(&self, name: String) -> Option<String> {
+            todo!()
+        }
+    }
+
+    static INTERNER: Mutex<Interner> = Mutex::new(Interner::new());
+
+    struct VM {
+        stack: Vec<i32>,
+        globals: HashMap<String, i32>,
+    }
+
+    impl VM {
+        fn stack_top(&self) -> &i32 {
+            self.stack.last().unwrap()
+        }
+
+        fn resolve(&mut self, name: String, value: i32) -> Result<(), String> {
+            if self.globals.contains_key(&name) {
+                //~^ map_entry
+                self.globals.insert(name, value);
+            } else {
+                let interner = INTERNER.lock().unwrap();
+                return Err(interner.resolve(name).unwrap().to_owned());
+            }
+
+            Ok(())
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/entry_unfixable.stderr b/src/tools/clippy/tests/ui/entry_unfixable.stderr
new file mode 100644
index 00000000000..9f9956d351b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/entry_unfixable.stderr
@@ -0,0 +1,41 @@
+error: usage of `contains_key` followed by `insert` on a `HashMap`
+  --> tests/ui/entry_unfixable.rs:28:13
+   |
+LL | /             if !self.values.contains_key(&name) {
+LL | |
+LL | |                 self.values.insert(name, value);
+LL | |                 true
+...  |
+LL | |                 false
+LL | |             }
+   | |_____________^
+   |
+   = note: `-D clippy::map-entry` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::map_entry)]`
+
+error: usage of `contains_key` followed by `insert` on a `HashMap`
+  --> tests/ui/entry_unfixable.rs:43:5
+   |
+LL | /     if hm.contains_key(&key) {
+LL | |
+LL | |         let bval = hm.get_mut(&key).unwrap();
+LL | |         *bval = false;
+LL | |     } else {
+LL | |         hm.insert(key, true);
+LL | |     }
+   | |_____^
+
+error: usage of `contains_key` followed by `insert` on a `HashMap`
+  --> tests/ui/entry_unfixable.rs:81:13
+   |
+LL | /             if self.globals.contains_key(&name) {
+LL | |
+LL | |                 self.globals.insert(name, value);
+LL | |             } else {
+LL | |                 let interner = INTERNER.lock().unwrap();
+LL | |                 return Err(interner.resolve(name).unwrap().to_owned());
+LL | |             }
+   | |_____________^
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/from_over_into.fixed b/src/tools/clippy/tests/ui/from_over_into.fixed
index 7d6780a0e02..7229e5a2d35 100644
--- a/src/tools/clippy/tests/ui/from_over_into.fixed
+++ b/src/tools/clippy/tests/ui/from_over_into.fixed
@@ -105,4 +105,15 @@ fn issue_12138() {
     }
 }
 
+fn issue_112502() {
+    struct MyInt(i64);
+
+    impl From<MyInt> for i64 {
+        //~^ from_over_into
+        fn from(val: MyInt) -> Self {
+            val.0
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/from_over_into.rs b/src/tools/clippy/tests/ui/from_over_into.rs
index 387ddde359c..9c75969c5c1 100644
--- a/src/tools/clippy/tests/ui/from_over_into.rs
+++ b/src/tools/clippy/tests/ui/from_over_into.rs
@@ -105,4 +105,15 @@ fn issue_12138() {
     }
 }
 
+fn issue_112502() {
+    struct MyInt(i64);
+
+    impl Into<i64> for MyInt {
+        //~^ from_over_into
+        fn into(self: MyInt) -> i64 {
+            self.0
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/from_over_into.stderr b/src/tools/clippy/tests/ui/from_over_into.stderr
index a564bccbaf7..fe779544dd5 100644
--- a/src/tools/clippy/tests/ui/from_over_into.stderr
+++ b/src/tools/clippy/tests/ui/from_over_into.stderr
@@ -107,5 +107,21 @@ LL |
 LL ~         fn from(val: Hello) {}
    |
 
-error: aborting due to 7 previous errors
+error: an implementation of `From` is preferred since it gives you `Into<_>` for free where the reverse isn't true
+  --> tests/ui/from_over_into.rs:111:5
+   |
+LL |     impl Into<i64> for MyInt {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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_112502::MyInt>`
+   |
+LL ~     impl From<MyInt> for i64 {
+LL |
+LL ~         fn from(val: MyInt) -> Self {
+LL ~             val.0
+   |
+
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.rs b/src/tools/clippy/tests/ui/ifs_same_cond.rs
index 6ecb7cb1eba..ebc3acb1b77 100644
--- a/src/tools/clippy/tests/ui/ifs_same_cond.rs
+++ b/src/tools/clippy/tests/ui/ifs_same_cond.rs
@@ -1,10 +1,5 @@
 #![warn(clippy::ifs_same_cond)]
-#![allow(
-    clippy::if_same_then_else,
-    clippy::comparison_chain,
-    clippy::needless_if,
-    clippy::needless_else
-)] // all empty blocks
+#![allow(clippy::if_same_then_else, clippy::needless_if, clippy::needless_else)] // all empty blocks
 
 fn ifs_same_cond() {
     let a = 0;
diff --git a/src/tools/clippy/tests/ui/ifs_same_cond.stderr b/src/tools/clippy/tests/ui/ifs_same_cond.stderr
index 81fbb921e84..df21e6f1b82 100644
--- a/src/tools/clippy/tests/ui/ifs_same_cond.stderr
+++ b/src/tools/clippy/tests/ui/ifs_same_cond.stderr
@@ -1,11 +1,11 @@
 error: this `if` has the same condition as a previous `if`
-  --> tests/ui/ifs_same_cond.rs:14:15
+  --> tests/ui/ifs_same_cond.rs:9:15
    |
 LL |     } else if b {
    |               ^
    |
 note: same as this
-  --> tests/ui/ifs_same_cond.rs:13:8
+  --> tests/ui/ifs_same_cond.rs:8:8
    |
 LL |     if b {
    |        ^
@@ -13,37 +13,37 @@ LL |     if b {
    = help: to override `-D warnings` add `#[allow(clippy::ifs_same_cond)]`
 
 error: this `if` has the same condition as a previous `if`
-  --> tests/ui/ifs_same_cond.rs:19:15
+  --> tests/ui/ifs_same_cond.rs:14:15
    |
 LL |     } else if a == 1 {
    |               ^^^^^^
    |
 note: same as this
-  --> tests/ui/ifs_same_cond.rs:18:8
+  --> tests/ui/ifs_same_cond.rs:13:8
    |
 LL |     if a == 1 {
    |        ^^^^^^
 
 error: this `if` has the same condition as a previous `if`
-  --> tests/ui/ifs_same_cond.rs:25:15
+  --> tests/ui/ifs_same_cond.rs:20:15
    |
 LL |     } else if 2 * a == 1 {
    |               ^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/ifs_same_cond.rs:23:8
+  --> tests/ui/ifs_same_cond.rs:18:8
    |
 LL |     if 2 * a == 1 {
    |        ^^^^^^^^^^
 
 error: this `if` has the same condition as a previous `if`
-  --> tests/ui/ifs_same_cond.rs:58:15
+  --> tests/ui/ifs_same_cond.rs:53:15
    |
 LL |     } else if a.contains("ah") {
    |               ^^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/ifs_same_cond.rs:57:8
+  --> tests/ui/ifs_same_cond.rs:52:8
    |
 LL |     if a.contains("ah") {
    |        ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
index 136238f9eca..1aab6c54407 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.fixed
@@ -228,3 +228,27 @@ fn regression_13524(a: usize, b: usize, c: bool) -> usize {
         123
     } else { b.saturating_sub(a) }
 }
+
+fn with_side_effect(a: u64) -> u64 {
+    println!("a = {a}");
+    a
+}
+
+fn arbitrary_expression() {
+    let (a, b) = (15u64, 20u64);
+
+    let _ = (a * 2).saturating_sub(b);
+    //~^ implicit_saturating_sub
+
+    let _ = a.saturating_sub(b * 2);
+    //~^ implicit_saturating_sub
+
+    let _ = a.saturating_sub(b * 2);
+    //~^ implicit_saturating_sub
+
+    let _ = if with_side_effect(a) > a {
+        with_side_effect(a) - a
+    } else {
+        0
+    };
+}
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
index 140cf033860..7ca57a2902d 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.rs
@@ -302,3 +302,27 @@ fn regression_13524(a: usize, b: usize, c: bool) -> usize {
         b - a
     }
 }
+
+fn with_side_effect(a: u64) -> u64 {
+    println!("a = {a}");
+    a
+}
+
+fn arbitrary_expression() {
+    let (a, b) = (15u64, 20u64);
+
+    let _ = if a * 2 > b { a * 2 - b } else { 0 };
+    //~^ implicit_saturating_sub
+
+    let _ = if a > b * 2 { a - b * 2 } else { 0 };
+    //~^ implicit_saturating_sub
+
+    let _ = if a < b * 2 { 0 } else { a - b * 2 };
+    //~^ implicit_saturating_sub
+
+    let _ = if with_side_effect(a) > a {
+        with_side_effect(a) - a
+    } else {
+        0
+    };
+}
diff --git a/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr b/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr
index f9c94d3ad84..0c225856fd0 100644
--- a/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr
+++ b/src/tools/clippy/tests/ui/implicit_saturating_sub.stderr
@@ -220,5 +220,23 @@ LL | |         b - a
 LL | |     }
    | |_____^ help: replace it with: `{ b.saturating_sub(a) }`
 
-error: aborting due to 24 previous errors
+error: manual arithmetic check found
+  --> tests/ui/implicit_saturating_sub.rs:314:13
+   |
+LL |     let _ = if a * 2 > b { a * 2 - b } else { 0 };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `(a * 2).saturating_sub(b)`
+
+error: manual arithmetic check found
+  --> tests/ui/implicit_saturating_sub.rs:317:13
+   |
+LL |     let _ = if a > b * 2 { a - b * 2 } else { 0 };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b * 2)`
+
+error: manual arithmetic check found
+  --> tests/ui/implicit_saturating_sub.rs:320:13
+   |
+LL |     let _ = if a < b * 2 { 0 } else { a - b * 2 };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `a.saturating_sub(b * 2)`
+
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.rs b/src/tools/clippy/tests/ui/incompatible_msrv.rs
index b4fea4cae5e..99101b2bb8f 100644
--- a/src/tools/clippy/tests/ui/incompatible_msrv.rs
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.rs
@@ -1,5 +1,6 @@
 #![warn(clippy::incompatible_msrv)]
 #![feature(custom_inner_attributes)]
+#![feature(panic_internals)]
 #![clippy::msrv = "1.3.0"]
 
 use std::collections::HashMap;
@@ -34,4 +35,42 @@ async fn issue12273(v: impl Future<Output = ()>) {
     v.await;
 }
 
+fn core_special_treatment(p: bool) {
+    // Do not lint code coming from `core` macros expanding into `core` function calls
+    if p {
+        panic!("foo"); // Do not lint
+    }
+
+    // But still lint code calling `core` functions directly
+    if p {
+        core::panicking::panic("foo");
+        //~^ ERROR: is `1.3.0` but this item is stable since `1.6.0`
+    }
+
+    // Lint code calling `core` from non-`core` macros
+    macro_rules! my_panic {
+        ($msg:expr) => {
+            core::panicking::panic($msg)
+        }; //~^ ERROR: is `1.3.0` but this item is stable since `1.6.0`
+    }
+    my_panic!("foo");
+
+    // Lint even when the macro comes from `core` and calls `core` functions
+    assert!(core::panicking::panic("out of luck"));
+    //~^ ERROR: is `1.3.0` but this item is stable since `1.6.0`
+}
+
+#[clippy::msrv = "1.26.0"]
+fn lang_items() {
+    // Do not lint lang items. `..=` will expand into `RangeInclusive::new()`, which was introduced
+    // in Rust 1.27.0.
+    let _ = 1..=3;
+}
+
+#[clippy::msrv = "1.80.0"]
+fn issue14212() {
+    let _ = std::iter::repeat_n((), 5);
+    //~^ ERROR: is `1.80.0` but this item is stable since `1.82.0`
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/incompatible_msrv.stderr b/src/tools/clippy/tests/ui/incompatible_msrv.stderr
index 56c9eae5aaf..5ea2bb9cc58 100644
--- a/src/tools/clippy/tests/ui/incompatible_msrv.stderr
+++ b/src/tools/clippy/tests/ui/incompatible_msrv.stderr
@@ -1,5 +1,5 @@
 error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.10.0`
-  --> tests/ui/incompatible_msrv.rs:13:39
+  --> tests/ui/incompatible_msrv.rs:14:39
    |
 LL |     assert_eq!(map.entry("poneyland").key(), &"poneyland");
    |                                       ^^^^^
@@ -8,16 +8,45 @@ LL |     assert_eq!(map.entry("poneyland").key(), &"poneyland");
    = help: to override `-D warnings` add `#[allow(clippy::incompatible_msrv)]`
 
 error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.12.0`
-  --> tests/ui/incompatible_msrv.rs:17:11
+  --> tests/ui/incompatible_msrv.rs:18:11
    |
 LL |         v.into_key();
    |           ^^^^^^^^^^
 
 error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.4.0`
-  --> tests/ui/incompatible_msrv.rs:21:5
+  --> tests/ui/incompatible_msrv.rs:22:5
    |
 LL |     sleep(Duration::new(1, 0));
    |     ^^^^^
 
-error: aborting due to 3 previous errors
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
+  --> tests/ui/incompatible_msrv.rs:46:9
+   |
+LL |         core::panicking::panic("foo");
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
+  --> tests/ui/incompatible_msrv.rs:53:13
+   |
+LL |             core::panicking::panic($msg)
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+...
+LL |     my_panic!("foo");
+   |     ---------------- in this macro invocation
+   |
+   = note: this error originates in the macro `my_panic` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: current MSRV (Minimum Supported Rust Version) is `1.3.0` but this item is stable since `1.6.0`
+  --> tests/ui/incompatible_msrv.rs:59:13
+   |
+LL |     assert!(core::panicking::panic("out of luck"));
+   |             ^^^^^^^^^^^^^^^^^^^^^^
+
+error: current MSRV (Minimum Supported Rust Version) is `1.80.0` but this item is stable since `1.82.0`
+  --> tests/ui/incompatible_msrv.rs:72:13
+   |
+LL |     let _ = std::iter::repeat_n((), 5);
+   |             ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/io_other_error.fixed b/src/tools/clippy/tests/ui/io_other_error.fixed
index 0054c56fb62..ce7e8ef281f 100644
--- a/src/tools/clippy/tests/ui/io_other_error.fixed
+++ b/src/tools/clippy/tests/ui/io_other_error.fixed
@@ -53,3 +53,8 @@ mod paths {
 fn under_msrv() {
     let _err = std::io::Error::new(std::io::ErrorKind::Other, E);
 }
+
+pub fn issue14346(x: i32) -> std::io::Error {
+    std::io::Error::other(format!("{x}"))
+    //~^ ERROR: this can be `std::io::Error::other(_)`
+}
diff --git a/src/tools/clippy/tests/ui/io_other_error.rs b/src/tools/clippy/tests/ui/io_other_error.rs
index 8529fb9a77f..b66e7f88ab1 100644
--- a/src/tools/clippy/tests/ui/io_other_error.rs
+++ b/src/tools/clippy/tests/ui/io_other_error.rs
@@ -53,3 +53,8 @@ mod paths {
 fn under_msrv() {
     let _err = std::io::Error::new(std::io::ErrorKind::Other, E);
 }
+
+pub fn issue14346(x: i32) -> std::io::Error {
+    std::io::Error::new(std::io::ErrorKind::Other, format!("{x}"))
+    //~^ ERROR: this can be `std::io::Error::other(_)`
+}
diff --git a/src/tools/clippy/tests/ui/io_other_error.stderr b/src/tools/clippy/tests/ui/io_other_error.stderr
index e79e05ecd40..b37e3d15064 100644
--- a/src/tools/clippy/tests/ui/io_other_error.stderr
+++ b/src/tools/clippy/tests/ui/io_other_error.stderr
@@ -48,5 +48,17 @@ LL -         let _err = io::Error::new(io::ErrorKind::Other, super::E);
 LL +         let _err = io::Error::other(super::E);
    |
 
-error: aborting due to 4 previous errors
+error: this can be `std::io::Error::other(_)`
+  --> tests/ui/io_other_error.rs:58:5
+   |
+LL |     std::io::Error::new(std::io::ErrorKind::Other, format!("{x}"))
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `std::io::Error::other`
+   |
+LL -     std::io::Error::new(std::io::ErrorKind::Other, format!("{x}"))
+LL +     std::io::Error::other(format!("{x}"))
+   |
+
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/literals.rs b/src/tools/clippy/tests/ui/literals.rs
index d21d49310a0..ba343a8f62f 100644
--- a/src/tools/clippy/tests/ui/literals.rs
+++ b/src/tools/clippy/tests/ui/literals.rs
@@ -30,6 +30,10 @@ fn main() {
     //~^ separated_literal_suffix
     //~| mixed_case_hex_literals
 
+    let fail2 = 0xab_CD_isize;
+    //~^ separated_literal_suffix
+    //~| mixed_case_hex_literals
+
     let fail_multi_zero = 000_123usize;
     //~^ unseparated_literal_suffix
     //~| zero_prefixed_literal
diff --git a/src/tools/clippy/tests/ui/literals.stderr b/src/tools/clippy/tests/ui/literals.stderr
index d65cd3c89eb..6bfeb91625b 100644
--- a/src/tools/clippy/tests/ui/literals.stderr
+++ b/src/tools/clippy/tests/ui/literals.stderr
@@ -25,6 +25,7 @@ error: inconsistent casing in hexadecimal literal
 LL |     let fail1 = 0xabCD;
    |                 ^^^^^^
    |
+   = help: consider using `0xabcd` or `0xABCD`
    = note: `-D clippy::mixed-case-hex-literals` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::mixed_case_hex_literals)]`
 
@@ -39,6 +40,8 @@ error: inconsistent casing in hexadecimal literal
    |
 LL |     let fail2 = 0xabCD_u32;
    |                 ^^^^^^^^^^
+   |
+   = help: consider using `0xabcd_u32` or `0xABCD_u32`
 
 error: integer type suffix should not be separated by an underscore
   --> tests/ui/literals.rs:29:17
@@ -51,9 +54,25 @@ error: inconsistent casing in hexadecimal literal
    |
 LL |     let fail2 = 0xabCD_isize;
    |                 ^^^^^^^^^^^^
+   |
+   = help: consider using `0xabcd_isize` or `0xABCD_isize`
+
+error: integer type suffix should not be separated by an underscore
+  --> tests/ui/literals.rs:33:17
+   |
+LL |     let fail2 = 0xab_CD_isize;
+   |                 ^^^^^^^^^^^^^ help: remove the underscore: `0xab_CDisize`
+
+error: inconsistent casing in hexadecimal literal
+  --> tests/ui/literals.rs:33:17
+   |
+LL |     let fail2 = 0xab_CD_isize;
+   |                 ^^^^^^^^^^^^^
+   |
+   = help: consider using `0xab_cd_isize` or `0xAB_CD_isize`
 
 error: integer type suffix should be separated by an underscore
-  --> tests/ui/literals.rs:33:27
+  --> tests/ui/literals.rs:37:27
    |
 LL |     let fail_multi_zero = 000_123usize;
    |                           ^^^^^^^^^^^^ help: add an underscore: `000_123_usize`
@@ -62,7 +81,7 @@ LL |     let fail_multi_zero = 000_123usize;
    = help: to override `-D warnings` add `#[allow(clippy::unseparated_literal_suffix)]`
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:33:27
+  --> tests/ui/literals.rs:37:27
    |
 LL |     let fail_multi_zero = 000_123usize;
    |                           ^^^^^^^^^^^^
@@ -81,13 +100,13 @@ LL +     let fail_multi_zero = 0o123usize;
    |
 
 error: integer type suffix should not be separated by an underscore
-  --> tests/ui/literals.rs:38:16
+  --> tests/ui/literals.rs:42:16
    |
 LL |     let ok10 = 0_i64;
    |                ^^^^^ help: remove the underscore: `0i64`
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:41:17
+  --> tests/ui/literals.rs:45:17
    |
 LL |     let fail8 = 0123;
    |                 ^^^^
@@ -103,13 +122,13 @@ LL |     let fail8 = 0o123;
    |                  +
 
 error: integer type suffix should not be separated by an underscore
-  --> tests/ui/literals.rs:51:16
+  --> tests/ui/literals.rs:55:16
    |
 LL |     let ok17 = 0x123_4567_8901_usize;
    |                ^^^^^^^^^^^^^^^^^^^^^ help: remove the underscore: `0x123_4567_8901usize`
 
 error: digits grouped inconsistently by underscores
-  --> tests/ui/literals.rs:56:18
+  --> tests/ui/literals.rs:60:18
    |
 LL |     let fail19 = 12_3456_21;
    |                  ^^^^^^^^^^ help: consider: `12_345_621`
@@ -118,19 +137,19 @@ LL |     let fail19 = 12_3456_21;
    = help: to override `-D warnings` add `#[allow(clippy::inconsistent_digit_grouping)]`
 
 error: digits grouped inconsistently by underscores
-  --> tests/ui/literals.rs:59:18
+  --> tests/ui/literals.rs:63:18
    |
 LL |     let fail22 = 3__4___23;
    |                  ^^^^^^^^^ help: consider: `3_423`
 
 error: digits grouped inconsistently by underscores
-  --> tests/ui/literals.rs:62:18
+  --> tests/ui/literals.rs:66:18
    |
 LL |     let fail23 = 3__16___23;
    |                  ^^^^^^^^^^ help: consider: `31_623`
 
 error: digits of hex, binary or octal literal not in groups of equal size
-  --> tests/ui/literals.rs:65:18
+  --> tests/ui/literals.rs:69:18
    |
 LL |     let fail24 = 0xAB_ABC_AB;
    |                  ^^^^^^^^^^^ help: consider: `0x0ABA_BCAB`
@@ -139,7 +158,7 @@ LL |     let fail24 = 0xAB_ABC_AB;
    = help: to override `-D warnings` add `#[allow(clippy::unusual_byte_groupings)]`
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:75:13
+  --> tests/ui/literals.rs:79:13
    |
 LL |     let _ = 08;
    |             ^^
@@ -151,7 +170,7 @@ LL +     let _ = 8;
    |
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:78:13
+  --> tests/ui/literals.rs:82:13
    |
 LL |     let _ = 09;
    |             ^^
@@ -163,7 +182,7 @@ LL +     let _ = 9;
    |
 
 error: this is a decimal constant
-  --> tests/ui/literals.rs:81:13
+  --> tests/ui/literals.rs:85:13
    |
 LL |     let _ = 089;
    |             ^^^
@@ -174,5 +193,5 @@ LL -     let _ = 089;
 LL +     let _ = 89;
    |
 
-error: aborting due to 20 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs
index 749d15f1cbd..b094b2021b3 100644
--- a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs
+++ b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.rs
@@ -24,6 +24,15 @@ fn main() {
     let result = if b <= a { 0 } else { a - b };
     //~^ inverted_saturating_sub
 
+    let result = if b * 2 <= a { 0 } else { a - b * 2 };
+    //~^ inverted_saturating_sub
+
+    let result = if b <= a * 2 { 0 } else { a * 2 - b };
+    //~^ inverted_saturating_sub
+
+    let result = if b + 3 <= a + 2 { 0 } else { (a + 2) - (b + 3) };
+    //~^ inverted_saturating_sub
+
     let af = 12f32;
     let bf = 13f32;
     // Should not lint!
diff --git a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr
index 8841210befd..fb0f0da772c 100644
--- a/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr
+++ b/src/tools/clippy/tests/ui/manual_arithmetic_check-2.stderr
@@ -71,5 +71,41 @@ note: this subtraction underflows when `a < b`
 LL |     let result = if b <= a { 0 } else { a - b };
    |                                         ^^^^^
 
-error: aborting due to 6 previous errors
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:27:27
+   |
+LL |     let result = if b * 2 <= a { 0 } else { a - b * 2 };
+   |                           ^^                --------- help: try replacing it with: `b * 2 - a`
+   |
+note: this subtraction underflows when `a < b * 2`
+  --> tests/ui/manual_arithmetic_check-2.rs:27:45
+   |
+LL |     let result = if b * 2 <= a { 0 } else { a - b * 2 };
+   |                                             ^^^^^^^^^
+
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:30:23
+   |
+LL |     let result = if b <= a * 2 { 0 } else { a * 2 - b };
+   |                       ^^                    --------- help: try replacing it with: `b - a * 2`
+   |
+note: this subtraction underflows when `a * 2 < b`
+  --> tests/ui/manual_arithmetic_check-2.rs:30:45
+   |
+LL |     let result = if b <= a * 2 { 0 } else { a * 2 - b };
+   |                                             ^^^^^^^^^
+
+error: inverted arithmetic check before subtraction
+  --> tests/ui/manual_arithmetic_check-2.rs:33:27
+   |
+LL |     let result = if b + 3 <= a + 2 { 0 } else { (a + 2) - (b + 3) };
+   |                           ^^                    ----------------- help: try replacing it with: `b + 3 - (a + 2)`
+   |
+note: this subtraction underflows when `a + 2 < b + 3`
+  --> tests/ui/manual_arithmetic_check-2.rs:33:49
+   |
+LL |     let result = if b + 3 <= a + 2 { 0 } else { (a + 2) - (b + 3) };
+   |                                                 ^^^^^^^^^^^^^^^^^
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_bits.stderr b/src/tools/clippy/tests/ui/manual_bits.stderr
index a50975ed474..44c4cf9239c 100644
--- a/src/tools/clippy/tests/ui/manual_bits.stderr
+++ b/src/tools/clippy/tests/ui/manual_bits.stderr
@@ -1,4 +1,4 @@
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:14:5
    |
 LL |     size_of::<i8>() * 8;
@@ -7,169 +7,169 @@ LL |     size_of::<i8>() * 8;
    = note: `-D clippy::manual-bits` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::manual_bits)]`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:16:5
    |
 LL |     size_of::<i16>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:18:5
    |
 LL |     size_of::<i32>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:20:5
    |
 LL |     size_of::<i64>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:22:5
    |
 LL |     size_of::<i128>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:24:5
    |
 LL |     size_of::<isize>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:27:5
    |
 LL |     size_of::<u8>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:29:5
    |
 LL |     size_of::<u16>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:31:5
    |
 LL |     size_of::<u32>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:33:5
    |
 LL |     size_of::<u64>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:35:5
    |
 LL |     size_of::<u128>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:37:5
    |
 LL |     size_of::<usize>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:40:5
    |
 LL |     8 * size_of::<i8>();
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:42:5
    |
 LL |     8 * size_of::<i16>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:44:5
    |
 LL |     8 * size_of::<i32>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:46:5
    |
 LL |     8 * size_of::<i64>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:48:5
    |
 LL |     8 * size_of::<i128>();
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:50:5
    |
 LL |     8 * size_of::<isize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:53:5
    |
 LL |     8 * size_of::<u8>();
    |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:55:5
    |
 LL |     8 * size_of::<u16>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:57:5
    |
 LL |     8 * size_of::<u32>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:59:5
    |
 LL |     8 * size_of::<u64>();
    |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:61:5
    |
 LL |     8 * size_of::<u128>();
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:63:5
    |
 LL |     8 * size_of::<usize>();
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:74:5
    |
 LL |     size_of::<Word>() * 8;
    |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS as usize`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:79:18
    |
 LL |     let _: u32 = (size_of::<u128>() * 8) as u32;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:81:18
    |
 LL |     let _: u32 = (size_of::<u128>() * 8).try_into().unwrap();
    |                  ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:83:13
    |
 LL |     let _ = (size_of::<u128>() * 8).pow(5);
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)`
 
-error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+error: usage of `size_of::<T>()` to obtain the size of `T` in bits
   --> tests/ui/manual_bits.rs:85:14
    |
 LL |     let _ = &(size_of::<u128>() * 8);
diff --git a/src/tools/clippy/tests/ui/manual_let_else.rs b/src/tools/clippy/tests/ui/manual_let_else.rs
index d2350d97ed0..a753566b34c 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else.rs
@@ -480,3 +480,37 @@ fn issue12337() {
         //~^ manual_let_else
     };
 }
+
+mod issue13768 {
+    enum Foo {
+        Str(String),
+        None,
+    }
+
+    fn foo(value: Foo) {
+        let signature = match value {
+            //~^ manual_let_else
+            Foo::Str(ref val) => val,
+            _ => {
+                println!("No signature found");
+                return;
+            },
+        };
+    }
+
+    enum Bar {
+        Str { inner: String },
+        None,
+    }
+
+    fn bar(mut value: Bar) {
+        let signature = match value {
+            //~^ manual_let_else
+            Bar::Str { ref mut inner } => inner,
+            _ => {
+                println!("No signature found");
+                return;
+            },
+        };
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else.stderr b/src/tools/clippy/tests/ui/manual_let_else.stderr
index 8f5cba64d54..ef042192114 100644
--- a/src/tools/clippy/tests/ui/manual_let_else.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else.stderr
@@ -489,5 +489,45 @@ error: this could be rewritten as `let...else`
 LL |         let v = if let Some(v_some) = g() { v_some } else { return };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider writing: `let Some(v) = g() else { return };`
 
-error: aborting due to 31 previous errors
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else.rs:491:9
+   |
+LL | /         let signature = match value {
+LL | |
+LL | |             Foo::Str(ref val) => val,
+LL | |             _ => {
+...  |
+LL | |             },
+LL | |         };
+   | |__________^
+   |
+help: consider writing
+   |
+LL ~         let Foo::Str(ref signature) = value else {
+LL +                 println!("No signature found");
+LL +                 return;
+LL +             };
+   |
+
+error: this could be rewritten as `let...else`
+  --> tests/ui/manual_let_else.rs:507:9
+   |
+LL | /         let signature = match value {
+LL | |
+LL | |             Bar::Str { ref mut inner } => inner,
+LL | |             _ => {
+...  |
+LL | |             },
+LL | |         };
+   | |__________^
+   |
+help: consider writing
+   |
+LL ~         let Bar::Str { inner: ref mut signature } = value else {
+LL +                 println!("No signature found");
+LL +                 return;
+LL +             };
+   |
+
+error: aborting due to 33 previous errors
 
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
index bd6339b7870..40e7a5d745c 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/cant_be_const.rs
@@ -218,3 +218,91 @@ mod with_ty_alias {
 fn mut_add(x: &mut i32) {
     *x += 1;
 }
+
+#[clippy::msrv = "1.87"]
+mod issue14020 {
+    use std::ops::Add;
+
+    fn f<T: Add>(a: T, b: T) -> <T as Add>::Output {
+        a + b
+    }
+}
+
+#[clippy::msrv = "1.87"]
+mod issue14290 {
+    use std::ops::{Deref, DerefMut};
+
+    struct Wrapper<T> {
+        t: T,
+    }
+
+    impl<T> Deref for Wrapper<T> {
+        type Target = T;
+
+        fn deref(&self) -> &Self::Target {
+            &self.t
+        }
+    }
+    impl<T> DerefMut for Wrapper<T> {
+        fn deref_mut(&mut self) -> &mut Self::Target {
+            &mut self.t
+        }
+    }
+
+    struct Example(bool);
+
+    fn do_something(mut a: Wrapper<Example>) {
+        a.0 = !a.0;
+    }
+
+    pub struct Stream(Vec<u8>);
+
+    impl Stream {
+        pub fn bytes(&self) -> &[u8] {
+            &self.0
+        }
+    }
+}
+
+#[clippy::msrv = "1.87"]
+mod issue14091 {
+    use std::mem::ManuallyDrop;
+
+    struct BucketSlotGuard<'a> {
+        id: u32,
+        free_list: &'a mut Vec<u32>,
+    }
+
+    impl BucketSlotGuard<'_> {
+        fn into_inner(self) -> u32 {
+            let this = ManuallyDrop::new(self);
+            this.id
+        }
+    }
+
+    use std::ops::{Deref, DerefMut};
+
+    struct Wrap<T>(T);
+
+    impl<T> Deref for Wrap<T> {
+        type Target = T;
+        fn deref(&self) -> &T {
+            &self.0
+        }
+    }
+
+    impl<T> DerefMut for Wrap<T> {
+        fn deref_mut(&mut self) -> &mut T {
+            &mut self.0
+        }
+    }
+
+    fn smart_two_field(v: &mut Wrap<(i32, i32)>) {
+        let _a = &mut v.0;
+        let _b = &mut v.1;
+    }
+
+    fn smart_destructure(v: &mut Wrap<(i32, i32)>) {
+        let (ref mut _head, ref mut _tail) = **v;
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_collect.fixed b/src/tools/clippy/tests/ui/needless_collect.fixed
index bad8c307586..6551fa56b42 100644
--- a/src/tools/clippy/tests/ui/needless_collect.fixed
+++ b/src/tools/clippy/tests/ui/needless_collect.fixed
@@ -98,6 +98,29 @@ fn main() {
     let mut out = vec![];
     values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
     let _y = values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
+
+    // Don't write a warning if we call `clone()` on the iterator
+    // https://github.com/rust-lang/rust-clippy/issues/13430
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let _cloned = my_collection.into_iter().clone();
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let my_iter = my_collection.into_iter();
+    let _cloned = my_iter.clone();
+    // Same for `as_slice()`, for same reason.
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let _sliced = my_collection.into_iter().as_slice();
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let my_iter = my_collection.into_iter();
+    let _sliced = my_iter.as_slice();
+    // Assignment outside of main scope
+    {
+        let x;
+        {
+            let xxx: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+            x = xxx.into_iter();
+            for i in x.as_slice() {}
+        }
+    }
 }
 
 fn foo(_: impl IntoIterator<Item = usize>) {}
diff --git a/src/tools/clippy/tests/ui/needless_collect.rs b/src/tools/clippy/tests/ui/needless_collect.rs
index 3dfb5194f40..973c41c6875 100644
--- a/src/tools/clippy/tests/ui/needless_collect.rs
+++ b/src/tools/clippy/tests/ui/needless_collect.rs
@@ -98,6 +98,29 @@ fn main() {
     let mut out = vec![];
     values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>();
     let _y = values.iter().cloned().map(|x| out.push(x)).collect::<Vec<_>>(); // this is fine
+
+    // Don't write a warning if we call `clone()` on the iterator
+    // https://github.com/rust-lang/rust-clippy/issues/13430
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let _cloned = my_collection.into_iter().clone();
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let my_iter = my_collection.into_iter();
+    let _cloned = my_iter.clone();
+    // Same for `as_slice()`, for same reason.
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let _sliced = my_collection.into_iter().as_slice();
+    let my_collection: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+    let my_iter = my_collection.into_iter();
+    let _sliced = my_iter.as_slice();
+    // Assignment outside of main scope
+    {
+        let x;
+        {
+            let xxx: Vec<()> = vec![()].into_iter().map(|()| {}).collect();
+            x = xxx.into_iter();
+            for i in x.as_slice() {}
+        }
+    }
 }
 
 fn foo(_: impl IntoIterator<Item = usize>) {}
diff --git a/src/tools/clippy/tests/ui/needless_late_init.fixed b/src/tools/clippy/tests/ui/needless_late_init.fixed
index eb67e6cc828..391d4bc3fcc 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.fixed
+++ b/src/tools/clippy/tests/ui/needless_late_init.fixed
@@ -297,3 +297,9 @@ fn issue13776() {
     let x;
     issue13776_mac!(x, 10); // should not lint
 }
+
+fn issue9895() {
+    
+    //~^ needless_late_init
+    let r = 5;
+}
diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs
index 7de2202dc32..6096e8300e1 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.rs
+++ b/src/tools/clippy/tests/ui/needless_late_init.rs
@@ -297,3 +297,9 @@ fn issue13776() {
     let x;
     issue13776_mac!(x, 10); // should not lint
 }
+
+fn issue9895() {
+    let r;
+    //~^ needless_late_init
+    (r = 5);
+}
diff --git a/src/tools/clippy/tests/ui/needless_late_init.stderr b/src/tools/clippy/tests/ui/needless_late_init.stderr
index 02fd2811da5..e7c36136847 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.stderr
+++ b/src/tools/clippy/tests/ui/needless_late_init.stderr
@@ -275,5 +275,21 @@ LL |         },
 LL ~     };
    |
 
-error: aborting due to 16 previous errors
+error: unneeded late initialization
+  --> tests/ui/needless_late_init.rs:302:5
+   |
+LL |     let r;
+   |     ^^^^^^ created here
+LL |
+LL |     (r = 5);
+   |     ^^^^^^^ initialised here
+   |
+help: move the declaration `r` here
+   |
+LL ~     
+LL |
+LL ~     let r = 5;
+   |
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.rs b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
index 885fb409417..aef7fff2870 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.rs
@@ -189,6 +189,42 @@ struct Obj(String);
 
 fn prefix_test(_unused_with_prefix: Obj) {}
 
+// Regression test for <https://github.com/rust-lang/rust-clippy/issues/13744>.
+// It's more idiomatic to write `Option<&T>` rather than `&Option<T>`.
+fn option_inner_ref(x: Option<String>) {
+    //~^ ERROR: this argument is passed by value, but not consumed in the function body
+    assert!(x.is_some());
+}
+
+mod non_standard {
+    #[derive(Debug)]
+    pub struct Option<T>(T);
+}
+
+fn non_standard_option(x: non_standard::Option<String>) {
+    //~^ needless_pass_by_value
+    dbg!(&x);
+}
+
+fn option_by_name(x: Option<std::option::Option<core::option::Option<non_standard::Option<String>>>>) {
+    //~^ needless_pass_by_value
+    dbg!(&x);
+}
+
+type OptStr = Option<String>;
+
+fn non_option(x: OptStr) {
+    //~^ needless_pass_by_value
+    dbg!(&x);
+}
+
+type Opt<T> = Option<T>;
+
+fn non_option_either(x: Opt<String>) {
+    //~^ needless_pass_by_value
+    dbg!(&x);
+}
+
 fn main() {
     // This should not cause an ICE either
     // https://github.com/rust-lang/rust-clippy/issues/3144
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
index 4ac4fdce972..e4381d1db53 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_value.stderr
@@ -17,43 +17,78 @@ error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:35:22
    |
 LL | fn bar(x: String, y: Wrapper) {
-   |                      ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
+   |                      ^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn bar(x: String, y: &Wrapper) {
+   |                      +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:44:71
    |
 LL | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: V) {
-   |                                                                       ^ help: consider taking a reference instead: `&V`
+   |                                                                       ^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_borrow_trait<T: Borrow<str>, U: AsRef<str>, V>(t: T, u: U, v: &V) {
+   |                                                                       +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:58:18
    |
 LL | fn test_match(x: Option<Option<String>>, y: Option<Option<String>>) {
-   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&Option<Option<String>>`
+   |                  ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_match(x: Option<Option<&String>>, y: Option<Option<String>>) {
+   |                                +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:73:24
    |
 LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
-   |                        ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
+   |                        ^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_destructure(x: &Wrapper, y: Wrapper, z: Wrapper) {
+   |                        +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:73:36
    |
 LL | fn test_destructure(x: Wrapper, y: Wrapper, z: Wrapper) {
-   |                                    ^^^^^^^ help: consider taking a reference instead: `&Wrapper`
+   |                                    ^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_destructure(x: Wrapper, y: &Wrapper, z: Wrapper) {
+   |                                    +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:92:49
    |
 LL | fn test_blanket_ref<T: Foo, S: Serialize>(vals: T, serializable: S) {}
-   |                                                 ^ help: consider taking a reference instead: `&T`
+   |                                                 ^
+   |
+help: consider taking a reference instead
+   |
+LL | fn test_blanket_ref<T: Foo, S: Serialize>(vals: &T, serializable: S) {}
+   |                                                 +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:95:18
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
-   |                  ^^^^^^ help: consider taking a reference instead: `&String`
+   |                  ^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn issue_2114(s: &String, t: String, u: Vec<i32>, v: Vec<i32>) {
+   |                  +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:95:29
@@ -76,7 +111,12 @@ error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:95:40
    |
 LL | fn issue_2114(s: String, t: String, u: Vec<i32>, v: Vec<i32>) {
-   |                                        ^^^^^^^^ help: consider taking a reference instead: `&Vec<i32>`
+   |                                        ^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn issue_2114(s: String, t: String, u: &Vec<i32>, v: Vec<i32>) {
+   |                                        +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:95:53
@@ -105,79 +145,175 @@ error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:115:12
    |
 LL |         t: String,
-   |            ^^^^^^ help: consider taking a reference instead: `&String`
+   |            ^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL |         t: &String,
+   |            +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:125:23
    |
 LL |     fn baz(&self, uu: U, ss: Self) {}
-   |                       ^ help: consider taking a reference instead: `&U`
+   |                       ^
+   |
+help: consider taking a reference instead
+   |
+LL |     fn baz(&self, uu: &U, ss: Self) {}
+   |                       +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:125:30
    |
 LL |     fn baz(&self, uu: U, ss: Self) {}
-   |                              ^^^^ help: consider taking a reference instead: `&Self`
+   |                              ^^^^
+   |
+help: consider taking a reference instead
+   |
+LL |     fn baz(&self, uu: U, ss: &Self) {}
+   |                              +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:149:24
    |
 LL | fn bar_copy(x: u32, y: CopyWrapper) {
-   |                        ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
+   |                        ^^^^^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/needless_pass_by_value.rs:147:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
+help: consider taking a reference instead
+   |
+LL | fn bar_copy(x: u32, y: &CopyWrapper) {
+   |                        +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:157:29
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
-   |                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
+   |                             ^^^^^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/needless_pass_by_value.rs:147:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
+help: consider taking a reference instead
+   |
+LL | fn test_destructure_copy(x: &CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
+   |                             +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:157:45
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
-   |                                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
+   |                                             ^^^^^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/needless_pass_by_value.rs:147:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
+help: consider taking a reference instead
+   |
+LL | fn test_destructure_copy(x: CopyWrapper, y: &CopyWrapper, z: CopyWrapper) {
+   |                                             +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:157:61
    |
 LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: CopyWrapper) {
-   |                                                             ^^^^^^^^^^^ help: consider taking a reference instead: `&CopyWrapper`
+   |                                                             ^^^^^^^^^^^
    |
 help: or consider marking this type as `Copy`
   --> tests/ui/needless_pass_by_value.rs:147:1
    |
 LL | struct CopyWrapper(u32);
    | ^^^^^^^^^^^^^^^^^^
+help: consider taking a reference instead
+   |
+LL | fn test_destructure_copy(x: CopyWrapper, y: CopyWrapper, z: &CopyWrapper) {
+   |                                                             +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:173:40
    |
 LL | fn some_fun<'b, S: Bar<'b, ()>>(items: S) {}
-   |                                        ^ help: consider taking a reference instead: `&S`
+   |                                        ^
+   |
+help: consider taking a reference instead
+   |
+LL | fn some_fun<'b, S: Bar<'b, ()>>(items: &S) {}
+   |                                        +
 
 error: this argument is passed by value, but not consumed in the function body
   --> tests/ui/needless_pass_by_value.rs:179:20
    |
 LL | fn more_fun(items: impl Club<'static, i32>) {}
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^ help: consider taking a reference instead: `&impl Club<'static, i32>`
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn more_fun(items: &impl Club<'static, i32>) {}
+   |                    +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:194:24
+   |
+LL | fn option_inner_ref(x: Option<String>) {
+   |                        ^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn option_inner_ref(x: Option<&String>) {
+   |                               +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:204:27
+   |
+LL | fn non_standard_option(x: non_standard::Option<String>) {
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn non_standard_option(x: &non_standard::Option<String>) {
+   |                           +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:209:22
+   |
+LL | fn option_by_name(x: Option<std::option::Option<core::option::Option<non_standard::Option<String>>>>) {
+   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn option_by_name(x: Option<std::option::Option<core::option::Option<&non_standard::Option<String>>>>) {
+   |                                                                      +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:216:18
+   |
+LL | fn non_option(x: OptStr) {
+   |                  ^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn non_option(x: &OptStr) {
+   |                  +
+
+error: this argument is passed by value, but not consumed in the function body
+  --> tests/ui/needless_pass_by_value.rs:223:25
+   |
+LL | fn non_option_either(x: Opt<String>) {
+   |                         ^^^^^^^^^^^
+   |
+help: consider taking a reference instead
+   |
+LL | fn non_option_either(x: &Opt<String>) {
+   |                         +
 
-error: aborting due to 22 previous errors
+error: aborting due to 27 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_return.fixed b/src/tools/clippy/tests/ui/needless_return.fixed
index efc073ebe87..ad625ad6d50 100644
--- a/src/tools/clippy/tests/ui/needless_return.fixed
+++ b/src/tools/clippy/tests/ui/needless_return.fixed
@@ -6,7 +6,8 @@
     clippy::single_match,
     clippy::needless_bool,
     clippy::equatable_if_let,
-    clippy::needless_else
+    clippy::needless_else,
+    clippy::missing_safety_doc
 )]
 #![warn(clippy::needless_return)]
 
@@ -442,3 +443,12 @@ fn b(x: Option<u8>) -> Option<u8> {
         },
     }
 }
+
+unsafe fn todo() -> *const u8 {
+    todo!()
+}
+
+pub unsafe fn issue_12157() -> *const i32 {
+    (unsafe { todo() } as *const i32)
+    //~^ needless_return
+}
diff --git a/src/tools/clippy/tests/ui/needless_return.rs b/src/tools/clippy/tests/ui/needless_return.rs
index 283d86f25fe..41d7e5bdd50 100644
--- a/src/tools/clippy/tests/ui/needless_return.rs
+++ b/src/tools/clippy/tests/ui/needless_return.rs
@@ -6,7 +6,8 @@
     clippy::single_match,
     clippy::needless_bool,
     clippy::equatable_if_let,
-    clippy::needless_else
+    clippy::needless_else,
+    clippy::missing_safety_doc
 )]
 #![warn(clippy::needless_return)]
 
@@ -451,3 +452,12 @@ fn b(x: Option<u8>) -> Option<u8> {
         },
     }
 }
+
+unsafe fn todo() -> *const u8 {
+    todo!()
+}
+
+pub unsafe fn issue_12157() -> *const i32 {
+    return unsafe { todo() } as *const i32;
+    //~^ needless_return
+}
diff --git a/src/tools/clippy/tests/ui/needless_return.stderr b/src/tools/clippy/tests/ui/needless_return.stderr
index 04c97a41d67..80863b9b62b 100644
--- a/src/tools/clippy/tests/ui/needless_return.stderr
+++ b/src/tools/clippy/tests/ui/needless_return.stderr
@@ -1,5 +1,5 @@
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:29:5
+  --> tests/ui/needless_return.rs:30:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:34:5
+  --> tests/ui/needless_return.rs:35:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:40:5
+  --> tests/ui/needless_return.rs:41:5
    |
 LL |     return true;;;
    |     ^^^^^^^^^^^
@@ -37,7 +37,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:46:5
+  --> tests/ui/needless_return.rs:47:5
    |
 LL |     return true;; ; ;
    |     ^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:52:9
+  --> tests/ui/needless_return.rs:53:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -61,7 +61,7 @@ LL +         true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:55:9
+  --> tests/ui/needless_return.rs:56:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL +         false
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:62:17
+  --> tests/ui/needless_return.rs:63:17
    |
 LL |         true => return false,
    |                 ^^^^^^^^^^^^
@@ -85,7 +85,7 @@ LL +         true => false,
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:65:13
+  --> tests/ui/needless_return.rs:66:13
    |
 LL |             return true;
    |             ^^^^^^^^^^^
@@ -97,7 +97,7 @@ LL +             true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:73:9
+  --> tests/ui/needless_return.rs:74:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -109,7 +109,7 @@ LL +         true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:76:16
+  --> tests/ui/needless_return.rs:77:16
    |
 LL |     let _ = || return true;
    |                ^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL +     let _ = || true;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:81:5
+  --> tests/ui/needless_return.rs:82:5
    |
 LL |     return the_answer!();
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -133,7 +133,7 @@ LL +     the_answer!()
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:85:21
+  --> tests/ui/needless_return.rs:86:21
    |
 LL |   fn test_void_fun() {
    |  _____________________^
@@ -148,7 +148,7 @@ LL + fn test_void_fun() {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:91:11
+  --> tests/ui/needless_return.rs:92:11
    |
 LL |       if b {
    |  ___________^
@@ -163,7 +163,7 @@ LL +     if b {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:94:13
+  --> tests/ui/needless_return.rs:95:13
    |
 LL |       } else {
    |  _____________^
@@ -178,7 +178,7 @@ LL +     } else {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:103:14
+  --> tests/ui/needless_return.rs:104:14
    |
 LL |         _ => return,
    |              ^^^^^^
@@ -190,7 +190,7 @@ LL +         _ => (),
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:112:24
+  --> tests/ui/needless_return.rs:113:24
    |
 LL |               let _ = 42;
    |  ________________________^
@@ -205,7 +205,7 @@ LL +             let _ = 42;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:116:14
+  --> tests/ui/needless_return.rs:117:14
    |
 LL |         _ => return,
    |              ^^^^^^
@@ -217,7 +217,7 @@ LL +         _ => (),
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:130:9
+  --> tests/ui/needless_return.rs:131:9
    |
 LL |         return String::from("test");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -229,7 +229,7 @@ LL +         String::from("test")
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:133:9
+  --> tests/ui/needless_return.rs:134:9
    |
 LL |         return String::new();
    |         ^^^^^^^^^^^^^^^^^^^^
@@ -241,7 +241,7 @@ LL +         String::new()
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:156:32
+  --> tests/ui/needless_return.rs:157:32
    |
 LL |         bar.unwrap_or_else(|_| return)
    |                                ^^^^^^
@@ -253,7 +253,7 @@ LL +         bar.unwrap_or_else(|_| {})
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:161:21
+  --> tests/ui/needless_return.rs:162:21
    |
 LL |           let _ = || {
    |  _____________________^
@@ -268,7 +268,7 @@ LL +         let _ = || {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:165:20
+  --> tests/ui/needless_return.rs:166:20
    |
 LL |         let _ = || return;
    |                    ^^^^^^
@@ -280,7 +280,7 @@ LL +         let _ = || {};
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:172:32
+  --> tests/ui/needless_return.rs:173:32
    |
 LL |         res.unwrap_or_else(|_| return Foo)
    |                                ^^^^^^^^^^
@@ -292,7 +292,7 @@ LL +         res.unwrap_or_else(|_| Foo)
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:182:5
+  --> tests/ui/needless_return.rs:183:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^
@@ -304,7 +304,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:187:5
+  --> tests/ui/needless_return.rs:188:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^
@@ -316,7 +316,7 @@ LL +     true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:193:9
+  --> tests/ui/needless_return.rs:194:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -328,7 +328,7 @@ LL +         true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:196:9
+  --> tests/ui/needless_return.rs:197:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^
@@ -340,7 +340,7 @@ LL +         false
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:203:17
+  --> tests/ui/needless_return.rs:204:17
    |
 LL |         true => return false,
    |                 ^^^^^^^^^^^^
@@ -352,7 +352,7 @@ LL +         true => false,
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:206:13
+  --> tests/ui/needless_return.rs:207:13
    |
 LL |             return true;
    |             ^^^^^^^^^^^
@@ -364,7 +364,7 @@ LL +             true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:214:9
+  --> tests/ui/needless_return.rs:215:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -376,7 +376,7 @@ LL +         true
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:217:16
+  --> tests/ui/needless_return.rs:218:16
    |
 LL |     let _ = || return true;
    |                ^^^^^^^^^^^
@@ -388,7 +388,7 @@ LL +     let _ = || true;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:222:5
+  --> tests/ui/needless_return.rs:223:5
    |
 LL |     return the_answer!();
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -400,7 +400,7 @@ LL +     the_answer!()
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:226:33
+  --> tests/ui/needless_return.rs:227:33
    |
 LL |   async fn async_test_void_fun() {
    |  _________________________________^
@@ -415,7 +415,7 @@ LL + async fn async_test_void_fun() {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:232:11
+  --> tests/ui/needless_return.rs:233:11
    |
 LL |       if b {
    |  ___________^
@@ -430,7 +430,7 @@ LL +     if b {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:235:13
+  --> tests/ui/needless_return.rs:236:13
    |
 LL |       } else {
    |  _____________^
@@ -445,7 +445,7 @@ LL +     } else {
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:244:14
+  --> tests/ui/needless_return.rs:245:14
    |
 LL |         _ => return,
    |              ^^^^^^
@@ -457,7 +457,7 @@ LL +         _ => (),
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:258:9
+  --> tests/ui/needless_return.rs:259:9
    |
 LL |         return String::from("test");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -469,7 +469,7 @@ LL +         String::from("test")
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:261:9
+  --> tests/ui/needless_return.rs:262:9
    |
 LL |         return String::new();
    |         ^^^^^^^^^^^^^^^^^^^^
@@ -481,7 +481,7 @@ LL +         String::new()
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:278:5
+  --> tests/ui/needless_return.rs:279:5
    |
 LL |     return format!("Hello {}", "world!");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -493,7 +493,7 @@ LL +     format!("Hello {}", "world!")
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:320:9
+  --> tests/ui/needless_return.rs:321:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^
@@ -508,7 +508,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:323:9
+  --> tests/ui/needless_return.rs:324:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^
@@ -521,7 +521,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:331:13
+  --> tests/ui/needless_return.rs:332:13
    |
 LL |             return 10;
    |             ^^^^^^^^^
@@ -536,7 +536,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:335:13
+  --> tests/ui/needless_return.rs:336:13
    |
 LL |             return 100;
    |             ^^^^^^^^^^
@@ -550,7 +550,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:344:9
+  --> tests/ui/needless_return.rs:345:9
    |
 LL |         return 0;
    |         ^^^^^^^^
@@ -563,7 +563,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:352:13
+  --> tests/ui/needless_return.rs:353:13
    |
 LL |             return *(x as *const isize);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -579,7 +579,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:355:13
+  --> tests/ui/needless_return.rs:356:13
    |
 LL |             return !*(x as *const isize);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -593,7 +593,7 @@ LL ~     }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:363:20
+  --> tests/ui/needless_return.rs:364:20
    |
 LL |           let _ = 42;
    |  ____________________^
@@ -608,7 +608,7 @@ LL +         let _ = 42;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:370:20
+  --> tests/ui/needless_return.rs:371:20
    |
 LL |         let _ = 42; return;
    |                    ^^^^^^^
@@ -620,7 +620,7 @@ LL +         let _ = 42;
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:383:9
+  --> tests/ui/needless_return.rs:384:9
    |
 LL |         return Ok(format!("ok!"));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -632,7 +632,7 @@ LL +         Ok(format!("ok!"))
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:386:9
+  --> tests/ui/needless_return.rs:387:9
    |
 LL |         return Err(format!("err!"));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -644,7 +644,7 @@ LL +         Err(format!("err!"))
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:393:9
+  --> tests/ui/needless_return.rs:394:9
    |
 LL |         return if true { 1 } else { 2 };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -656,7 +656,7 @@ LL +         if true { 1 } else { 2 }
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:398:9
+  --> tests/ui/needless_return.rs:399:9
    |
 LL |         return if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else { 5 };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -668,7 +668,7 @@ LL +         (if b1 { 0 } else { 1 } | if b2 { 2 } else { 3 } | if b3 { 4 } else
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:420:5
+  --> tests/ui/needless_return.rs:421:5
    |
 LL |     return { "a".to_string() } + "b" + { "c" };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -680,7 +680,7 @@ LL +     ({ "a".to_string() } + "b" + { "c" })
    |
 
 error: unneeded `return` statement
-  --> tests/ui/needless_return.rs:425:5
+  --> tests/ui/needless_return.rs:426:5
    |
 LL |     return "".split("").next().unwrap().to_string();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -691,5 +691,17 @@ LL -     return "".split("").next().unwrap().to_string();
 LL +     "".split("").next().unwrap().to_string()
    |
 
-error: aborting due to 54 previous errors
+error: unneeded `return` statement
+  --> tests/ui/needless_return.rs:461:5
+   |
+LL |     return unsafe { todo() } as *const i32;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: remove `return` and wrap the sequence with parentheses
+   |
+LL -     return unsafe { todo() } as *const i32;
+LL +     (unsafe { todo() } as *const i32)
+   |
+
+error: aborting due to 55 previous errors
 
diff --git a/src/tools/clippy/tests/ui/never_loop.rs b/src/tools/clippy/tests/ui/never_loop.rs
index 2d8e04c192e..e0f54ef899b 100644
--- a/src/tools/clippy/tests/ui/never_loop.rs
+++ b/src/tools/clippy/tests/ui/never_loop.rs
@@ -422,6 +422,34 @@ pub fn issue12205() -> Option<()> {
     }
 }
 
+fn stmt_after_return() {
+    for v in 0..10 {
+        //~^ never_loop
+        break;
+        println!("{v}");
+    }
+}
+
+fn loop_label() {
+    'outer: for v in 0..10 {
+        //~^ never_loop
+        loop {
+            //~^ never_loop
+            break 'outer;
+        }
+        return;
+    }
+
+    for v in 0..10 {
+        //~^ never_loop
+        'inner: loop {
+            //~^ never_loop
+            break 'inner;
+        }
+        return;
+    }
+}
+
 fn main() {
     test1();
     test2();
diff --git a/src/tools/clippy/tests/ui/never_loop.stderr b/src/tools/clippy/tests/ui/never_loop.stderr
index f6d6d109542..bc9a7ec48b4 100644
--- a/src/tools/clippy/tests/ui/never_loop.stderr
+++ b/src/tools/clippy/tests/ui/never_loop.stderr
@@ -164,5 +164,73 @@ LL | |         unimplemented!("not yet");
 LL | |     }
    | |_____^
 
-error: aborting due to 16 previous errors
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:426:5
+   |
+LL | /     for v in 0..10 {
+LL | |
+LL | |         break;
+LL | |         println!("{v}");
+LL | |     }
+   | |_____^
+   |
+help: if you need the first element of the iterator, try writing
+   |
+LL -     for v in 0..10 {
+LL +     if let Some(v) = (0..10).next() {
+   |
+
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:434:5
+   |
+LL | /     'outer: for v in 0..10 {
+LL | |
+LL | |         loop {
+...  |
+LL | |         return;
+LL | |     }
+   | |_____^
+   |
+help: if you need the first element of the iterator, try writing
+   |
+LL -     'outer: for v in 0..10 {
+LL +     if let Some(v) = (0..10).next() {
+   |
+
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:436:9
+   |
+LL | /         loop {
+LL | |
+LL | |             break 'outer;
+LL | |         }
+   | |_________^
+
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:443:5
+   |
+LL | /     for v in 0..10 {
+LL | |
+LL | |         'inner: loop {
+...  |
+LL | |         return;
+LL | |     }
+   | |_____^
+   |
+help: if you need the first element of the iterator, try writing
+   |
+LL -     for v in 0..10 {
+LL +     if let Some(v) = (0..10).next() {
+   |
+
+error: this loop never actually loops
+  --> tests/ui/never_loop.rs:445:9
+   |
+LL | /         'inner: loop {
+LL | |
+LL | |             break 'inner;
+LL | |         }
+   | |_________^
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/never_loop_fixable.fixed b/src/tools/clippy/tests/ui/never_loop_fixable.fixed
new file mode 100644
index 00000000000..5bc9ff1bb4d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/never_loop_fixable.fixed
@@ -0,0 +1,20 @@
+#![allow(clippy::iter_next_slice, clippy::needless_return)]
+
+fn no_break_or_continue_loop() {
+    if let Some(i) = [1, 2, 3].iter().next() {
+        //~^ never_loop
+        return;
+    }
+}
+
+fn no_break_or_continue_loop_outer() {
+    if let Some(i) = [1, 2, 3].iter().next() {
+        //~^ never_loop
+        return;
+        loop {
+            if true {
+                continue;
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/never_loop_fixable.rs b/src/tools/clippy/tests/ui/never_loop_fixable.rs
new file mode 100644
index 00000000000..9782bc107e9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/never_loop_fixable.rs
@@ -0,0 +1,20 @@
+#![allow(clippy::iter_next_slice, clippy::needless_return)]
+
+fn no_break_or_continue_loop() {
+    for i in [1, 2, 3].iter() {
+        //~^ never_loop
+        return;
+    }
+}
+
+fn no_break_or_continue_loop_outer() {
+    for i in [1, 2, 3].iter() {
+        //~^ never_loop
+        return;
+        loop {
+            if true {
+                continue;
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/never_loop_fixable.stderr b/src/tools/clippy/tests/ui/never_loop_fixable.stderr
new file mode 100644
index 00000000000..ee02d9a4297
--- /dev/null
+++ b/src/tools/clippy/tests/ui/never_loop_fixable.stderr
@@ -0,0 +1,35 @@
+error: this loop never actually loops
+  --> tests/ui/never_loop_fixable.rs:4:5
+   |
+LL | /     for i in [1, 2, 3].iter() {
+LL | |
+LL | |         return;
+LL | |     }
+   | |_____^
+   |
+   = note: `#[deny(clippy::never_loop)]` on by default
+help: if you need the first element of the iterator, try writing
+   |
+LL -     for i in [1, 2, 3].iter() {
+LL +     if let Some(i) = [1, 2, 3].iter().next() {
+   |
+
+error: this loop never actually loops
+  --> tests/ui/never_loop_fixable.rs:11:5
+   |
+LL | /     for i in [1, 2, 3].iter() {
+LL | |
+LL | |         return;
+LL | |         loop {
+...  |
+LL | |     }
+   | |_____^
+   |
+help: if you need the first element of the iterator, try writing
+   |
+LL -     for i in [1, 2, 3].iter() {
+LL +     if let Some(i) = [1, 2, 3].iter().next() {
+   |
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.fixed b/src/tools/clippy/tests/ui/option_if_let_else.fixed
index f5a869cf283..ee309889601 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.fixed
+++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed
@@ -268,3 +268,23 @@ fn issue11893() {
         panic!("Haven't thought about this condition.");
     }
 }
+
+mod issue13964 {
+    #[derive(Debug)]
+    struct A(Option<String>);
+
+    fn foo(a: A) {
+        let _ = match a.0 {
+            Some(x) => x,
+            None => panic!("{a:?} is invalid."),
+        };
+    }
+
+    fn bar(a: A) {
+        let _ = if let Some(x) = a.0 {
+            x
+        } else {
+            panic!("{a:?} is invalid.")
+        };
+    }
+}
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.rs b/src/tools/clippy/tests/ui/option_if_let_else.rs
index d48272e618a..525a5df4371 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.rs
+++ b/src/tools/clippy/tests/ui/option_if_let_else.rs
@@ -331,3 +331,23 @@ fn issue11893() {
         panic!("Haven't thought about this condition.");
     }
 }
+
+mod issue13964 {
+    #[derive(Debug)]
+    struct A(Option<String>);
+
+    fn foo(a: A) {
+        let _ = match a.0 {
+            Some(x) => x,
+            None => panic!("{a:?} is invalid."),
+        };
+    }
+
+    fn bar(a: A) {
+        let _ = if let Some(x) = a.0 {
+            x
+        } else {
+            panic!("{a:?} is invalid.")
+        };
+    }
+}
diff --git a/src/tools/clippy/tests/ui/ptr_eq.fixed b/src/tools/clippy/tests/ui/ptr_eq.fixed
index 1ccd2c2237d..df6305ed497 100644
--- a/src/tools/clippy/tests/ui/ptr_eq.fixed
+++ b/src/tools/clippy/tests/ui/ptr_eq.fixed
@@ -20,8 +20,10 @@ fn main() {
     //~^ ptr_eq
     let _ = std::ptr::eq(a, b);
     //~^ ptr_eq
-    let _ = a.as_ptr() == b as *const _;
-    let _ = a.as_ptr() == b.as_ptr();
+    let _ = std::ptr::eq(a.as_ptr(), b as *const _);
+    //~^ ptr_eq
+    let _ = std::ptr::eq(a.as_ptr(), b.as_ptr());
+    //~^ ptr_eq
 
     // Do not lint
 
@@ -31,9 +33,22 @@ fn main() {
     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 _ = std::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _);
+    //~^ ptr_eq
+    let _ = std::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr());
+    //~^ ptr_eq
 
     let _ = a == b;
     let _ = core::ptr::eq(a, b);
+
+    let (x, y) = (&0u32, &mut 1u32);
+    let _ = std::ptr::eq(x, y);
+    //~^ ptr_eq
+
+    let _ = !std::ptr::eq(x, y);
+    //~^ ptr_eq
+
+    #[allow(clippy::eq_op)]
+    let _issue14337 = std::ptr::eq(main as *const (), main as *const ());
+    //~^ ptr_eq
 }
diff --git a/src/tools/clippy/tests/ui/ptr_eq.rs b/src/tools/clippy/tests/ui/ptr_eq.rs
index 0bc58a57fa5..0ed0ff0d137 100644
--- a/src/tools/clippy/tests/ui/ptr_eq.rs
+++ b/src/tools/clippy/tests/ui/ptr_eq.rs
@@ -21,7 +21,9 @@ fn main() {
     let _ = a as *const _ == b as *const _;
     //~^ ptr_eq
     let _ = a.as_ptr() == b as *const _;
+    //~^ ptr_eq
     let _ = a.as_ptr() == b.as_ptr();
+    //~^ ptr_eq
 
     // Do not lint
 
@@ -32,8 +34,21 @@ fn main() {
     let b = &mut [1, 2, 3];
 
     let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+    //~^ ptr_eq
     let _ = a.as_mut_ptr() == b.as_mut_ptr();
+    //~^ ptr_eq
 
     let _ = a == b;
     let _ = core::ptr::eq(a, b);
+
+    let (x, y) = (&0u32, &mut 1u32);
+    let _ = x as *const u32 == y as *mut u32 as *const u32;
+    //~^ ptr_eq
+
+    let _ = x as *const u32 != y as *mut u32 as *const u32;
+    //~^ ptr_eq
+
+    #[allow(clippy::eq_op)]
+    let _issue14337 = main as *const () == main as *const ();
+    //~^ ptr_eq
 }
diff --git a/src/tools/clippy/tests/ui/ptr_eq.stderr b/src/tools/clippy/tests/ui/ptr_eq.stderr
index 8e8b34f26ff..33190df284a 100644
--- a/src/tools/clippy/tests/ui/ptr_eq.stderr
+++ b/src/tools/clippy/tests/ui/ptr_eq.stderr
@@ -13,5 +13,47 @@ error: use `std::ptr::eq` when comparing raw pointers
 LL |     let _ = a as *const _ == b as *const _;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a, b)`
 
-error: aborting due to 2 previous errors
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:23:13
+   |
+LL |     let _ = a.as_ptr() == b as *const _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_ptr(), b as *const _)`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:25:13
+   |
+LL |     let _ = a.as_ptr() == b.as_ptr();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_ptr(), b.as_ptr())`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:36:13
+   |
+LL |     let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _)`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:38:13
+   |
+LL |     let _ = a.as_mut_ptr() == b.as_mut_ptr();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr())`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:45:13
+   |
+LL |     let _ = x as *const u32 == y as *mut u32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(x, y)`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:48:13
+   |
+LL |     let _ = x as *const u32 != y as *mut u32 as *const u32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `!std::ptr::eq(x, y)`
+
+error: use `std::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq.rs:52:23
+   |
+LL |     let _issue14337 = main as *const () == main as *const ();
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `std::ptr::eq(main as *const (), main as *const ())`
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed b/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed
index b3e82fae38f..d8ee4ea88f8 100644
--- a/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed
+++ b/src/tools/clippy/tests/ui/ptr_eq_no_std.fixed
@@ -32,8 +32,10 @@ fn main() {
     //~^ ptr_eq
     let _ = core::ptr::eq(a, b);
     //~^ ptr_eq
-    let _ = a.as_ptr() == b as *const _;
-    let _ = a.as_ptr() == b.as_ptr();
+    let _ = core::ptr::eq(a.as_ptr(), b as *const _);
+    //~^ ptr_eq
+    let _ = core::ptr::eq(a.as_ptr(), b.as_ptr());
+    //~^ ptr_eq
 
     // Do not lint
 
@@ -43,8 +45,10 @@ fn main() {
     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 _ = core::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _);
+    //~^ ptr_eq
+    let _ = core::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr());
+    //~^ ptr_eq
 
     let _ = a == b;
     let _ = core::ptr::eq(a, b);
diff --git a/src/tools/clippy/tests/ui/ptr_eq_no_std.rs b/src/tools/clippy/tests/ui/ptr_eq_no_std.rs
index ba78f5ee5f8..a236314c29b 100644
--- a/src/tools/clippy/tests/ui/ptr_eq_no_std.rs
+++ b/src/tools/clippy/tests/ui/ptr_eq_no_std.rs
@@ -33,7 +33,9 @@ fn main() {
     let _ = a as *const _ == b as *const _;
     //~^ ptr_eq
     let _ = a.as_ptr() == b as *const _;
+    //~^ ptr_eq
     let _ = a.as_ptr() == b.as_ptr();
+    //~^ ptr_eq
 
     // Do not lint
 
@@ -44,7 +46,9 @@ fn main() {
     let b = &mut [1, 2, 3];
 
     let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+    //~^ ptr_eq
     let _ = a.as_mut_ptr() == b.as_mut_ptr();
+    //~^ ptr_eq
 
     let _ = a == b;
     let _ = core::ptr::eq(a, b);
diff --git a/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr b/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr
index 8c7b1ff7666..5b8135dc8e8 100644
--- a/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr
+++ b/src/tools/clippy/tests/ui/ptr_eq_no_std.stderr
@@ -13,5 +13,29 @@ error: use `core::ptr::eq` when comparing raw pointers
 LL |     let _ = a as *const _ == b as *const _;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a, b)`
 
-error: aborting due to 2 previous errors
+error: use `core::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq_no_std.rs:35:13
+   |
+LL |     let _ = a.as_ptr() == b as *const _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_ptr(), b as *const _)`
+
+error: use `core::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq_no_std.rs:37:13
+   |
+LL |     let _ = a.as_ptr() == b.as_ptr();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_ptr(), b.as_ptr())`
+
+error: use `core::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq_no_std.rs:48:13
+   |
+LL |     let _ = a.as_mut_ptr() == b as *mut [i32] as *mut _;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_mut_ptr(), b as *mut [i32] as *mut _)`
+
+error: use `core::ptr::eq` when comparing raw pointers
+  --> tests/ui/ptr_eq_no_std.rs:50:13
+   |
+LL |     let _ = a.as_mut_ptr() == b.as_mut_ptr();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `core::ptr::eq(a.as_mut_ptr(), b.as_mut_ptr())`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed
index 8dfef3202be..fff41f57828 100644
--- a/src/tools/clippy/tests/ui/question_mark.fixed
+++ b/src/tools/clippy/tests/ui/question_mark.fixed
@@ -375,3 +375,58 @@ fn issue12412(foo: &Foo, bar: &Bar) -> Option<()> {
     //~^^^ question_mark
     Some(())
 }
+
+struct StructWithOptionString {
+    opt_x: Option<String>,
+}
+
+struct WrapperStructWithString(String);
+
+#[allow(clippy::disallowed_names)]
+fn issue_13417(foo: &mut StructWithOptionString) -> Option<String> {
+    let x = foo.opt_x.as_ref()?;
+    //~^^^ question_mark
+    let opt_y = Some(x.clone());
+    std::mem::replace(&mut foo.opt_x, opt_y)
+}
+
+#[allow(clippy::disallowed_names)]
+fn issue_13417_mut(foo: &mut StructWithOptionString) -> Option<String> {
+    let x = foo.opt_x.as_mut()?;
+    //~^^^ question_mark
+    let opt_y = Some(x.clone());
+    std::mem::replace(&mut foo.opt_x, opt_y)
+}
+
+#[allow(clippy::disallowed_names)]
+#[allow(unused)]
+fn issue_13417_weirder(foo: &mut StructWithOptionString, mut bar: Option<WrapperStructWithString>) -> Option<()> {
+    let x @ y = foo.opt_x.as_ref()?;
+    //~^^^ question_mark
+    let x @ &WrapperStructWithString(_) = bar.as_ref()?;
+    //~^^^ question_mark
+    let x @ &mut WrapperStructWithString(_) = bar.as_mut()?;
+    //~^^^ question_mark
+    Some(())
+}
+
+#[clippy::msrv = "1.12"]
+fn msrv_1_12(arg: Option<i32>) -> Option<i32> {
+    if arg.is_none() {
+        return None;
+    }
+    let val = match arg {
+        Some(val) => val,
+        None => return None,
+    };
+    println!("{}", val);
+    Some(val)
+}
+
+#[clippy::msrv = "1.13"]
+fn msrv_1_13(arg: Option<i32>) -> Option<i32> {
+    arg?;
+    let val = arg?;
+    println!("{}", val);
+    Some(val)
+}
diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs
index fffaa803f39..c71c8ee984e 100644
--- a/src/tools/clippy/tests/ui/question_mark.rs
+++ b/src/tools/clippy/tests/ui/question_mark.rs
@@ -452,3 +452,75 @@ fn issue12412(foo: &Foo, bar: &Bar) -> Option<()> {
     //~^^^ question_mark
     Some(())
 }
+
+struct StructWithOptionString {
+    opt_x: Option<String>,
+}
+
+struct WrapperStructWithString(String);
+
+#[allow(clippy::disallowed_names)]
+fn issue_13417(foo: &mut StructWithOptionString) -> Option<String> {
+    let Some(ref x) = foo.opt_x else {
+        return None;
+    };
+    //~^^^ question_mark
+    let opt_y = Some(x.clone());
+    std::mem::replace(&mut foo.opt_x, opt_y)
+}
+
+#[allow(clippy::disallowed_names)]
+fn issue_13417_mut(foo: &mut StructWithOptionString) -> Option<String> {
+    let Some(ref mut x) = foo.opt_x else {
+        return None;
+    };
+    //~^^^ question_mark
+    let opt_y = Some(x.clone());
+    std::mem::replace(&mut foo.opt_x, opt_y)
+}
+
+#[allow(clippy::disallowed_names)]
+#[allow(unused)]
+fn issue_13417_weirder(foo: &mut StructWithOptionString, mut bar: Option<WrapperStructWithString>) -> Option<()> {
+    let Some(ref x @ ref y) = foo.opt_x else {
+        return None;
+    };
+    //~^^^ question_mark
+    let Some(ref x @ WrapperStructWithString(_)) = bar else {
+        return None;
+    };
+    //~^^^ question_mark
+    let Some(ref mut x @ WrapperStructWithString(_)) = bar else {
+        return None;
+    };
+    //~^^^ question_mark
+    Some(())
+}
+
+#[clippy::msrv = "1.12"]
+fn msrv_1_12(arg: Option<i32>) -> Option<i32> {
+    if arg.is_none() {
+        return None;
+    }
+    let val = match arg {
+        Some(val) => val,
+        None => return None,
+    };
+    println!("{}", val);
+    Some(val)
+}
+
+#[clippy::msrv = "1.13"]
+fn msrv_1_13(arg: Option<i32>) -> Option<i32> {
+    if arg.is_none() {
+        //~^ question_mark
+        return None;
+    }
+    let val = match arg {
+        //~^ question_mark
+        Some(val) => val,
+        None => return None,
+    };
+    println!("{}", val);
+    Some(val)
+}
diff --git a/src/tools/clippy/tests/ui/question_mark.stderr b/src/tools/clippy/tests/ui/question_mark.stderr
index c4db0fbc302..183b8866a74 100644
--- a/src/tools/clippy/tests/ui/question_mark.stderr
+++ b/src/tools/clippy/tests/ui/question_mark.stderr
@@ -215,5 +215,65 @@ LL | |         return None;
 LL | |     };
    | |______^ help: replace it with: `let v = bar.foo.owned.clone()?;`
 
-error: aborting due to 22 previous errors
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:464:5
+   |
+LL | /     let Some(ref x) = foo.opt_x else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x = foo.opt_x.as_ref()?;`
+
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:474:5
+   |
+LL | /     let Some(ref mut x) = foo.opt_x else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x = foo.opt_x.as_mut()?;`
+
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:485:5
+   |
+LL | /     let Some(ref x @ ref y) = foo.opt_x else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x @ y = foo.opt_x.as_ref()?;`
+
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:489:5
+   |
+LL | /     let Some(ref x @ WrapperStructWithString(_)) = bar else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x @ &WrapperStructWithString(_) = bar.as_ref()?;`
+
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:493:5
+   |
+LL | /     let Some(ref mut x @ WrapperStructWithString(_)) = bar else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let x @ &mut WrapperStructWithString(_) = bar.as_mut()?;`
+
+error: this block may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:515:5
+   |
+LL | /     if arg.is_none() {
+LL | |
+LL | |         return None;
+LL | |     }
+   | |_____^ help: replace it with: `arg?;`
+
+error: this `match` expression can be replaced with `?`
+  --> tests/ui/question_mark.rs:519:15
+   |
+LL |       let val = match arg {
+   |  _______________^
+LL | |
+LL | |         Some(val) => val,
+LL | |         None => return None,
+LL | |     };
+   | |_____^ help: try instead: `arg?`
+
+error: aborting due to 29 previous errors
 
diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
index b7ed3aab004..a98b73c9e1c 100644
--- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
+++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.rs
@@ -3,12 +3,7 @@
 // ifs_same_cond warning is different from `ifs_same_cond`.
 // clippy::if_same_then_else, clippy::comparison_chain -- all empty blocks
 #![allow(incomplete_features)]
-#![allow(
-    clippy::comparison_chain,
-    clippy::if_same_then_else,
-    clippy::ifs_same_cond,
-    clippy::uninlined_format_args
-)]
+#![allow(clippy::if_same_then_else, clippy::ifs_same_cond, clippy::uninlined_format_args)]
 
 use std::marker::ConstParamTy;
 
diff --git a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
index 6cd4f96c13e..35dcbadce59 100644
--- a/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
+++ b/src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr
@@ -1,11 +1,11 @@
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:39:15
+  --> tests/ui/same_functions_in_if_condition.rs:34:15
    |
 LL |     } else if function() {
    |               ^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:38:8
+  --> tests/ui/same_functions_in_if_condition.rs:33:8
    |
 LL |     if function() {
    |        ^^^^^^^^^^
@@ -16,61 +16,61 @@ LL | #![deny(clippy::same_functions_in_if_condition)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:44:15
+  --> tests/ui/same_functions_in_if_condition.rs:39:15
    |
 LL |     } else if fn_arg(a) {
    |               ^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:43:8
+  --> tests/ui/same_functions_in_if_condition.rs:38:8
    |
 LL |     if fn_arg(a) {
    |        ^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:49:15
+  --> tests/ui/same_functions_in_if_condition.rs:44:15
    |
 LL |     } else if obj.method() {
    |               ^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:48:8
+  --> tests/ui/same_functions_in_if_condition.rs:43:8
    |
 LL |     if obj.method() {
    |        ^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:54:15
+  --> tests/ui/same_functions_in_if_condition.rs:49:15
    |
 LL |     } else if obj.method_arg(a) {
    |               ^^^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:53:8
+  --> tests/ui/same_functions_in_if_condition.rs:48:8
    |
 LL |     if obj.method_arg(a) {
    |        ^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:60:15
+  --> tests/ui/same_functions_in_if_condition.rs:55:15
    |
 LL |     } else if v.pop().is_none() {
    |               ^^^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:59:8
+  --> tests/ui/same_functions_in_if_condition.rs:54:8
    |
 LL |     if v.pop().is_none() {
    |        ^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> tests/ui/same_functions_in_if_condition.rs:65:15
+  --> tests/ui/same_functions_in_if_condition.rs:60:15
    |
 LL |     } else if v.len() == 42 {
    |               ^^^^^^^^^^^^^
    |
 note: same as this
-  --> tests/ui/same_functions_in_if_condition.rs:64:8
+  --> tests/ui/same_functions_in_if_condition.rs:59:8
    |
 LL |     if v.len() == 42 {
    |        ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/single_match.fixed b/src/tools/clippy/tests/ui/single_match.fixed
index c6ffe93eb7a..0e198ec7934 100644
--- a/src/tools/clippy/tests/ui/single_match.fixed
+++ b/src/tools/clippy/tests/ui/single_match.fixed
@@ -1,3 +1,4 @@
+//@require-annotations-for-level: WARN
 #![warn(clippy::single_match)]
 #![allow(
     unused,
@@ -18,13 +19,9 @@ fn single_match() {
     //~^^^^^^ single_match
 
     let x = Some(1u8);
-    match x {
-        // Note the missing block braces.
-        // We suggest `if let Some(y) = x { .. }` because the macro
-        // is expanded before we can do anything.
-        Some(y) => println!("{:?}", y),
-        _ => (),
-    }
+    if let Some(y) = x { println!("{:?}", y) }
+    //~^^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
 
     let z = (1u8, 1u8);
     if let (2..=3, 7..=9) = z { dummy() };
@@ -358,21 +355,14 @@ fn irrefutable_match() {
 
     let mut x = vec![1i8];
 
-    // Should not lint.
-    match x.pop() {
-        // bla
-        Some(u) => println!("{u}"),
-        // more comments!
-        None => {},
-    }
-    // Should not lint.
-    match x.pop() {
-        // bla
-        Some(u) => {
-            // bla
-            println!("{u}");
-        },
+    if let Some(u) = x.pop() { println!("{u}") }
+    //~^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
+
+    if let Some(u) = x.pop() {
         // bla
-        None => {},
+        println!("{u}");
     }
+    //~^^^^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
 }
diff --git a/src/tools/clippy/tests/ui/single_match.rs b/src/tools/clippy/tests/ui/single_match.rs
index dc758fa4281..fcac65f8aaf 100644
--- a/src/tools/clippy/tests/ui/single_match.rs
+++ b/src/tools/clippy/tests/ui/single_match.rs
@@ -1,3 +1,4 @@
+//@require-annotations-for-level: WARN
 #![warn(clippy::single_match)]
 #![allow(
     unused,
@@ -28,6 +29,8 @@ fn single_match() {
         Some(y) => println!("{:?}", y),
         _ => (),
     }
+    //~^^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
 
     let z = (1u8, 1u8);
     match z {
@@ -437,14 +440,15 @@ fn irrefutable_match() {
 
     let mut x = vec![1i8];
 
-    // Should not lint.
     match x.pop() {
         // bla
         Some(u) => println!("{u}"),
         // more comments!
         None => {},
     }
-    // Should not lint.
+    //~^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
+
     match x.pop() {
         // bla
         Some(u) => {
@@ -454,4 +458,6 @@ fn irrefutable_match() {
         // bla
         None => {},
     }
+    //~^^^^^^^^^ single_match
+    //~| NOTE: you might want to preserve the comments from inside the `match`
 }
diff --git a/src/tools/clippy/tests/ui/single_match.stderr b/src/tools/clippy/tests/ui/single_match.stderr
index c8829695948..2467423b9c1 100644
--- a/src/tools/clippy/tests/ui/single_match.stderr
+++ b/src/tools/clippy/tests/ui/single_match.stderr
@@ -1,5 +1,5 @@
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:15:5
+  --> tests/ui/single_match.rs:16:5
    |
 LL | /     match x {
 LL | |         Some(y) => {
@@ -19,7 +19,18 @@ LL ~     };
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:33:5
+  --> tests/ui/single_match.rs:25:5
+   |
+LL | /     match x {
+...  |
+LL | |         _ => (),
+LL | |     }
+   | |_____^ help: try: `if let Some(y) = x { println!("{:?}", y) }`
+   |
+   = note: you might want to preserve the comments from inside the `match`
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> tests/ui/single_match.rs:36:5
    |
 LL | /     match z {
 LL | |         (2..=3, 7..=9) => dummy(),
@@ -28,7 +39,7 @@ LL | |     };
    | |_____^ help: try: `if let (2..=3, 7..=9) = z { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:63:5
+  --> tests/ui/single_match.rs:66:5
    |
 LL | /     match x {
 LL | |         Some(y) => dummy(),
@@ -37,7 +48,7 @@ LL | |     };
    | |_____^ help: try: `if let Some(y) = x { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:69:5
+  --> tests/ui/single_match.rs:72:5
    |
 LL | /     match y {
 LL | |         Ok(y) => dummy(),
@@ -46,7 +57,7 @@ LL | |     };
    | |_____^ help: try: `if let Ok(y) = y { dummy() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:77:5
+  --> tests/ui/single_match.rs:80:5
    |
 LL | /     match c {
 LL | |         Cow::Borrowed(..) => dummy(),
@@ -55,7 +66,7 @@ LL | |     };
    | |_____^ help: try: `if let Cow::Borrowed(..) = c { dummy() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:99:5
+  --> tests/ui/single_match.rs:102:5
    |
 LL | /     match x {
 LL | |         "test" => println!(),
@@ -64,7 +75,7 @@ LL | |     }
    | |_____^ help: try: `if x == "test" { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:113:5
+  --> tests/ui/single_match.rs:116:5
    |
 LL | /     match x {
 LL | |         Foo::A => println!(),
@@ -73,7 +84,7 @@ LL | |     }
    | |_____^ help: try: `if x == Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:120:5
+  --> tests/ui/single_match.rs:123:5
    |
 LL | /     match x {
 LL | |         FOO_C => println!(),
@@ -82,7 +93,7 @@ LL | |     }
    | |_____^ help: try: `if x == FOO_C { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:126:5
+  --> tests/ui/single_match.rs:129:5
    |
 LL | /     match &&x {
 LL | |         Foo::A => println!(),
@@ -91,7 +102,7 @@ LL | |     }
    | |_____^ help: try: `if x == Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:133:5
+  --> tests/ui/single_match.rs:136:5
    |
 LL | /     match &x {
 LL | |         Foo::A => println!(),
@@ -100,7 +111,7 @@ LL | |     }
    | |_____^ help: try: `if x == &Foo::A { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:151:5
+  --> tests/ui/single_match.rs:154:5
    |
 LL | /     match x {
 LL | |         Bar::A => println!(),
@@ -109,7 +120,7 @@ LL | |     }
    | |_____^ help: try: `if let Bar::A = x { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:160:5
+  --> tests/ui/single_match.rs:163:5
    |
 LL | /     match x {
 LL | |         None => println!(),
@@ -118,7 +129,7 @@ LL | |     };
    | |_____^ help: try: `if let None = x { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:183:5
+  --> tests/ui/single_match.rs:186:5
    |
 LL | /     match x {
 LL | |         (Some(_), _) => {},
@@ -127,7 +138,7 @@ LL | |     }
    | |_____^ help: try: `if let (Some(_), _) = x {}`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:190:5
+  --> tests/ui/single_match.rs:193:5
    |
 LL | /     match x {
 LL | |         (Some(E::V), _) => todo!(),
@@ -136,7 +147,7 @@ LL | |     }
    | |_____^ help: try: `if let (Some(E::V), _) = x { todo!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:197:5
+  --> tests/ui/single_match.rs:200:5
    |
 LL | /     match (Some(42), Some(E::V), Some(42)) {
 LL | |         (.., Some(E::V), _) => {},
@@ -145,7 +156,7 @@ LL | |     }
    | |_____^ help: try: `if let (.., Some(E::V), _) = (Some(42), Some(E::V), Some(42)) {}`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:270:5
+  --> tests/ui/single_match.rs:273:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -165,7 +176,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:279:5
+  --> tests/ui/single_match.rs:282:5
    |
 LL | /     match bar {
 LL | |         #[rustfmt::skip]
@@ -187,7 +198,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:360:5
+  --> tests/ui/single_match.rs:363:5
    |
 LL | /     match Ok::<_, u32>(Some(A)) {
 LL | |         Ok(Some(A)) => println!(),
@@ -196,7 +207,7 @@ LL | |     }
    | |_____^ help: try: `if let Ok(Some(A)) = Ok::<_, u32>(Some(A)) { println!() }`
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match.rs:376:5
+  --> tests/ui/single_match.rs:379:5
    |
 LL | /     match &Some(A) {
 LL | |         Some(A | B) => println!(),
@@ -205,7 +216,7 @@ LL | |     }
    | |_____^ help: try: `if let Some(A | B) = &Some(A) { println!() }`
 
 error: you seem to be trying to use `match` for an equality check. Consider using `if`
-  --> tests/ui/single_match.rs:384:5
+  --> tests/ui/single_match.rs:387:5
    |
 LL | /     match &s[0..3] {
 LL | |         b"foo" => println!(),
@@ -214,7 +225,7 @@ LL | |     }
    | |_____^ help: try: `if &s[0..3] == b"foo" { println!() }`
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:398:5
+  --> tests/ui/single_match.rs:401:5
    |
 LL | /     match DATA {
 LL | |         DATA => println!(),
@@ -223,7 +234,7 @@ LL | |     }
    | |_____^ help: try: `println!();`
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:404:5
+  --> tests/ui/single_match.rs:407:5
    |
 LL | /     match CONST_I32 {
 LL | |         CONST_I32 => println!(),
@@ -232,7 +243,7 @@ LL | |     }
    | |_____^ help: try: `println!();`
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:411:5
+  --> tests/ui/single_match.rs:414:5
    |
 LL | /     match i {
 LL | |         i => {
@@ -252,7 +263,7 @@ LL +     }
    |
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:420:5
+  --> tests/ui/single_match.rs:423:5
    |
 LL | /     match i {
 LL | |         i => {},
@@ -261,7 +272,7 @@ LL | |     }
    | |_____^ help: `match` expression can be removed
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:426:5
+  --> tests/ui/single_match.rs:429:5
    |
 LL | /     match i {
 LL | |         i => (),
@@ -270,7 +281,7 @@ LL | |     }
    | |_____^ help: `match` expression can be removed
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match.rs:432:5
+  --> tests/ui/single_match.rs:435:5
    |
 LL | /     match CONST_I32 {
 LL | |         CONST_I32 => println!(),
@@ -278,5 +289,37 @@ LL | |         _ => {},
 LL | |     }
    | |_____^ help: try: `println!();`
 
-error: aborting due to 26 previous errors
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> tests/ui/single_match.rs:443:5
+   |
+LL | /     match x.pop() {
+LL | |         // bla
+LL | |         Some(u) => println!("{u}"),
+...  |
+LL | |     }
+   | |_____^ help: try: `if let Some(u) = x.pop() { println!("{u}") }`
+   |
+   = note: you might want to preserve the comments from inside the `match`
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> tests/ui/single_match.rs:452:5
+   |
+LL | /     match x.pop() {
+LL | |         // bla
+LL | |         Some(u) => {
+...  |
+LL | |         None => {},
+LL | |     }
+   | |_____^
+   |
+   = note: you might want to preserve the comments from inside the `match`
+help: try
+   |
+LL ~     if let Some(u) = x.pop() {
+LL +         // bla
+LL +         println!("{u}");
+LL +     }
+   |
+
+error: aborting due to 29 previous errors
 
diff --git a/src/tools/clippy/tests/ui/single_match_else.fixed b/src/tools/clippy/tests/ui/single_match_else.fixed
index 64782bf62a7..fde13fb90db 100644
--- a/src/tools/clippy/tests/ui/single_match_else.fixed
+++ b/src/tools/clippy/tests/ui/single_match_else.fixed
@@ -1,4 +1,5 @@
 //@aux-build: proc_macros.rs
+//@require-annotations-for-level: WARN
 
 #![warn(clippy::single_match_else)]
 #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
@@ -90,6 +91,13 @@ fn main() {
     }
     //~^^^^^^^ single_match_else
 
+    if let Some(a) = Some(1) { println!("${:?}", a) } else {
+        println!("else block");
+        return;
+    }
+    //~^^^^^^^^ single_match_else
+    //~| NOTE: you might want to preserve the comments from inside the `match`
+
     // lint here
     use std::convert::Infallible;
     if let Ok(a) = Result::<i32, &Infallible>::Ok(1) { println!("${:?}", a) } else {
diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs
index 3f86f4d5180..ca282200067 100644
--- a/src/tools/clippy/tests/ui/single_match_else.rs
+++ b/src/tools/clippy/tests/ui/single_match_else.rs
@@ -1,4 +1,5 @@
 //@aux-build: proc_macros.rs
+//@require-annotations-for-level: WARN
 
 #![warn(clippy::single_match_else)]
 #![allow(unused, clippy::needless_return, clippy::no_effect, clippy::uninlined_format_args)]
@@ -99,6 +100,17 @@ fn main() {
     }
     //~^^^^^^^ single_match_else
 
+    match Some(1) {
+        Some(a) => println!("${:?}", a),
+        // This is an inner comment
+        None => {
+            println!("else block");
+            return;
+        },
+    }
+    //~^^^^^^^^ single_match_else
+    //~| NOTE: you might want to preserve the comments from inside the `match`
+
     // lint here
     use std::convert::Infallible;
     match Result::<i32, &Infallible>::Ok(1) {
diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr
index 7d4ba5fb75e..570480f9a3f 100644
--- a/src/tools/clippy/tests/ui/single_match_else.stderr
+++ b/src/tools/clippy/tests/ui/single_match_else.stderr
@@ -1,5 +1,5 @@
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:17:13
+  --> tests/ui/single_match_else.rs:18:13
    |
 LL |       let _ = match ExprNode::Butterflies {
    |  _____________^
@@ -22,7 +22,7 @@ LL ~     };
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:83:5
+  --> tests/ui/single_match_else.rs:84:5
    |
 LL | /     match Some(1) {
 LL | |         Some(a) => println!("${:?}", a),
@@ -42,7 +42,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:93:5
+  --> tests/ui/single_match_else.rs:94:5
    |
 LL | /     match Some(1) {
 LL | |         Some(a) => println!("${:?}", a),
@@ -62,7 +62,28 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:104:5
+  --> tests/ui/single_match_else.rs:103:5
+   |
+LL | /     match Some(1) {
+LL | |         Some(a) => println!("${:?}", a),
+LL | |         // This is an inner comment
+LL | |         None => {
+...  |
+LL | |         },
+LL | |     }
+   | |_____^
+   |
+   = note: you might want to preserve the comments from inside the `match`
+help: try
+   |
+LL ~     if let Some(a) = Some(1) { println!("${:?}", a) } else {
+LL +         println!("else block");
+LL +         return;
+LL +     }
+   |
+
+error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
+  --> tests/ui/single_match_else.rs:116:5
    |
 LL | /     match Result::<i32, &Infallible>::Ok(1) {
 LL | |         Ok(a) => println!("${:?}", a),
@@ -81,7 +102,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:114:5
+  --> tests/ui/single_match_else.rs:126:5
    |
 LL | /     match Cow::from("moo") {
 LL | |         Cow::Owned(a) => println!("${:?}", a),
@@ -100,7 +121,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:125:5
+  --> tests/ui/single_match_else.rs:137:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -123,7 +144,7 @@ LL +     }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:137:5
+  --> tests/ui/single_match_else.rs:149:5
    |
 LL | /     match bar {
 LL | |         Some(v) => {
@@ -147,7 +168,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:150:5
+  --> tests/ui/single_match_else.rs:162:5
    |
 LL | /     match bar {
 LL | |         Some(v) => unsafe {
@@ -171,7 +192,7 @@ LL +     } }
    |
 
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> tests/ui/single_match_else.rs:163:5
+  --> tests/ui/single_match_else.rs:175:5
    |
 LL | /     match bar {
 LL | |         #[rustfmt::skip]
@@ -196,7 +217,7 @@ LL +     }
    |
 
 error: this pattern is irrefutable, `match` is useless
-  --> tests/ui/single_match_else.rs:213:5
+  --> tests/ui/single_match_else.rs:225:5
    |
 LL | /     match ExprNode::Butterflies {
 LL | |         ExprNode::Butterflies => Some(&NODE),
@@ -207,5 +228,5 @@ LL | |         },
 LL | |     }
    | |_____^ help: try: `Some(&NODE)`
 
-error: aborting due to 10 previous errors
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/size_of_ref.stderr b/src/tools/clippy/tests/ui/size_of_ref.stderr
index 6ac0b0dd2f0..46af9f55dea 100644
--- a/src/tools/clippy/tests/ui/size_of_ref.stderr
+++ b/src/tools/clippy/tests/ui/size_of_ref.stderr
@@ -1,28 +1,28 @@
-error: argument to `std::mem::size_of_val()` is a reference to a reference
+error: argument to `size_of_val()` is a reference to a reference
   --> tests/ui/size_of_ref.rs:13:5
    |
 LL |     size_of_val(&&x);
    |     ^^^^^^^^^^^^^^^^
    |
-   = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
+   = help: dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type
    = note: `-D clippy::size-of-ref` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::size_of_ref)]`
 
-error: argument to `std::mem::size_of_val()` is a reference to a reference
+error: argument to `size_of_val()` is a reference to a reference
   --> tests/ui/size_of_ref.rs:16:5
    |
 LL |     size_of_val(&y);
    |     ^^^^^^^^^^^^^^^
    |
-   = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
+   = help: dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type
 
-error: argument to `std::mem::size_of_val()` is a reference to a reference
+error: argument to `size_of_val()` is a reference to a reference
   --> tests/ui/size_of_ref.rs:28:9
    |
 LL |         std::mem::size_of_val(&self) + (std::mem::size_of::<u8>() * self.data.capacity())
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: dereference the argument to `std::mem::size_of_val()` to get the size of the value instead of the size of the reference-type
+   = help: dereference the argument to `size_of_val()` to get the size of the value instead of the size of the reference-type
 
 error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/string_to_string.rs b/src/tools/clippy/tests/ui/string_to_string.rs
index 94174e1253b..7c5bd8a897b 100644
--- a/src/tools/clippy/tests/ui/string_to_string.rs
+++ b/src/tools/clippy/tests/ui/string_to_string.rs
@@ -1,8 +1,21 @@
 #![warn(clippy::string_to_string)]
-#![allow(clippy::redundant_clone)]
+#![allow(clippy::redundant_clone, clippy::unnecessary_literal_unwrap)]
 
 fn main() {
     let mut message = String::from("Hello");
     let mut v = message.to_string();
     //~^ string_to_string
+
+    let variable1 = String::new();
+    let v = &variable1;
+    let variable2 = Some(v);
+    let _ = variable2.map(|x| {
+        println!();
+        x.to_string()
+    });
+    //~^^ string_to_string
+
+    let x = Some(String::new());
+    let _ = x.unwrap_or_else(|| v.to_string());
+    //~^ string_to_string
 }
diff --git a/src/tools/clippy/tests/ui/string_to_string.stderr b/src/tools/clippy/tests/ui/string_to_string.stderr
index ae80597d1f8..99eea06f18e 100644
--- a/src/tools/clippy/tests/ui/string_to_string.stderr
+++ b/src/tools/clippy/tests/ui/string_to_string.stderr
@@ -8,5 +8,21 @@ LL |     let mut v = message.to_string();
    = note: `-D clippy::string-to-string` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::string_to_string)]`
 
-error: aborting due to 1 previous error
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string.rs:14:9
+   |
+LL |         x.to_string()
+   |         ^^^^^^^^^^^^^
+   |
+   = help: consider using `.clone()`
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string.rs:19:33
+   |
+LL |     let _ = x.unwrap_or_else(|| v.to_string());
+   |                                 ^^^^^^^^^^^^^
+   |
+   = help: consider using `.clone()`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/string_to_string_in_map.fixed b/src/tools/clippy/tests/ui/string_to_string_in_map.fixed
new file mode 100644
index 00000000000..efc085539f1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/string_to_string_in_map.fixed
@@ -0,0 +1,20 @@
+#![deny(clippy::string_to_string)]
+#![allow(clippy::unnecessary_literal_unwrap, clippy::useless_vec, clippy::iter_cloned_collect)]
+
+fn main() {
+    let variable1 = String::new();
+    let v = &variable1;
+    let variable2 = Some(v);
+    let _ = variable2.cloned();
+    //~^ string_to_string
+    let _ = variable2.cloned();
+    //~^ string_to_string
+    #[rustfmt::skip]
+    let _ = variable2.cloned();
+    //~^ string_to_string
+
+    let _ = vec![String::new()].iter().cloned().collect::<Vec<_>>();
+    //~^ string_to_string
+    let _ = vec![String::new()].iter().cloned().collect::<Vec<_>>();
+    //~^ string_to_string
+}
diff --git a/src/tools/clippy/tests/ui/string_to_string_in_map.rs b/src/tools/clippy/tests/ui/string_to_string_in_map.rs
new file mode 100644
index 00000000000..5bf1d7ba5a2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/string_to_string_in_map.rs
@@ -0,0 +1,20 @@
+#![deny(clippy::string_to_string)]
+#![allow(clippy::unnecessary_literal_unwrap, clippy::useless_vec, clippy::iter_cloned_collect)]
+
+fn main() {
+    let variable1 = String::new();
+    let v = &variable1;
+    let variable2 = Some(v);
+    let _ = variable2.map(String::to_string);
+    //~^ string_to_string
+    let _ = variable2.map(|x| x.to_string());
+    //~^ string_to_string
+    #[rustfmt::skip]
+    let _ = variable2.map(|x| { x.to_string() });
+    //~^ string_to_string
+
+    let _ = vec![String::new()].iter().map(String::to_string).collect::<Vec<_>>();
+    //~^ string_to_string
+    let _ = vec![String::new()].iter().map(|x| x.to_string()).collect::<Vec<_>>();
+    //~^ string_to_string
+}
diff --git a/src/tools/clippy/tests/ui/string_to_string_in_map.stderr b/src/tools/clippy/tests/ui/string_to_string_in_map.stderr
new file mode 100644
index 00000000000..35aeed656ee
--- /dev/null
+++ b/src/tools/clippy/tests/ui/string_to_string_in_map.stderr
@@ -0,0 +1,38 @@
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:8:23
+   |
+LL |     let _ = variable2.map(String::to_string);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+   |
+note: the lint level is defined here
+  --> tests/ui/string_to_string_in_map.rs:1:9
+   |
+LL | #![deny(clippy::string_to_string)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:10:23
+   |
+LL |     let _ = variable2.map(|x| x.to_string());
+   |                       ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:13:23
+   |
+LL |     let _ = variable2.map(|x| { x.to_string() });
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:16:40
+   |
+LL |     let _ = vec![String::new()].iter().map(String::to_string).collect::<Vec<_>>();
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+
+error: `to_string()` called on a `String`
+  --> tests/ui/string_to_string_in_map.rs:18:40
+   |
+LL |     let _ = vec![String::new()].iter().map(|x| x.to_string()).collect::<Vec<_>>();
+   |                                        ^^^^^^^^^^^^^^^^^^^^^^ help: try: `cloned()`
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/struct_fields.rs b/src/tools/clippy/tests/ui/struct_fields.rs
index 3dce530efff..e7ff2e6573b 100644
--- a/src/tools/clippy/tests/ui/struct_fields.rs
+++ b/src/tools/clippy/tests/ui/struct_fields.rs
@@ -344,4 +344,31 @@ struct Use {
     //~^ struct_field_names
 }
 
+// should lint on private fields of public structs (renaming them is not breaking-exported-api)
+pub struct PubStructFieldNamedAfterStruct {
+    pub_struct_field_named_after_struct: bool,
+    //~^ ERROR: field name starts with the struct's name
+    other1: bool,
+    other2: bool,
+}
+pub struct PubStructFieldPrefix {
+    //~^ ERROR: all fields have the same prefix: `field`
+    field_foo: u8,
+    field_bar: u8,
+    field_baz: u8,
+}
+// ...but should not lint on structs with public fields.
+pub struct PubStructPubAndPrivateFields {
+    /// One could argue that this field should be linted, but currently, any public field stops all
+    /// checking.
+    pub_struct_pub_and_private_fields_1: bool,
+    pub pub_struct_pub_and_private_fields_2: bool,
+}
+// nor on common prefixes if one of the involved fields is public
+pub struct PubStructPubAndPrivateFieldPrefix {
+    pub field_foo: u8,
+    field_bar: u8,
+    field_baz: u8,
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/struct_fields.stderr b/src/tools/clippy/tests/ui/struct_fields.stderr
index 79186cc1cfd..a5ff1b12590 100644
--- a/src/tools/clippy/tests/ui/struct_fields.stderr
+++ b/src/tools/clippy/tests/ui/struct_fields.stderr
@@ -281,5 +281,24 @@ error: field name starts with the struct's name
 LL |     use_baz: bool,
    |     ^^^^^^^^^^^^^
 
-error: aborting due to 24 previous errors
+error: field name starts with the struct's name
+  --> tests/ui/struct_fields.rs:349:5
+   |
+LL |     pub_struct_field_named_after_struct: bool,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: all fields have the same prefix: `field`
+  --> tests/ui/struct_fields.rs:354:1
+   |
+LL | / pub struct PubStructFieldPrefix {
+LL | |
+LL | |     field_foo: u8,
+LL | |     field_bar: u8,
+LL | |     field_baz: u8,
+LL | | }
+   | |_^
+   |
+   = help: remove the prefixes
+
+error: aborting due to 26 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs b/src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs
index 02adeece280..f14f6085c9a 100644
--- a/src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_path_debug_formatting.rs
@@ -41,3 +41,9 @@ fn main() {
     let deref_path = DerefPath { path };
     println!("{:?}", &*deref_path); //~ unnecessary_debug_formatting
 }
+
+#[test]
+fn issue_14345() {
+    let input = std::path::Path::new("/foo/bar");
+    assert!(input.ends_with("baz"), "{input:?}");
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index bf271aef763..5410033dbd8 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -195,19 +195,11 @@ fn main() {
     //~^ unnecessary_to_owned
     let _ = slice.iter().copied();
     //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].iter().cloned();
-    //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].iter().cloned();
-    //~^ unnecessary_to_owned
 
     let _ = slice.iter().copied();
     //~^ unnecessary_to_owned
     let _ = slice.iter().copied();
     //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].iter().cloned();
-    //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].iter().cloned();
-    //~^ unnecessary_to_owned
 
     let _ = check_files(&[FileType::Account]);
 
@@ -317,19 +309,6 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
 
 fn require_string(_: &String) {}
 
-#[clippy::msrv = "1.35"]
-fn _msrv_1_35() {
-    // `copied` was stabilized in 1.36, so clippy should use `cloned`.
-    let _ = &["x"][..].iter().cloned();
-    //~^ unnecessary_to_owned
-}
-
-#[clippy::msrv = "1.36"]
-fn _msrv_1_36() {
-    let _ = &["x"][..].iter().copied();
-    //~^ unnecessary_to_owned
-}
-
 // https://github.com/rust-lang/rust-clippy/issues/8507
 mod issue_8507 {
     #![allow(dead_code)]
@@ -680,3 +659,18 @@ fn issue13624() -> impl IntoIterator {
 
     cow.into_owned().into_iter()
 }
+
+mod issue_14242 {
+    use std::rc::Rc;
+
+    #[derive(Copy, Clone)]
+    struct Foo;
+
+    fn rc_slice_provider() -> Rc<[Foo]> {
+        Rc::from([Foo])
+    }
+
+    fn iterator_provider() -> impl Iterator<Item = Foo> {
+        rc_slice_provider().to_vec().into_iter()
+    }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index 95b95ab6bd2..0619dd4ddec 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -195,19 +195,11 @@ fn main() {
     //~^ unnecessary_to_owned
     let _ = slice.to_owned().into_iter();
     //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
-    //~^ unnecessary_to_owned
-    let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
-    //~^ unnecessary_to_owned
 
     let _ = IntoIterator::into_iter(slice.to_vec());
     //~^ unnecessary_to_owned
     let _ = IntoIterator::into_iter(slice.to_owned());
     //~^ unnecessary_to_owned
-    let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
-    //~^ unnecessary_to_owned
-    let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
-    //~^ unnecessary_to_owned
 
     let _ = check_files(&[FileType::Account]);
 
@@ -317,19 +309,6 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
 
 fn require_string(_: &String) {}
 
-#[clippy::msrv = "1.35"]
-fn _msrv_1_35() {
-    // `copied` was stabilized in 1.36, so clippy should use `cloned`.
-    let _ = &["x"][..].to_vec().into_iter();
-    //~^ unnecessary_to_owned
-}
-
-#[clippy::msrv = "1.36"]
-fn _msrv_1_36() {
-    let _ = &["x"][..].to_vec().into_iter();
-    //~^ unnecessary_to_owned
-}
-
 // https://github.com/rust-lang/rust-clippy/issues/8507
 mod issue_8507 {
     #![allow(dead_code)]
@@ -680,3 +659,18 @@ fn issue13624() -> impl IntoIterator {
 
     cow.into_owned().into_iter()
 }
+
+mod issue_14242 {
+    use std::rc::Rc;
+
+    #[derive(Copy, Clone)]
+    struct Foo;
+
+    fn rc_slice_provider() -> Rc<[Foo]> {
+        Rc::from([Foo])
+    }
+
+    fn iterator_provider() -> impl Iterator<Item = Foo> {
+        rc_slice_provider().to_vec().into_iter()
+    }
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
index 4daa3876e60..8926db34da8 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
@@ -1,11 +1,11 @@
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:225:64
+  --> tests/ui/unnecessary_to_owned.rs:217:64
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                                                                ^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:225:20
+  --> tests/ui/unnecessary_to_owned.rs:217:20
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,49 +13,49 @@ LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned())
    = help: to override `-D warnings` add `#[allow(clippy::redundant_clone)]`
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:227:40
+  --> tests/ui/unnecessary_to_owned.rs:219:40
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                                        ^^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:227:21
+  --> tests/ui/unnecessary_to_owned.rs:219:21
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                     ^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:229:48
+  --> tests/ui/unnecessary_to_owned.rs:221:48
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                                                ^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:229:19
+  --> tests/ui/unnecessary_to_owned.rs:221:19
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:231:35
+  --> tests/ui/unnecessary_to_owned.rs:223:35
    |
 LL |     require_str(&String::from("x").to_string());
    |                                   ^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:231:18
+  --> tests/ui/unnecessary_to_owned.rs:223:18
    |
 LL |     require_str(&String::from("x").to_string());
    |                  ^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> tests/ui/unnecessary_to_owned.rs:233:39
+  --> tests/ui/unnecessary_to_owned.rs:225:39
    |
 LL |     require_slice(&[String::from("x")].to_owned());
    |                                       ^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> tests/ui/unnecessary_to_owned.rs:233:20
+  --> tests/ui/unnecessary_to_owned.rs:225:20
    |
 LL |     require_slice(&[String::from("x")].to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^
@@ -442,43 +442,19 @@ LL |     let _ = slice.to_owned().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:198:13
-   |
-LL |     let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
-
-error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:200:13
-   |
-LL |     let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
-
-error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:203:13
+  --> tests/ui/unnecessary_to_owned.rs:199:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_vec());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:205:13
+  --> tests/ui/unnecessary_to_owned.rs:201:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_owned());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
-error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:207:13
-   |
-LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
-
-error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:209:13
-   |
-LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
-
 error: allocating a new `String` only to create a temporary `&str` from it
-  --> tests/ui/unnecessary_to_owned.rs:237:26
+  --> tests/ui/unnecessary_to_owned.rs:229:26
    |
 LL |     let _ref_str: &str = &String::from_utf8(slice.to_vec()).expect("not UTF-8");
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -490,7 +466,7 @@ LL +     let _ref_str: &str = core::str::from_utf8(&slice).expect("not UTF-8");
    |
 
 error: allocating a new `String` only to create a temporary `&str` from it
-  --> tests/ui/unnecessary_to_owned.rs:239:26
+  --> tests/ui/unnecessary_to_owned.rs:231:26
    |
 LL |     let _ref_str: &str = &String::from_utf8(b"foo".to_vec()).unwrap();
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -502,7 +478,7 @@ LL +     let _ref_str: &str = core::str::from_utf8(b"foo").unwrap();
    |
 
 error: allocating a new `String` only to create a temporary `&str` from it
-  --> tests/ui/unnecessary_to_owned.rs:241:26
+  --> tests/ui/unnecessary_to_owned.rs:233:26
    |
 LL |     let _ref_str: &str = &String::from_utf8(b"foo".as_slice().to_owned()).unwrap();
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -514,7 +490,7 @@ LL +     let _ref_str: &str = core::str::from_utf8(b"foo".as_slice()).unwrap();
    |
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:299:14
+  --> tests/ui/unnecessary_to_owned.rs:291:14
    |
 LL |     for t in file_types.to_vec() {
    |              ^^^^^^^^^^^^^^^^^^^
@@ -526,65 +502,53 @@ LL |
 LL ~         let path = match get_file_path(t) {
    |
 
-error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:323:14
-   |
-LL |     let _ = &["x"][..].to_vec().into_iter();
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
-
-error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:329:14
-   |
-LL |     let _ = &["x"][..].to_vec().into_iter();
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
-
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:378:24
+  --> tests/ui/unnecessary_to_owned.rs:357:24
    |
 LL |         Box::new(build(y.to_string()))
    |                        ^^^^^^^^^^^^^ help: use: `y`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:488:12
+  --> tests/ui/unnecessary_to_owned.rs:467:12
    |
 LL |         id("abc".to_string())
    |            ^^^^^^^^^^^^^^^^^ help: use: `"abc"`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:632:37
+  --> tests/ui/unnecessary_to_owned.rs:611:37
    |
 LL |         IntoFuture::into_future(foo([].to_vec(), &0));
    |                                     ^^^^^^^^^^^ help: use: `[]`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:643:18
+  --> tests/ui/unnecessary_to_owned.rs:622:18
    |
 LL |         s.remove(&a.to_vec());
    |                  ^^^^^^^^^^^ help: replace it with: `a`
 
 error: unnecessary use of `to_owned`
-  --> tests/ui/unnecessary_to_owned.rs:648:14
+  --> tests/ui/unnecessary_to_owned.rs:627:14
    |
 LL |     s.remove(&"b".to_owned());
    |              ^^^^^^^^^^^^^^^ help: replace it with: `"b"`
 
 error: unnecessary use of `to_string`
-  --> tests/ui/unnecessary_to_owned.rs:650:14
+  --> tests/ui/unnecessary_to_owned.rs:629:14
    |
 LL |     s.remove(&"b".to_string());
    |              ^^^^^^^^^^^^^^^^ help: replace it with: `"b"`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:656:14
+  --> tests/ui/unnecessary_to_owned.rs:635:14
    |
 LL |     s.remove(&["b"].to_vec());
    |              ^^^^^^^^^^^^^^^ help: replace it with: `["b"].as_slice()`
 
 error: unnecessary use of `to_vec`
-  --> tests/ui/unnecessary_to_owned.rs:658:14
+  --> tests/ui/unnecessary_to_owned.rs:637:14
    |
 LL |     s.remove(&(&["b"]).to_vec());
    |              ^^^^^^^^^^^^^^^^^^ help: replace it with: `(&["b"]).as_slice()`
 
-error: aborting due to 88 previous errors
+error: aborting due to 82 previous errors