about summary refs log tree commit diff
path: root/src/tools/clippy/tests
diff options
context:
space:
mode:
authorflip1995 <philipp.krones@embecosm.com>2022-05-05 15:12:52 +0100
committerflip1995 <philipp.krones@embecosm.com>2022-05-05 15:12:52 +0100
commit496384531ea92e2efec8802e2d3b45b6ffff9bd8 (patch)
treeadf01cc3834c46a1187cc85f1cae1936617f436f /src/tools/clippy/tests
parent322a14919d6cc67af45477b623857b30fae63f9d (diff)
parent7c21f91b15b7604f818565646b686d90f99d1baf (diff)
downloadrust-496384531ea92e2efec8802e2d3b45b6ffff9bd8.tar.gz
rust-496384531ea92e2efec8802e2d3b45b6ffff9bd8.zip
Merge commit '7c21f91b15b7604f818565646b686d90f99d1baf' into clippyup
Diffstat (limited to 'src/tools/clippy/tests')
-rw-r--r--src/tools/clippy/tests/dogfood.rs6
-rw-r--r--src/tools/clippy/tests/lint_message_convention.rs2
-rw-r--r--src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr4
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed2
-rw-r--r--src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs41
-rw-r--r--src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr25
-rw-r--r--src/tools/clippy/tests/ui-toml/await_holding_invalid_type/clippy.toml4
-rw-r--r--src/tools/clippy/tests/ui-toml/functions_maxlines/test.rs1
-rw-r--r--src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr8
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs16
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr21
-rw-r--r--src/tools/clippy/tests/ui-toml/large_include_file/too_big.txt1
-rw-r--r--src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr2
-rw-r--r--src/tools/clippy/tests/ui/assertions_on_constants.rs10
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs2
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_with_span.rs32
-rw-r--r--src/tools/clippy/tests/ui/bytes_count_to_len.fixed34
-rw-r--r--src/tools/clippy/tests/ui/bytes_count_to_len.rs34
-rw-r--r--src/tools/clippy/tests/ui/bytes_count_to_len.stderr28
-rw-r--r--src/tools/clippy/tests/ui/cast.rs14
-rw-r--r--src/tools/clippy/tests/ui/cast.stderr14
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.rs6
-rw-r--r--src/tools/clippy/tests/ui/cast_slice_different_sizes.rs43
-rw-r--r--src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr85
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.fixed7
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.rs9
-rw-r--r--src/tools/clippy/tests/ui/collapsible_else_if.stderr11
-rw-r--r--src/tools/clippy/tests/ui/crashes/auxiliary/ice-8681-aux.rs6
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2865.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3151.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-5944.rs1
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8250.stderr10
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-8681.rs10
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-96721.rs10
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-96721.stderr8
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed15
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs15
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr46
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed13
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs13
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr50
-rw-r--r--src/tools/clippy/tests/ui/deprecated.rs4
-rw-r--r--src/tools/clippy/tests/ui/deprecated.stderr32
-rw-r--r--src/tools/clippy/tests/ui/doc_unsafe.rs2
-rw-r--r--src/tools/clippy/tests/ui/doc_unsafe.stderr12
-rw-r--r--src/tools/clippy/tests/ui/drop_non_drop.stderr4
-rw-r--r--src/tools/clippy/tests/ui/empty_drop.fixed24
-rw-r--r--src/tools/clippy/tests/ui/empty_drop.rs30
-rw-r--r--src/tools/clippy/tests/ui/empty_drop.stderr22
-rw-r--r--src/tools/clippy/tests/ui/eta.fixed20
-rw-r--r--src/tools/clippy/tests/ui/eta.rs16
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr14
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_lifetimes.rs42
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr20
-rw-r--r--src/tools/clippy/tests/ui/format_push_string.rs7
-rw-r--r--src/tools/clippy/tests/ui/format_push_string.stderr19
-rw-r--r--src/tools/clippy/tests/ui/identity_op.rs34
-rw-r--r--src/tools/clippy/tests/ui/identity_op.stderr128
-rw-r--r--src/tools/clippy/tests/ui/impl.rs2
-rw-r--r--src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed18
-rw-r--r--src/tools/clippy/tests/ui/is_digit_ascii_radix.rs18
-rw-r--r--src/tools/clippy/tests/ui/is_digit_ascii_radix.stderr22
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.fixed2
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.rs2
-rw-r--r--src/tools/clippy/tests/ui/iter_with_drain.fixed9
-rw-r--r--src/tools/clippy/tests/ui/iter_with_drain.rs9
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_drop.rs1
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_drop.stderr6
-rw-r--r--src/tools/clippy/tests/ui/let_unit.fixed52
-rw-r--r--src/tools/clippy/tests/ui/let_unit.rs52
-rw-r--r--src/tools/clippy/tests/ui/let_unit.stderr71
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.fixed69
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.rs13
-rw-r--r--src/tools/clippy/tests/ui/manual_bits.stderr126
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs78
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr41
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs (renamed from src/tools/clippy/tests/ui/manual_non_exhaustive.rs)63
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr (renamed from src/tools/clippy/tests/ui/manual_non_exhaustive.stderr)58
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.fixed117
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.rs117
-rw-r--r--src/tools/clippy/tests/ui/manual_split_once.stderr211
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed16
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.rs16
-rw-r--r--src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr54
-rw-r--r--src/tools/clippy/tests/ui/mut_from_ref.rs20
-rw-r--r--src/tools/clippy/tests/ui/mut_from_ref.stderr14
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_fixable.fixed7
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_fixable.rs7
-rw-r--r--src/tools/clippy/tests/ui/needless_for_each_fixable.stderr16
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.rs73
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init.stderr99
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init_fixable.fixed8
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init_fixable.rs10
-rw-r--r--src/tools/clippy/tests/ui/needless_late_init_fixable.stderr49
-rw-r--r--src/tools/clippy/tests/ui/needless_match.fixed12
-rw-r--r--src/tools/clippy/tests/ui/needless_match.rs12
-rw-r--r--src/tools/clippy/tests/ui/needless_match.stderr8
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.fixed14
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.rs14
-rw-r--r--src/tools/clippy/tests/ui/needless_option_take.fixed15
-rw-r--r--src/tools/clippy/tests/ui/needless_option_take.rs15
-rw-r--r--src/tools/clippy/tests/ui/needless_option_take.stderr10
-rw-r--r--src/tools/clippy/tests/ui/needless_splitn.fixed20
-rw-r--r--src/tools/clippy/tests/ui/needless_splitn.rs20
-rw-r--r--src/tools/clippy/tests/ui/needless_splitn.stderr44
-rw-r--r--src/tools/clippy/tests/ui/new_without_default.rs2
-rw-r--r--src/tools/clippy/tests/ui/non_expressive_names.rs2
-rw-r--r--src/tools/clippy/tests/ui/numbered_fields.fixed5
-rw-r--r--src/tools/clippy/tests/ui/numbered_fields.rs5
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.fixed7
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.rs7
-rw-r--r--src/tools/clippy/tests/ui/option_if_let_else.stderr30
-rw-r--r--src/tools/clippy/tests/ui/option_take_on_temporary.fixed15
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.fixed2
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.rs2
-rw-r--r--src/tools/clippy/tests/ui/panicking_macros.rs2
-rw-r--r--src/tools/clippy/tests/ui/pub_use.rs14
-rw-r--r--src/tools/clippy/tests/ui/pub_use.stderr11
-rw-r--r--src/tools/clippy/tests/ui/redundant_pub_crate.fixed10
-rw-r--r--src/tools/clippy/tests/ui/redundant_pub_crate.rs10
-rw-r--r--src/tools/clippy/tests/ui/rename.fixed89
-rw-r--r--src/tools/clippy/tests/ui/rename.rs89
-rw-r--r--src/tools/clippy/tests/ui/rename.stderr194
-rw-r--r--src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs15
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.rs19
-rw-r--r--src/tools/clippy/tests/ui/same_functions_in_if_condition.stderr24
-rw-r--r--src/tools/clippy/tests/ui/shadow.rs1
-rw-r--r--src/tools/clippy/tests/ui/shadow.stderr88
-rw-r--r--src/tools/clippy/tests/ui/similar_names.rs3
-rw-r--r--src/tools/clippy/tests/ui/similar_names.stderr28
-rw-r--r--src/tools/clippy/tests/ui/single_char_lifetime_names.rs1
-rw-r--r--src/tools/clippy/tests/ui/single_char_lifetime_names.stderr10
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.rs18
-rw-r--r--src/tools/clippy/tests/ui/single_match_else.stderr11
-rw-r--r--src/tools/clippy/tests/ui/stable_sort_primitive.stderr14
-rw-r--r--src/tools/clippy/tests/ui/suspicious_else_formatting.rs2
-rw-r--r--src/tools/clippy/tests/ui/to_digit_is_some.fixed4
-rw-r--r--src/tools/clippy/tests/ui/to_digit_is_some.rs4
-rw-r--r--src/tools/clippy/tests/ui/to_digit_is_some.stderr8
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs3
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr10
-rw-r--r--src/tools/clippy/tests/ui/transmute_collection.rs5
-rw-r--r--src/tools/clippy/tests/ui/trim_split_whitespace.fixed91
-rw-r--r--src/tools/clippy/tests/ui/trim_split_whitespace.rs91
-rw-r--r--src/tools/clippy/tests/ui/trim_split_whitespace.stderr52
-rw-r--r--src/tools/clippy/tests/ui/type_repetition_in_bounds.rs3
-rw-r--r--src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr10
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs1
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr36
-rw-r--r--src/tools/clippy/tests/ui/uninit.rs1
-rw-r--r--src/tools/clippy/tests/ui/uninit.stderr6
-rw-r--r--src/tools/clippy/tests/ui/unit_arg.rs3
-rw-r--r--src/tools/clippy/tests/ui/unit_arg.stderr20
-rw-r--r--src/tools/clippy/tests/ui/unit_hash.rs1
-rw-r--r--src/tools/clippy/tests/ui/unit_hash.stderr6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed22
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs22
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr16
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed12
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs12
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.stderr176
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.fixed7
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.rs7
-rw-r--r--src/tools/clippy/tests/ui/unnested_or_patterns.stderr40
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.fixed6
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.rs6
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.stderr2
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.fixed3
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.rs3
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.stderr42
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention.rs5
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention.stderr18
-rw-r--r--src/tools/clippy/tests/ui/wrong_self_convention2.rs10
176 files changed, 3258 insertions, 1064 deletions
diff --git a/src/tools/clippy/tests/dogfood.rs b/src/tools/clippy/tests/dogfood.rs
index 67af9d05bf4..eb97d1933d5 100644
--- a/src/tools/clippy/tests/dogfood.rs
+++ b/src/tools/clippy/tests/dogfood.rs
@@ -80,9 +80,13 @@ fn run_clippy_for_package(project: &str) {
         .args(&["-D", "clippy::pedantic"])
         .arg("-Cdebuginfo=0"); // disable debuginfo to generate less data in the target dir
 
-    // internal lints only exist if we build with the internal feature
     if cfg!(feature = "internal") {
+        // internal lints only exist if we build with the internal feature
         command.args(&["-D", "clippy::internal"]);
+    } else {
+        // running a clippy built without internal lints on the clippy source
+        // that contains e.g. `allow(clippy::invalid_paths)`
+        command.args(&["-A", "unknown_lints"]);
     }
 
     let output = command.output().unwrap();
diff --git a/src/tools/clippy/tests/lint_message_convention.rs b/src/tools/clippy/tests/lint_message_convention.rs
index dc82ba891fb..dd1d4412036 100644
--- a/src/tools/clippy/tests/lint_message_convention.rs
+++ b/src/tools/clippy/tests/lint_message_convention.rs
@@ -66,7 +66,7 @@ fn lint_message_convention() {
 
     // make sure that lint messages:
     // * are not capitalized
-    // * don't have puncuation at the end of the last sentence
+    // * don't have punctuation at the end of the last sentence
 
     // these directories have interesting tests
     let test_dirs = ["ui", "ui-cargo", "ui-internal", "ui-toml"]
diff --git a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
index 558d1299160..0852fe65aaf 100644
--- a/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
+++ b/src/tools/clippy/tests/ui-internal/collapsible_span_lint_calls.stderr
@@ -29,7 +29,7 @@ LL | |             db.help(help_msg);
 LL | |         });
    | |__________^ help: collapse into: `span_lint_and_help(cx, TEST_LINT, expr.span, lint_msg, None, help_msg)`
 
-error: this call is collspible
+error: this call is collapsible
   --> $DIR/collapsible_span_lint_calls.rs:45:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
@@ -37,7 +37,7 @@ LL | |             db.span_note(expr.span, note_msg);
 LL | |         });
    | |__________^ help: collapse into: `span_lint_and_note(cx, TEST_LINT, expr.span, lint_msg, Some(expr.span), note_msg)`
 
-error: this call is collspible
+error: this call is collapsible
   --> $DIR/collapsible_span_lint_calls.rs:48:9
    |
 LL | /         span_lint_and_then(cx, TEST_LINT, expr.span, lint_msg, |db| {
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
index 6b7fd6efe39..eaea218e128 100644
--- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 #![deny(clippy::internal)]
-#![allow(clippy::missing_clippy_version_attribute)]
+#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
 #![feature(rustc_private)]
 
 extern crate rustc_span;
diff --git a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
index 98d7d7adad1..7efebb8fae4 100644
--- a/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
+++ b/src/tools/clippy/tests/ui-internal/interning_defined_symbol.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 #![deny(clippy::internal)]
-#![allow(clippy::missing_clippy_version_attribute)]
+#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
 #![feature(rustc_private)]
 
 extern crate rustc_span;
diff --git a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs
new file mode 100644
index 00000000000..fbef5c4564b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs
@@ -0,0 +1,41 @@
+#![warn(clippy::await_holding_invalid_type)]
+use std::net::Ipv4Addr;
+
+async fn bad() -> u32 {
+    let _x = String::from("hello");
+    baz().await
+}
+
+async fn bad_reason() -> u32 {
+    let _x = Ipv4Addr::new(127, 0, 0, 1);
+    baz().await
+}
+
+async fn good() -> u32 {
+    {
+        let _x = String::from("hi!");
+        let _y = Ipv4Addr::new(127, 0, 0, 1);
+    }
+    baz().await;
+    let _x = String::from("hi!");
+    47
+}
+
+async fn baz() -> u32 {
+    42
+}
+
+#[allow(clippy::manual_async_fn)]
+fn block_bad() -> impl std::future::Future<Output = u32> {
+    async move {
+        let _x = String::from("hi!");
+        baz().await
+    }
+}
+
+fn main() {
+    good();
+    bad();
+    bad_reason();
+    block_bad();
+}
diff --git a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
new file mode 100644
index 00000000000..62c45b54634
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
@@ -0,0 +1,25 @@
+error: `std::string::String` may not be held across an `await` point per `clippy.toml`
+  --> $DIR/await_holding_invalid_type.rs:5:9
+   |
+LL |     let _x = String::from("hello");
+   |         ^^
+   |
+   = note: `-D clippy::await-holding-invalid-type` implied by `-D warnings`
+   = note: strings are bad
+
+error: `std::net::Ipv4Addr` may not be held across an `await` point per `clippy.toml`
+  --> $DIR/await_holding_invalid_type.rs:10:9
+   |
+LL |     let _x = Ipv4Addr::new(127, 0, 0, 1);
+   |         ^^
+
+error: `std::string::String` may not be held across an `await` point per `clippy.toml`
+  --> $DIR/await_holding_invalid_type.rs:31:13
+   |
+LL |         let _x = String::from("hi!");
+   |             ^^
+   |
+   = note: strings are bad
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/clippy.toml b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/clippy.toml
new file mode 100644
index 00000000000..79990096b84
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/clippy.toml
@@ -0,0 +1,4 @@
+await-holding-invalid-types = [
+    { path = "std::string::String", reason = "strings are bad" },
+    "std::net::Ipv4Addr",
+]
diff --git a/src/tools/clippy/tests/ui-toml/functions_maxlines/test.rs b/src/tools/clippy/tests/ui-toml/functions_maxlines/test.rs
index e678c896fd3..4ac0378544c 100644
--- a/src/tools/clippy/tests/ui-toml/functions_maxlines/test.rs
+++ b/src/tools/clippy/tests/ui-toml/functions_maxlines/test.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::too_many_lines)]
+#![allow(clippy::let_unit_value)]
 
 // This function should be considered one line.
 fn many_comments_but_one_line_of_code() {
diff --git a/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr b/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
index d736bf89973..dc255bdcaba 100644
--- a/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/functions_maxlines/test.stderr
@@ -1,5 +1,5 @@
 error: this function has too many lines (2/1)
-  --> $DIR/test.rs:18:1
+  --> $DIR/test.rs:19:1
    |
 LL | / fn too_many_lines() {
 LL | |     println!("This is bad.");
@@ -10,7 +10,7 @@ LL | | }
    = note: `-D clippy::too-many-lines` implied by `-D warnings`
 
 error: this function has too many lines (4/1)
-  --> $DIR/test.rs:24:1
+  --> $DIR/test.rs:25:1
    |
 LL | / async fn async_too_many_lines() {
 LL | |     println!("This is bad.");
@@ -19,7 +19,7 @@ LL | | }
    | |_^
 
 error: this function has too many lines (4/1)
-  --> $DIR/test.rs:30:1
+  --> $DIR/test.rs:31:1
    |
 LL | / fn closure_too_many_lines() {
 LL | |     let _ = {
@@ -30,7 +30,7 @@ LL | | }
    | |_^
 
 error: this function has too many lines (2/1)
-  --> $DIR/test.rs:52:1
+  --> $DIR/test.rs:53:1
    |
 LL | / fn comment_before_code() {
 LL | |     let _ = "test";
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/clippy.toml b/src/tools/clippy/tests/ui-toml/large_include_file/clippy.toml
new file mode 100644
index 00000000000..ea34bf9fbe0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/clippy.toml
@@ -0,0 +1 @@
+max-include-file-size = 600
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs
new file mode 100644
index 00000000000..f3dbb6ad1cf
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.rs
@@ -0,0 +1,16 @@
+#![warn(clippy::large_include_file)]
+
+// Good
+const GOOD_INCLUDE_BYTES: &[u8; 581] = include_bytes!("large_include_file.rs");
+const GOOD_INCLUDE_STR: &str = include_str!("large_include_file.rs");
+
+#[allow(clippy::large_include_file)]
+const ALLOWED_TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
+#[allow(clippy::large_include_file)]
+const ALLOWED_TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
+
+// Bad
+const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
+const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
new file mode 100644
index 00000000000..6a685a58318
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/large_include_file.stderr
@@ -0,0 +1,21 @@
+error: attempted to include a large file
+  --> $DIR/large_include_file.rs:13:43
+   |
+LL | const TOO_BIG_INCLUDE_BYTES: &[u8; 654] = include_bytes!("too_big.txt");
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::large-include-file` implied by `-D warnings`
+   = note: the configuration allows a maximum size of 600 bytes
+   = note: this error originates in the macro `include_bytes` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: attempted to include a large file
+  --> $DIR/large_include_file.rs:14:35
+   |
+LL | const TOO_BIG_INCLUDE_STR: &str = include_str!("too_big.txt");
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the configuration allows a maximum size of 600 bytes
+   = note: this error originates in the macro `include_str` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/large_include_file/too_big.txt b/src/tools/clippy/tests/ui-toml/large_include_file/too_big.txt
new file mode 100644
index 00000000000..9829c46bc00
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_include_file/too_big.txt
@@ -0,0 +1 @@
+Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Maecenas accumsan lacus vel facilisis volutpat. Etiam dignissim diam quis enim lobortis scelerisque fermentum dui faucibus. Tellus id interdum velit laoreet id donec ultrices. Est ultricies integer quis auctor elit sed vulputate. Erat velit scelerisque in dictum non consectetur a erat nam. Sed blandit libero volutpat sed. Tortor condimentum lacinia quis vel eros. Enim ut tellus elementum sagittis vitae et leo duis. Congue mauris rhoncus aenean vel elit scelerisque. Id consectetur purus ut faucibus pulvinar elementum integer.
\ No newline at end of file
diff --git a/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr
index a1e7361c0cb..5dae5af7eb5 100644
--- a/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr
+++ b/src/tools/clippy/tests/ui-toml/min_rust_version/min_rust_version.stderr
@@ -1,4 +1,4 @@
-error: you are using an explicit closure for copying elements
+error: you are using an explicit closure for cloning elements
   --> $DIR/min_rust_version.rs:74:26
    |
 LL |     let _: Option<u64> = Some(&16).map(|b| *b);
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index 00ddbd608a7..8701809b4da 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -1,4 +1,4 @@
-error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `max-suggested-slice-pattern-length`, `third-party` at line 5 column 1
+error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `max-suggested-slice-pattern-length`, `await-holding-invalid-types`, `max-include-file-size`, `third-party` at line 5 column 1
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/assertions_on_constants.rs b/src/tools/clippy/tests/ui/assertions_on_constants.rs
index 7477c01ca78..7bea9563d47 100644
--- a/src/tools/clippy/tests/ui/assertions_on_constants.rs
+++ b/src/tools/clippy/tests/ui/assertions_on_constants.rs
@@ -1,4 +1,4 @@
-#![allow(non_fmt_panics)]
+#![allow(non_fmt_panics, clippy::needless_bool)]
 
 macro_rules! assert_const {
     ($len:expr) => {
@@ -28,6 +28,12 @@ fn main() {
     assert_const!(3);
     assert_const!(-1);
 
-    // Don't lint on this:
+    // Don't lint if based on `cfg!(..)`:
     assert!(cfg!(feature = "hey") || cfg!(not(feature = "asdf")));
+
+    let flag: bool = cfg!(not(feature = "asdf"));
+    assert!(flag);
+
+    const CFG_FLAG: &bool = &cfg!(feature = "hey");
+    assert!(!CFG_FLAG);
 }
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
index 4b7b7fec78f..ed7b17651e6 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
@@ -13,7 +13,7 @@ use proc_macro::{quote, TokenStream};
 
 #[proc_macro_derive(DeriveSomething)]
 pub fn derive(_: TokenStream) -> TokenStream {
-    // Shound not trigger `used_underscore_binding`
+    // Should not trigger `used_underscore_binding`
     let _inside_derive = 1;
     assert_eq!(_inside_derive, _inside_derive);
 
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_with_span.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_with_span.rs
new file mode 100644
index 00000000000..8ea631f2bbd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_with_span.rs
@@ -0,0 +1,32 @@
+// compile-flags: --emit=link
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{token_stream::IntoIter, Group, Span, TokenStream, TokenTree};
+
+#[proc_macro]
+pub fn with_span(input: TokenStream) -> TokenStream {
+    let mut iter = input.into_iter();
+    let span = iter.next().unwrap().span();
+    let mut res = TokenStream::new();
+    write_with_span(span, iter, &mut res);
+    res
+}
+
+fn write_with_span(s: Span, input: IntoIter, out: &mut TokenStream) {
+    for mut tt in input {
+        if let TokenTree::Group(g) = tt {
+            let mut stream = TokenStream::new();
+            write_with_span(s, g.stream().into_iter(), &mut stream);
+            let mut group = Group::new(g.delimiter(), stream);
+            group.set_span(s);
+            out.extend([TokenTree::Group(group)]);
+        } else {
+            tt.set_span(s);
+            out.extend([tt]);
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/bytes_count_to_len.fixed b/src/tools/clippy/tests/ui/bytes_count_to_len.fixed
new file mode 100644
index 00000000000..860642363b5
--- /dev/null
+++ b/src/tools/clippy/tests/ui/bytes_count_to_len.fixed
@@ -0,0 +1,34 @@
+// run-rustfix
+#![warn(clippy::bytes_count_to_len)]
+use std::fs::File;
+use std::io::Read;
+
+fn main() {
+    // should fix, because type is String
+    let _ = String::from("foo").len();
+
+    let s1 = String::from("foo");
+    let _ = s1.len();
+
+    // should fix, because type is &str
+    let _ = "foo".len();
+
+    let s2 = "foo";
+    let _ = s2.len();
+
+    // make sure using count() normally doesn't trigger warning
+    let vector = [0, 1, 2];
+    let _ = vector.iter().count();
+
+    // The type is slice, so should not fix
+    let _ = &[1, 2, 3].bytes().count();
+
+    let bytes: &[u8] = &[1, 2, 3];
+    bytes.bytes().count();
+
+    // The type is File, so should not fix
+    let _ = File::open("foobar").unwrap().bytes().count();
+
+    let f = File::open("foobar").unwrap();
+    let _ = f.bytes().count();
+}
diff --git a/src/tools/clippy/tests/ui/bytes_count_to_len.rs b/src/tools/clippy/tests/ui/bytes_count_to_len.rs
new file mode 100644
index 00000000000..162730c2842
--- /dev/null
+++ b/src/tools/clippy/tests/ui/bytes_count_to_len.rs
@@ -0,0 +1,34 @@
+// run-rustfix
+#![warn(clippy::bytes_count_to_len)]
+use std::fs::File;
+use std::io::Read;
+
+fn main() {
+    // should fix, because type is String
+    let _ = String::from("foo").bytes().count();
+
+    let s1 = String::from("foo");
+    let _ = s1.bytes().count();
+
+    // should fix, because type is &str
+    let _ = "foo".bytes().count();
+
+    let s2 = "foo";
+    let _ = s2.bytes().count();
+
+    // make sure using count() normally doesn't trigger warning
+    let vector = [0, 1, 2];
+    let _ = vector.iter().count();
+
+    // The type is slice, so should not fix
+    let _ = &[1, 2, 3].bytes().count();
+
+    let bytes: &[u8] = &[1, 2, 3];
+    bytes.bytes().count();
+
+    // The type is File, so should not fix
+    let _ = File::open("foobar").unwrap().bytes().count();
+
+    let f = File::open("foobar").unwrap();
+    let _ = f.bytes().count();
+}
diff --git a/src/tools/clippy/tests/ui/bytes_count_to_len.stderr b/src/tools/clippy/tests/ui/bytes_count_to_len.stderr
new file mode 100644
index 00000000000..224deb77987
--- /dev/null
+++ b/src/tools/clippy/tests/ui/bytes_count_to_len.stderr
@@ -0,0 +1,28 @@
+error: using long and hard to read `.bytes().count()`
+  --> $DIR/bytes_count_to_len.rs:8:13
+   |
+LL |     let _ = String::from("foo").bytes().count();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `String::from("foo").len()`
+   |
+   = note: `-D clippy::bytes-count-to-len` implied by `-D warnings`
+
+error: using long and hard to read `.bytes().count()`
+  --> $DIR/bytes_count_to_len.rs:11:13
+   |
+LL |     let _ = s1.bytes().count();
+   |             ^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `s1.len()`
+
+error: using long and hard to read `.bytes().count()`
+  --> $DIR/bytes_count_to_len.rs:14:13
+   |
+LL |     let _ = "foo".bytes().count();
+   |             ^^^^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `"foo".len()`
+
+error: using long and hard to read `.bytes().count()`
+  --> $DIR/bytes_count_to_len.rs:17:13
+   |
+LL |     let _ = s2.bytes().count();
+   |             ^^^^^^^^^^^^^^^^^^ help: consider calling `.len()` instead: `s2.len()`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs
index cf85a5ca931..e6031e9adae 100644
--- a/src/tools/clippy/tests/ui/cast.rs
+++ b/src/tools/clippy/tests/ui/cast.rs
@@ -1,13 +1,13 @@
 #![feature(repr128)]
 #![allow(incomplete_features)]
-
-#[warn(
+#![warn(
     clippy::cast_precision_loss,
     clippy::cast_possible_truncation,
     clippy::cast_sign_loss,
     clippy::cast_possible_wrap
 )]
-#[allow(clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation)]
+#![allow(clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation)]
+
 fn main() {
     // Test clippy::cast_precision_loss
     let x0 = 1i32;
@@ -252,3 +252,11 @@ fn main() {
         }
     }
 }
+
+fn avoid_subtract_overflow(q: u32) {
+    let c = (q >> 16) as u8;
+    c as usize;
+
+    let c = (q / 1000) as u8;
+    c as usize;
+}
diff --git a/src/tools/clippy/tests/ui/cast.stderr b/src/tools/clippy/tests/ui/cast.stderr
index 7a68c0984f1..0c63b4af308 100644
--- a/src/tools/clippy/tests/ui/cast.stderr
+++ b/src/tools/clippy/tests/ui/cast.stderr
@@ -194,5 +194,17 @@ error: casting `main::E10` to `u16` may truncate the value
 LL |             let _ = self as u16;
    |                     ^^^^^^^^^^^
 
-error: aborting due to 31 previous errors
+error: casting `u32` to `u8` may truncate the value
+  --> $DIR/cast.rs:257:13
+   |
+LL |     let c = (q >> 16) as u8;
+   |             ^^^^^^^^^^^^^^^
+
+error: casting `u32` to `u8` may truncate the value
+  --> $DIR/cast.rs:260:13
+   |
+LL |     let c = (q / 1000) as u8;
+   |             ^^^^^^^^^^^^^^^^
+
+error: aborting due to 33 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast_alignment.rs b/src/tools/clippy/tests/ui/cast_alignment.rs
index e4e7290a30e..95bb883df1b 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.rs
+++ b/src/tools/clippy/tests/ui/cast_alignment.rs
@@ -44,8 +44,8 @@ fn main() {
         let _ = core::ptr::read_unaligned(ptr as *const u16);
         let _ = core::intrinsics::unaligned_volatile_load(ptr as *const u16);
         let ptr = &mut data as *mut [u8; 2] as *mut u8;
-        let _ = (ptr as *mut u16).write_unaligned(0);
-        let _ = core::ptr::write_unaligned(ptr as *mut u16, 0);
-        let _ = core::intrinsics::unaligned_volatile_store(ptr as *mut u16, 0);
+        (ptr as *mut u16).write_unaligned(0);
+        core::ptr::write_unaligned(ptr as *mut u16, 0);
+        core::intrinsics::unaligned_volatile_store(ptr as *mut u16, 0);
     }
 }
diff --git a/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs b/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs
index cfe1cca2eba..24d7eb28a19 100644
--- a/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs
+++ b/src/tools/clippy/tests/ui/cast_slice_different_sizes.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::let_unit_value)]
+
 fn main() {
     let x: [i32; 3] = [1_i32, 2, 3];
     let r_x = &x;
@@ -37,3 +39,44 @@ fn main() {
     let long_chain_restore =
         r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8] as *const [u32];
 }
+
+// foo and foo2 should not fire, they're the same size
+fn foo(x: *mut [u8]) -> *mut [u8] {
+    x as *mut [u8]
+}
+
+fn foo2(x: *mut [u8]) -> *mut [u8] {
+    x as *mut _
+}
+
+// Test that casts as part of function returns work
+fn bar(x: *mut [u16]) -> *mut [u8] {
+    x as *mut [u8]
+}
+
+fn uwu(x: *mut [u16]) -> *mut [u8] {
+    x as *mut _
+}
+
+fn bar2(x: *mut [u16]) -> *mut [u8] {
+    x as _
+}
+
+// constify
+fn bar3(x: *mut [u16]) -> *const [u8] {
+    x as _
+}
+
+// unconstify
+fn bar4(x: *const [u16]) -> *mut [u8] {
+    x as _
+}
+
+// function returns plus blocks
+fn blocks(x: *mut [u16]) -> *mut [u8] {
+    ({ x }) as _
+}
+
+fn more_blocks(x: *mut [u16]) -> *mut [u8] {
+    { ({ x }) as _ }
+}
diff --git a/src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr b/src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr
index a37cec7cb3b..40721dcd05d 100644
--- a/src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr
+++ b/src/tools/clippy/tests/ui/cast_slice_different_sizes.stderr
@@ -1,5 +1,5 @@
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:7:13
+  --> $DIR/cast_slice_different_sizes.rs:9:13
    |
 LL |     let b = a as *const [u8];
    |             ^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(a as *const u8, ..)`
@@ -7,25 +7,25 @@ LL |     let b = a as *const [u8];
    = note: `#[deny(clippy::cast_slice_different_sizes)]` on by default
 
 error: casting between raw pointers to `[u8]` (element size 1) and `[u32]` (element size 4) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:8:13
+  --> $DIR/cast_slice_different_sizes.rs:10:13
    |
 LL |     let c = b as *const [u32];
    |             ^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(b as *const u32, ..)`
 
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:11:16
+  --> $DIR/cast_slice_different_sizes.rs:13:16
    |
 LL |     let loss = r_x as *const [i32] as *const [u8];
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)`
 
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:18:24
+  --> $DIR/cast_slice_different_sizes.rs:20:24
    |
 LL |     let loss_block_1 = { r_x as *const [i32] } as *const [u8];
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts({ r_x as *const [i32] } as *const u8, ..)`
 
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:19:24
+  --> $DIR/cast_slice_different_sizes.rs:21:24
    |
 LL |       let loss_block_2 = {
    |  ________________________^
@@ -43,10 +43,79 @@ LL ~     } as *const u8, ..);
    |
 
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:36:27
+  --> $DIR/cast_slice_different_sizes.rs:38:27
    |
 LL |     let long_chain_loss = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8];
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const u8, ..)`
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)`
 
-error: aborting due to 6 previous errors
+error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
+  --> $DIR/cast_slice_different_sizes.rs:53:36
+   |
+LL |   fn bar(x: *mut [u16]) -> *mut [u8] {
+   |  ____________________________________^
+LL | |     x as *mut [u8]
+LL | | }
+   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`
+
+error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
+  --> $DIR/cast_slice_different_sizes.rs:57:36
+   |
+LL |   fn uwu(x: *mut [u16]) -> *mut [u8] {
+   |  ____________________________________^
+LL | |     x as *mut _
+LL | | }
+   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`
+
+error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
+  --> $DIR/cast_slice_different_sizes.rs:61:37
+   |
+LL |   fn bar2(x: *mut [u16]) -> *mut [u8] {
+   |  _____________________________________^
+LL | |     x as _
+LL | | }
+   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`
+
+error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
+  --> $DIR/cast_slice_different_sizes.rs:66:39
+   |
+LL |   fn bar3(x: *mut [u16]) -> *const [u8] {
+   |  _______________________________________^
+LL | |     x as _
+LL | | }
+   | |_^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(x as *const u8, ..)`
+
+error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
+  --> $DIR/cast_slice_different_sizes.rs:71:39
+   |
+LL |   fn bar4(x: *const [u16]) -> *mut [u8] {
+   |  _______________________________________^
+LL | |     x as _
+LL | | }
+   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(x as *mut u8, ..)`
+
+error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
+  --> $DIR/cast_slice_different_sizes.rs:76:39
+   |
+LL |   fn blocks(x: *mut [u16]) -> *mut [u8] {
+   |  _______________________________________^
+LL | |     ({ x }) as _
+LL | | }
+   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)`
+
+error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
+  --> $DIR/cast_slice_different_sizes.rs:80:44
+   |
+LL |   fn more_blocks(x: *mut [u16]) -> *mut [u8] {
+   |  ____________________________________________^
+LL | |     { ({ x }) as _ }
+LL | | }
+   | |_^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)`
+
+error: casting between raw pointers to `[u16]` (element size 2) and `[u8]` (element size 1) does not adjust the count
+  --> $DIR/cast_slice_different_sizes.rs:81:5
+   |
+LL |     { ({ x }) as _ }
+   |     ^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts_mut`: `core::ptr::slice_from_raw_parts_mut(({ x }) as *mut u8, ..)`
+
+error: aborting due to 14 previous errors
 
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.fixed b/src/tools/clippy/tests/ui/collapsible_else_if.fixed
index bb6c4c0703d..d6a5a785067 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.fixed
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.fixed
@@ -75,3 +75,10 @@ fn main() {
         }
     }
 }
+
+#[rustfmt::skip]
+#[allow(dead_code)]
+fn issue_7318() {
+    if true { println!("I've been resolved!")
+    }else if false {}
+}
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.rs b/src/tools/clippy/tests/ui/collapsible_else_if.rs
index 6d4f688db8c..4399fc8b2bd 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.rs
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.rs
@@ -89,3 +89,12 @@ fn main() {
         }
     }
 }
+
+#[rustfmt::skip]
+#[allow(dead_code)]
+fn issue_7318() {
+    if true { println!("I've been resolved!")
+    }else{
+        if false {}
+    }
+}
diff --git a/src/tools/clippy/tests/ui/collapsible_else_if.stderr b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
index 6970f660979..45b2094c994 100644
--- a/src/tools/clippy/tests/ui/collapsible_else_if.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_else_if.stderr
@@ -150,5 +150,14 @@ LL +         println!("!")
 LL +     }
    |
 
-error: aborting due to 7 previous errors
+error: this `else { if .. }` block can be collapsed
+  --> $DIR/collapsible_else_if.rs:97:10
+   |
+LL |       }else{
+   |  __________^
+LL | |         if false {}
+LL | |     }
+   | |_____^ help: collapse nested if block: `if false {}`
+
+error: aborting due to 8 previous errors
 
diff --git a/src/tools/clippy/tests/ui/crashes/auxiliary/ice-8681-aux.rs b/src/tools/clippy/tests/ui/crashes/auxiliary/ice-8681-aux.rs
new file mode 100644
index 00000000000..95b63151325
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/auxiliary/ice-8681-aux.rs
@@ -0,0 +1,6 @@
+pub fn foo(x: &u32) -> u32 {
+    /* Safety:
+     * This is totally ok.
+     */
+    unsafe { *(x as *const u32) }
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2865.rs b/src/tools/clippy/tests/ui/crashes/ice-2865.rs
index 6b1ceb50569..c6298139601 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2865.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2865.rs
@@ -1,4 +1,4 @@
-#[allow(dead_code)]
+#![allow(dead_code, clippy::extra_unused_lifetimes)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/2865
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3151.rs b/src/tools/clippy/tests/ui/crashes/ice-3151.rs
index fef4d7db84d..268ba86fc7a 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3151.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3151.rs
@@ -1,4 +1,4 @@
-/// Test for https://github.com/rust-lang/rust-clippy/issues/2865
+/// Test for https://github.com/rust-lang/rust-clippy/issues/3151
 
 #[derive(Clone)]
 pub struct HashMap<V, S> {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-5944.rs b/src/tools/clippy/tests/ui/crashes/ice-5944.rs
index 5caf29c6197..ce46bc1acc1 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-5944.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-5944.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::repeat_once)]
+#![allow(clippy::let_unit_value)]
 
 trait Repeat {
     fn repeat(&self) {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8250.stderr b/src/tools/clippy/tests/ui/crashes/ice-8250.stderr
index 04ea4456656..8ed8f3b3a06 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-8250.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-8250.stderr
@@ -1,11 +1,3 @@
-error: manual implementation of `split_once`
-  --> $DIR/ice-8250.rs:2:13
-   |
-LL |     let _ = s[1..].splitn(2, '.').next()?;
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s[1..].split_once('.').map_or(s[1..], |x| x.0)`
-   |
-   = note: `-D clippy::manual-split-once` implied by `-D warnings`
-
 error: unnecessary use of `splitn`
   --> $DIR/ice-8250.rs:2:13
    |
@@ -14,5 +6,5 @@ LL |     let _ = s[1..].splitn(2, '.').next()?;
    |
    = note: `-D clippy::needless-splitn` implied by `-D warnings`
 
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/crashes/ice-8681.rs b/src/tools/clippy/tests/ui/crashes/ice-8681.rs
new file mode 100644
index 00000000000..ee14f011f63
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-8681.rs
@@ -0,0 +1,10 @@
+// aux-build: ice-8681-aux.rs
+
+#![warn(clippy::undocumented_unsafe_blocks)]
+
+#[path = "auxiliary/ice-8681-aux.rs"]
+mod ice_8681_aux;
+
+fn main() {
+    let _ = ice_8681_aux::foo(&0u32);
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-96721.rs b/src/tools/clippy/tests/ui/crashes/ice-96721.rs
new file mode 100644
index 00000000000..4b3fb764010
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-96721.rs
@@ -0,0 +1,10 @@
+macro_rules! foo {
+    () => {
+        "bar.rs"
+    };
+}
+
+#[path = foo!()] //~ ERROR malformed `path` attribute
+mod abc {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-96721.stderr b/src/tools/clippy/tests/ui/crashes/ice-96721.stderr
new file mode 100644
index 00000000000..78c567b8e77
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-96721.stderr
@@ -0,0 +1,8 @@
+error: malformed `path` attribute input
+  --> $DIR/ice-96721.rs:7:1
+   |
+LL | #[path = foo!()] //~ ERROR malformed `path` attribute
+   | ^^^^^^^^^^^^^^^^ help: must be of the form: `#[path = "file"]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
index e0b4a2f6942..a28bff76755 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
@@ -2,12 +2,15 @@
 // aux-build:macro_rules.rs
 
 #![warn(clippy::default_numeric_fallback)]
-#![allow(unused)]
-#![allow(clippy::never_loop)]
-#![allow(clippy::no_effect)]
-#![allow(clippy::unnecessary_operation)]
-#![allow(clippy::branches_sharing_code)]
-#![allow(clippy::match_single_binding)]
+#![allow(
+    unused,
+    clippy::never_loop,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::branches_sharing_code,
+    clippy::match_single_binding,
+    clippy::let_unit_value
+)]
 
 #[macro_use]
 extern crate macro_rules;
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
index 50bbb6eec6c..b48435cc7b2 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
@@ -2,12 +2,15 @@
 // aux-build:macro_rules.rs
 
 #![warn(clippy::default_numeric_fallback)]
-#![allow(unused)]
-#![allow(clippy::never_loop)]
-#![allow(clippy::no_effect)]
-#![allow(clippy::unnecessary_operation)]
-#![allow(clippy::branches_sharing_code)]
-#![allow(clippy::match_single_binding)]
+#![allow(
+    unused,
+    clippy::never_loop,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::branches_sharing_code,
+    clippy::match_single_binding,
+    clippy::let_unit_value
+)]
 
 #[macro_use]
 extern crate macro_rules;
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr
index f8a2407b693..f8b6c7746ed 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.stderr
@@ -1,5 +1,5 @@
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:18:17
+  --> $DIR/default_numeric_fallback_f64.rs:21:17
    |
 LL |         let x = 0.12;
    |                 ^^^^ help: consider adding suffix: `0.12_f64`
@@ -7,133 +7,133 @@ LL |         let x = 0.12;
    = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:19:18
+  --> $DIR/default_numeric_fallback_f64.rs:22:18
    |
 LL |         let x = [1., 2., 3.];
    |                  ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:19:22
+  --> $DIR/default_numeric_fallback_f64.rs:22:22
    |
 LL |         let x = [1., 2., 3.];
    |                      ^^ help: consider adding suffix: `2.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:19:26
+  --> $DIR/default_numeric_fallback_f64.rs:22:26
    |
 LL |         let x = [1., 2., 3.];
    |                          ^^ help: consider adding suffix: `3.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:20:28
+  --> $DIR/default_numeric_fallback_f64.rs:23:28
    |
 LL |         let x = if true { (1., 2.) } else { (3., 4.) };
    |                            ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:20:32
+  --> $DIR/default_numeric_fallback_f64.rs:23:32
    |
 LL |         let x = if true { (1., 2.) } else { (3., 4.) };
    |                                ^^ help: consider adding suffix: `2.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:20:46
+  --> $DIR/default_numeric_fallback_f64.rs:23:46
    |
 LL |         let x = if true { (1., 2.) } else { (3., 4.) };
    |                                              ^^ help: consider adding suffix: `3.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:20:50
+  --> $DIR/default_numeric_fallback_f64.rs:23:50
    |
 LL |         let x = if true { (1., 2.) } else { (3., 4.) };
    |                                                  ^^ help: consider adding suffix: `4.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:21:23
+  --> $DIR/default_numeric_fallback_f64.rs:24:23
    |
 LL |         let x = match 1. {
    |                       ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:22:18
+  --> $DIR/default_numeric_fallback_f64.rs:25:18
    |
 LL |             _ => 1.,
    |                  ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:40:21
+  --> $DIR/default_numeric_fallback_f64.rs:43:21
    |
 LL |             let y = 1.;
    |                     ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:48:21
+  --> $DIR/default_numeric_fallback_f64.rs:51:21
    |
 LL |             let y = 1.;
    |                     ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:54:21
+  --> $DIR/default_numeric_fallback_f64.rs:57:21
    |
 LL |             let y = 1.;
    |                     ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:66:9
+  --> $DIR/default_numeric_fallback_f64.rs:69:9
    |
 LL |         1.
    |         ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:72:27
+  --> $DIR/default_numeric_fallback_f64.rs:75:27
    |
 LL |         let f = || -> _ { 1. };
    |                           ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:76:29
+  --> $DIR/default_numeric_fallback_f64.rs:79:29
    |
 LL |         let f = || -> f64 { 1. };
    |                             ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:90:21
+  --> $DIR/default_numeric_fallback_f64.rs:93:21
    |
 LL |         generic_arg(1.);
    |                     ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:93:32
+  --> $DIR/default_numeric_fallback_f64.rs:96:32
    |
 LL |         let x: _ = generic_arg(1.);
    |                                ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:111:28
+  --> $DIR/default_numeric_fallback_f64.rs:114:28
    |
 LL |         GenericStruct { x: 1. };
    |                            ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:114:36
+  --> $DIR/default_numeric_fallback_f64.rs:117:36
    |
 LL |         let _ = GenericStruct { x: 1. };
    |                                    ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:132:24
+  --> $DIR/default_numeric_fallback_f64.rs:135:24
    |
 LL |         GenericEnum::X(1.);
    |                        ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:152:23
+  --> $DIR/default_numeric_fallback_f64.rs:155:23
    |
 LL |         s.generic_arg(1.);
    |                       ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:159:21
+  --> $DIR/default_numeric_fallback_f64.rs:162:21
    |
 LL |             let x = 22.;
    |                     ^^^ help: consider adding suffix: `22.0_f64`
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
index bded9e2c0e8..fa85d278c8f 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
@@ -2,11 +2,14 @@
 // aux-build:macro_rules.rs
 
 #![warn(clippy::default_numeric_fallback)]
-#![allow(unused)]
-#![allow(clippy::never_loop)]
-#![allow(clippy::no_effect)]
-#![allow(clippy::unnecessary_operation)]
-#![allow(clippy::branches_sharing_code)]
+#![allow(
+    unused,
+    clippy::never_loop,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::branches_sharing_code,
+    clippy::let_unit_value
+)]
 
 #[macro_use]
 extern crate macro_rules;
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
index 3fceefa551c..71acccd702b 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
@@ -2,11 +2,14 @@
 // aux-build:macro_rules.rs
 
 #![warn(clippy::default_numeric_fallback)]
-#![allow(unused)]
-#![allow(clippy::never_loop)]
-#![allow(clippy::no_effect)]
-#![allow(clippy::unnecessary_operation)]
-#![allow(clippy::branches_sharing_code)]
+#![allow(
+    unused,
+    clippy::never_loop,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::branches_sharing_code,
+    clippy::let_unit_value
+)]
 
 #[macro_use]
 extern crate macro_rules;
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr
index 6f9e124704b..3cc84ff1132 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.stderr
@@ -1,5 +1,5 @@
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:17:17
+  --> $DIR/default_numeric_fallback_i32.rs:20:17
    |
 LL |         let x = 22;
    |                 ^^ help: consider adding suffix: `22_i32`
@@ -7,145 +7,145 @@ LL |         let x = 22;
    = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:18:18
+  --> $DIR/default_numeric_fallback_i32.rs:21:18
    |
 LL |         let x = [1, 2, 3];
    |                  ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:18:21
+  --> $DIR/default_numeric_fallback_i32.rs:21:21
    |
 LL |         let x = [1, 2, 3];
    |                     ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:18:24
+  --> $DIR/default_numeric_fallback_i32.rs:21:24
    |
 LL |         let x = [1, 2, 3];
    |                        ^ help: consider adding suffix: `3_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:19:28
+  --> $DIR/default_numeric_fallback_i32.rs:22:28
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                            ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:19:31
+  --> $DIR/default_numeric_fallback_i32.rs:22:31
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                               ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:19:44
+  --> $DIR/default_numeric_fallback_i32.rs:22:44
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                                            ^ help: consider adding suffix: `3_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:19:47
+  --> $DIR/default_numeric_fallback_i32.rs:22:47
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                                               ^ help: consider adding suffix: `4_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:20:23
+  --> $DIR/default_numeric_fallback_i32.rs:23:23
    |
 LL |         let x = match 1 {
    |                       ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:21:13
+  --> $DIR/default_numeric_fallback_i32.rs:24:13
    |
 LL |             1 => 1,
    |             ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:21:18
+  --> $DIR/default_numeric_fallback_i32.rs:24:18
    |
 LL |             1 => 1,
    |                  ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:22:18
+  --> $DIR/default_numeric_fallback_i32.rs:25:18
    |
 LL |             _ => 2,
    |                  ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:39:21
+  --> $DIR/default_numeric_fallback_i32.rs:42:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:47:21
+  --> $DIR/default_numeric_fallback_i32.rs:50:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:53:21
+  --> $DIR/default_numeric_fallback_i32.rs:56:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:65:9
+  --> $DIR/default_numeric_fallback_i32.rs:68:9
    |
 LL |         1
    |         ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:71:27
+  --> $DIR/default_numeric_fallback_i32.rs:74:27
    |
 LL |         let f = || -> _ { 1 };
    |                           ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:75:29
+  --> $DIR/default_numeric_fallback_i32.rs:78:29
    |
 LL |         let f = || -> i32 { 1 };
    |                             ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:89:21
+  --> $DIR/default_numeric_fallback_i32.rs:92:21
    |
 LL |         generic_arg(1);
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:92:32
+  --> $DIR/default_numeric_fallback_i32.rs:95:32
    |
 LL |         let x: _ = generic_arg(1);
    |                                ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:110:28
+  --> $DIR/default_numeric_fallback_i32.rs:113:28
    |
 LL |         GenericStruct { x: 1 };
    |                            ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:113:36
+  --> $DIR/default_numeric_fallback_i32.rs:116:36
    |
 LL |         let _ = GenericStruct { x: 1 };
    |                                    ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:131:24
+  --> $DIR/default_numeric_fallback_i32.rs:134:24
    |
 LL |         GenericEnum::X(1);
    |                        ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:151:23
+  --> $DIR/default_numeric_fallback_i32.rs:154:23
    |
 LL |         s.generic_arg(1);
    |                       ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:158:21
+  --> $DIR/default_numeric_fallback_i32.rs:161:21
    |
 LL |             let x = 22;
    |                     ^^ help: consider adding suffix: `22_i32`
diff --git a/src/tools/clippy/tests/ui/deprecated.rs b/src/tools/clippy/tests/ui/deprecated.rs
index 39a2601fee9..07270bd7636 100644
--- a/src/tools/clippy/tests/ui/deprecated.rs
+++ b/src/tools/clippy/tests/ui/deprecated.rs
@@ -1,3 +1,7 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
 #![warn(clippy::should_assert_eq)]
 #![warn(clippy::extend_from_slice)]
 #![warn(clippy::range_step_by_zero)]
diff --git a/src/tools/clippy/tests/ui/deprecated.stderr b/src/tools/clippy/tests/ui/deprecated.stderr
index 6095f134d55..0e142ac8f20 100644
--- a/src/tools/clippy/tests/ui/deprecated.stderr
+++ b/src/tools/clippy/tests/ui/deprecated.stderr
@@ -1,5 +1,5 @@
 error: lint `clippy::should_assert_eq` has been removed: `assert!()` will be more flexible with RFC 2011
-  --> $DIR/deprecated.rs:1:9
+  --> $DIR/deprecated.rs:5:9
    |
 LL | #![warn(clippy::should_assert_eq)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,91 +7,91 @@ LL | #![warn(clippy::should_assert_eq)]
    = note: `-D renamed-and-removed-lints` implied by `-D warnings`
 
 error: lint `clippy::extend_from_slice` has been removed: `.extend_from_slice(_)` is a faster way to extend a Vec by a slice
-  --> $DIR/deprecated.rs:2:9
+  --> $DIR/deprecated.rs:6:9
    |
 LL | #![warn(clippy::extend_from_slice)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::range_step_by_zero` has been removed: `iterator.step_by(0)` panics nowadays
-  --> $DIR/deprecated.rs:3:9
+  --> $DIR/deprecated.rs:7:9
    |
 LL | #![warn(clippy::range_step_by_zero)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::unstable_as_slice` has been removed: `Vec::as_slice` has been stabilized in 1.7
-  --> $DIR/deprecated.rs:4:9
+  --> $DIR/deprecated.rs:8:9
    |
 LL | #![warn(clippy::unstable_as_slice)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::unstable_as_mut_slice` has been removed: `Vec::as_mut_slice` has been stabilized in 1.7
-  --> $DIR/deprecated.rs:5:9
+  --> $DIR/deprecated.rs:9:9
    |
 LL | #![warn(clippy::unstable_as_mut_slice)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::misaligned_transmute` has been removed: this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr
-  --> $DIR/deprecated.rs:6:9
+  --> $DIR/deprecated.rs:10:9
    |
 LL | #![warn(clippy::misaligned_transmute)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::assign_ops` has been removed: using compound assignment operators (e.g., `+=`) is harmless
-  --> $DIR/deprecated.rs:7:9
+  --> $DIR/deprecated.rs:11:9
    |
 LL | #![warn(clippy::assign_ops)]
    |         ^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::if_let_redundant_pattern_matching` has been removed: this lint has been changed to redundant_pattern_matching
-  --> $DIR/deprecated.rs:8:9
+  --> $DIR/deprecated.rs:12:9
    |
 LL | #![warn(clippy::if_let_redundant_pattern_matching)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::unsafe_vector_initialization` has been removed: the replacement suggested by this lint had substantially different behavior
-  --> $DIR/deprecated.rs:9:9
+  --> $DIR/deprecated.rs:13:9
    |
 LL | #![warn(clippy::unsafe_vector_initialization)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::unused_collect` has been removed: `collect` has been marked as #[must_use] in rustc and that covers all cases of this lint
-  --> $DIR/deprecated.rs:10:9
+  --> $DIR/deprecated.rs:14:9
    |
 LL | #![warn(clippy::unused_collect)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::replace_consts` has been removed: associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants
-  --> $DIR/deprecated.rs:11:9
+  --> $DIR/deprecated.rs:15:9
    |
 LL | #![warn(clippy::replace_consts)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::regex_macro` has been removed: the regex! macro has been removed from the regex crate in 2018
-  --> $DIR/deprecated.rs:12:9
+  --> $DIR/deprecated.rs:16:9
    |
 LL | #![warn(clippy::regex_macro)]
    |         ^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::find_map` has been removed: this lint has been replaced by `manual_find_map`, a more specific lint
-  --> $DIR/deprecated.rs:13:9
+  --> $DIR/deprecated.rs:17:9
    |
 LL | #![warn(clippy::find_map)]
    |         ^^^^^^^^^^^^^^^^
 
 error: lint `clippy::filter_map` has been removed: this lint has been replaced by `manual_filter_map`, a more specific lint
-  --> $DIR/deprecated.rs:14:9
+  --> $DIR/deprecated.rs:18:9
    |
 LL | #![warn(clippy::filter_map)]
    |         ^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::pub_enum_variant_names` has been removed: set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items
-  --> $DIR/deprecated.rs:15:9
+  --> $DIR/deprecated.rs:19:9
    |
 LL | #![warn(clippy::pub_enum_variant_names)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: lint `clippy::wrong_pub_self_convention` has been removed: set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items
-  --> $DIR/deprecated.rs:16:9
+  --> $DIR/deprecated.rs:20:9
    |
 LL | #![warn(clippy::wrong_pub_self_convention)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/doc_unsafe.rs b/src/tools/clippy/tests/ui/doc_unsafe.rs
index 4464a21b3b6..b91f7aa0dd8 100644
--- a/src/tools/clippy/tests/ui/doc_unsafe.rs
+++ b/src/tools/clippy/tests/ui/doc_unsafe.rs
@@ -1,5 +1,7 @@
 // aux-build:doc_unsafe_macros.rs
 
+#![allow(clippy::let_unit_value)]
+
 #[macro_use]
 extern crate doc_unsafe_macros;
 
diff --git a/src/tools/clippy/tests/ui/doc_unsafe.stderr b/src/tools/clippy/tests/ui/doc_unsafe.stderr
index d68b8a0c67b..904b88eaef6 100644
--- a/src/tools/clippy/tests/ui/doc_unsafe.stderr
+++ b/src/tools/clippy/tests/ui/doc_unsafe.stderr
@@ -1,5 +1,5 @@
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:7:1
+  --> $DIR/doc_unsafe.rs:9:1
    |
 LL | / pub unsafe fn destroy_the_planet() {
 LL | |     unimplemented!();
@@ -9,7 +9,7 @@ LL | | }
    = note: `-D clippy::missing-safety-doc` implied by `-D warnings`
 
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:30:5
+  --> $DIR/doc_unsafe.rs:32:5
    |
 LL | /     pub unsafe fn republished() {
 LL | |         unimplemented!();
@@ -17,13 +17,13 @@ LL | |     }
    | |_____^
 
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:38:5
+  --> $DIR/doc_unsafe.rs:40:5
    |
 LL |     unsafe fn woefully_underdocumented(self);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: docs for unsafe trait missing `# Safety` section
-  --> $DIR/doc_unsafe.rs:44:1
+  --> $DIR/doc_unsafe.rs:46:1
    |
 LL | / pub unsafe trait UnsafeTrait {
 LL | |     fn method();
@@ -31,7 +31,7 @@ LL | | }
    | |_^
 
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:74:5
+  --> $DIR/doc_unsafe.rs:76:5
    |
 LL | /     pub unsafe fn more_undocumented_unsafe() -> Self {
 LL | |         unimplemented!();
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^
 
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:90:9
+  --> $DIR/doc_unsafe.rs:92:9
    |
 LL | /         pub unsafe fn whee() {
 LL | |             unimplemented!()
diff --git a/src/tools/clippy/tests/ui/drop_non_drop.stderr b/src/tools/clippy/tests/ui/drop_non_drop.stderr
index f73068901c5..30121033de7 100644
--- a/src/tools/clippy/tests/ui/drop_non_drop.stderr
+++ b/src/tools/clippy/tests/ui/drop_non_drop.stderr
@@ -1,4 +1,4 @@
-error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends it's contained lifetimes
+error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes
   --> $DIR/drop_non_drop.rs:22:5
    |
 LL |     drop(Foo);
@@ -11,7 +11,7 @@ note: argument has type `main::Foo`
 LL |     drop(Foo);
    |          ^^^
 
-error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends it's contained lifetimes
+error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends its contained lifetimes
   --> $DIR/drop_non_drop.rs:37:5
    |
 LL |     drop(Baz(Foo));
diff --git a/src/tools/clippy/tests/ui/empty_drop.fixed b/src/tools/clippy/tests/ui/empty_drop.fixed
new file mode 100644
index 00000000000..2e1b768461a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_drop.fixed
@@ -0,0 +1,24 @@
+// run-rustfix
+#![warn(clippy::empty_drop)]
+#![allow(unused)]
+
+// should cause an error
+struct Foo;
+
+
+
+// shouldn't cause an error
+struct Bar;
+
+impl Drop for Bar {
+    fn drop(&mut self) {
+        println!("dropping bar!");
+    }
+}
+
+// should error
+struct Baz;
+
+
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_drop.rs b/src/tools/clippy/tests/ui/empty_drop.rs
new file mode 100644
index 00000000000..75232b0334d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_drop.rs
@@ -0,0 +1,30 @@
+// run-rustfix
+#![warn(clippy::empty_drop)]
+#![allow(unused)]
+
+// should cause an error
+struct Foo;
+
+impl Drop for Foo {
+    fn drop(&mut self) {}
+}
+
+// shouldn't cause an error
+struct Bar;
+
+impl Drop for Bar {
+    fn drop(&mut self) {
+        println!("dropping bar!");
+    }
+}
+
+// should error
+struct Baz;
+
+impl Drop for Baz {
+    fn drop(&mut self) {
+        {}
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_drop.stderr b/src/tools/clippy/tests/ui/empty_drop.stderr
new file mode 100644
index 00000000000..70f7880d036
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_drop.stderr
@@ -0,0 +1,22 @@
+error: empty drop implementation
+  --> $DIR/empty_drop.rs:8:1
+   |
+LL | / impl Drop for Foo {
+LL | |     fn drop(&mut self) {}
+LL | | }
+   | |_^ help: try removing this impl
+   |
+   = note: `-D clippy::empty-drop` implied by `-D warnings`
+
+error: empty drop implementation
+  --> $DIR/empty_drop.rs:24:1
+   |
+LL | / impl Drop for Baz {
+LL | |     fn drop(&mut self) {
+LL | |         {}
+LL | |     }
+LL | | }
+   | |_^ help: try removing this impl
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index 5aedbea381f..6c2272f4dff 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -37,7 +37,7 @@ fn main() {
     }
 
     // See #815
-    let e = Some(1u8).map(divergent);
+    let e = Some(1u8).map(|a| divergent(a));
     let e = Some(1u8).map(generic);
     let e = Some(1u8).map(generic);
     // See #515
@@ -211,6 +211,10 @@ fn mutable_closure_in_loop() {
     let mut closure = |n| value += n;
     for _ in 0..5 {
         Some(1).map(&mut closure);
+
+        let mut value = 0;
+        let mut in_loop = |n| value += n;
+        Some(1).map(in_loop);
     }
 }
 
@@ -229,7 +233,7 @@ fn late_bound_lifetimes() {
     {
     }
     map_str(|s| take_asref_path(s));
-    map_str_to_path(std::convert::AsRef::as_ref);
+    map_str_to_path(|s| s.as_ref());
 }
 
 mod type_param_bound {
@@ -275,3 +279,15 @@ mod bind_by_ref {
         Some(A).map(|ref a| B::from(a));
     }
 }
+
+// #7812 False positive on coerced closure
+fn coerced_closure() {
+    fn function_returning_unit<F: FnMut(i32)>(f: F) {}
+    function_returning_unit(|x| std::process::exit(x));
+
+    fn arr() -> &'static [u8; 0] {
+        &[]
+    }
+    fn slice_fn(_: impl FnOnce() -> &'static [u8]) {}
+    slice_fn(|| arr());
+}
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index 5fdf7fb9771..a1a9c0dfbf3 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -211,6 +211,10 @@ fn mutable_closure_in_loop() {
     let mut closure = |n| value += n;
     for _ in 0..5 {
         Some(1).map(|n| closure(n));
+
+        let mut value = 0;
+        let mut in_loop = |n| value += n;
+        Some(1).map(|n| in_loop(n));
     }
 }
 
@@ -275,3 +279,15 @@ mod bind_by_ref {
         Some(A).map(|ref a| B::from(a));
     }
 }
+
+// #7812 False positive on coerced closure
+fn coerced_closure() {
+    fn function_returning_unit<F: FnMut(i32)>(f: F) {}
+    function_returning_unit(|x| std::process::exit(x));
+
+    fn arr() -> &'static [u8; 0] {
+        &[]
+    }
+    fn slice_fn(_: impl FnOnce() -> &'static [u8]) {}
+    slice_fn(|| arr());
+}
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index cda84982c9b..bf2e97e744a 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -25,12 +25,6 @@ LL |     all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
    |                          ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
 
 error: redundant closure
-  --> $DIR/eta.rs:40:27
-   |
-LL |     let e = Some(1u8).map(|a| divergent(a));
-   |                           ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `divergent`
-
-error: redundant closure
   --> $DIR/eta.rs:41:27
    |
 LL |     let e = Some(1u8).map(|a| generic(a));
@@ -117,10 +111,10 @@ LL |         Some(1).map(|n| closure(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
 
 error: redundant closure
-  --> $DIR/eta.rs:232:21
+  --> $DIR/eta.rs:217:21
    |
-LL |     map_str_to_path(|s| s.as_ref());
-   |                     ^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::convert::AsRef::as_ref`
+LL |         Some(1).map(|n| in_loop(n));
+   |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
 
-error: aborting due to 20 previous errors
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
index 150acfbfee7..f76127a7105 100644
--- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.rs
@@ -72,4 +72,46 @@ mod issue4291 {
     }
 }
 
+mod issue6437 {
+    pub struct Scalar;
+
+    impl<'a> std::ops::AddAssign<&Scalar> for &mut Scalar {
+        fn add_assign(&mut self, _rhs: &Scalar) {
+            unimplemented!();
+        }
+    }
+
+    impl<'b> Scalar {
+        pub fn something<'c>() -> Self {
+            Self
+        }
+    }
+}
+
+// https://github.com/rust-lang/rust-clippy/pull/8737#pullrequestreview-951268213
+mod first_case {
+    use serde::de::Visitor;
+    pub trait Expected {
+        fn fmt(&self, formatter: &mut std::fmt::Formatter);
+    }
+
+    impl<'de, T> Expected for T
+    where
+        T: Visitor<'de>,
+    {
+        fn fmt(&self, formatter: &mut std::fmt::Formatter) {}
+    }
+}
+
+// https://github.com/rust-lang/rust-clippy/pull/8737#pullrequestreview-951268213
+mod second_case {
+    pub trait Source {
+        fn hey();
+    }
+
+    impl<'a, T: Source + ?Sized + 'a> Source for Box<T> {
+        fn hey() {}
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
index 9143fb2c208..fcc12d4ce14 100644
--- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr
@@ -18,5 +18,23 @@ error: this lifetime isn't used in the function definition
 LL |         fn unused_lt<'a>(x: u8) {}
    |                      ^^
 
-error: aborting due to 3 previous errors
+error: this lifetime isn't used in the impl
+  --> $DIR/extra_unused_lifetimes.rs:78:10
+   |
+LL |     impl<'a> std::ops::AddAssign<&Scalar> for &mut Scalar {
+   |          ^^
+
+error: this lifetime isn't used in the impl
+  --> $DIR/extra_unused_lifetimes.rs:84:10
+   |
+LL |     impl<'b> Scalar {
+   |          ^^
+
+error: this lifetime isn't used in the function definition
+  --> $DIR/extra_unused_lifetimes.rs:85:26
+   |
+LL |         pub fn something<'c>() -> Self {
+   |                          ^^
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/format_push_string.rs b/src/tools/clippy/tests/ui/format_push_string.rs
new file mode 100644
index 00000000000..4db13d650eb
--- /dev/null
+++ b/src/tools/clippy/tests/ui/format_push_string.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::format_push_string)]
+
+fn main() {
+    let mut string = String::new();
+    string += &format!("{:?}", 1234);
+    string.push_str(&format!("{:?}", 5678));
+}
diff --git a/src/tools/clippy/tests/ui/format_push_string.stderr b/src/tools/clippy/tests/ui/format_push_string.stderr
new file mode 100644
index 00000000000..953784bcc06
--- /dev/null
+++ b/src/tools/clippy/tests/ui/format_push_string.stderr
@@ -0,0 +1,19 @@
+error: `format!(..)` appended to existing `String`
+  --> $DIR/format_push_string.rs:5:5
+   |
+LL |     string += &format!("{:?}", 1234);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::format-push-string` implied by `-D warnings`
+   = help: consider using `write!` to avoid the extra allocation
+
+error: `format!(..)` appended to existing `String`
+  --> $DIR/format_push_string.rs:6:5
+   |
+LL |     string.push_str(&format!("{:?}", 5678));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider using `write!` to avoid the extra allocation
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs
index edc3fe1aec1..fec54d00ccb 100644
--- a/src/tools/clippy/tests/ui/identity_op.rs
+++ b/src/tools/clippy/tests/ui/identity_op.rs
@@ -1,3 +1,5 @@
+use std::fmt::Write as _;
+
 const ONE: i64 = 1;
 const NEG_ONE: i64 = -1;
 const ZERO: i64 = 0;
@@ -7,7 +9,7 @@ struct A(String);
 impl std::ops::Shl<i32> for A {
     type Output = A;
     fn shl(mut self, other: i32) -> Self {
-        self.0.push_str(&format!("{}", other));
+        let _ = write!(self.0, "{}", other);
         self
     }
 }
@@ -75,4 +77,34 @@ fn main() {
     (x + 1) % 3; // no error
     4 % 3; // no error
     4 % -3; // no error
+
+    // See #8724
+    let a = 0;
+    let b = true;
+    0 + if b { 1 } else { 2 };
+    0 + if b { 1 } else { 2 } + if b { 3 } else { 4 }; // no error
+    0 + match a { 0 => 10, _ => 20 };
+    0 + match a { 0 => 10, _ => 20 } + match a { 0 => 30, _ => 40 }; // no error
+    0 + if b { 1 } else { 2 } + match a { 0 => 30, _ => 40 }; // no error
+    0 + match a { 0 => 10, _ => 20 } + if b { 3 } else { 4 }; // no error
+    
+    0 + if b { 0 + 1 } else { 2 };
+    0 + match a { 0 =>  0 + 10, _ => 20 };
+    0 + if b { 0 + 1 } else { 2 } + match a { 0 => 0 + 30, _ => 40 };
+
+    let _ = 0 + if 0 + 1 > 0 { 1 } else { 2 } + if 0 + 1 > 0 { 3 } else { 4 };
+    let _ = 0 + match 0 + 1 { 0 => 10, _ => 20 } + match 0 + 1  { 0 => 30, _ => 40 };
+
+    0 + if b { 1 } else { 2 } + if b { 3 } else { 4 } + 0;
+    
+    0 + { a } + 3; // no error
+    0 + loop { let mut c = 0; if c == 10 { break c; } c += 1; } + { a * 2 }; // no error
+    
+    fn f(_: i32) {
+        todo!();
+    }
+    f(1 * a + { 8 * 5 });
+    f(0 + if b { 1 } else { 2 } + 3); // no error
+    const _: i32 = { 2 * 4 } + 0 + 3;
+    const _: i32 = 0 + { 1 + 2 * 3 } + 3; // no error
 }
diff --git a/src/tools/clippy/tests/ui/identity_op.stderr b/src/tools/clippy/tests/ui/identity_op.stderr
index 706f01a3dd6..d8cb65839cb 100644
--- a/src/tools/clippy/tests/ui/identity_op.stderr
+++ b/src/tools/clippy/tests/ui/identity_op.stderr
@@ -1,5 +1,5 @@
 error: the operation is ineffective. Consider reducing it to `x`
-  --> $DIR/identity_op.rs:37:5
+  --> $DIR/identity_op.rs:39:5
    |
 LL |     x + 0;
    |     ^^^^^
@@ -7,106 +7,196 @@ LL |     x + 0;
    = note: `-D clippy::identity-op` implied by `-D warnings`
 
 error: the operation is ineffective. Consider reducing it to `x`
-  --> $DIR/identity_op.rs:38:5
+  --> $DIR/identity_op.rs:40:5
    |
 LL |     x + (1 - 1);
    |     ^^^^^^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `x`
-  --> $DIR/identity_op.rs:40:5
+  --> $DIR/identity_op.rs:42:5
    |
 LL |     0 + x;
    |     ^^^^^
 
 error: the operation is ineffective. Consider reducing it to `x`
-  --> $DIR/identity_op.rs:43:5
+  --> $DIR/identity_op.rs:45:5
    |
 LL |     x | (0);
    |     ^^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `x`
-  --> $DIR/identity_op.rs:46:5
+  --> $DIR/identity_op.rs:48:5
    |
 LL |     x * 1;
    |     ^^^^^
 
 error: the operation is ineffective. Consider reducing it to `x`
-  --> $DIR/identity_op.rs:47:5
+  --> $DIR/identity_op.rs:49:5
    |
 LL |     1 * x;
    |     ^^^^^
 
 error: the operation is ineffective. Consider reducing it to `x`
-  --> $DIR/identity_op.rs:53:5
+  --> $DIR/identity_op.rs:55:5
    |
 LL |     -1 & x;
    |     ^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `u`
-  --> $DIR/identity_op.rs:56:5
+  --> $DIR/identity_op.rs:58:5
    |
 LL |     u & 255;
    |     ^^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `42`
-  --> $DIR/identity_op.rs:59:5
+  --> $DIR/identity_op.rs:61:5
    |
 LL |     42 << 0;
    |     ^^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `1`
-  --> $DIR/identity_op.rs:60:5
+  --> $DIR/identity_op.rs:62:5
    |
 LL |     1 >> 0;
    |     ^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `42`
-  --> $DIR/identity_op.rs:61:5
+  --> $DIR/identity_op.rs:63:5
    |
 LL |     42 >> 0;
    |     ^^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `&x`
-  --> $DIR/identity_op.rs:62:5
+  --> $DIR/identity_op.rs:64:5
    |
 LL |     &x >> 0;
    |     ^^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `x`
-  --> $DIR/identity_op.rs:63:5
+  --> $DIR/identity_op.rs:65:5
    |
 LL |     x >> &0;
    |     ^^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `2`
-  --> $DIR/identity_op.rs:70:5
+  --> $DIR/identity_op.rs:72:5
    |
 LL |     2 % 3;
    |     ^^^^^
 
 error: the operation is ineffective. Consider reducing it to `-2`
-  --> $DIR/identity_op.rs:71:5
+  --> $DIR/identity_op.rs:73:5
    |
 LL |     -2 % 3;
    |     ^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `2`
-  --> $DIR/identity_op.rs:72:5
+  --> $DIR/identity_op.rs:74:5
    |
 LL |     2 % -3 + x;
    |     ^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `-2`
-  --> $DIR/identity_op.rs:73:5
+  --> $DIR/identity_op.rs:75:5
    |
 LL |     -2 % -3 + x;
    |     ^^^^^^^
 
 error: the operation is ineffective. Consider reducing it to `1`
-  --> $DIR/identity_op.rs:74:9
+  --> $DIR/identity_op.rs:76:9
    |
 LL |     x + 1 % 3;
    |         ^^^^^
 
-error: aborting due to 18 previous errors
+error: the operation is ineffective. Consider reducing it to `if b { 1 } else { 2 }`
+  --> $DIR/identity_op.rs:84:5
+   |
+LL |     0 + if b { 1 } else { 2 };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `match a { 0 => 10, _ => 20 }`
+  --> $DIR/identity_op.rs:86:5
+   |
+LL |     0 + match a { 0 => 10, _ => 20 };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `if b { 0 + 1 } else { 2 }`
+  --> $DIR/identity_op.rs:91:5
+   |
+LL |     0 + if b { 0 + 1 } else { 2 };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `1`
+  --> $DIR/identity_op.rs:91:16
+   |
+LL |     0 + if b { 0 + 1 } else { 2 };
+   |                ^^^^^
+
+error: the operation is ineffective. Consider reducing it to `match a { 0 =>  0 + 10, _ => 20 }`
+  --> $DIR/identity_op.rs:92:5
+   |
+LL |     0 + match a { 0 =>  0 + 10, _ => 20 };
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `10`
+  --> $DIR/identity_op.rs:92:25
+   |
+LL |     0 + match a { 0 =>  0 + 10, _ => 20 };
+   |                         ^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `1`
+  --> $DIR/identity_op.rs:93:16
+   |
+LL |     0 + if b { 0 + 1 } else { 2 } + match a { 0 => 0 + 30, _ => 40 };
+   |                ^^^^^
+
+error: the operation is ineffective. Consider reducing it to `30`
+  --> $DIR/identity_op.rs:93:52
+   |
+LL |     0 + if b { 0 + 1 } else { 2 } + match a { 0 => 0 + 30, _ => 40 };
+   |                                                    ^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `1`
+  --> $DIR/identity_op.rs:95:20
+   |
+LL |     let _ = 0 + if 0 + 1 > 0 { 1 } else { 2 } + if 0 + 1 > 0 { 3 } else { 4 };
+   |                    ^^^^^
+
+error: the operation is ineffective. Consider reducing it to `1`
+  --> $DIR/identity_op.rs:95:52
+   |
+LL |     let _ = 0 + if 0 + 1 > 0 { 1 } else { 2 } + if 0 + 1 > 0 { 3 } else { 4 };
+   |                                                    ^^^^^
+
+error: the operation is ineffective. Consider reducing it to `1`
+  --> $DIR/identity_op.rs:96:23
+   |
+LL |     let _ = 0 + match 0 + 1 { 0 => 10, _ => 20 } + match 0 + 1  { 0 => 30, _ => 40 };
+   |                       ^^^^^
+
+error: the operation is ineffective. Consider reducing it to `1`
+  --> $DIR/identity_op.rs:96:58
+   |
+LL |     let _ = 0 + match 0 + 1 { 0 => 10, _ => 20 } + match 0 + 1  { 0 => 30, _ => 40 };
+   |                                                          ^^^^^
+
+error: the operation is ineffective. Consider reducing it to `0 + if b { 1 } else { 2 } + if b { 3 } else { 4 }`
+  --> $DIR/identity_op.rs:98:5
+   |
+LL |     0 + if b { 1 } else { 2 } + if b { 3 } else { 4 } + 0;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `a`
+  --> $DIR/identity_op.rs:106:7
+   |
+LL |     f(1 * a + { 8 * 5 });
+   |       ^^^^^
+
+error: the operation is ineffective. Consider reducing it to `{ 2 * 4 }`
+  --> $DIR/identity_op.rs:108:20
+   |
+LL |     const _: i32 = { 2 * 4 } + 0 + 3;
+   |                    ^^^^^^^^^^^^^
+
+error: aborting due to 33 previous errors
 
diff --git a/src/tools/clippy/tests/ui/impl.rs b/src/tools/clippy/tests/ui/impl.rs
index 39443775015..aea52a852f9 100644
--- a/src/tools/clippy/tests/ui/impl.rs
+++ b/src/tools/clippy/tests/ui/impl.rs
@@ -1,4 +1,4 @@
-#![allow(dead_code)]
+#![allow(dead_code, clippy::extra_unused_lifetimes)]
 #![warn(clippy::multiple_inherent_impl)]
 
 struct MyStruct;
diff --git a/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed b/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed
new file mode 100644
index 00000000000..c0ba647d707
--- /dev/null
+++ b/src/tools/clippy/tests/ui/is_digit_ascii_radix.fixed
@@ -0,0 +1,18 @@
+// run-rustfix
+
+#![warn(clippy::is_digit_ascii_radix)]
+
+const TEN: u32 = 10;
+
+fn main() {
+    let c: char = '6';
+
+    // Should trigger the lint.
+    let _ = c.is_ascii_digit();
+    let _ = c.is_ascii_hexdigit();
+    let _ = c.is_ascii_hexdigit();
+
+    // Should not trigger the lint.
+    let _ = c.is_digit(11);
+    let _ = c.is_digit(TEN);
+}
diff --git a/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs b/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs
new file mode 100644
index 00000000000..68e3f3243d9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/is_digit_ascii_radix.rs
@@ -0,0 +1,18 @@
+// run-rustfix
+
+#![warn(clippy::is_digit_ascii_radix)]
+
+const TEN: u32 = 10;
+
+fn main() {
+    let c: char = '6';
+
+    // Should trigger the lint.
+    let _ = c.is_digit(10);
+    let _ = c.is_digit(16);
+    let _ = c.is_digit(0x10);
+
+    // Should not trigger the lint.
+    let _ = c.is_digit(11);
+    let _ = c.is_digit(TEN);
+}
diff --git a/src/tools/clippy/tests/ui/is_digit_ascii_radix.stderr b/src/tools/clippy/tests/ui/is_digit_ascii_radix.stderr
new file mode 100644
index 00000000000..dc5cb2913ae
--- /dev/null
+++ b/src/tools/clippy/tests/ui/is_digit_ascii_radix.stderr
@@ -0,0 +1,22 @@
+error: use of `char::is_digit` with literal radix of 10
+  --> $DIR/is_digit_ascii_radix.rs:11:13
+   |
+LL |     let _ = c.is_digit(10);
+   |             ^^^^^^^^^^^^^^ help: try: `c.is_ascii_digit()`
+   |
+   = note: `-D clippy::is-digit-ascii-radix` implied by `-D warnings`
+
+error: use of `char::is_digit` with literal radix of 16
+  --> $DIR/is_digit_ascii_radix.rs:12:13
+   |
+LL |     let _ = c.is_digit(16);
+   |             ^^^^^^^^^^^^^^ help: try: `c.is_ascii_hexdigit()`
+
+error: use of `char::is_digit` with literal radix of 16
+  --> $DIR/is_digit_ascii_radix.rs:13:13
+   |
+LL |     let _ = c.is_digit(0x10);
+   |             ^^^^^^^^^^^^^^^^ help: try: `c.is_ascii_hexdigit()`
+
+error: aborting due to 3 previous errors
+
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
index 56761ebbcb8..7c2b05d837b 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::let_unit_value)]
 
 fn main() {
     let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
index 98321d889b5..f2d0b155d2c 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::let_unit_value)]
 
 fn main() {
     let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
diff --git a/src/tools/clippy/tests/ui/iter_with_drain.fixed b/src/tools/clippy/tests/ui/iter_with_drain.fixed
index aea4dba9dd5..0330d554926 100644
--- a/src/tools/clippy/tests/ui/iter_with_drain.fixed
+++ b/src/tools/clippy/tests/ui/iter_with_drain.fixed
@@ -39,6 +39,15 @@ fn should_not_help() {
     let _: Vec<_> = b.drain(0..a.len()).collect();
 }
 
+fn _closed_range(mut x: Vec<String>) {
+    let _: Vec<String> = x.drain(0..=x.len()).collect();
+}
+
+fn _with_mut(x: &mut Vec<String>, y: &mut VecDeque<String>) {
+    let _: Vec<String> = x.drain(..).collect();
+    let _: Vec<String> = y.drain(..).collect();
+}
+
 #[derive(Default)]
 struct Bomb {
     fire: Vec<u8>,
diff --git a/src/tools/clippy/tests/ui/iter_with_drain.rs b/src/tools/clippy/tests/ui/iter_with_drain.rs
index 271878cffb4..993936fb8de 100644
--- a/src/tools/clippy/tests/ui/iter_with_drain.rs
+++ b/src/tools/clippy/tests/ui/iter_with_drain.rs
@@ -39,6 +39,15 @@ fn should_not_help() {
     let _: Vec<_> = b.drain(0..a.len()).collect();
 }
 
+fn _closed_range(mut x: Vec<String>) {
+    let _: Vec<String> = x.drain(0..=x.len()).collect();
+}
+
+fn _with_mut(x: &mut Vec<String>, y: &mut VecDeque<String>) {
+    let _: Vec<String> = x.drain(..).collect();
+    let _: Vec<String> = y.drain(..).collect();
+}
+
 #[derive(Default)]
 struct Bomb {
     fire: Vec<u8>,
diff --git a/src/tools/clippy/tests/ui/let_underscore_drop.rs b/src/tools/clippy/tests/ui/let_underscore_drop.rs
index 50744f81c3c..11b50492ab2 100644
--- a/src/tools/clippy/tests/ui/let_underscore_drop.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_drop.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::let_underscore_drop)]
+#![allow(clippy::let_unit_value)]
 
 struct Droppable;
 
diff --git a/src/tools/clippy/tests/ui/let_underscore_drop.stderr b/src/tools/clippy/tests/ui/let_underscore_drop.stderr
index 66069e0c5e1..ee7bbe995f1 100644
--- a/src/tools/clippy/tests/ui/let_underscore_drop.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_drop.stderr
@@ -1,5 +1,5 @@
 error: non-binding `let` on a type that implements `Drop`
-  --> $DIR/let_underscore_drop.rs:16:5
+  --> $DIR/let_underscore_drop.rs:17:5
    |
 LL |     let _ = Box::new(());
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let _ = Box::new(());
    = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
 
 error: non-binding `let` on a type that implements `Drop`
-  --> $DIR/let_underscore_drop.rs:17:5
+  --> $DIR/let_underscore_drop.rs:18:5
    |
 LL |     let _ = Droppable;
    |     ^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL |     let _ = Droppable;
    = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
 
 error: non-binding `let` on a type that implements `Drop`
-  --> $DIR/let_underscore_drop.rs:18:5
+  --> $DIR/let_underscore_drop.rs:19:5
    |
 LL |     let _ = Some(Droppable);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/let_unit.fixed b/src/tools/clippy/tests/ui/let_unit.fixed
index f398edc23cb..e72b7462325 100644
--- a/src/tools/clippy/tests/ui/let_unit.fixed
+++ b/src/tools/clippy/tests/ui/let_unit.fixed
@@ -61,3 +61,55 @@ fn multiline_sugg() {
 
 #[derive(Copy, Clone)]
 pub struct ContainsUnit(()); // should be fine
+
+fn _returns_generic() {
+    fn f<T>() -> T {
+        unimplemented!()
+    }
+    fn f2<T, U>(_: T) -> U {
+        unimplemented!()
+    }
+    fn f3<T>(x: T) -> T {
+        x
+    }
+    fn f4<T>(mut x: Vec<T>) -> T {
+        x.pop().unwrap()
+    }
+
+    let _: () = f(); // Ok
+    let _: () = f(); // Lint.
+
+    let _: () = f2(0i32); // Ok
+    let _: () = f2(0i32); // Lint.
+
+    f3(()); // Lint
+    f3(()); // Lint
+
+    f4(vec![()]); // Lint
+    f4(vec![()]); // Lint
+
+    // Ok
+    let _: () = {
+        let x = 5;
+        f2(x)
+    };
+
+    let _: () = if true { f() } else { f2(0) }; // Ok
+    let _: () = if true { f() } else { f2(0) }; // Lint
+
+    // Ok
+    let _: () = match Some(0) {
+        None => f2(1),
+        Some(0) => f(),
+        Some(1) => f2(3),
+        Some(_) => f2('x'),
+    };
+
+    // Lint
+    match Some(0) {
+        None => f2(1),
+        Some(0) => f(),
+        Some(1) => f2(3),
+        Some(_) => (),
+    };
+}
diff --git a/src/tools/clippy/tests/ui/let_unit.rs b/src/tools/clippy/tests/ui/let_unit.rs
index af5b1fb2ac7..47ee0a76724 100644
--- a/src/tools/clippy/tests/ui/let_unit.rs
+++ b/src/tools/clippy/tests/ui/let_unit.rs
@@ -61,3 +61,55 @@ fn multiline_sugg() {
 
 #[derive(Copy, Clone)]
 pub struct ContainsUnit(()); // should be fine
+
+fn _returns_generic() {
+    fn f<T>() -> T {
+        unimplemented!()
+    }
+    fn f2<T, U>(_: T) -> U {
+        unimplemented!()
+    }
+    fn f3<T>(x: T) -> T {
+        x
+    }
+    fn f4<T>(mut x: Vec<T>) -> T {
+        x.pop().unwrap()
+    }
+
+    let _: () = f(); // Ok
+    let x: () = f(); // Lint.
+
+    let _: () = f2(0i32); // Ok
+    let x: () = f2(0i32); // Lint.
+
+    let _: () = f3(()); // Lint
+    let x: () = f3(()); // Lint
+
+    let _: () = f4(vec![()]); // Lint
+    let x: () = f4(vec![()]); // Lint
+
+    // Ok
+    let _: () = {
+        let x = 5;
+        f2(x)
+    };
+
+    let _: () = if true { f() } else { f2(0) }; // Ok
+    let x: () = if true { f() } else { f2(0) }; // Lint
+
+    // Ok
+    let _: () = match Some(0) {
+        None => f2(1),
+        Some(0) => f(),
+        Some(1) => f2(3),
+        Some(_) => f2('x'),
+    };
+
+    // Lint
+    let _: () = match Some(0) {
+        None => f2(1),
+        Some(0) => f(),
+        Some(1) => f2(3),
+        Some(_) => (),
+    };
+}
diff --git a/src/tools/clippy/tests/ui/let_unit.stderr b/src/tools/clippy/tests/ui/let_unit.stderr
index f2600c6c228..13ec11a6d33 100644
--- a/src/tools/clippy/tests/ui/let_unit.stderr
+++ b/src/tools/clippy/tests/ui/let_unit.stderr
@@ -34,5 +34,74 @@ LL +         .map(|_| ())
 LL +         .next()
  ...
 
-error: aborting due to 3 previous errors
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:80:5
+   |
+LL |     let x: () = f(); // Lint.
+   |     ^^^^-^^^^^^^^^^^
+   |         |
+   |         help: use a wild (`_`) binding: `_`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:83:5
+   |
+LL |     let x: () = f2(0i32); // Lint.
+   |     ^^^^-^^^^^^^^^^^^^^^^
+   |         |
+   |         help: use a wild (`_`) binding: `_`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:85:5
+   |
+LL |     let _: () = f3(()); // Lint
+   |     ^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f3(());`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:86:5
+   |
+LL |     let x: () = f3(()); // Lint
+   |     ^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f3(());`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:88:5
+   |
+LL |     let _: () = f4(vec![()]); // Lint
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f4(vec![()]);`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:89:5
+   |
+LL |     let x: () = f4(vec![()]); // Lint
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f4(vec![()]);`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:98:5
+   |
+LL |     let x: () = if true { f() } else { f2(0) }; // Lint
+   |     ^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         help: use a wild (`_`) binding: `_`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:109:5
+   |
+LL | /     let _: () = match Some(0) {
+LL | |         None => f2(1),
+LL | |         Some(0) => f(),
+LL | |         Some(1) => f2(3),
+LL | |         Some(_) => (),
+LL | |     };
+   | |______^
+   |
+help: omit the `let` binding
+   |
+LL ~     match Some(0) {
+LL +         None => f2(1),
+LL +         Some(0) => f(),
+LL +         Some(1) => f2(3),
+LL +         Some(_) => (),
+LL +     };
+   |
+
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_bits.fixed b/src/tools/clippy/tests/ui/manual_bits.fixed
index 4f1b19b75b8..386360dbdcd 100644
--- a/src/tools/clippy/tests/ui/manual_bits.fixed
+++ b/src/tools/clippy/tests/ui/manual_bits.fixed
@@ -1,38 +1,44 @@
 // run-rustfix
 
 #![warn(clippy::manual_bits)]
-#![allow(clippy::no_effect, path_statements, unused_must_use, clippy::unnecessary_operation)]
+#![allow(
+    clippy::no_effect,
+    clippy::useless_conversion,
+    path_statements,
+    unused_must_use,
+    clippy::unnecessary_operation
+)]
 
 use std::mem::{size_of, size_of_val};
 
 fn main() {
-    i8::BITS;
-    i16::BITS;
-    i32::BITS;
-    i64::BITS;
-    i128::BITS;
-    isize::BITS;
-
-    u8::BITS;
-    u16::BITS;
-    u32::BITS;
-    u64::BITS;
-    u128::BITS;
-    usize::BITS;
-
-    i8::BITS;
-    i16::BITS;
-    i32::BITS;
-    i64::BITS;
-    i128::BITS;
-    isize::BITS;
-
-    u8::BITS;
-    u16::BITS;
-    u32::BITS;
-    u64::BITS;
-    u128::BITS;
-    usize::BITS;
+    i8::BITS as usize;
+    i16::BITS as usize;
+    i32::BITS as usize;
+    i64::BITS as usize;
+    i128::BITS as usize;
+    isize::BITS as usize;
+
+    u8::BITS as usize;
+    u16::BITS as usize;
+    u32::BITS as usize;
+    u64::BITS as usize;
+    u128::BITS as usize;
+    usize::BITS as usize;
+
+    i8::BITS as usize;
+    i16::BITS as usize;
+    i32::BITS as usize;
+    i64::BITS as usize;
+    i128::BITS as usize;
+    isize::BITS as usize;
+
+    u8::BITS as usize;
+    u16::BITS as usize;
+    u32::BITS as usize;
+    u64::BITS as usize;
+    u128::BITS as usize;
+    usize::BITS as usize;
 
     size_of::<usize>() * 4;
     4 * size_of::<usize>();
@@ -42,7 +48,12 @@ fn main() {
     size_of_val(&0u32) * 8;
 
     type Word = u32;
-    Word::BITS;
+    Word::BITS as usize;
     type Bool = bool;
     size_of::<Bool>() * 8;
+
+    let _: u32 = u128::BITS as u32;
+    let _: u32 = u128::BITS.try_into().unwrap();
+    let _ = (u128::BITS as usize).pow(5);
+    let _ = &(u128::BITS as usize);
 }
diff --git a/src/tools/clippy/tests/ui/manual_bits.rs b/src/tools/clippy/tests/ui/manual_bits.rs
index f8a01313e6a..62638f047eb 100644
--- a/src/tools/clippy/tests/ui/manual_bits.rs
+++ b/src/tools/clippy/tests/ui/manual_bits.rs
@@ -1,7 +1,13 @@
 // run-rustfix
 
 #![warn(clippy::manual_bits)]
-#![allow(clippy::no_effect, path_statements, unused_must_use, clippy::unnecessary_operation)]
+#![allow(
+    clippy::no_effect,
+    clippy::useless_conversion,
+    path_statements,
+    unused_must_use,
+    clippy::unnecessary_operation
+)]
 
 use std::mem::{size_of, size_of_val};
 
@@ -45,4 +51,9 @@ fn main() {
     size_of::<Word>() * 8;
     type Bool = bool;
     size_of::<Bool>() * 8;
+
+    let _: u32 = (size_of::<u128>() * 8) as u32;
+    let _: u32 = (size_of::<u128>() * 8).try_into().unwrap();
+    let _ = (size_of::<u128>() * 8).pow(5);
+    let _ = &(size_of::<u128>() * 8);
 }
diff --git a/src/tools/clippy/tests/ui/manual_bits.stderr b/src/tools/clippy/tests/ui/manual_bits.stderr
index c4f5af2dcb0..69c591a203d 100644
--- a/src/tools/clippy/tests/ui/manual_bits.stderr
+++ b/src/tools/clippy/tests/ui/manual_bits.stderr
@@ -1,154 +1,178 @@
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:9:5
+  --> $DIR/manual_bits.rs:15:5
    |
 LL |     size_of::<i8>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
    |
    = note: `-D clippy::manual-bits` implied by `-D warnings`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:10:5
+  --> $DIR/manual_bits.rs:16:5
    |
 LL |     size_of::<i16>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:11:5
+  --> $DIR/manual_bits.rs:17:5
    |
 LL |     size_of::<i32>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:12:5
+  --> $DIR/manual_bits.rs:18:5
    |
 LL |     size_of::<i64>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:13:5
+  --> $DIR/manual_bits.rs:19:5
    |
 LL |     size_of::<i128>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:14:5
+  --> $DIR/manual_bits.rs:20:5
    |
 LL |     size_of::<isize>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:16:5
+  --> $DIR/manual_bits.rs:22:5
    |
 LL |     size_of::<u8>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:17:5
+  --> $DIR/manual_bits.rs:23:5
    |
 LL |     size_of::<u16>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:18:5
+  --> $DIR/manual_bits.rs:24:5
    |
 LL |     size_of::<u32>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:19:5
+  --> $DIR/manual_bits.rs:25:5
    |
 LL |     size_of::<u64>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:20:5
+  --> $DIR/manual_bits.rs:26:5
    |
 LL |     size_of::<u128>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:21:5
+  --> $DIR/manual_bits.rs:27:5
    |
 LL |     size_of::<usize>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:23:5
+  --> $DIR/manual_bits.rs:29:5
    |
 LL |     8 * size_of::<i8>();
-   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `i8::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:24:5
+  --> $DIR/manual_bits.rs:30:5
    |
 LL |     8 * size_of::<i16>();
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i16::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:25:5
+  --> $DIR/manual_bits.rs:31:5
    |
 LL |     8 * size_of::<i32>();
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i32::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:26:5
+  --> $DIR/manual_bits.rs:32:5
    |
 LL |     8 * size_of::<i64>();
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `i64::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:27:5
+  --> $DIR/manual_bits.rs:33:5
    |
 LL |     8 * size_of::<i128>();
-   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `i128::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:28:5
+  --> $DIR/manual_bits.rs:34:5
    |
 LL |     8 * size_of::<isize>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `isize::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:30:5
+  --> $DIR/manual_bits.rs:36:5
    |
 LL |     8 * size_of::<u8>();
-   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^ help: consider using: `u8::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:31:5
+  --> $DIR/manual_bits.rs:37:5
    |
 LL |     8 * size_of::<u16>();
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u16::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:32:5
+  --> $DIR/manual_bits.rs:38:5
    |
 LL |     8 * size_of::<u32>();
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u32::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:33:5
+  --> $DIR/manual_bits.rs:39:5
    |
 LL |     8 * size_of::<u64>();
-   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^ help: consider using: `u64::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:34:5
+  --> $DIR/manual_bits.rs:40:5
    |
 LL |     8 * size_of::<u128>();
-   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `u128::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:35:5
+  --> $DIR/manual_bits.rs:41:5
    |
 LL |     8 * size_of::<usize>();
-   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `usize::BITS as usize`
 
 error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
-  --> $DIR/manual_bits.rs:45:5
+  --> $DIR/manual_bits.rs:51:5
    |
 LL |     size_of::<Word>() * 8;
-   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS`
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: consider using: `Word::BITS as usize`
+
+error: usage of `mem::size_of::<T>()` to obtain the size of `T` in bits
+  --> $DIR/manual_bits.rs:55: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
+  --> $DIR/manual_bits.rs:56: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
+  --> $DIR/manual_bits.rs:57: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
+  --> $DIR/manual_bits.rs:58:14
+   |
+LL |     let _ = &(size_of::<u128>() * 8);
+   |              ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(u128::BITS as usize)`
 
-error: aborting due to 25 previous errors
+error: aborting due to 29 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
new file mode 100644
index 00000000000..f23c6d69b4c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
@@ -0,0 +1,78 @@
+#![warn(clippy::manual_non_exhaustive)]
+#![allow(unused)]
+
+enum E {
+    A,
+    B,
+    #[doc(hidden)]
+    _C,
+}
+
+// user forgot to remove the marker
+#[non_exhaustive]
+enum Ep {
+    A,
+    B,
+    #[doc(hidden)]
+    _C,
+}
+
+// marker variant does not have doc hidden attribute, should be ignored
+enum NoDocHidden {
+    A,
+    B,
+    _C,
+}
+
+// name of variant with doc hidden does not start with underscore, should be ignored
+enum NoUnderscore {
+    A,
+    B,
+    #[doc(hidden)]
+    C,
+}
+
+// variant with doc hidden is not unit, should be ignored
+enum NotUnit {
+    A,
+    B,
+    #[doc(hidden)]
+    _C(bool),
+}
+
+// variant with doc hidden is the only one, should be ignored
+enum OnlyMarker {
+    #[doc(hidden)]
+    _A,
+}
+
+// variant with multiple markers, should be ignored
+enum MultipleMarkers {
+    A,
+    #[doc(hidden)]
+    _B,
+    #[doc(hidden)]
+    _C,
+}
+
+// already non_exhaustive and no markers, should be ignored
+#[non_exhaustive]
+enum NonExhaustive {
+    A,
+    B,
+}
+
+// marked is used, don't lint
+enum UsedHidden {
+    #[doc(hidden)]
+    _A,
+    B,
+    C,
+}
+fn foo(x: &mut UsedHidden) {
+    if matches!(*x, UsedHidden::B) {
+        *x = UsedHidden::_A;
+    }
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
new file mode 100644
index 00000000000..317a45d2cbd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
@@ -0,0 +1,41 @@
+error: this seems like a manual implementation of the non-exhaustive pattern
+  --> $DIR/manual_non_exhaustive_enum.rs:4:1
+   |
+LL |   enum E {
+   |   ^-----
+   |   |
+   |  _help: add the attribute: `#[non_exhaustive] enum E`
+   | |
+LL | |     A,
+LL | |     B,
+LL | |     #[doc(hidden)]
+LL | |     _C,
+LL | | }
+   | |_^
+   |
+   = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
+help: remove this variant
+  --> $DIR/manual_non_exhaustive_enum.rs:8:5
+   |
+LL |     _C,
+   |     ^^
+
+error: this seems like a manual implementation of the non-exhaustive pattern
+  --> $DIR/manual_non_exhaustive_enum.rs:13:1
+   |
+LL | / enum Ep {
+LL | |     A,
+LL | |     B,
+LL | |     #[doc(hidden)]
+LL | |     _C,
+LL | | }
+   | |_^
+   |
+help: remove this variant
+  --> $DIR/manual_non_exhaustive_enum.rs:17:5
+   |
+LL |     _C,
+   |     ^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive.rs b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs
index 7a788f48520..498eee4447b 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive.rs
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.rs
@@ -1,69 +1,6 @@
 #![warn(clippy::manual_non_exhaustive)]
 #![allow(unused)]
 
-mod enums {
-    enum E {
-        A,
-        B,
-        #[doc(hidden)]
-        _C,
-    }
-
-    // user forgot to remove the marker
-    #[non_exhaustive]
-    enum Ep {
-        A,
-        B,
-        #[doc(hidden)]
-        _C,
-    }
-
-    // marker variant does not have doc hidden attribute, should be ignored
-    enum NoDocHidden {
-        A,
-        B,
-        _C,
-    }
-
-    // name of variant with doc hidden does not start with underscore, should be ignored
-    enum NoUnderscore {
-        A,
-        B,
-        #[doc(hidden)]
-        C,
-    }
-
-    // variant with doc hidden is not unit, should be ignored
-    enum NotUnit {
-        A,
-        B,
-        #[doc(hidden)]
-        _C(bool),
-    }
-
-    // variant with doc hidden is the only one, should be ignored
-    enum OnlyMarker {
-        #[doc(hidden)]
-        _A,
-    }
-
-    // variant with multiple markers, should be ignored
-    enum MultipleMarkers {
-        A,
-        #[doc(hidden)]
-        _B,
-        #[doc(hidden)]
-        _C,
-    }
-
-    // already non_exhaustive and no markers, should be ignored
-    #[non_exhaustive]
-    enum NonExhaustive {
-        A,
-        B,
-    }
-}
-
 mod structs {
     struct S {
         pub a: i32,
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
index 613c5e8ca1d..e0766c17b75 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive.stderr
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_struct.stderr
@@ -1,44 +1,5 @@
 error: this seems like a manual implementation of the non-exhaustive pattern
-  --> $DIR/manual_non_exhaustive.rs:5:5
-   |
-LL |       enum E {
-   |       ^-----
-   |       |
-   |  _____help: add the attribute: `#[non_exhaustive] enum E`
-   | |
-LL | |         A,
-LL | |         B,
-LL | |         #[doc(hidden)]
-LL | |         _C,
-LL | |     }
-   | |_____^
-   |
-   = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
-help: remove this variant
-  --> $DIR/manual_non_exhaustive.rs:9:9
-   |
-LL |         _C,
-   |         ^^
-
-error: this seems like a manual implementation of the non-exhaustive pattern
-  --> $DIR/manual_non_exhaustive.rs:14:5
-   |
-LL | /     enum Ep {
-LL | |         A,
-LL | |         B,
-LL | |         #[doc(hidden)]
-LL | |         _C,
-LL | |     }
-   | |_____^
-   |
-help: remove this variant
-  --> $DIR/manual_non_exhaustive.rs:18:9
-   |
-LL |         _C,
-   |         ^^
-
-error: this seems like a manual implementation of the non-exhaustive pattern
-  --> $DIR/manual_non_exhaustive.rs:68:5
+  --> $DIR/manual_non_exhaustive_struct.rs:5:5
    |
 LL |       struct S {
    |       ^-------
@@ -51,14 +12,15 @@ LL | |         _c: (),
 LL | |     }
    | |_____^
    |
+   = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
 help: remove this field
-  --> $DIR/manual_non_exhaustive.rs:71:9
+  --> $DIR/manual_non_exhaustive_struct.rs:8:9
    |
 LL |         _c: (),
    |         ^^^^^^
 
 error: this seems like a manual implementation of the non-exhaustive pattern
-  --> $DIR/manual_non_exhaustive.rs:76:5
+  --> $DIR/manual_non_exhaustive_struct.rs:13:5
    |
 LL | /     struct Sp {
 LL | |         pub a: i32,
@@ -68,13 +30,13 @@ LL | |     }
    | |_____^
    |
 help: remove this field
-  --> $DIR/manual_non_exhaustive.rs:79:9
+  --> $DIR/manual_non_exhaustive_struct.rs:16:9
    |
 LL |         _c: (),
    |         ^^^^^^
 
 error: this seems like a manual implementation of the non-exhaustive pattern
-  --> $DIR/manual_non_exhaustive.rs:117:5
+  --> $DIR/manual_non_exhaustive_struct.rs:54:5
    |
 LL |     struct T(pub i32, pub i32, ());
    |     --------^^^^^^^^^^^^^^^^^^^^^^^
@@ -82,22 +44,22 @@ LL |     struct T(pub i32, pub i32, ());
    |     help: add the attribute: `#[non_exhaustive] struct T`
    |
 help: remove this field
-  --> $DIR/manual_non_exhaustive.rs:117:32
+  --> $DIR/manual_non_exhaustive_struct.rs:54:32
    |
 LL |     struct T(pub i32, pub i32, ());
    |                                ^^
 
 error: this seems like a manual implementation of the non-exhaustive pattern
-  --> $DIR/manual_non_exhaustive.rs:121:5
+  --> $DIR/manual_non_exhaustive_struct.rs:58:5
    |
 LL |     struct Tp(pub i32, pub i32, ());
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: remove this field
-  --> $DIR/manual_non_exhaustive.rs:121:33
+  --> $DIR/manual_non_exhaustive_struct.rs:58:33
    |
 LL |     struct Tp(pub i32, pub i32, ());
    |                                 ^^
 
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_split_once.fixed b/src/tools/clippy/tests/ui/manual_split_once.fixed
index d5113df569a..c7ca770434a 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.fixed
+++ b/src/tools/clippy/tests/ui/manual_split_once.fixed
@@ -2,7 +2,7 @@
 
 #![feature(custom_inner_attributes)]
 #![warn(clippy::manual_split_once)]
-#![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::needless_splitn)]
+#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
 
 extern crate itertools;
 
@@ -10,27 +10,25 @@ extern crate itertools;
 use itertools::Itertools;
 
 fn main() {
-    let _ = Some("key=value".split_once('=').map_or("key=value", |x| x.0));
     let _ = "key=value".splitn(2, '=').nth(2);
-    let _ = "key=value".split_once('=').map_or("key=value", |x| x.0);
-    let _ = "key=value".split_once('=').map_or("key=value", |x| x.0);
     let _ = "key=value".split_once('=').unwrap().1;
     let _ = "key=value".split_once('=').unwrap().1;
     let (_, _) = "key=value".split_once('=').unwrap();
 
     let s = String::from("key=value");
-    let _ = s.split_once('=').map_or(&*s, |x| x.0);
+    let _ = s.split_once('=').unwrap().1;
 
     let s = Box::<str>::from("key=value");
-    let _ = s.split_once('=').map_or(&*s, |x| x.0);
+    let _ = s.split_once('=').unwrap().1;
 
     let s = &"key=value";
-    let _ = s.split_once('=').map_or(*s, |x| x.0);
+    let _ = s.split_once('=').unwrap().1;
 
     fn _f(s: &str) -> Option<&str> {
-        let _ = s.split_once("key=value").map_or(s, |x| x.0);
-        let _ = s.split_once("key=value")?.1;
-        let _ = s.split_once("key=value")?.1;
+        let _ = s.split_once('=')?.1;
+        let _ = s.split_once('=')?.1;
+        let _ = s.rsplit_once('=')?.0;
+        let _ = s.rsplit_once('=')?.0;
         None
     }
 
@@ -38,19 +36,112 @@ fn main() {
     let _ = [0, 1, 2].splitn(2, |&x| x == 1).nth(1).unwrap();
 
     // `rsplitn` gives the results in the reverse order of `rsplit_once`
-    let _ = "key=value".rsplitn(2, '=').next().unwrap();
     let _ = "key=value".rsplit_once('=').unwrap().0;
-    let _ = "key=value".rsplit_once('=').map(|x| x.1);
     let (_, _) = "key=value".rsplit_once('=').map(|(x, y)| (y, x)).unwrap();
+    let _ = s.rsplit_once('=').map(|x| x.0);
+}
+
+fn indirect() -> Option<()> {
+    let (l, r) = "a.b.c".split_once('.').unwrap();
+    
+    
+
+    let (l, r) = "a.b.c".split_once('.')?;
+    
+    
+
+    let (l, r) = "a.b.c".rsplit_once('.').unwrap();
+    
+    
+
+    let (l, r) = "a.b.c".rsplit_once('.')?;
+    
+    
+
+    // could lint, currently doesn't
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let other = 1;
+    let l = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let mut mut_binding = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let tuple = (iter.next()?, iter.next()?);
+
+    // should not lint
+
+    let mut missing_unwrap = "a.b.c".splitn(2, '.');
+    let l = missing_unwrap.next();
+    let r = missing_unwrap.next();
+
+    let mut mixed_unrap = "a.b.c".splitn(2, '.');
+    let unwrap = mixed_unrap.next().unwrap();
+    let question_mark = mixed_unrap.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let same_name = iter.next()?;
+    let same_name = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let shadows_existing = "d";
+    let shadows_existing = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let becomes_shadowed = iter.next()?;
+    let becomes_shadowed = "d";
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let l = iter.next()?;
+    let r = iter.next()?;
+    let third_usage = iter.next()?;
+
+    let mut n_three = "a.b.c".splitn(3, '.');
+    let l = n_three.next()?;
+    let r = n_three.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    {
+        let in_block = iter.next()?;
+    }
+    let r = iter.next()?;
+
+    let mut lacks_binding = "a.b.c".splitn(2, '.');
+    let _ = lacks_binding.next()?;
+    let r = lacks_binding.next()?;
+
+    let mut mapped = "a.b.c".splitn(2, '.').map(|_| "~");
+    let l = iter.next()?;
+    let r = iter.next()?;
+
+    let mut assigned = "";
+    let mut iter = "a.b.c".splitn(2, '.');
+    let l = iter.next()?;
+    assigned = iter.next()?;
+
+    None
 }
 
 fn _msrv_1_51() {
     #![clippy::msrv = "1.51"]
-    // `str::split_once` was stabilized in 1.16. Do not lint this
+    // `str::split_once` was stabilized in 1.52. Do not lint this
     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let a = iter.next().unwrap();
+    let b = iter.next().unwrap();
 }
 
 fn _msrv_1_52() {
     #![clippy::msrv = "1.52"]
     let _ = "key=value".split_once('=').unwrap().1;
+
+    let (a, b) = "a.b.c".split_once('.').unwrap();
+    
+    
 }
diff --git a/src/tools/clippy/tests/ui/manual_split_once.rs b/src/tools/clippy/tests/ui/manual_split_once.rs
index 80e02952dbd..ee2848a251e 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.rs
+++ b/src/tools/clippy/tests/ui/manual_split_once.rs
@@ -2,7 +2,7 @@
 
 #![feature(custom_inner_attributes)]
 #![warn(clippy::manual_split_once)]
-#![allow(clippy::iter_skip_next, clippy::iter_nth_zero, clippy::needless_splitn)]
+#![allow(unused, clippy::iter_skip_next, clippy::iter_nth_zero)]
 
 extern crate itertools;
 
@@ -10,27 +10,25 @@ extern crate itertools;
 use itertools::Itertools;
 
 fn main() {
-    let _ = "key=value".splitn(2, '=').next();
     let _ = "key=value".splitn(2, '=').nth(2);
-    let _ = "key=value".splitn(2, '=').next().unwrap();
-    let _ = "key=value".splitn(2, '=').nth(0).unwrap();
     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
     let _ = "key=value".splitn(2, '=').skip(1).next().unwrap();
     let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap();
 
     let s = String::from("key=value");
-    let _ = s.splitn(2, '=').next().unwrap();
+    let _ = s.splitn(2, '=').nth(1).unwrap();
 
     let s = Box::<str>::from("key=value");
-    let _ = s.splitn(2, '=').nth(0).unwrap();
+    let _ = s.splitn(2, '=').nth(1).unwrap();
 
     let s = &"key=value";
-    let _ = s.splitn(2, '=').skip(0).next().unwrap();
+    let _ = s.splitn(2, '=').skip(1).next().unwrap();
 
     fn _f(s: &str) -> Option<&str> {
-        let _ = s.splitn(2, "key=value").next()?;
-        let _ = s.splitn(2, "key=value").nth(1)?;
-        let _ = s.splitn(2, "key=value").skip(1).next()?;
+        let _ = s.splitn(2, '=').nth(1)?;
+        let _ = s.splitn(2, '=').skip(1).next()?;
+        let _ = s.rsplitn(2, '=').nth(1)?;
+        let _ = s.rsplitn(2, '=').skip(1).next()?;
         None
     }
 
@@ -38,19 +36,112 @@ fn main() {
     let _ = [0, 1, 2].splitn(2, |&x| x == 1).nth(1).unwrap();
 
     // `rsplitn` gives the results in the reverse order of `rsplit_once`
-    let _ = "key=value".rsplitn(2, '=').next().unwrap();
     let _ = "key=value".rsplitn(2, '=').nth(1).unwrap();
-    let _ = "key=value".rsplitn(2, '=').nth(0);
     let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap();
+    let _ = s.rsplitn(2, '=').nth(1);
+}
+
+fn indirect() -> Option<()> {
+    let mut iter = "a.b.c".splitn(2, '.');
+    let l = iter.next().unwrap();
+    let r = iter.next().unwrap();
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let l = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".rsplitn(2, '.');
+    let r = iter.next().unwrap();
+    let l = iter.next().unwrap();
+
+    let mut iter = "a.b.c".rsplitn(2, '.');
+    let r = iter.next()?;
+    let l = iter.next()?;
+
+    // could lint, currently doesn't
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let other = 1;
+    let l = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let mut mut_binding = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let tuple = (iter.next()?, iter.next()?);
+
+    // should not lint
+
+    let mut missing_unwrap = "a.b.c".splitn(2, '.');
+    let l = missing_unwrap.next();
+    let r = missing_unwrap.next();
+
+    let mut mixed_unrap = "a.b.c".splitn(2, '.');
+    let unwrap = mixed_unrap.next().unwrap();
+    let question_mark = mixed_unrap.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let same_name = iter.next()?;
+    let same_name = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let shadows_existing = "d";
+    let shadows_existing = iter.next()?;
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let becomes_shadowed = iter.next()?;
+    let becomes_shadowed = "d";
+    let r = iter.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let l = iter.next()?;
+    let r = iter.next()?;
+    let third_usage = iter.next()?;
+
+    let mut n_three = "a.b.c".splitn(3, '.');
+    let l = n_three.next()?;
+    let r = n_three.next()?;
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    {
+        let in_block = iter.next()?;
+    }
+    let r = iter.next()?;
+
+    let mut lacks_binding = "a.b.c".splitn(2, '.');
+    let _ = lacks_binding.next()?;
+    let r = lacks_binding.next()?;
+
+    let mut mapped = "a.b.c".splitn(2, '.').map(|_| "~");
+    let l = iter.next()?;
+    let r = iter.next()?;
+
+    let mut assigned = "";
+    let mut iter = "a.b.c".splitn(2, '.');
+    let l = iter.next()?;
+    assigned = iter.next()?;
+
+    None
 }
 
 fn _msrv_1_51() {
     #![clippy::msrv = "1.51"]
-    // `str::split_once` was stabilized in 1.16. Do not lint this
+    // `str::split_once` was stabilized in 1.52. Do not lint this
     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let a = iter.next().unwrap();
+    let b = iter.next().unwrap();
 }
 
 fn _msrv_1_52() {
     #![clippy::msrv = "1.52"]
     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
+
+    let mut iter = "a.b.c".splitn(2, '.');
+    let a = iter.next().unwrap();
+    let b = iter.next().unwrap();
 }
diff --git a/src/tools/clippy/tests/ui/manual_split_once.stderr b/src/tools/clippy/tests/ui/manual_split_once.stderr
index af9c7a2d41b..2563a6904b7 100644
--- a/src/tools/clippy/tests/ui/manual_split_once.stderr
+++ b/src/tools/clippy/tests/ui/manual_split_once.stderr
@@ -1,100 +1,213 @@
 error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:13:13
+  --> $DIR/manual_split_once.rs:14:13
    |
-LL |     let _ = "key=value".splitn(2, '=').next();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Some("key=value".split_once('=').map_or("key=value", |x| x.0))`
+LL |     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1`
    |
    = note: `-D clippy::manual-split-once` implied by `-D warnings`
 
 error: manual implementation of `split_once`
   --> $DIR/manual_split_once.rs:15:13
    |
-LL |     let _ = "key=value".splitn(2, '=').next().unwrap();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').map_or("key=value", |x| x.0)`
-
-error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:16:13
-   |
-LL |     let _ = "key=value".splitn(2, '=').nth(0).unwrap();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').map_or("key=value", |x| x.0)`
-
-error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:17:13
-   |
-LL |     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1`
-
-error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:18:13
-   |
 LL |     let _ = "key=value".splitn(2, '=').skip(1).next().unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1`
 
 error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:19:18
+  --> $DIR/manual_split_once.rs:16:18
    |
 LL |     let (_, _) = "key=value".splitn(2, '=').next_tuple().unwrap();
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=')`
 
 error: manual implementation of `split_once`
+  --> $DIR/manual_split_once.rs:19:13
+   |
+LL |     let _ = s.splitn(2, '=').nth(1).unwrap();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').unwrap().1`
+
+error: manual implementation of `split_once`
   --> $DIR/manual_split_once.rs:22:13
    |
-LL |     let _ = s.splitn(2, '=').next().unwrap();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').map_or(&*s, |x| x.0)`
+LL |     let _ = s.splitn(2, '=').nth(1).unwrap();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').unwrap().1`
 
 error: manual implementation of `split_once`
   --> $DIR/manual_split_once.rs:25:13
    |
-LL |     let _ = s.splitn(2, '=').nth(0).unwrap();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').map_or(&*s, |x| x.0)`
+LL |     let _ = s.splitn(2, '=').skip(1).next().unwrap();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').unwrap().1`
 
 error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:28:13
+  --> $DIR/manual_split_once.rs:28:17
    |
-LL |     let _ = s.splitn(2, '=').skip(0).next().unwrap();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=').map_or(*s, |x| x.0)`
+LL |         let _ = s.splitn(2, '=').nth(1)?;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=')?.1`
 
 error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:31:17
+  --> $DIR/manual_split_once.rs:29:17
    |
-LL |         let _ = s.splitn(2, "key=value").next()?;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once("key=value").map_or(s, |x| x.0)`
+LL |         let _ = s.splitn(2, '=').skip(1).next()?;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once('=')?.1`
 
-error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:32:17
+error: manual implementation of `rsplit_once`
+  --> $DIR/manual_split_once.rs:30:17
    |
-LL |         let _ = s.splitn(2, "key=value").nth(1)?;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once("key=value")?.1`
+LL |         let _ = s.rsplitn(2, '=').nth(1)?;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit_once('=')?.0`
 
-error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:33:17
+error: manual implementation of `rsplit_once`
+  --> $DIR/manual_split_once.rs:31:17
    |
-LL |         let _ = s.splitn(2, "key=value").skip(1).next()?;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.split_once("key=value")?.1`
+LL |         let _ = s.rsplitn(2, '=').skip(1).next()?;
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit_once('=')?.0`
 
 error: manual implementation of `rsplit_once`
-  --> $DIR/manual_split_once.rs:42:13
+  --> $DIR/manual_split_once.rs:39:13
    |
 LL |     let _ = "key=value".rsplitn(2, '=').nth(1).unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".rsplit_once('=').unwrap().0`
 
 error: manual implementation of `rsplit_once`
-  --> $DIR/manual_split_once.rs:43:13
+  --> $DIR/manual_split_once.rs:40:18
    |
-LL |     let _ = "key=value".rsplitn(2, '=').nth(0);
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".rsplit_once('=').map(|x| x.1)`
+LL |     let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap();
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))`
 
 error: manual implementation of `rsplit_once`
-  --> $DIR/manual_split_once.rs:44:18
+  --> $DIR/manual_split_once.rs:41:13
    |
-LL |     let (_, _) = "key=value".rsplitn(2, '=').next_tuple().unwrap();
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".rsplit_once('=').map(|(x, y)| (y, x))`
+LL |     let _ = s.rsplitn(2, '=').nth(1);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit_once('=').map(|x| x.0)`
+
+error: manual implementation of `split_once`
+  --> $DIR/manual_split_once.rs:45:5
+   |
+LL |     let mut iter = "a.b.c".splitn(2, '.');
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let l = iter.next().unwrap();
+   |     ----------------------------- first usage here
+LL |     let r = iter.next().unwrap();
+   |     ----------------------------- second usage here
+   |
+help: try `split_once`
+   |
+LL |     let (l, r) = "a.b.c".split_once('.').unwrap();
+   |
+help: remove the `iter` usages
+   |
+LL -     let l = iter.next().unwrap();
+LL +     
+   | 
+help: remove the `iter` usages
+   |
+LL -     let r = iter.next().unwrap();
+LL +     
+   | 
 
 error: manual implementation of `split_once`
-  --> $DIR/manual_split_once.rs:55:13
+  --> $DIR/manual_split_once.rs:49:5
+   |
+LL |     let mut iter = "a.b.c".splitn(2, '.');
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let l = iter.next()?;
+   |     --------------------- first usage here
+LL |     let r = iter.next()?;
+   |     --------------------- second usage here
+   |
+help: try `split_once`
+   |
+LL |     let (l, r) = "a.b.c".split_once('.')?;
+   |
+help: remove the `iter` usages
+   |
+LL -     let l = iter.next()?;
+LL +     
+   | 
+help: remove the `iter` usages
+   |
+LL -     let r = iter.next()?;
+LL +     
+   | 
+
+error: manual implementation of `rsplit_once`
+  --> $DIR/manual_split_once.rs:53:5
+   |
+LL |     let mut iter = "a.b.c".rsplitn(2, '.');
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let r = iter.next().unwrap();
+   |     ----------------------------- first usage here
+LL |     let l = iter.next().unwrap();
+   |     ----------------------------- second usage here
+   |
+help: try `rsplit_once`
+   |
+LL |     let (l, r) = "a.b.c".rsplit_once('.').unwrap();
+   |
+help: remove the `iter` usages
+   |
+LL -     let r = iter.next().unwrap();
+LL +     
+   | 
+help: remove the `iter` usages
+   |
+LL -     let l = iter.next().unwrap();
+LL +     
+   | 
+
+error: manual implementation of `rsplit_once`
+  --> $DIR/manual_split_once.rs:57:5
+   |
+LL |     let mut iter = "a.b.c".rsplitn(2, '.');
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let r = iter.next()?;
+   |     --------------------- first usage here
+LL |     let l = iter.next()?;
+   |     --------------------- second usage here
+   |
+help: try `rsplit_once`
+   |
+LL |     let (l, r) = "a.b.c".rsplit_once('.')?;
+   |
+help: remove the `iter` usages
+   |
+LL -     let r = iter.next()?;
+LL +     
+   | 
+help: remove the `iter` usages
+   |
+LL -     let l = iter.next()?;
+LL +     
+   | 
+
+error: manual implementation of `split_once`
+  --> $DIR/manual_split_once.rs:142:13
    |
 LL |     let _ = "key=value".splitn(2, '=').nth(1).unwrap();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split_once('=').unwrap().1`
 
-error: aborting due to 16 previous errors
+error: manual implementation of `split_once`
+  --> $DIR/manual_split_once.rs:144:5
+   |
+LL |     let mut iter = "a.b.c".splitn(2, '.');
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     let a = iter.next().unwrap();
+   |     ----------------------------- first usage here
+LL |     let b = iter.next().unwrap();
+   |     ----------------------------- second usage here
+   |
+help: try `split_once`
+   |
+LL |     let (a, b) = "a.b.c".split_once('.').unwrap();
+   |
+help: remove the `iter` usages
+   |
+LL -     let a = iter.next().unwrap();
+LL +     
+   | 
+help: remove the `iter` usages
+   |
+LL -     let b = iter.next().unwrap();
+LL +     
+   | 
+
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
index 5d57638af43..a7b36d53cd2 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.fixed
@@ -5,7 +5,8 @@
     unused_variables,
     overflowing_literals,
     clippy::excessive_precision,
-    clippy::inconsistent_digit_grouping
+    clippy::inconsistent_digit_grouping,
+    clippy::unusual_byte_groupings
 )]
 
 fn main() {
@@ -25,5 +26,18 @@ fn main() {
     let fail28 = 241_251_235E723_f64;
     let ok29 = 42279.911_32;
 
+    // testing that the suggestion actually fits in its type
+    let fail30 = 127_i8; // should be i8
+    let fail31 = 240_u8; // should be u8
+    let ok32 = 360_8; // doesnt fit in either, should be ignored
+    let fail33 = 0x1234_i16;
+    let fail34 = 0xABCD_u16;
+    let ok35 = 0x12345_16;
+    let fail36 = 0xFFFF_FFFF_FFFF_FFFF_u64; // u64
+
+    // issue #6129
+    let ok37 = 123_32.123;
+    let ok38 = 124_64.0;
+
     let _ = 1.123_45E1_f32;
 }
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
index 12171452885..c97b31965c7 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.rs
@@ -5,7 +5,8 @@
     unused_variables,
     overflowing_literals,
     clippy::excessive_precision,
-    clippy::inconsistent_digit_grouping
+    clippy::inconsistent_digit_grouping,
+    clippy::unusual_byte_groupings
 )]
 
 fn main() {
@@ -25,5 +26,18 @@ fn main() {
     let fail28 = 241251235E723_64;
     let ok29 = 42279.911_32;
 
+    // testing that the suggestion actually fits in its type
+    let fail30 = 127_8; // should be i8
+    let fail31 = 240_8; // should be u8
+    let ok32 = 360_8; // doesnt fit in either, should be ignored
+    let fail33 = 0x1234_16;
+    let fail34 = 0xABCD_16;
+    let ok35 = 0x12345_16;
+    let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64
+
+    // issue #6129
+    let ok37 = 123_32.123;
+    let ok38 = 124_64.0;
+
     let _ = 1.12345E1_32;
 }
diff --git a/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr b/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr
index d24543c26e4..fb761d9bde4 100644
--- a/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr
+++ b/src/tools/clippy/tests/ui/mistyped_literal_suffix.stderr
@@ -1,5 +1,5 @@
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:12:18
+  --> $DIR/mistyped_literal_suffix.rs:13:18
    |
 LL |     let fail14 = 2_32;
    |                  ^^^^ help: did you mean to write: `2_i32`
@@ -7,64 +7,94 @@ LL |     let fail14 = 2_32;
    = note: `#[deny(clippy::mistyped_literal_suffixes)]` on by default
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:13:18
+  --> $DIR/mistyped_literal_suffix.rs:14:18
    |
 LL |     let fail15 = 4_64;
    |                  ^^^^ help: did you mean to write: `4_i64`
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:14:18
+  --> $DIR/mistyped_literal_suffix.rs:15:18
    |
 LL |     let fail16 = 7_8; //
    |                  ^^^ help: did you mean to write: `7_i8`
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:15:18
+  --> $DIR/mistyped_literal_suffix.rs:16:18
    |
 LL |     let fail17 = 23_16; //
    |                  ^^^^^ help: did you mean to write: `23_i16`
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:18:18
+  --> $DIR/mistyped_literal_suffix.rs:19:18
    |
 LL |     let fail20 = 2__8; //
    |                  ^^^^ help: did you mean to write: `2_i8`
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:19:18
+  --> $DIR/mistyped_literal_suffix.rs:20:18
    |
 LL |     let fail21 = 4___16; //
    |                  ^^^^^^ help: did you mean to write: `4_i16`
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:22:18
+  --> $DIR/mistyped_literal_suffix.rs:23:18
    |
 LL |     let fail25 = 1E2_32;
    |                  ^^^^^^ help: did you mean to write: `1E2_f32`
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:23:18
+  --> $DIR/mistyped_literal_suffix.rs:24:18
    |
 LL |     let fail26 = 43E7_64;
    |                  ^^^^^^^ help: did you mean to write: `43E7_f64`
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:24:18
+  --> $DIR/mistyped_literal_suffix.rs:25:18
    |
 LL |     let fail27 = 243E17_32;
    |                  ^^^^^^^^^ help: did you mean to write: `243E17_f32`
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:25:18
+  --> $DIR/mistyped_literal_suffix.rs:26:18
    |
 LL |     let fail28 = 241251235E723_64;
    |                  ^^^^^^^^^^^^^^^^ help: did you mean to write: `241_251_235E723_f64`
 
 error: mistyped literal suffix
-  --> $DIR/mistyped_literal_suffix.rs:28:13
+  --> $DIR/mistyped_literal_suffix.rs:30:18
+   |
+LL |     let fail30 = 127_8; // should be i8
+   |                  ^^^^^ help: did you mean to write: `127_i8`
+
+error: mistyped literal suffix
+  --> $DIR/mistyped_literal_suffix.rs:31:18
+   |
+LL |     let fail31 = 240_8; // should be u8
+   |                  ^^^^^ help: did you mean to write: `240_u8`
+
+error: mistyped literal suffix
+  --> $DIR/mistyped_literal_suffix.rs:33:18
+   |
+LL |     let fail33 = 0x1234_16;
+   |                  ^^^^^^^^^ help: did you mean to write: `0x1234_i16`
+
+error: mistyped literal suffix
+  --> $DIR/mistyped_literal_suffix.rs:34:18
+   |
+LL |     let fail34 = 0xABCD_16;
+   |                  ^^^^^^^^^ help: did you mean to write: `0xABCD_u16`
+
+error: mistyped literal suffix
+  --> $DIR/mistyped_literal_suffix.rs:36:18
+   |
+LL |     let fail36 = 0xFFFF_FFFF_FFFF_FFFF_64; // u64
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: did you mean to write: `0xFFFF_FFFF_FFFF_FFFF_u64`
+
+error: mistyped literal suffix
+  --> $DIR/mistyped_literal_suffix.rs:42:13
    |
 LL |     let _ = 1.12345E1_32;
    |             ^^^^^^^^^^^^ help: did you mean to write: `1.123_45E1_f32`
 
-error: aborting due to 11 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/mut_from_ref.rs b/src/tools/clippy/tests/ui/mut_from_ref.rs
index a9a04c8f56b..370dbd58821 100644
--- a/src/tools/clippy/tests/ui/mut_from_ref.rs
+++ b/src/tools/clippy/tests/ui/mut_from_ref.rs
@@ -5,7 +5,7 @@ struct Foo;
 
 impl Foo {
     fn this_wont_hurt_a_bit(&self) -> &mut Foo {
-        unimplemented!()
+        unsafe { unimplemented!() }
     }
 }
 
@@ -15,29 +15,37 @@ trait Ouch {
 
 impl Ouch for Foo {
     fn ouch(x: &Foo) -> &mut Foo {
-        unimplemented!()
+        unsafe { unimplemented!() }
     }
 }
 
 fn fail(x: &u32) -> &mut u16 {
-    unimplemented!()
+    unsafe { unimplemented!() }
 }
 
 fn fail_lifetime<'a>(x: &'a u32, y: &mut u32) -> &'a mut u32 {
-    unimplemented!()
+    unsafe { unimplemented!() }
 }
 
 fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {
-    unimplemented!()
+    unsafe { unimplemented!() }
 }
 
 // this is OK, because the result borrows y
 fn works<'a>(x: &u32, y: &'a mut u32) -> &'a mut u32 {
-    unimplemented!()
+    unsafe { unimplemented!() }
 }
 
 // this is also OK, because the result could borrow y
 fn also_works<'a>(x: &'a u32, y: &'a mut u32) -> &'a mut u32 {
+    unsafe { unimplemented!() }
+}
+
+unsafe fn also_broken(x: &u32) -> &mut u32 {
+    unimplemented!()
+}
+
+fn without_unsafe(x: &u32) -> &mut u32 {
     unimplemented!()
 }
 
diff --git a/src/tools/clippy/tests/ui/mut_from_ref.stderr b/src/tools/clippy/tests/ui/mut_from_ref.stderr
index 4787999920b..b76d6a13ffb 100644
--- a/src/tools/clippy/tests/ui/mut_from_ref.stderr
+++ b/src/tools/clippy/tests/ui/mut_from_ref.stderr
@@ -59,5 +59,17 @@ note: immutable borrow here
 LL | fn fail_double<'a, 'b>(x: &'a u32, y: &'a u32, z: &'b mut u32) -> &'a mut u32 {
    |                           ^^^^^^^     ^^^^^^^
 
-error: aborting due to 5 previous errors
+error: mutable borrow from immutable input(s)
+  --> $DIR/mut_from_ref.rs:44:35
+   |
+LL | unsafe fn also_broken(x: &u32) -> &mut u32 {
+   |                                   ^^^^^^^^
+   |
+note: immutable borrow here
+  --> $DIR/mut_from_ref.rs:44:26
+   |
+LL | unsafe fn also_broken(x: &u32) -> &mut u32 {
+   |                          ^^^^
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
index f00f9ee4c33..c1685f7b6d7 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.fixed
@@ -1,6 +1,11 @@
 // run-rustfix
 #![warn(clippy::needless_for_each)]
-#![allow(unused, clippy::needless_return, clippy::match_single_binding)]
+#![allow(
+    unused,
+    clippy::needless_return,
+    clippy::match_single_binding,
+    clippy::let_unit_value
+)]
 
 use std::collections::HashMap;
 
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
index 1bd400d348b..ad17b0956fa 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.rs
@@ -1,6 +1,11 @@
 // run-rustfix
 #![warn(clippy::needless_for_each)]
-#![allow(unused, clippy::needless_return, clippy::match_single_binding)]
+#![allow(
+    unused,
+    clippy::needless_return,
+    clippy::match_single_binding,
+    clippy::let_unit_value
+)]
 
 use std::collections::HashMap;
 
diff --git a/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr b/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr
index 6487e57266c..08e995851d7 100644
--- a/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_for_each_fixable.stderr
@@ -1,5 +1,5 @@
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:10:5
+  --> $DIR/needless_for_each_fixable.rs:15:5
    |
 LL | /     v.iter().for_each(|elem| {
 LL | |         acc += elem;
@@ -15,7 +15,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:13:5
+  --> $DIR/needless_for_each_fixable.rs:18:5
    |
 LL | /     v.into_iter().for_each(|elem| {
 LL | |         acc += elem;
@@ -30,7 +30,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:17:5
+  --> $DIR/needless_for_each_fixable.rs:22:5
    |
 LL | /     [1, 2, 3].iter().for_each(|elem| {
 LL | |         acc += elem;
@@ -45,7 +45,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:22:5
+  --> $DIR/needless_for_each_fixable.rs:27:5
    |
 LL | /     hash_map.iter().for_each(|(k, v)| {
 LL | |         acc += k + v;
@@ -60,7 +60,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:25:5
+  --> $DIR/needless_for_each_fixable.rs:30:5
    |
 LL | /     hash_map.iter_mut().for_each(|(k, v)| {
 LL | |         acc += *k + *v;
@@ -75,7 +75,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:28:5
+  --> $DIR/needless_for_each_fixable.rs:33:5
    |
 LL | /     hash_map.keys().for_each(|k| {
 LL | |         acc += k;
@@ -90,7 +90,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:31:5
+  --> $DIR/needless_for_each_fixable.rs:36:5
    |
 LL | /     hash_map.values().for_each(|v| {
 LL | |         acc += v;
@@ -105,7 +105,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:38:5
+  --> $DIR/needless_for_each_fixable.rs:43:5
    |
 LL | /     my_vec().iter().for_each(|elem| {
 LL | |         acc += elem;
diff --git a/src/tools/clippy/tests/ui/needless_late_init.rs b/src/tools/clippy/tests/ui/needless_late_init.rs
index 89e012c066f..54e66b391b8 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.rs
+++ b/src/tools/clippy/tests/ui/needless_late_init.rs
@@ -1,4 +1,15 @@
-#![allow(unused)]
+#![feature(let_chains)]
+#![allow(unused, clippy::nonminimal_bool, clippy::let_unit_value)]
+
+use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
+use std::rc::Rc;
+
+struct SignificantDrop;
+impl std::ops::Drop for SignificantDrop {
+    fn drop(&mut self) {
+        println!("dropped");
+    }
+}
 
 fn main() {
     let a;
@@ -17,13 +28,6 @@ fn main() {
         b = "five"
     }
 
-    let c;
-    if let Some(n) = Some(5) {
-        c = n;
-    } else {
-        c = -50;
-    }
-
     let d;
     if true {
         let temp = 5;
@@ -36,7 +40,7 @@ fn main() {
     if true {
         e = format!("{} {}", a, b);
     } else {
-        e = format!("{}", c);
+        e = format!("{}", n);
     }
 
     let f;
@@ -52,7 +56,27 @@ fn main() {
         panic!();
     }
 
-    println!("{}", a);
+    // Drop order only matters if both are significant
+    let x;
+    let y = SignificantDrop;
+    x = 1;
+
+    let x;
+    let y = 1;
+    x = SignificantDrop;
+
+    let x;
+    // types that should be considered insignificant
+    let y = 1;
+    let y = "2";
+    let y = String::new();
+    let y = vec![3.0];
+    let y = HashMap::<usize, usize>::new();
+    let y = BTreeMap::<usize, usize>::new();
+    let y = HashSet::<usize>::new();
+    let y = BTreeSet::<usize>::new();
+    let y = Box::new(4);
+    x = SignificantDrop;
 }
 
 async fn in_async() -> &'static str {
@@ -176,5 +200,32 @@ fn does_not_lint() {
     }
     in_macro!();
 
-    println!("{}", x);
+    // ignore if-lets - https://github.com/rust-lang/rust-clippy/issues/8613
+    let x;
+    if let Some(n) = Some("v") {
+        x = 1;
+    } else {
+        x = 2;
+    }
+
+    let x;
+    if true && let Some(n) = Some("let chains too") {
+        x = 1;
+    } else {
+        x = 2;
+    }
+
+    // ignore mut bindings
+    // https://github.com/shepmaster/twox-hash/blob/b169c16d86eb8ea4a296b0acb9d00ca7e3c3005f/src/sixty_four.rs#L88-L93
+    // https://github.com/dtolnay/thiserror/blob/21c26903e29cb92ba1a7ff11e82ae2001646b60d/tests/test_generics.rs#L91-L100
+    let mut x: usize;
+    x = 1;
+    x = 2;
+    x = 3;
+
+    // should not move the declaration if `x` has a significant drop, and there
+    // is another binding with a significant drop between it and the first usage
+    let x;
+    let y = SignificantDrop;
+    x = SignificantDrop;
 }
diff --git a/src/tools/clippy/tests/ui/needless_late_init.stderr b/src/tools/clippy/tests/ui/needless_late_init.stderr
index ef79e635d2a..d33a117b288 100644
--- a/src/tools/clippy/tests/ui/needless_late_init.stderr
+++ b/src/tools/clippy/tests/ui/needless_late_init.stderr
@@ -1,5 +1,5 @@
-error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:4:5
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:15:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -20,8 +20,8 @@ help: add a semicolon after the `match` expression
 LL |     };
    |      +
 
-error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:13:5
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:24:5
    |
 LL |     let b;
    |     ^^^^^^
@@ -41,29 +41,8 @@ help: add a semicolon after the `if` expression
 LL |     };
    |      +
 
-error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:20:5
-   |
-LL |     let c;
-   |     ^^^^^^
-   |
-help: declare `c` here
-   |
-LL |     let c = if let Some(n) = Some(5) {
-   |     +++++++
-help: remove the assignments from the branches
-   |
-LL ~         n
-LL |     } else {
-LL ~         -50
-   |
-help: add a semicolon after the `if` expression
-   |
-LL |     };
-   |      +
-
-error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:27:5
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:31:5
    |
 LL |     let d;
    |     ^^^^^^
@@ -83,8 +62,8 @@ help: add a semicolon after the `if` expression
 LL |     };
    |      +
 
-error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:35:5
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:39:5
    |
 LL |     let e;
    |     ^^^^^^
@@ -97,15 +76,15 @@ help: remove the assignments from the branches
    |
 LL ~         format!("{} {}", a, b)
 LL |     } else {
-LL ~         format!("{}", c)
+LL ~         format!("{}", n)
    |
 help: add a semicolon after the `if` expression
    |
 LL |     };
    |      +
 
-error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:42:5
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:46:5
    |
 LL |     let f;
    |     ^^^^^^
@@ -120,8 +99,8 @@ LL -         1 => f = "three",
 LL +         1 => "three",
    | 
 
-error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:48:5
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:52:5
    |
 LL |     let g: usize;
    |     ^^^^^^^^^^^^^
@@ -140,8 +119,50 @@ help: add a semicolon after the `if` expression
 LL |     };
    |      +
 
-error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:63:5
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:60:5
+   |
+LL |     let x;
+   |     ^^^^^^ created here
+LL |     let y = SignificantDrop;
+LL |     x = 1;
+   |     ^^^^^ initialised here
+   |
+help: declare `x` here
+   |
+LL |     let x = 1;
+   |     ~~~~~
+
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:64:5
+   |
+LL |     let x;
+   |     ^^^^^^ created here
+LL |     let y = 1;
+LL |     x = SignificantDrop;
+   |     ^^^^^^^^^^^^^^^^^^^ initialised here
+   |
+help: declare `x` here
+   |
+LL |     let x = SignificantDrop;
+   |     ~~~~~
+
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:68:5
+   |
+LL |     let x;
+   |     ^^^^^^ created here
+...
+LL |     x = SignificantDrop;
+   |     ^^^^^^^^^^^^^^^^^^^ initialised here
+   |
+help: declare `x` here
+   |
+LL |     let x = SignificantDrop;
+   |     ~~~~~
+
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:87:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -161,8 +182,8 @@ help: add a semicolon after the `match` expression
 LL |     };
    |      +
 
-error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:80:5
+error: unneeded late initialization
+  --> $DIR/needless_late_init.rs:104:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -182,5 +203,5 @@ help: add a semicolon after the `match` expression
 LL |     };
    |      +
 
-error: aborting due to 9 previous errors
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_late_init_fixable.fixed b/src/tools/clippy/tests/ui/needless_late_init_fixable.fixed
index b516f9d86b7..724477e8691 100644
--- a/src/tools/clippy/tests/ui/needless_late_init_fixable.fixed
+++ b/src/tools/clippy/tests/ui/needless_late_init_fixable.fixed
@@ -15,11 +15,5 @@ fn main() {
     let d: usize = 1;
 
     
-    let mut e = 1;
-    e = 2;
-
-    
-    let h = format!("{}", e);
-
-    println!("{}", a);
+    let e = format!("{}", d);
 }
diff --git a/src/tools/clippy/tests/ui/needless_late_init_fixable.rs b/src/tools/clippy/tests/ui/needless_late_init_fixable.rs
index 75a4bc916de..3e6bd363672 100644
--- a/src/tools/clippy/tests/ui/needless_late_init_fixable.rs
+++ b/src/tools/clippy/tests/ui/needless_late_init_fixable.rs
@@ -14,12 +14,6 @@ fn main() {
     let d: usize;
     d = 1;
 
-    let mut e;
-    e = 1;
-    e = 2;
-
-    let h;
-    h = format!("{}", e);
-
-    println!("{}", a);
+    let e;
+    e = format!("{}", d);
 }
diff --git a/src/tools/clippy/tests/ui/needless_late_init_fixable.stderr b/src/tools/clippy/tests/ui/needless_late_init_fixable.stderr
index 3f3d4f5286b..8c664309e3e 100644
--- a/src/tools/clippy/tests/ui/needless_late_init_fixable.stderr
+++ b/src/tools/clippy/tests/ui/needless_late_init_fixable.stderr
@@ -1,8 +1,10 @@
-error: unneeded late initalization
+error: unneeded late initialization
   --> $DIR/needless_late_init_fixable.rs:6:5
    |
 LL |     let a;
-   |     ^^^^^^
+   |     ^^^^^^ created here
+LL |     a = "zero";
+   |     ^^^^^^^^^^ initialised here
    |
    = note: `-D clippy::needless-late-init` implied by `-D warnings`
 help: declare `a` here
@@ -10,60 +12,59 @@ help: declare `a` here
 LL |     let a = "zero";
    |     ~~~~~
 
-error: unneeded late initalization
+error: unneeded late initialization
   --> $DIR/needless_late_init_fixable.rs:9:5
    |
 LL |     let b;
-   |     ^^^^^^
+   |     ^^^^^^ created here
+LL |     let c;
+LL |     b = 1;
+   |     ^^^^^ initialised here
    |
 help: declare `b` here
    |
 LL |     let b = 1;
    |     ~~~~~
 
-error: unneeded late initalization
+error: unneeded late initialization
   --> $DIR/needless_late_init_fixable.rs:10:5
    |
 LL |     let c;
-   |     ^^^^^^
+   |     ^^^^^^ created here
+LL |     b = 1;
+LL |     c = 2;
+   |     ^^^^^ initialised here
    |
 help: declare `c` here
    |
 LL |     let c = 2;
    |     ~~~~~
 
-error: unneeded late initalization
+error: unneeded late initialization
   --> $DIR/needless_late_init_fixable.rs:14:5
    |
 LL |     let d: usize;
-   |     ^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^ created here
+LL |     d = 1;
+   |     ^^^^^ initialised here
    |
 help: declare `d` here
    |
 LL |     let d: usize = 1;
    |     ~~~~~~~~~~~~
 
-error: unneeded late initalization
+error: unneeded late initialization
   --> $DIR/needless_late_init_fixable.rs:17:5
    |
-LL |     let mut e;
-   |     ^^^^^^^^^^
+LL |     let e;
+   |     ^^^^^^ created here
+LL |     e = format!("{}", d);
+   |     ^^^^^^^^^^^^^^^^^^^^ initialised here
    |
 help: declare `e` here
    |
-LL |     let mut e = 1;
-   |     ~~~~~~~~~
-
-error: unneeded late initalization
-  --> $DIR/needless_late_init_fixable.rs:21:5
-   |
-LL |     let h;
-   |     ^^^^^^
-   |
-help: declare `h` here
-   |
-LL |     let h = format!("{}", e);
+LL |     let e = format!("{}", d);
    |     ~~~~~
 
-error: aborting due to 6 previous errors
+error: aborting due to 5 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_match.fixed b/src/tools/clippy/tests/ui/needless_match.fixed
index 9ccccaa1725..b997e5316cf 100644
--- a/src/tools/clippy/tests/ui/needless_match.fixed
+++ b/src/tools/clippy/tests/ui/needless_match.fixed
@@ -80,6 +80,18 @@ fn if_let_option() {
     } else {
         None
     };
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) { Some(a) } else { Some(2) };
+}
+
+fn if_let_option_result() -> Result<(), ()> {
+    fn f(x: i32) -> Result<Option<i32>, ()> {
+        Ok(Some(x))
+    }
+    // Don't trigger
+    let _ = if let Some(v) = f(1)? { Some(v) } else { f(2)? };
+    Ok(())
 }
 
 fn if_let_result() {
diff --git a/src/tools/clippy/tests/ui/needless_match.rs b/src/tools/clippy/tests/ui/needless_match.rs
index d210ecff7f1..90482775a1e 100644
--- a/src/tools/clippy/tests/ui/needless_match.rs
+++ b/src/tools/clippy/tests/ui/needless_match.rs
@@ -103,6 +103,18 @@ fn if_let_option() {
     } else {
         None
     };
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) { Some(a) } else { Some(2) };
+}
+
+fn if_let_option_result() -> Result<(), ()> {
+    fn f(x: i32) -> Result<Option<i32>, ()> {
+        Ok(Some(x))
+    }
+    // Don't trigger
+    let _ = if let Some(v) = f(1)? { Some(v) } else { f(2)? };
+    Ok(())
 }
 
 fn if_let_result() {
diff --git a/src/tools/clippy/tests/ui/needless_match.stderr b/src/tools/clippy/tests/ui/needless_match.stderr
index 34c5226f060..2d679631c6f 100644
--- a/src/tools/clippy/tests/ui/needless_match.stderr
+++ b/src/tools/clippy/tests/ui/needless_match.stderr
@@ -72,19 +72,19 @@ LL |     let _ = if let Some(a) = Some(1) { Some(a) } else { None };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:110:31
+  --> $DIR/needless_match.rs:122:31
    |
 LL |     let _: Result<i32, i32> = if let Err(e) = x { Err(e) } else { x };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:111:31
+  --> $DIR/needless_match.rs:123:31
    |
 LL |     let _: Result<i32, i32> = if let Ok(val) = x { Ok(val) } else { x };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:117:21
+  --> $DIR/needless_match.rs:129:21
    |
 LL |       let _: Simple = if let Simple::A = x {
    |  _____________________^
@@ -97,7 +97,7 @@ LL | |     };
    | |_____^ help: replace it with: `x`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:156:26
+  --> $DIR/needless_match.rs:168:26
    |
 LL |           let _: Complex = match ce {
    |  __________________________^
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
index c09b07db3dc..acd22c6bb43 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
@@ -16,6 +16,20 @@ fn main() {
     let _ = Some(Box::new(1)).as_deref();
     let _ = Some(Box::new(1)).as_deref_mut();
 
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    for _ in 0..3 {
+        let _ = x.as_deref_mut();
+    }
+
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    let mut closure = || {
+        let _ = x.as_deref_mut();
+    };
+    closure();
+    closure();
+
     // #7846
     let mut i = 0;
     let mut opt_vec = vec![Some(&mut i)];
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.rs b/src/tools/clippy/tests/ui/needless_option_as_deref.rs
index c3ba27ecccf..61eda5052a2 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.rs
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.rs
@@ -16,6 +16,20 @@ fn main() {
     let _ = Some(Box::new(1)).as_deref();
     let _ = Some(Box::new(1)).as_deref_mut();
 
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    for _ in 0..3 {
+        let _ = x.as_deref_mut();
+    }
+
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    let mut closure = || {
+        let _ = x.as_deref_mut();
+    };
+    closure();
+    closure();
+
     // #7846
     let mut i = 0;
     let mut opt_vec = vec![Some(&mut i)];
diff --git a/src/tools/clippy/tests/ui/needless_option_take.fixed b/src/tools/clippy/tests/ui/needless_option_take.fixed
new file mode 100644
index 00000000000..29691e81666
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_option_take.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+
+fn main() {
+    println!("Testing non erroneous option_take_on_temporary");
+    let mut option = Some(1);
+    let _ = Box::new(move || option.take().unwrap());
+
+    println!("Testing non erroneous option_take_on_temporary");
+    let x = Some(3);
+    x.as_ref();
+
+    println!("Testing erroneous option_take_on_temporary");
+    let x = Some(3);
+    x.as_ref();
+}
diff --git a/src/tools/clippy/tests/ui/needless_option_take.rs b/src/tools/clippy/tests/ui/needless_option_take.rs
new file mode 100644
index 00000000000..9f4109eb463
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_option_take.rs
@@ -0,0 +1,15 @@
+// run-rustfix
+
+fn main() {
+    println!("Testing non erroneous option_take_on_temporary");
+    let mut option = Some(1);
+    let _ = Box::new(move || option.take().unwrap());
+
+    println!("Testing non erroneous option_take_on_temporary");
+    let x = Some(3);
+    x.as_ref();
+
+    println!("Testing erroneous option_take_on_temporary");
+    let x = Some(3);
+    x.as_ref().take();
+}
diff --git a/src/tools/clippy/tests/ui/needless_option_take.stderr b/src/tools/clippy/tests/ui/needless_option_take.stderr
new file mode 100644
index 00000000000..cb3bf015b36
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_option_take.stderr
@@ -0,0 +1,10 @@
+error: called `Option::take()` on a temporary value
+  --> $DIR/needless_option_take.rs:14:5
+   |
+LL |     x.as_ref().take();
+   |     ^^^^^^^^^^^^^^^^^ help: try: `x.as_ref()`
+   |
+   = note: `-D clippy::needless-option-take` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/needless_splitn.fixed b/src/tools/clippy/tests/ui/needless_splitn.fixed
index f6a4b2f17d3..61f5fc4e679 100644
--- a/src/tools/clippy/tests/ui/needless_splitn.fixed
+++ b/src/tools/clippy/tests/ui/needless_splitn.fixed
@@ -24,4 +24,24 @@ fn main() {
     let _ = str.rsplitn(2, '=').nth(1);
     let (_, _) = str.rsplitn(2, '=').next_tuple().unwrap();
     let (_, _) = str.rsplit('=').next_tuple().unwrap();
+
+    let _ = str.split('=').next();
+    let _ = str.split('=').nth(3);
+    let _ = str.splitn(5, '=').nth(4);
+    let _ = str.splitn(5, '=').nth(5);
+}
+
+fn _question_mark(s: &str) -> Option<()> {
+    let _ = s.split('=').next()?;
+    let _ = s.split('=').nth(0)?;
+    let _ = s.rsplit('=').next()?;
+    let _ = s.rsplit('=').nth(0)?;
+
+    Some(())
+}
+
+fn _test_msrv() {
+    #![clippy::msrv = "1.51"]
+    // `manual_split_once` MSRV shouldn't apply to `needless_splitn`
+    let _ = "key=value".split('=').nth(0).unwrap();
 }
diff --git a/src/tools/clippy/tests/ui/needless_splitn.rs b/src/tools/clippy/tests/ui/needless_splitn.rs
index 6ba32255bb2..71d9a7077fa 100644
--- a/src/tools/clippy/tests/ui/needless_splitn.rs
+++ b/src/tools/clippy/tests/ui/needless_splitn.rs
@@ -24,4 +24,24 @@ fn main() {
     let _ = str.rsplitn(2, '=').nth(1);
     let (_, _) = str.rsplitn(2, '=').next_tuple().unwrap();
     let (_, _) = str.rsplitn(3, '=').next_tuple().unwrap();
+
+    let _ = str.splitn(5, '=').next();
+    let _ = str.splitn(5, '=').nth(3);
+    let _ = str.splitn(5, '=').nth(4);
+    let _ = str.splitn(5, '=').nth(5);
+}
+
+fn _question_mark(s: &str) -> Option<()> {
+    let _ = s.splitn(2, '=').next()?;
+    let _ = s.splitn(2, '=').nth(0)?;
+    let _ = s.rsplitn(2, '=').next()?;
+    let _ = s.rsplitn(2, '=').nth(0)?;
+
+    Some(())
+}
+
+fn _test_msrv() {
+    #![clippy::msrv = "1.51"]
+    // `manual_split_once` MSRV shouldn't apply to `needless_splitn`
+    let _ = "key=value".splitn(2, '=').nth(0).unwrap();
 }
diff --git a/src/tools/clippy/tests/ui/needless_splitn.stderr b/src/tools/clippy/tests/ui/needless_splitn.stderr
index 66de2256554..f112b29e7f2 100644
--- a/src/tools/clippy/tests/ui/needless_splitn.stderr
+++ b/src/tools/clippy/tests/ui/needless_splitn.stderr
@@ -36,5 +36,47 @@ error: unnecessary use of `rsplitn`
 LL |     let (_, _) = str.rsplitn(3, '=').next_tuple().unwrap();
    |                  ^^^^^^^^^^^^^^^^^^^ help: try this: `str.rsplit('=')`
 
-error: aborting due to 6 previous errors
+error: unnecessary use of `splitn`
+  --> $DIR/needless_splitn.rs:28:13
+   |
+LL |     let _ = str.splitn(5, '=').next();
+   |             ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')`
+
+error: unnecessary use of `splitn`
+  --> $DIR/needless_splitn.rs:29:13
+   |
+LL |     let _ = str.splitn(5, '=').nth(3);
+   |             ^^^^^^^^^^^^^^^^^^ help: try this: `str.split('=')`
+
+error: unnecessary use of `splitn`
+  --> $DIR/needless_splitn.rs:35:13
+   |
+LL |     let _ = s.splitn(2, '=').next()?;
+   |             ^^^^^^^^^^^^^^^^ help: try this: `s.split('=')`
+
+error: unnecessary use of `splitn`
+  --> $DIR/needless_splitn.rs:36:13
+   |
+LL |     let _ = s.splitn(2, '=').nth(0)?;
+   |             ^^^^^^^^^^^^^^^^ help: try this: `s.split('=')`
+
+error: unnecessary use of `rsplitn`
+  --> $DIR/needless_splitn.rs:37:13
+   |
+LL |     let _ = s.rsplitn(2, '=').next()?;
+   |             ^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit('=')`
+
+error: unnecessary use of `rsplitn`
+  --> $DIR/needless_splitn.rs:38:13
+   |
+LL |     let _ = s.rsplitn(2, '=').nth(0)?;
+   |             ^^^^^^^^^^^^^^^^^ help: try this: `s.rsplit('=')`
+
+error: unnecessary use of `splitn`
+  --> $DIR/needless_splitn.rs:46:13
+   |
+LL |     let _ = "key=value".splitn(2, '=').nth(0).unwrap();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `"key=value".split('=')`
+
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/new_without_default.rs b/src/tools/clippy/tests/ui/new_without_default.rs
index e94f99c95f4..538927b1805 100644
--- a/src/tools/clippy/tests/ui/new_without_default.rs
+++ b/src/tools/clippy/tests/ui/new_without_default.rs
@@ -1,4 +1,4 @@
-#![allow(dead_code, clippy::missing_safety_doc)]
+#![allow(dead_code, clippy::missing_safety_doc, clippy::extra_unused_lifetimes)]
 #![warn(clippy::new_without_default)]
 
 pub struct Foo;
diff --git a/src/tools/clippy/tests/ui/non_expressive_names.rs b/src/tools/clippy/tests/ui/non_expressive_names.rs
index 9937005d68d..583096ac054 100644
--- a/src/tools/clippy/tests/ui/non_expressive_names.rs
+++ b/src/tools/clippy/tests/ui/non_expressive_names.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::all)]
-#![allow(unused, clippy::println_empty_string, non_snake_case)]
+#![allow(unused, clippy::println_empty_string, non_snake_case, clippy::let_unit_value)]
 
 #[derive(Clone, Debug)]
 enum MaybeInst {
diff --git a/src/tools/clippy/tests/ui/numbered_fields.fixed b/src/tools/clippy/tests/ui/numbered_fields.fixed
index 1da97e96879..3710b3e9c81 100644
--- a/src/tools/clippy/tests/ui/numbered_fields.fixed
+++ b/src/tools/clippy/tests/ui/numbered_fields.fixed
@@ -30,4 +30,9 @@ fn main() {
 
     // Ok because it's in macro
     let _ = tuple_struct_init!();
+
+    type Alias = TupleStruct;
+
+    // Aliases can't be tuple constructed #8638
+    let _ = Alias { 0: 0, 1: 1, 2: 2 };
 }
diff --git a/src/tools/clippy/tests/ui/numbered_fields.rs b/src/tools/clippy/tests/ui/numbered_fields.rs
index 08ec405a560..2af84bc0642 100644
--- a/src/tools/clippy/tests/ui/numbered_fields.rs
+++ b/src/tools/clippy/tests/ui/numbered_fields.rs
@@ -38,4 +38,9 @@ fn main() {
 
     // Ok because it's in macro
     let _ = tuple_struct_init!();
+
+    type Alias = TupleStruct;
+
+    // Aliases can't be tuple constructed #8638
+    let _ = Alias { 0: 0, 1: 1, 2: 2 };
 }
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 7790c816481..e12e13a57f1 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.fixed
+++ b/src/tools/clippy/tests/ui/option_if_let_else.fixed
@@ -1,6 +1,11 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
-#![allow(clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let)]
+#![allow(
+    clippy::redundant_closure,
+    clippy::ref_option_ref,
+    clippy::equatable_if_let,
+    clippy::let_unit_value
+)]
 
 fn bad1(string: Option<&str>) -> (bool, &str) {
     string.map_or((false, "hello"), |x| (true, x))
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 3d9f76ee4a6..b5206fc26a9 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.rs
+++ b/src/tools/clippy/tests/ui/option_if_let_else.rs
@@ -1,6 +1,11 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
-#![allow(clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let)]
+#![allow(
+    clippy::redundant_closure,
+    clippy::ref_option_ref,
+    clippy::equatable_if_let,
+    clippy::let_unit_value
+)]
 
 fn bad1(string: Option<&str>) -> (bool, &str) {
     if let Some(x) = string {
diff --git a/src/tools/clippy/tests/ui/option_if_let_else.stderr b/src/tools/clippy/tests/ui/option_if_let_else.stderr
index 546131ceb5b..40aef977b98 100644
--- a/src/tools/clippy/tests/ui/option_if_let_else.stderr
+++ b/src/tools/clippy/tests/ui/option_if_let_else.stderr
@@ -1,5 +1,5 @@
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:6:5
+  --> $DIR/option_if_let_else.rs:11:5
    |
 LL | /     if let Some(x) = string {
 LL | |         (true, x)
@@ -11,19 +11,19 @@ LL | |     }
    = note: `-D clippy::option-if-let-else` implied by `-D warnings`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:24:13
+  --> $DIR/option_if_let_else.rs:29:13
    |
 LL |     let _ = if let Some(s) = *string { s.len() } else { 0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:25:13
+  --> $DIR/option_if_let_else.rs:30:13
    |
 LL |     let _ = if let Some(s) = &num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:26:13
+  --> $DIR/option_if_let_else.rs:31:13
    |
 LL |       let _ = if let Some(s) = &mut num {
    |  _____________^
@@ -43,13 +43,13 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:32:13
+  --> $DIR/option_if_let_else.rs:37:13
    |
 LL |     let _ = if let Some(ref s) = num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:33:13
+  --> $DIR/option_if_let_else.rs:38:13
    |
 LL |       let _ = if let Some(mut s) = num {
    |  _____________^
@@ -69,7 +69,7 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:39:13
+  --> $DIR/option_if_let_else.rs:44:13
    |
 LL |       let _ = if let Some(ref mut s) = num {
    |  _____________^
@@ -89,7 +89,7 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:48:5
+  --> $DIR/option_if_let_else.rs:53:5
    |
 LL | /     if let Some(x) = arg {
 LL | |         let y = x * x;
@@ -108,7 +108,7 @@ LL +     })
    |
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:61:13
+  --> $DIR/option_if_let_else.rs:66:13
    |
 LL |       let _ = if let Some(x) = arg {
    |  _____________^
@@ -120,7 +120,7 @@ LL | |     };
    | |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)`
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:70:13
+  --> $DIR/option_if_let_else.rs:75:13
    |
 LL |       let _ = if let Some(x) = arg {
    |  _____________^
@@ -143,7 +143,7 @@ LL ~     }, |x| x * x * x * x);
    |
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:103:13
+  --> $DIR/option_if_let_else.rs:108:13
    |
 LL | /             if let Some(idx) = s.find('.') {
 LL | |                 vec![s[..idx].to_string(), s[idx..].to_string()]
@@ -153,13 +153,13 @@ LL | |             }
    | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:127:13
+  --> $DIR/option_if_let_else.rs:132:13
    |
 LL |     let _ = if let Some(x) = optional { x + 2 } else { 5 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:136:13
+  --> $DIR/option_if_let_else.rs:141:13
    |
 LL |       let _ = if let Some(x) = Some(0) {
    |  _____________^
@@ -181,13 +181,13 @@ LL ~         });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:164:13
+  --> $DIR/option_if_let_else.rs:169:13
    |
 LL |     let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:168:13
+  --> $DIR/option_if_let_else.rs:173:13
    |
 LL |       let _ = if let Some(x) = Some(0) {
    |  _____________^
diff --git a/src/tools/clippy/tests/ui/option_take_on_temporary.fixed b/src/tools/clippy/tests/ui/option_take_on_temporary.fixed
new file mode 100644
index 00000000000..29691e81666
--- /dev/null
+++ b/src/tools/clippy/tests/ui/option_take_on_temporary.fixed
@@ -0,0 +1,15 @@
+// run-rustfix
+
+fn main() {
+    println!("Testing non erroneous option_take_on_temporary");
+    let mut option = Some(1);
+    let _ = Box::new(move || option.take().unwrap());
+
+    println!("Testing non erroneous option_take_on_temporary");
+    let x = Some(3);
+    x.as_ref();
+
+    println!("Testing erroneous option_take_on_temporary");
+    let x = Some(3);
+    x.as_ref();
+}
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.fixed b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
index 6e0d5a87f68..844cc4b7a09 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.fixed
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::or_then_unwrap)]
-#![allow(clippy::map_identity)]
+#![allow(clippy::map_identity, clippy::let_unit_value)]
 
 struct SomeStruct;
 impl SomeStruct {
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.rs b/src/tools/clippy/tests/ui/or_then_unwrap.rs
index e406a71d46d..1528ef9be96 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.rs
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.rs
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::or_then_unwrap)]
-#![allow(clippy::map_identity)]
+#![allow(clippy::map_identity, clippy::let_unit_value)]
 
 struct SomeStruct;
 impl SomeStruct {
diff --git a/src/tools/clippy/tests/ui/panicking_macros.rs b/src/tools/clippy/tests/ui/panicking_macros.rs
index 12a0c776ae2..041ef17fa68 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.rs
+++ b/src/tools/clippy/tests/ui/panicking_macros.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::assertions_on_constants, clippy::eq_op)]
+#![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::let_unit_value)]
 #![feature(inline_const)]
 #![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]
 
diff --git a/src/tools/clippy/tests/ui/pub_use.rs b/src/tools/clippy/tests/ui/pub_use.rs
new file mode 100644
index 00000000000..65542bedec7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/pub_use.rs
@@ -0,0 +1,14 @@
+#![warn(clippy::pub_use)]
+#![allow(unused_imports)]
+#![no_main]
+
+pub mod outer {
+    mod inner {
+        pub struct Test {}
+    }
+    // should be linted
+    pub use inner::Test;
+}
+
+// should not be linted
+use std::fmt;
diff --git a/src/tools/clippy/tests/ui/pub_use.stderr b/src/tools/clippy/tests/ui/pub_use.stderr
new file mode 100644
index 00000000000..9ab710df818
--- /dev/null
+++ b/src/tools/clippy/tests/ui/pub_use.stderr
@@ -0,0 +1,11 @@
+error: using `pub use`
+  --> $DIR/pub_use.rs:10:5
+   |
+LL |     pub use inner::Test;
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::pub-use` implied by `-D warnings`
+   = help: move the exported item to a public module instead
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.fixed b/src/tools/clippy/tests/ui/redundant_pub_crate.fixed
index 25f2fd061b8..106947de68c 100644
--- a/src/tools/clippy/tests/ui/redundant_pub_crate.fixed
+++ b/src/tools/clippy/tests/ui/redundant_pub_crate.fixed
@@ -104,4 +104,14 @@ mod m4 {
 
 pub use m4::*;
 
+mod issue_8732 {
+    #[allow(unused_macros)]
+    macro_rules! some_macro {
+        () => {};
+    }
+
+    #[allow(unused_imports)]
+    pub(crate) use some_macro; // ok: macro exports are exempt
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/redundant_pub_crate.rs b/src/tools/clippy/tests/ui/redundant_pub_crate.rs
index 616286b4f39..f96cfd31843 100644
--- a/src/tools/clippy/tests/ui/redundant_pub_crate.rs
+++ b/src/tools/clippy/tests/ui/redundant_pub_crate.rs
@@ -104,4 +104,14 @@ mod m4 {
 
 pub use m4::*;
 
+mod issue_8732 {
+    #[allow(unused_macros)]
+    macro_rules! some_macro {
+        () => {};
+    }
+
+    #[allow(unused_imports)]
+    pub(crate) use some_macro; // ok: macro exports are exempt
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/rename.fixed b/src/tools/clippy/tests/ui/rename.fixed
index 24a0c812291..9c4079ad6d3 100644
--- a/src/tools/clippy/tests/ui/rename.fixed
+++ b/src/tools/clippy/tests/ui/rename.fixed
@@ -1,71 +1,70 @@
-//! Test for Clippy lint renames.
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
 // run-rustfix
 
-#![allow(dead_code)]
-// allow the new lint name here, to test if the new name works
-#![allow(clippy::module_name_repetitions)]
-#![allow(clippy::new_without_default)]
+#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::box_collection)]
 #![allow(clippy::redundant_static_lifetimes)]
 #![allow(clippy::cognitive_complexity)]
+#![allow(clippy::disallowed_methods)]
+#![allow(clippy::disallowed_types)]
+#![allow(clippy::for_loops_over_fallibles)]
+#![allow(clippy::useless_conversion)]
+#![allow(clippy::match_result_ok)]
+#![allow(clippy::new_without_default)]
 #![allow(clippy::bind_instead_of_map)]
-#![allow(clippy::box_collection)]
-#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::expect_used)]
 #![allow(clippy::map_unwrap_or)]
 #![allow(clippy::unwrap_used)]
-#![allow(clippy::expect_used)]
-#![allow(clippy::for_loops_over_fallibles)]
-#![allow(clippy::useless_conversion)]
-#![allow(clippy::invisible_characters)]
+#![allow(clippy::needless_borrow)]
 #![allow(clippy::single_char_add_str)]
-#![allow(clippy::match_result_ok)]
-#![allow(clippy::disallowed_types)]
-#![allow(clippy::disallowed_methods)]
+#![allow(clippy::module_name_repetitions)]
 #![allow(clippy::recursive_format_impl)]
-// uplifted lints
-#![allow(invalid_value)]
-#![allow(array_into_iter)]
-#![allow(unused_labels)]
+#![allow(clippy::invisible_characters)]
 #![allow(drop_bounds)]
-#![allow(temporary_cstring_as_ptr)]
-#![allow(non_fmt_panics)]
-#![allow(unknown_lints)]
+#![allow(array_into_iter)]
 #![allow(invalid_atomic_ordering)]
+#![allow(invalid_value)]
 #![allow(enum_intrinsics_non_enums)]
-// warn for the old lint name here, to test if the renaming worked
-#![warn(clippy::module_name_repetitions)]
-#![warn(clippy::new_without_default)]
+#![allow(non_fmt_panics)]
+#![allow(temporary_cstring_as_ptr)]
+#![allow(unknown_lints)]
+#![allow(unused_labels)]
+#![warn(clippy::blocks_in_if_conditions)]
+#![warn(clippy::blocks_in_if_conditions)]
+#![warn(clippy::box_collection)]
 #![warn(clippy::redundant_static_lifetimes)]
 #![warn(clippy::cognitive_complexity)]
+#![warn(clippy::disallowed_methods)]
+#![warn(clippy::disallowed_types)]
+#![warn(clippy::for_loops_over_fallibles)]
+#![warn(clippy::for_loops_over_fallibles)]
+#![warn(clippy::useless_conversion)]
+#![warn(clippy::match_result_ok)]
+#![warn(clippy::new_without_default)]
 #![warn(clippy::bind_instead_of_map)]
-#![warn(clippy::box_collection)]
-#![warn(clippy::blocks_in_if_conditions)]
-#![warn(clippy::blocks_in_if_conditions)]
-#![warn(clippy::map_unwrap_or)]
+#![warn(clippy::expect_used)]
 #![warn(clippy::map_unwrap_or)]
 #![warn(clippy::map_unwrap_or)]
 #![warn(clippy::unwrap_used)]
-#![warn(clippy::unwrap_used)]
-#![warn(clippy::expect_used)]
+#![warn(clippy::needless_borrow)]
 #![warn(clippy::expect_used)]
-#![warn(clippy::for_loops_over_fallibles)]
-#![warn(clippy::for_loops_over_fallibles)]
-#![warn(clippy::useless_conversion)]
-#![warn(clippy::invisible_characters)]
+#![warn(clippy::map_unwrap_or)]
+#![warn(clippy::unwrap_used)]
 #![warn(clippy::single_char_add_str)]
-#![warn(clippy::match_result_ok)]
-#![warn(clippy::disallowed_types)]
-#![warn(clippy::disallowed_methods)]
-#![warn(clippy::needless_borrow)]
+#![warn(clippy::module_name_repetitions)]
 #![warn(clippy::recursive_format_impl)]
-// uplifted lints
-#![warn(invalid_value)]
-#![warn(array_into_iter)]
-#![warn(unused_labels)]
+#![warn(clippy::invisible_characters)]
 #![warn(drop_bounds)]
-#![warn(temporary_cstring_as_ptr)]
-#![warn(non_fmt_panics)]
-#![warn(unknown_lints)]
+#![warn(array_into_iter)]
 #![warn(invalid_atomic_ordering)]
+#![warn(invalid_value)]
 #![warn(enum_intrinsics_non_enums)]
+#![warn(non_fmt_panics)]
+#![warn(temporary_cstring_as_ptr)]
+#![warn(unknown_lints)]
+#![warn(unused_labels)]
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/rename.rs b/src/tools/clippy/tests/ui/rename.rs
index ea64234c680..e83e66b7fbd 100644
--- a/src/tools/clippy/tests/ui/rename.rs
+++ b/src/tools/clippy/tests/ui/rename.rs
@@ -1,71 +1,70 @@
-//! Test for Clippy lint renames.
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
 // run-rustfix
 
-#![allow(dead_code)]
-// allow the new lint name here, to test if the new name works
-#![allow(clippy::module_name_repetitions)]
-#![allow(clippy::new_without_default)]
+#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::box_collection)]
 #![allow(clippy::redundant_static_lifetimes)]
 #![allow(clippy::cognitive_complexity)]
+#![allow(clippy::disallowed_methods)]
+#![allow(clippy::disallowed_types)]
+#![allow(clippy::for_loops_over_fallibles)]
+#![allow(clippy::useless_conversion)]
+#![allow(clippy::match_result_ok)]
+#![allow(clippy::new_without_default)]
 #![allow(clippy::bind_instead_of_map)]
-#![allow(clippy::box_collection)]
-#![allow(clippy::blocks_in_if_conditions)]
+#![allow(clippy::expect_used)]
 #![allow(clippy::map_unwrap_or)]
 #![allow(clippy::unwrap_used)]
-#![allow(clippy::expect_used)]
-#![allow(clippy::for_loops_over_fallibles)]
-#![allow(clippy::useless_conversion)]
-#![allow(clippy::invisible_characters)]
+#![allow(clippy::needless_borrow)]
 #![allow(clippy::single_char_add_str)]
-#![allow(clippy::match_result_ok)]
-#![allow(clippy::disallowed_types)]
-#![allow(clippy::disallowed_methods)]
+#![allow(clippy::module_name_repetitions)]
 #![allow(clippy::recursive_format_impl)]
-// uplifted lints
-#![allow(invalid_value)]
-#![allow(array_into_iter)]
-#![allow(unused_labels)]
+#![allow(clippy::invisible_characters)]
 #![allow(drop_bounds)]
-#![allow(temporary_cstring_as_ptr)]
-#![allow(non_fmt_panics)]
-#![allow(unknown_lints)]
+#![allow(array_into_iter)]
 #![allow(invalid_atomic_ordering)]
+#![allow(invalid_value)]
 #![allow(enum_intrinsics_non_enums)]
-// warn for the old lint name here, to test if the renaming worked
-#![warn(clippy::stutter)]
-#![warn(clippy::new_without_default_derive)]
+#![allow(non_fmt_panics)]
+#![allow(temporary_cstring_as_ptr)]
+#![allow(unknown_lints)]
+#![allow(unused_labels)]
+#![warn(clippy::block_in_if_condition_expr)]
+#![warn(clippy::block_in_if_condition_stmt)]
+#![warn(clippy::box_vec)]
 #![warn(clippy::const_static_lifetime)]
 #![warn(clippy::cyclomatic_complexity)]
+#![warn(clippy::disallowed_method)]
+#![warn(clippy::disallowed_type)]
+#![warn(clippy::for_loop_over_option)]
+#![warn(clippy::for_loop_over_result)]
+#![warn(clippy::identity_conversion)]
+#![warn(clippy::if_let_some_result)]
+#![warn(clippy::new_without_default_derive)]
 #![warn(clippy::option_and_then_some)]
-#![warn(clippy::box_vec)]
-#![warn(clippy::block_in_if_condition_expr)]
-#![warn(clippy::block_in_if_condition_stmt)]
+#![warn(clippy::option_expect_used)]
 #![warn(clippy::option_map_unwrap_or)]
 #![warn(clippy::option_map_unwrap_or_else)]
-#![warn(clippy::result_map_unwrap_or_else)]
 #![warn(clippy::option_unwrap_used)]
-#![warn(clippy::result_unwrap_used)]
-#![warn(clippy::option_expect_used)]
+#![warn(clippy::ref_in_deref)]
 #![warn(clippy::result_expect_used)]
-#![warn(clippy::for_loop_over_option)]
-#![warn(clippy::for_loop_over_result)]
-#![warn(clippy::identity_conversion)]
-#![warn(clippy::zero_width_space)]
+#![warn(clippy::result_map_unwrap_or_else)]
+#![warn(clippy::result_unwrap_used)]
 #![warn(clippy::single_char_push_str)]
-#![warn(clippy::if_let_some_result)]
-#![warn(clippy::disallowed_type)]
-#![warn(clippy::disallowed_method)]
-#![warn(clippy::ref_in_deref)]
+#![warn(clippy::stutter)]
 #![warn(clippy::to_string_in_display)]
-// uplifted lints
-#![warn(clippy::invalid_ref)]
-#![warn(clippy::into_iter_on_array)]
-#![warn(clippy::unused_label)]
+#![warn(clippy::zero_width_space)]
 #![warn(clippy::drop_bounds)]
-#![warn(clippy::temporary_cstring_as_ptr)]
-#![warn(clippy::panic_params)]
-#![warn(clippy::unknown_clippy_lints)]
+#![warn(clippy::into_iter_on_array)]
 #![warn(clippy::invalid_atomic_ordering)]
+#![warn(clippy::invalid_ref)]
 #![warn(clippy::mem_discriminant_non_enum)]
+#![warn(clippy::panic_params)]
+#![warn(clippy::temporary_cstring_as_ptr)]
+#![warn(clippy::unknown_clippy_lints)]
+#![warn(clippy::unused_label)]
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/rename.stderr b/src/tools/clippy/tests/ui/rename.stderr
index 8b132a78384..f811b10d017 100644
--- a/src/tools/clippy/tests/ui/rename.stderr
+++ b/src/tools/clippy/tests/ui/rename.stderr
@@ -1,82 +1,82 @@
-error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
+error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
   --> $DIR/rename.rs:35:9
    |
-LL | #![warn(clippy::stutter)]
-   |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
+LL | #![warn(clippy::block_in_if_condition_expr)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
    |
    = note: `-D renamed-and-removed-lints` implied by `-D warnings`
 
-error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
+error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
   --> $DIR/rename.rs:36:9
    |
-LL | #![warn(clippy::new_without_default_derive)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
+LL | #![warn(clippy::block_in_if_condition_stmt)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
 
-error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
+error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
   --> $DIR/rename.rs:37:9
    |
+LL | #![warn(clippy::box_vec)]
+   |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
+
+error: lint `clippy::const_static_lifetime` has been renamed to `clippy::redundant_static_lifetimes`
+  --> $DIR/rename.rs:38:9
+   |
 LL | #![warn(clippy::const_static_lifetime)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::redundant_static_lifetimes`
 
 error: lint `clippy::cyclomatic_complexity` has been renamed to `clippy::cognitive_complexity`
-  --> $DIR/rename.rs:38:9
+  --> $DIR/rename.rs:39:9
    |
 LL | #![warn(clippy::cyclomatic_complexity)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::cognitive_complexity`
 
-error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
-  --> $DIR/rename.rs:39:9
-   |
-LL | #![warn(clippy::option_and_then_some)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
-
-error: lint `clippy::box_vec` has been renamed to `clippy::box_collection`
+error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
   --> $DIR/rename.rs:40:9
    |
-LL | #![warn(clippy::box_vec)]
-   |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::box_collection`
+LL | #![warn(clippy::disallowed_method)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
 
-error: lint `clippy::block_in_if_condition_expr` has been renamed to `clippy::blocks_in_if_conditions`
+error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
   --> $DIR/rename.rs:41:9
    |
-LL | #![warn(clippy::block_in_if_condition_expr)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
+LL | #![warn(clippy::disallowed_type)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
 
-error: lint `clippy::block_in_if_condition_stmt` has been renamed to `clippy::blocks_in_if_conditions`
+error: lint `clippy::for_loop_over_option` has been renamed to `clippy::for_loops_over_fallibles`
   --> $DIR/rename.rs:42:9
    |
-LL | #![warn(clippy::block_in_if_condition_stmt)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::blocks_in_if_conditions`
+LL | #![warn(clippy::for_loop_over_option)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
 
-error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
+error: lint `clippy::for_loop_over_result` has been renamed to `clippy::for_loops_over_fallibles`
   --> $DIR/rename.rs:43:9
    |
-LL | #![warn(clippy::option_map_unwrap_or)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
+LL | #![warn(clippy::for_loop_over_result)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
 
-error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
+error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
   --> $DIR/rename.rs:44:9
    |
-LL | #![warn(clippy::option_map_unwrap_or_else)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
+LL | #![warn(clippy::identity_conversion)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
 
-error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
+error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
   --> $DIR/rename.rs:45:9
    |
-LL | #![warn(clippy::result_map_unwrap_or_else)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
+LL | #![warn(clippy::if_let_some_result)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
 
-error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
+error: lint `clippy::new_without_default_derive` has been renamed to `clippy::new_without_default`
   --> $DIR/rename.rs:46:9
    |
-LL | #![warn(clippy::option_unwrap_used)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
+LL | #![warn(clippy::new_without_default_derive)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::new_without_default`
 
-error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
+error: lint `clippy::option_and_then_some` has been renamed to `clippy::bind_instead_of_map`
   --> $DIR/rename.rs:47:9
    |
-LL | #![warn(clippy::result_unwrap_used)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
+LL | #![warn(clippy::option_and_then_some)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::bind_instead_of_map`
 
 error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_used`
   --> $DIR/rename.rs:48:9
@@ -84,107 +84,113 @@ error: lint `clippy::option_expect_used` has been renamed to `clippy::expect_use
 LL | #![warn(clippy::option_expect_used)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
-error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
+error: lint `clippy::option_map_unwrap_or` has been renamed to `clippy::map_unwrap_or`
   --> $DIR/rename.rs:49:9
    |
-LL | #![warn(clippy::result_expect_used)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
+LL | #![warn(clippy::option_map_unwrap_or)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
-error: lint `clippy::for_loop_over_option` has been renamed to `clippy::for_loops_over_fallibles`
+error: lint `clippy::option_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
   --> $DIR/rename.rs:50:9
    |
-LL | #![warn(clippy::for_loop_over_option)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
+LL | #![warn(clippy::option_map_unwrap_or_else)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
-error: lint `clippy::for_loop_over_result` has been renamed to `clippy::for_loops_over_fallibles`
+error: lint `clippy::option_unwrap_used` has been renamed to `clippy::unwrap_used`
   --> $DIR/rename.rs:51:9
    |
-LL | #![warn(clippy::for_loop_over_result)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::for_loops_over_fallibles`
+LL | #![warn(clippy::option_unwrap_used)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
-error: lint `clippy::identity_conversion` has been renamed to `clippy::useless_conversion`
+error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
   --> $DIR/rename.rs:52:9
    |
-LL | #![warn(clippy::identity_conversion)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::useless_conversion`
+LL | #![warn(clippy::ref_in_deref)]
+   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
 
-error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
+error: lint `clippy::result_expect_used` has been renamed to `clippy::expect_used`
   --> $DIR/rename.rs:53:9
    |
-LL | #![warn(clippy::zero_width_space)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
+LL | #![warn(clippy::result_expect_used)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::expect_used`
 
-error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
+error: lint `clippy::result_map_unwrap_or_else` has been renamed to `clippy::map_unwrap_or`
   --> $DIR/rename.rs:54:9
    |
-LL | #![warn(clippy::single_char_push_str)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
+LL | #![warn(clippy::result_map_unwrap_or_else)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::map_unwrap_or`
 
-error: lint `clippy::if_let_some_result` has been renamed to `clippy::match_result_ok`
+error: lint `clippy::result_unwrap_used` has been renamed to `clippy::unwrap_used`
   --> $DIR/rename.rs:55:9
    |
-LL | #![warn(clippy::if_let_some_result)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::match_result_ok`
+LL | #![warn(clippy::result_unwrap_used)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::unwrap_used`
 
-error: lint `clippy::disallowed_type` has been renamed to `clippy::disallowed_types`
+error: lint `clippy::single_char_push_str` has been renamed to `clippy::single_char_add_str`
   --> $DIR/rename.rs:56:9
    |
-LL | #![warn(clippy::disallowed_type)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_types`
+LL | #![warn(clippy::single_char_push_str)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::single_char_add_str`
 
-error: lint `clippy::disallowed_method` has been renamed to `clippy::disallowed_methods`
+error: lint `clippy::stutter` has been renamed to `clippy::module_name_repetitions`
   --> $DIR/rename.rs:57:9
    |
-LL | #![warn(clippy::disallowed_method)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::disallowed_methods`
+LL | #![warn(clippy::stutter)]
+   |         ^^^^^^^^^^^^^^^ help: use the new name: `clippy::module_name_repetitions`
 
-error: lint `clippy::ref_in_deref` has been renamed to `clippy::needless_borrow`
+error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
   --> $DIR/rename.rs:58:9
    |
-LL | #![warn(clippy::ref_in_deref)]
-   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::needless_borrow`
+LL | #![warn(clippy::to_string_in_display)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
 
-error: lint `clippy::to_string_in_display` has been renamed to `clippy::recursive_format_impl`
+error: lint `clippy::zero_width_space` has been renamed to `clippy::invisible_characters`
   --> $DIR/rename.rs:59:9
    |
-LL | #![warn(clippy::to_string_in_display)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::recursive_format_impl`
+LL | #![warn(clippy::zero_width_space)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `clippy::invisible_characters`
 
-error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
-  --> $DIR/rename.rs:61:9
+error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
+  --> $DIR/rename.rs:60:9
    |
-LL | #![warn(clippy::invalid_ref)]
-   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
+LL | #![warn(clippy::drop_bounds)]
+   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
 
 error: lint `clippy::into_iter_on_array` has been renamed to `array_into_iter`
-  --> $DIR/rename.rs:62:9
+  --> $DIR/rename.rs:61:9
    |
 LL | #![warn(clippy::into_iter_on_array)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `array_into_iter`
 
-error: lint `clippy::unused_label` has been renamed to `unused_labels`
+error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
+  --> $DIR/rename.rs:62:9
+   |
+LL | #![warn(clippy::invalid_atomic_ordering)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
+
+error: lint `clippy::invalid_ref` has been renamed to `invalid_value`
   --> $DIR/rename.rs:63:9
    |
-LL | #![warn(clippy::unused_label)]
-   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
+LL | #![warn(clippy::invalid_ref)]
+   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_value`
 
-error: lint `clippy::drop_bounds` has been renamed to `drop_bounds`
+error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
   --> $DIR/rename.rs:64:9
    |
-LL | #![warn(clippy::drop_bounds)]
-   |         ^^^^^^^^^^^^^^^^^^^ help: use the new name: `drop_bounds`
+LL | #![warn(clippy::mem_discriminant_non_enum)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
 
-error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
+error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
   --> $DIR/rename.rs:65:9
    |
-LL | #![warn(clippy::temporary_cstring_as_ptr)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
+LL | #![warn(clippy::panic_params)]
+   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
 
-error: lint `clippy::panic_params` has been renamed to `non_fmt_panics`
+error: lint `clippy::temporary_cstring_as_ptr` has been renamed to `temporary_cstring_as_ptr`
   --> $DIR/rename.rs:66:9
    |
-LL | #![warn(clippy::panic_params)]
-   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `non_fmt_panics`
+LL | #![warn(clippy::temporary_cstring_as_ptr)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `temporary_cstring_as_ptr`
 
 error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
   --> $DIR/rename.rs:67:9
@@ -192,17 +198,11 @@ error: lint `clippy::unknown_clippy_lints` has been renamed to `unknown_lints`
 LL | #![warn(clippy::unknown_clippy_lints)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unknown_lints`
 
-error: lint `clippy::invalid_atomic_ordering` has been renamed to `invalid_atomic_ordering`
+error: lint `clippy::unused_label` has been renamed to `unused_labels`
   --> $DIR/rename.rs:68:9
    |
-LL | #![warn(clippy::invalid_atomic_ordering)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `invalid_atomic_ordering`
-
-error: lint `clippy::mem_discriminant_non_enum` has been renamed to `enum_intrinsics_non_enums`
-  --> $DIR/rename.rs:69:9
-   |
-LL | #![warn(clippy::mem_discriminant_non_enum)]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `enum_intrinsics_non_enums`
+LL | #![warn(clippy::unused_label)]
+   |         ^^^^^^^^^^^^^^^^^^^^ help: use the new name: `unused_labels`
 
 error: aborting due to 34 previous errors
 
diff --git a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs
index 38fc9969804..086331af6b5 100644
--- a/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs
+++ b/src/tools/clippy/tests/ui/rest_pat_in_fully_bound_structs.rs
@@ -39,4 +39,19 @@ fn main() {
 
     // No lint
     foo!(a_struct);
+
+    #[non_exhaustive]
+    struct B {
+        a: u32,
+        b: u32,
+        c: u64,
+    }
+
+    let b_struct = B { a: 5, b: 42, c: 342 };
+
+    match b_struct {
+        B { a: 5, b: 42, .. } => {},
+        B { a: 0, b: 0, c: 128, .. } => {}, // No Lint
+        _ => {},
+    }
 }
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 7f28f025790..3d2295912c9 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
@@ -1,3 +1,5 @@
+#![feature(adt_const_params)]
+#![allow(incomplete_features)]
 #![warn(clippy::same_functions_in_if_condition)]
 #![allow(clippy::ifs_same_cond)] // This warning is different from `ifs_same_cond`.
 #![allow(clippy::if_same_then_else, clippy::comparison_chain)] // all empty blocks
@@ -87,4 +89,21 @@ fn main() {
         "linux"
     };
     println!("{}", os);
+
+    #[derive(PartialEq, Eq)]
+    enum E {
+        A,
+        B,
+    }
+    fn generic<const P: E>() -> bool {
+        match P {
+            E::A => true,
+            E::B => false,
+        }
+    }
+    if generic::<{ E::A }>() {
+        println!("A");
+    } else if generic::<{ E::B }>() {
+        println!("B");
+    }
 }
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 363a03846d2..71e82910ef7 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,72 +1,72 @@
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:29:15
+  --> $DIR/same_functions_in_if_condition.rs:31:15
    |
 LL |     } else if function() {
    |               ^^^^^^^^^^
    |
    = note: `-D clippy::same-functions-in-if-condition` implied by `-D warnings`
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:28:8
+  --> $DIR/same_functions_in_if_condition.rs:30:8
    |
 LL |     if function() {
    |        ^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:34:15
+  --> $DIR/same_functions_in_if_condition.rs:36:15
    |
 LL |     } else if fn_arg(a) {
    |               ^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:33:8
+  --> $DIR/same_functions_in_if_condition.rs:35:8
    |
 LL |     if fn_arg(a) {
    |        ^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:39:15
+  --> $DIR/same_functions_in_if_condition.rs:41:15
    |
 LL |     } else if obj.method() {
    |               ^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:38:8
+  --> $DIR/same_functions_in_if_condition.rs:40:8
    |
 LL |     if obj.method() {
    |        ^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:44:15
+  --> $DIR/same_functions_in_if_condition.rs:46:15
    |
 LL |     } else if obj.method_arg(a) {
    |               ^^^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:43:8
+  --> $DIR/same_functions_in_if_condition.rs:45:8
    |
 LL |     if obj.method_arg(a) {
    |        ^^^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:51:15
+  --> $DIR/same_functions_in_if_condition.rs:53:15
    |
 LL |     } else if v.pop() == None {
    |               ^^^^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:49:8
+  --> $DIR/same_functions_in_if_condition.rs:51:8
    |
 LL |     if v.pop() == None {
    |        ^^^^^^^^^^^^^^^
 
 error: this `if` has the same function call as a previous `if`
-  --> $DIR/same_functions_in_if_condition.rs:56:15
+  --> $DIR/same_functions_in_if_condition.rs:58:15
    |
 LL |     } else if v.len() == 42 {
    |               ^^^^^^^^^^^^^
    |
 note: same as this
-  --> $DIR/same_functions_in_if_condition.rs:54:8
+  --> $DIR/same_functions_in_if_condition.rs:56:8
    |
 LL |     if v.len() == 42 {
    |        ^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/shadow.rs b/src/tools/clippy/tests/ui/shadow.rs
index 0321f8c4cdf..a394ef8f25c 100644
--- a/src/tools/clippy/tests/ui/shadow.rs
+++ b/src/tools/clippy/tests/ui/shadow.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)]
+#![allow(clippy::let_unit_value)]
 
 fn shadow_same() {
     let x = 1;
diff --git a/src/tools/clippy/tests/ui/shadow.stderr b/src/tools/clippy/tests/ui/shadow.stderr
index f8b9221d555..3bd41d06260 100644
--- a/src/tools/clippy/tests/ui/shadow.stderr
+++ b/src/tools/clippy/tests/ui/shadow.stderr
@@ -1,266 +1,266 @@
 error: `x` is shadowed by itself in `x`
-  --> $DIR/shadow.rs:5:9
+  --> $DIR/shadow.rs:6:9
    |
 LL |     let x = x;
    |         ^
    |
    = note: `-D clippy::shadow-same` implied by `-D warnings`
 note: previous binding is here
-  --> $DIR/shadow.rs:4:9
+  --> $DIR/shadow.rs:5:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `mut x` is shadowed by itself in `&x`
-  --> $DIR/shadow.rs:6:13
+  --> $DIR/shadow.rs:7:13
    |
 LL |     let mut x = &x;
    |             ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:5:9
+  --> $DIR/shadow.rs:6:9
    |
 LL |     let x = x;
    |         ^
 
 error: `x` is shadowed by itself in `&mut x`
-  --> $DIR/shadow.rs:7:9
+  --> $DIR/shadow.rs:8:9
    |
 LL |     let x = &mut x;
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:6:9
+  --> $DIR/shadow.rs:7:9
    |
 LL |     let mut x = &x;
    |         ^^^^^
 
 error: `x` is shadowed by itself in `*x`
-  --> $DIR/shadow.rs:8:9
+  --> $DIR/shadow.rs:9:9
    |
 LL |     let x = *x;
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:7:9
+  --> $DIR/shadow.rs:8:9
    |
 LL |     let x = &mut x;
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:13:9
+  --> $DIR/shadow.rs:14:9
    |
 LL |     let x = x.0;
    |         ^
    |
    = note: `-D clippy::shadow-reuse` implied by `-D warnings`
 note: previous binding is here
-  --> $DIR/shadow.rs:12:9
+  --> $DIR/shadow.rs:13:9
    |
 LL |     let x = ([[0]], ());
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:14:9
+  --> $DIR/shadow.rs:15:9
    |
 LL |     let x = x[0];
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:13:9
+  --> $DIR/shadow.rs:14:9
    |
 LL |     let x = x.0;
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:15:10
+  --> $DIR/shadow.rs:16:10
    |
 LL |     let [x] = x;
    |          ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:14:9
+  --> $DIR/shadow.rs:15:9
    |
 LL |     let x = x[0];
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:16:9
+  --> $DIR/shadow.rs:17:9
    |
 LL |     let x = Some(x);
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:15:10
+  --> $DIR/shadow.rs:16:10
    |
 LL |     let [x] = x;
    |          ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:17:9
+  --> $DIR/shadow.rs:18:9
    |
 LL |     let x = foo(x);
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:16:9
+  --> $DIR/shadow.rs:17:9
    |
 LL |     let x = Some(x);
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:18:9
+  --> $DIR/shadow.rs:19:9
    |
 LL |     let x = || x;
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:17:9
+  --> $DIR/shadow.rs:18:9
    |
 LL |     let x = foo(x);
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:19:9
+  --> $DIR/shadow.rs:20:9
    |
 LL |     let x = Some(1).map(|_| x)?;
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:18:9
+  --> $DIR/shadow.rs:19:9
    |
 LL |     let x = || x;
    |         ^
 
 error: `y` is shadowed
-  --> $DIR/shadow.rs:21:9
+  --> $DIR/shadow.rs:22:9
    |
 LL |     let y = match y {
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:20:9
+  --> $DIR/shadow.rs:21:9
    |
 LL |     let y = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:30:9
+  --> $DIR/shadow.rs:31:9
    |
 LL |     let x = 2;
    |         ^
    |
    = note: `-D clippy::shadow-unrelated` implied by `-D warnings`
 note: previous binding is here
-  --> $DIR/shadow.rs:29:9
+  --> $DIR/shadow.rs:30:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:35:13
+  --> $DIR/shadow.rs:36:13
    |
 LL |         let x = 1;
    |             ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:34:10
+  --> $DIR/shadow.rs:35:10
    |
 LL |     fn f(x: u32) {
    |          ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:40:14
+  --> $DIR/shadow.rs:41:14
    |
 LL |         Some(x) => {
    |              ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:37:9
+  --> $DIR/shadow.rs:38:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:41:17
+  --> $DIR/shadow.rs:42:17
    |
 LL |             let x = 1;
    |                 ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:40:14
+  --> $DIR/shadow.rs:41:14
    |
 LL |         Some(x) => {
    |              ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:45:17
+  --> $DIR/shadow.rs:46:17
    |
 LL |     if let Some(x) = Some(1) {}
    |                 ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:37:9
+  --> $DIR/shadow.rs:38:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:46:20
+  --> $DIR/shadow.rs:47:20
    |
 LL |     while let Some(x) = Some(1) {}
    |                    ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:37:9
+  --> $DIR/shadow.rs:38:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:47:15
+  --> $DIR/shadow.rs:48:15
    |
 LL |     let _ = |[x]: [u32; 1]| {
    |               ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:37:9
+  --> $DIR/shadow.rs:38:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:48:13
+  --> $DIR/shadow.rs:49:13
    |
 LL |         let x = 1;
    |             ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:47:15
+  --> $DIR/shadow.rs:48:15
    |
 LL |     let _ = |[x]: [u32; 1]| {
    |               ^
 
 error: `y` is shadowed
-  --> $DIR/shadow.rs:51:17
+  --> $DIR/shadow.rs:52:17
    |
 LL |     if let Some(y) = y {}
    |                 ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:50:9
+  --> $DIR/shadow.rs:51:9
    |
 LL |     let y = Some(1);
    |         ^
 
 error: `_b` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:87:9
+  --> $DIR/shadow.rs:88:9
    |
 LL |     let _b = _a;
    |         ^^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:86:28
+  --> $DIR/shadow.rs:87:28
    |
 LL | pub async fn foo2(_a: i32, _b: i64) {
    |                            ^^
diff --git a/src/tools/clippy/tests/ui/similar_names.rs b/src/tools/clippy/tests/ui/similar_names.rs
index 76f6ce9ee6b..c21225d153b 100644
--- a/src/tools/clippy/tests/ui/similar_names.rs
+++ b/src/tools/clippy/tests/ui/similar_names.rs
@@ -3,7 +3,8 @@
     unused,
     clippy::println_empty_string,
     clippy::empty_loop,
-    clippy::diverging_sub_expression
+    clippy::diverging_sub_expression,
+    clippy::let_unit_value
 )]
 
 struct Foo {
diff --git a/src/tools/clippy/tests/ui/similar_names.stderr b/src/tools/clippy/tests/ui/similar_names.stderr
index faf572b0c6b..6e772693897 100644
--- a/src/tools/clippy/tests/ui/similar_names.stderr
+++ b/src/tools/clippy/tests/ui/similar_names.stderr
@@ -1,84 +1,84 @@
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:20:9
+  --> $DIR/similar_names.rs:21:9
    |
 LL |     let bpple: i32;
    |         ^^^^^
    |
    = note: `-D clippy::similar-names` implied by `-D warnings`
 note: existing binding defined here
-  --> $DIR/similar_names.rs:18:9
+  --> $DIR/similar_names.rs:19:9
    |
 LL |     let apple: i32;
    |         ^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:22:9
+  --> $DIR/similar_names.rs:23:9
    |
 LL |     let cpple: i32;
    |         ^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:18:9
+  --> $DIR/similar_names.rs:19:9
    |
 LL |     let apple: i32;
    |         ^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:46:9
+  --> $DIR/similar_names.rs:47:9
    |
 LL |     let bluby: i32;
    |         ^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:45:9
+  --> $DIR/similar_names.rs:46:9
    |
 LL |     let blubx: i32;
    |         ^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:50:9
+  --> $DIR/similar_names.rs:51:9
    |
 LL |     let coke: i32;
    |         ^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:48:9
+  --> $DIR/similar_names.rs:49:9
    |
 LL |     let cake: i32;
    |         ^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:68:9
+  --> $DIR/similar_names.rs:69:9
    |
 LL |     let xyzeabc: i32;
    |         ^^^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:66:9
+  --> $DIR/similar_names.rs:67:9
    |
 LL |     let xyz1abc: i32;
    |         ^^^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:72:9
+  --> $DIR/similar_names.rs:73:9
    |
 LL |     let parsee: i32;
    |         ^^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:70:9
+  --> $DIR/similar_names.rs:71:9
    |
 LL |     let parser: i32;
    |         ^^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:93:16
+  --> $DIR/similar_names.rs:94:16
    |
 LL |         bpple: sprang,
    |                ^^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:92:16
+  --> $DIR/similar_names.rs:93:16
    |
 LL |         apple: spring,
    |                ^^^^^^
diff --git a/src/tools/clippy/tests/ui/single_char_lifetime_names.rs b/src/tools/clippy/tests/ui/single_char_lifetime_names.rs
index 261d8bc7260..69c5b236f7c 100644
--- a/src/tools/clippy/tests/ui/single_char_lifetime_names.rs
+++ b/src/tools/clippy/tests/ui/single_char_lifetime_names.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::single_char_lifetime_names)]
+#![allow(clippy::let_unit_value)]
 
 // Lifetimes should only be linted when they're introduced
 struct DiagnosticCtx<'a, 'b>
diff --git a/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr b/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr
index 013b64f46a8..1438b3999db 100644
--- a/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr
+++ b/src/tools/clippy/tests/ui/single_char_lifetime_names.stderr
@@ -1,5 +1,5 @@
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:4:22
+  --> $DIR/single_char_lifetime_names.rs:5:22
    |
 LL | struct DiagnosticCtx<'a, 'b>
    |                      ^^
@@ -8,7 +8,7 @@ LL | struct DiagnosticCtx<'a, 'b>
    = help: use a more informative name
 
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:4:26
+  --> $DIR/single_char_lifetime_names.rs:5:26
    |
 LL | struct DiagnosticCtx<'a, 'b>
    |                          ^^
@@ -16,7 +16,7 @@ LL | struct DiagnosticCtx<'a, 'b>
    = help: use a more informative name
 
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:13:6
+  --> $DIR/single_char_lifetime_names.rs:14:6
    |
 LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
    |      ^^
@@ -24,7 +24,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
    = help: use a more informative name
 
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:13:10
+  --> $DIR/single_char_lifetime_names.rs:14:10
    |
 LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
    |          ^^
@@ -32,7 +32,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
    = help: use a more informative name
 
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:33:15
+  --> $DIR/single_char_lifetime_names.rs:34:15
    |
 LL | fn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) {
    |               ^^
diff --git a/src/tools/clippy/tests/ui/single_match_else.rs b/src/tools/clippy/tests/ui/single_match_else.rs
index b624a41a29b..82387f3d80b 100644
--- a/src/tools/clippy/tests/ui/single_match_else.rs
+++ b/src/tools/clippy/tests/ui/single_match_else.rs
@@ -1,7 +1,12 @@
+// aux-build: proc_macro_with_span.rs
+
 #![warn(clippy::single_match_else)]
 #![allow(clippy::needless_return)]
 #![allow(clippy::no_effect)]
 
+extern crate proc_macro_with_span;
+use proc_macro_with_span::with_span;
+
 enum ExprNode {
     ExprAddrOf,
     Butterflies,
@@ -11,13 +16,22 @@ enum ExprNode {
 static NODE: ExprNode = ExprNode::Unicorns;
 
 fn unwrap_addr() -> Option<&'static ExprNode> {
-    match ExprNode::Butterflies {
+    let _ = match ExprNode::Butterflies {
         ExprNode::ExprAddrOf => Some(&NODE),
         _ => {
             let x = 5;
             None
         },
-    }
+    };
+
+    // Don't lint
+    with_span!(span match ExprNode::Butterflies {
+        ExprNode::ExprAddrOf => Some(&NODE),
+        _ => {
+            let x = 5;
+            None
+        },
+    })
 }
 
 macro_rules! unwrap_addr {
diff --git a/src/tools/clippy/tests/ui/single_match_else.stderr b/src/tools/clippy/tests/ui/single_match_else.stderr
index 21ea704b62a..7756c6f204e 100644
--- a/src/tools/clippy/tests/ui/single_match_else.stderr
+++ b/src/tools/clippy/tests/ui/single_match_else.stderr
@@ -1,22 +1,23 @@
 error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
-  --> $DIR/single_match_else.rs:14:5
+  --> $DIR/single_match_else.rs:19:13
    |
-LL | /     match ExprNode::Butterflies {
+LL |       let _ = match ExprNode::Butterflies {
+   |  _____________^
 LL | |         ExprNode::ExprAddrOf => Some(&NODE),
 LL | |         _ => {
 LL | |             let x = 5;
 LL | |             None
 LL | |         },
-LL | |     }
+LL | |     };
    | |_____^
    |
    = note: `-D clippy::single-match-else` implied by `-D warnings`
 help: try this
    |
-LL ~     if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else {
+LL ~     let _ = if let ExprNode::ExprAddrOf = ExprNode::Butterflies { Some(&NODE) } else {
 LL +         let x = 5;
 LL +         None
-LL +     }
+LL ~     };
    |
 
 error: aborting due to previous error
diff --git a/src/tools/clippy/tests/ui/stable_sort_primitive.stderr b/src/tools/clippy/tests/ui/stable_sort_primitive.stderr
index b8d22ed2504..c35e0c22ae8 100644
--- a/src/tools/clippy/tests/ui/stable_sort_primitive.stderr
+++ b/src/tools/clippy/tests/ui/stable_sort_primitive.stderr
@@ -5,7 +5,7 @@ LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
    |
    = note: `-D clippy::stable-sort-primitive` implied by `-D warnings`
-   = note: an unstable sort would perform faster without any observable difference for this data type
+   = note: an unstable sort typically performs faster without any observable difference for this data type
 
 error: used `sort` on primitive type `bool`
   --> $DIR/stable_sort_primitive.rs:9:5
@@ -13,7 +13,7 @@ error: used `sort` on primitive type `bool`
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
    |
-   = note: an unstable sort would perform faster without any observable difference for this data type
+   = note: an unstable sort typically performs faster without any observable difference for this data type
 
 error: used `sort` on primitive type `char`
   --> $DIR/stable_sort_primitive.rs:11:5
@@ -21,7 +21,7 @@ error: used `sort` on primitive type `char`
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
    |
-   = note: an unstable sort would perform faster without any observable difference for this data type
+   = note: an unstable sort typically performs faster without any observable difference for this data type
 
 error: used `sort` on primitive type `str`
   --> $DIR/stable_sort_primitive.rs:13:5
@@ -29,7 +29,7 @@ error: used `sort` on primitive type `str`
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
    |
-   = note: an unstable sort would perform faster without any observable difference for this data type
+   = note: an unstable sort typically performs faster without any observable difference for this data type
 
 error: used `sort` on primitive type `tuple`
   --> $DIR/stable_sort_primitive.rs:15:5
@@ -37,7 +37,7 @@ error: used `sort` on primitive type `tuple`
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
    |
-   = note: an unstable sort would perform faster without any observable difference for this data type
+   = note: an unstable sort typically performs faster without any observable difference for this data type
 
 error: used `sort` on primitive type `array`
   --> $DIR/stable_sort_primitive.rs:17:5
@@ -45,7 +45,7 @@ error: used `sort` on primitive type `array`
 LL |     vec.sort();
    |     ^^^^^^^^^^ help: try: `vec.sort_unstable()`
    |
-   = note: an unstable sort would perform faster without any observable difference for this data type
+   = note: an unstable sort typically performs faster without any observable difference for this data type
 
 error: used `sort` on primitive type `i32`
   --> $DIR/stable_sort_primitive.rs:19:5
@@ -53,7 +53,7 @@ error: used `sort` on primitive type `i32`
 LL |     arr.sort();
    |     ^^^^^^^^^^ help: try: `arr.sort_unstable()`
    |
-   = note: an unstable sort would perform faster without any observable difference for this data type
+   = note: an unstable sort typically performs faster without any observable difference for this data type
 
 error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
index fcd827a91c7..21753e5dc6a 100644
--- a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
+++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
@@ -1,7 +1,7 @@
 // aux-build:proc_macro_suspicious_else_formatting.rs
 
 #![warn(clippy::suspicious_else_formatting)]
-#![allow(clippy::if_same_then_else)]
+#![allow(clippy::if_same_then_else, clippy::let_unit_value)]
 
 extern crate proc_macro_suspicious_else_formatting;
 use proc_macro_suspicious_else_formatting::DeriveBadSpan;
diff --git a/src/tools/clippy/tests/ui/to_digit_is_some.fixed b/src/tools/clippy/tests/ui/to_digit_is_some.fixed
index 19184df0bec..3c5e9642714 100644
--- a/src/tools/clippy/tests/ui/to_digit_is_some.fixed
+++ b/src/tools/clippy/tests/ui/to_digit_is_some.fixed
@@ -6,6 +6,6 @@ fn main() {
     let c = 'x';
     let d = &c;
 
-    let _ = d.is_digit(10);
-    let _ = char::is_digit(c, 10);
+    let _ = d.is_digit(8);
+    let _ = char::is_digit(c, 8);
 }
diff --git a/src/tools/clippy/tests/ui/to_digit_is_some.rs b/src/tools/clippy/tests/ui/to_digit_is_some.rs
index 45a6728ebf5..4f247c06cee 100644
--- a/src/tools/clippy/tests/ui/to_digit_is_some.rs
+++ b/src/tools/clippy/tests/ui/to_digit_is_some.rs
@@ -6,6 +6,6 @@ fn main() {
     let c = 'x';
     let d = &c;
 
-    let _ = d.to_digit(10).is_some();
-    let _ = char::to_digit(c, 10).is_some();
+    let _ = d.to_digit(8).is_some();
+    let _ = char::to_digit(c, 8).is_some();
 }
diff --git a/src/tools/clippy/tests/ui/to_digit_is_some.stderr b/src/tools/clippy/tests/ui/to_digit_is_some.stderr
index 177d3ccd3e2..10a1b393a39 100644
--- a/src/tools/clippy/tests/ui/to_digit_is_some.stderr
+++ b/src/tools/clippy/tests/ui/to_digit_is_some.stderr
@@ -1,16 +1,16 @@
 error: use of `.to_digit(..).is_some()`
   --> $DIR/to_digit_is_some.rs:9:13
    |
-LL |     let _ = d.to_digit(10).is_some();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `d.is_digit(10)`
+LL |     let _ = d.to_digit(8).is_some();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `d.is_digit(8)`
    |
    = note: `-D clippy::to-digit-is-some` implied by `-D warnings`
 
 error: use of `.to_digit(..).is_some()`
   --> $DIR/to_digit_is_some.rs:10:13
    |
-LL |     let _ = char::to_digit(c, 10).is_some();
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `char::is_digit(c, 10)`
+LL |     let _ = char::to_digit(c, 8).is_some();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `char::is_digit(c, 8)`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
index f5ca91143af..a21d4c5d637 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
@@ -95,4 +95,7 @@ trait FooIter: Iterator<Item = Foo> {
     }
 }
 
+// This should not lint
+fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
index 6f8c8e47dfb..d0a4cfb8837 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.stderr
@@ -67,5 +67,13 @@ LL |         Self: Iterator<Item = Foo>,
    |
    = help: consider removing this trait bound
 
-error: aborting due to 8 previous errors
+error: this trait bound is already specified in the where clause
+  --> $DIR/trait_duplication_in_bounds.rs:99:23
+   |
+LL | fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
+   |                       ^^^^^^^^^^
+   |
+   = help: consider removing this trait bound
+
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/transmute_collection.rs b/src/tools/clippy/tests/ui/transmute_collection.rs
index cd5a7127791..5a431bee04a 100644
--- a/src/tools/clippy/tests/ui/transmute_collection.rs
+++ b/src/tools/clippy/tests/ui/transmute_collection.rs
@@ -1,7 +1,7 @@
 #![warn(clippy::unsound_collection_transmute)]
 
 use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
-use std::mem::transmute;
+use std::mem::{transmute, MaybeUninit};
 
 fn main() {
     unsafe {
@@ -43,5 +43,8 @@ fn main() {
         // wrong layout
         let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, [u8; 4]>::new());
         let _ = transmute::<_, HashMap<u32, u32>>(HashMap::<[u8; 4], u32>::new());
+
+        let _ = transmute::<_, Vec<u8>>(Vec::<MaybeUninit<u8>>::new());
+        let _ = transmute::<_, Vec<*mut u32>>(Vec::<Box<u32>>::new());
     }
 }
diff --git a/src/tools/clippy/tests/ui/trim_split_whitespace.fixed b/src/tools/clippy/tests/ui/trim_split_whitespace.fixed
new file mode 100644
index 00000000000..e4d352f7367
--- /dev/null
+++ b/src/tools/clippy/tests/ui/trim_split_whitespace.fixed
@@ -0,0 +1,91 @@
+// run-rustfix
+#![warn(clippy::trim_split_whitespace)]
+#![allow(clippy::let_unit_value)]
+
+struct Custom;
+impl Custom {
+    fn trim(self) -> Self {
+        self
+    }
+    fn split_whitespace(self) {}
+}
+
+struct DerefStr(&'static str);
+impl std::ops::Deref for DerefStr {
+    type Target = str;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+
+struct DerefStrAndCustom(&'static str);
+impl std::ops::Deref for DerefStrAndCustom {
+    type Target = str;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+impl DerefStrAndCustom {
+    fn trim(self) -> Self {
+        self
+    }
+    fn split_whitespace(self) {}
+}
+
+struct DerefStrAndCustomSplit(&'static str);
+impl std::ops::Deref for DerefStrAndCustomSplit {
+    type Target = str;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+impl DerefStrAndCustomSplit {
+    #[allow(dead_code)]
+    fn split_whitespace(self) {}
+}
+
+struct DerefStrAndCustomTrim(&'static str);
+impl std::ops::Deref for DerefStrAndCustomTrim {
+    type Target = str;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+impl DerefStrAndCustomTrim {
+    fn trim(self) -> Self {
+        self
+    }
+}
+
+fn main() {
+    // &str
+    let _ = " A B C ".split_whitespace(); // should trigger lint
+    let _ = " A B C ".split_whitespace(); // should trigger lint
+    let _ = " A B C ".split_whitespace(); // should trigger lint
+
+    // String
+    let _ = (" A B C ").to_string().split_whitespace(); // should trigger lint
+    let _ = (" A B C ").to_string().split_whitespace(); // should trigger lint
+    let _ = (" A B C ").to_string().split_whitespace(); // should trigger lint
+
+    // Custom
+    let _ = Custom.trim().split_whitespace(); // should not trigger lint
+
+    // Deref<Target=str>
+    let s = DerefStr(" A B C ");
+    let _ = s.split_whitespace(); // should trigger lint
+
+    // Deref<Target=str> + custom impl
+    let s = DerefStrAndCustom(" A B C ");
+    let _ = s.trim().split_whitespace(); // should not trigger lint
+
+    // Deref<Target=str> + only custom split_ws() impl
+    let s = DerefStrAndCustomSplit(" A B C ");
+    let _ = s.split_whitespace(); // should trigger lint
+    // Expl: trim() is called on str (deref) and returns &str.
+    //       Thus split_ws() is called on str as well and the custom impl on S is unused
+
+    // Deref<Target=str> + only custom trim() impl
+    let s = DerefStrAndCustomTrim(" A B C ");
+    let _ = s.trim().split_whitespace(); // should not trigger lint
+}
diff --git a/src/tools/clippy/tests/ui/trim_split_whitespace.rs b/src/tools/clippy/tests/ui/trim_split_whitespace.rs
new file mode 100644
index 00000000000..f98451a9837
--- /dev/null
+++ b/src/tools/clippy/tests/ui/trim_split_whitespace.rs
@@ -0,0 +1,91 @@
+// run-rustfix
+#![warn(clippy::trim_split_whitespace)]
+#![allow(clippy::let_unit_value)]
+
+struct Custom;
+impl Custom {
+    fn trim(self) -> Self {
+        self
+    }
+    fn split_whitespace(self) {}
+}
+
+struct DerefStr(&'static str);
+impl std::ops::Deref for DerefStr {
+    type Target = str;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+
+struct DerefStrAndCustom(&'static str);
+impl std::ops::Deref for DerefStrAndCustom {
+    type Target = str;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+impl DerefStrAndCustom {
+    fn trim(self) -> Self {
+        self
+    }
+    fn split_whitespace(self) {}
+}
+
+struct DerefStrAndCustomSplit(&'static str);
+impl std::ops::Deref for DerefStrAndCustomSplit {
+    type Target = str;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+impl DerefStrAndCustomSplit {
+    #[allow(dead_code)]
+    fn split_whitespace(self) {}
+}
+
+struct DerefStrAndCustomTrim(&'static str);
+impl std::ops::Deref for DerefStrAndCustomTrim {
+    type Target = str;
+    fn deref(&self) -> &Self::Target {
+        self.0
+    }
+}
+impl DerefStrAndCustomTrim {
+    fn trim(self) -> Self {
+        self
+    }
+}
+
+fn main() {
+    // &str
+    let _ = " A B C ".trim().split_whitespace(); // should trigger lint
+    let _ = " A B C ".trim_start().split_whitespace(); // should trigger lint
+    let _ = " A B C ".trim_end().split_whitespace(); // should trigger lint
+
+    // String
+    let _ = (" A B C ").to_string().trim().split_whitespace(); // should trigger lint
+    let _ = (" A B C ").to_string().trim_start().split_whitespace(); // should trigger lint
+    let _ = (" A B C ").to_string().trim_end().split_whitespace(); // should trigger lint
+
+    // Custom
+    let _ = Custom.trim().split_whitespace(); // should not trigger lint
+
+    // Deref<Target=str>
+    let s = DerefStr(" A B C ");
+    let _ = s.trim().split_whitespace(); // should trigger lint
+
+    // Deref<Target=str> + custom impl
+    let s = DerefStrAndCustom(" A B C ");
+    let _ = s.trim().split_whitespace(); // should not trigger lint
+
+    // Deref<Target=str> + only custom split_ws() impl
+    let s = DerefStrAndCustomSplit(" A B C ");
+    let _ = s.trim().split_whitespace(); // should trigger lint
+    // Expl: trim() is called on str (deref) and returns &str.
+    //       Thus split_ws() is called on str as well and the custom impl on S is unused
+
+    // Deref<Target=str> + only custom trim() impl
+    let s = DerefStrAndCustomTrim(" A B C ");
+    let _ = s.trim().split_whitespace(); // should not trigger lint
+}
diff --git a/src/tools/clippy/tests/ui/trim_split_whitespace.stderr b/src/tools/clippy/tests/ui/trim_split_whitespace.stderr
new file mode 100644
index 00000000000..5ae7849e27d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/trim_split_whitespace.stderr
@@ -0,0 +1,52 @@
+error: found call to `str::trim` before `str::split_whitespace`
+  --> $DIR/trim_split_whitespace.rs:62:23
+   |
+LL |     let _ = " A B C ".trim().split_whitespace(); // should trigger lint
+   |                       ^^^^^^^ help: remove `trim()`
+   |
+   = note: `-D clippy::trim-split-whitespace` implied by `-D warnings`
+
+error: found call to `str::trim_start` before `str::split_whitespace`
+  --> $DIR/trim_split_whitespace.rs:63:23
+   |
+LL |     let _ = " A B C ".trim_start().split_whitespace(); // should trigger lint
+   |                       ^^^^^^^^^^^^^ help: remove `trim_start()`
+
+error: found call to `str::trim_end` before `str::split_whitespace`
+  --> $DIR/trim_split_whitespace.rs:64:23
+   |
+LL |     let _ = " A B C ".trim_end().split_whitespace(); // should trigger lint
+   |                       ^^^^^^^^^^^ help: remove `trim_end()`
+
+error: found call to `str::trim` before `str::split_whitespace`
+  --> $DIR/trim_split_whitespace.rs:67:37
+   |
+LL |     let _ = (" A B C ").to_string().trim().split_whitespace(); // should trigger lint
+   |                                     ^^^^^^^ help: remove `trim()`
+
+error: found call to `str::trim_start` before `str::split_whitespace`
+  --> $DIR/trim_split_whitespace.rs:68:37
+   |
+LL |     let _ = (" A B C ").to_string().trim_start().split_whitespace(); // should trigger lint
+   |                                     ^^^^^^^^^^^^^ help: remove `trim_start()`
+
+error: found call to `str::trim_end` before `str::split_whitespace`
+  --> $DIR/trim_split_whitespace.rs:69:37
+   |
+LL |     let _ = (" A B C ").to_string().trim_end().split_whitespace(); // should trigger lint
+   |                                     ^^^^^^^^^^^ help: remove `trim_end()`
+
+error: found call to `str::trim` before `str::split_whitespace`
+  --> $DIR/trim_split_whitespace.rs:76:15
+   |
+LL |     let _ = s.trim().split_whitespace(); // should trigger lint
+   |               ^^^^^^^ help: remove `trim()`
+
+error: found call to `str::trim` before `str::split_whitespace`
+  --> $DIR/trim_split_whitespace.rs:84:15
+   |
+LL |     let _ = s.trim().split_whitespace(); // should trigger lint
+   |               ^^^^^^^ help: remove `trim()`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs b/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs
index fc740ee11d6..d11432f9046 100644
--- a/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/type_repetition_in_bounds.rs
@@ -79,4 +79,7 @@ where
     u: U,
 }
 
+// This should not lint
+fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr
index 148c19c7d07..abc25e59496 100644
--- a/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr
+++ b/src/tools/clippy/tests/ui/type_repetition_in_bounds.stderr
@@ -19,5 +19,13 @@ LL |     Self: Copy + Default + Ord,
    |
    = help: consider combining the bounds: `Self: Clone + Copy + Default + Ord`
 
-error: aborting due to 2 previous errors
+error: this type has already been used as a bound predicate
+  --> $DIR/type_repetition_in_bounds.rs:83:43
+   |
+LL | fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {}
+   |                                           ^^^^^^^^^^
+   |
+   = help: consider combining the bounds: `impl AsRef<str>: AsRef<str> + AsRef<str>`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
index afa337c45f4..7be15b0b2dd 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
@@ -1,6 +1,7 @@
 // aux-build:proc_macro_unsafe.rs
 
 #![warn(clippy::undocumented_unsafe_blocks)]
+#![allow(clippy::let_unit_value)]
 
 extern crate proc_macro_unsafe;
 
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
index 856a07fd316..87d445bd7b8 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
@@ -1,5 +1,5 @@
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:256:19
+  --> $DIR/undocumented_unsafe_blocks.rs:257:19
    |
 LL |     /* Safety: */ unsafe {}
    |                   ^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     /* Safety: */ unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:260:5
+  --> $DIR/undocumented_unsafe_blocks.rs:261:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -16,7 +16,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:264:14
+  --> $DIR/undocumented_unsafe_blocks.rs:265:14
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |              ^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:264:29
+  --> $DIR/undocumented_unsafe_blocks.rs:265:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                             ^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:264:48
+  --> $DIR/undocumented_unsafe_blocks.rs:265:48
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                                                ^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:268:18
+  --> $DIR/undocumented_unsafe_blocks.rs:269:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                  ^^^^^^^^^
@@ -48,7 +48,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:268:37
+  --> $DIR/undocumented_unsafe_blocks.rs:269:37
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                                     ^^^^^^^^^
@@ -56,7 +56,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:272:14
+  --> $DIR/undocumented_unsafe_blocks.rs:273:14
    |
 LL |     let _ = *unsafe { &42 };
    |              ^^^^^^^^^^^^^^
@@ -64,7 +64,7 @@ LL |     let _ = *unsafe { &42 };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:277:19
+  --> $DIR/undocumented_unsafe_blocks.rs:278:19
    |
 LL |     let _ = match unsafe {} {
    |                   ^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     let _ = match unsafe {} {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:283:14
+  --> $DIR/undocumented_unsafe_blocks.rs:284:14
    |
 LL |     let _ = &unsafe {};
    |              ^^^^^^^^^
@@ -80,7 +80,7 @@ LL |     let _ = &unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:287:14
+  --> $DIR/undocumented_unsafe_blocks.rs:288:14
    |
 LL |     let _ = [unsafe {}; 5];
    |              ^^^^^^^^^
@@ -88,7 +88,7 @@ LL |     let _ = [unsafe {}; 5];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:291:13
+  --> $DIR/undocumented_unsafe_blocks.rs:292:13
    |
 LL |     let _ = unsafe {};
    |             ^^^^^^^^^
@@ -96,7 +96,7 @@ LL |     let _ = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:301:8
+  --> $DIR/undocumented_unsafe_blocks.rs:302:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
@@ -104,7 +104,7 @@ LL |     t!(unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:307:13
+  --> $DIR/undocumented_unsafe_blocks.rs:308:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -116,7 +116,7 @@ LL |     t!();
    = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:315:5
+  --> $DIR/undocumented_unsafe_blocks.rs:316:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
@@ -124,7 +124,7 @@ LL |     unsafe {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:319:5
+  --> $DIR/undocumented_unsafe_blocks.rs:320:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -132,7 +132,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:329:5
+  --> $DIR/undocumented_unsafe_blocks.rs:330:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
@@ -140,7 +140,7 @@ LL |     unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:333:20
+  --> $DIR/undocumented_unsafe_blocks.rs:334:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/uninit.rs b/src/tools/clippy/tests/ui/uninit.rs
index 1ed3883c1f0..dac5ce272c0 100644
--- a/src/tools/clippy/tests/ui/uninit.rs
+++ b/src/tools/clippy/tests/ui/uninit.rs
@@ -1,4 +1,5 @@
 #![feature(stmt_expr_attributes)]
+#![allow(clippy::let_unit_value)]
 
 use std::mem::{self, MaybeUninit};
 
diff --git a/src/tools/clippy/tests/ui/uninit.stderr b/src/tools/clippy/tests/ui/uninit.stderr
index 85b64a8419a..15ef2349489 100644
--- a/src/tools/clippy/tests/ui/uninit.stderr
+++ b/src/tools/clippy/tests/ui/uninit.stderr
@@ -1,5 +1,5 @@
 error: this call for this type may be undefined behavior
-  --> $DIR/uninit.rs:6:29
+  --> $DIR/uninit.rs:7:29
    |
 LL |     let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,13 +7,13 @@ LL |     let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
    = note: `#[deny(clippy::uninit_assumed_init)]` on by default
 
 error: this call for this type may be undefined behavior
-  --> $DIR/uninit.rs:9:31
+  --> $DIR/uninit.rs:10:31
    |
 LL |     let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this call for this type may be undefined behavior
-  --> $DIR/uninit.rs:24:29
+  --> $DIR/uninit.rs:25:29
    |
 LL |     let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() };
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unit_arg.rs b/src/tools/clippy/tests/ui/unit_arg.rs
index 535683729f6..38be87bddf1 100644
--- a/src/tools/clippy/tests/ui/unit_arg.rs
+++ b/src/tools/clippy/tests/ui/unit_arg.rs
@@ -7,7 +7,8 @@
     clippy::unnecessary_wraps,
     clippy::or_fun_call,
     clippy::needless_question_mark,
-    clippy::self_named_constructors
+    clippy::self_named_constructors,
+    clippy::let_unit_value
 )]
 
 use std::fmt::Debug;
diff --git a/src/tools/clippy/tests/ui/unit_arg.stderr b/src/tools/clippy/tests/ui/unit_arg.stderr
index 5cfb367a7be..394dee29dc9 100644
--- a/src/tools/clippy/tests/ui/unit_arg.stderr
+++ b/src/tools/clippy/tests/ui/unit_arg.stderr
@@ -1,5 +1,5 @@
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:56:5
+  --> $DIR/unit_arg.rs:57:5
    |
 LL | /     foo({
 LL | |         1;
@@ -20,7 +20,7 @@ LL ~     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:59:5
+  --> $DIR/unit_arg.rs:60:5
    |
 LL |     foo(foo(1));
    |     ^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL ~     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:60:5
+  --> $DIR/unit_arg.rs:61:5
    |
 LL | /     foo({
 LL | |         foo(1);
@@ -54,7 +54,7 @@ LL ~     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:65:5
+  --> $DIR/unit_arg.rs:66:5
    |
 LL | /     b.bar({
 LL | |         1;
@@ -74,7 +74,7 @@ LL ~     b.bar(());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:68:5
+  --> $DIR/unit_arg.rs:69:5
    |
 LL |     taking_multiple_units(foo(0), foo(1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -87,7 +87,7 @@ LL ~     taking_multiple_units((), ());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:69:5
+  --> $DIR/unit_arg.rs:70:5
    |
 LL | /     taking_multiple_units(foo(0), {
 LL | |         foo(1);
@@ -110,7 +110,7 @@ LL ~     taking_multiple_units((), ());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:73:5
+  --> $DIR/unit_arg.rs:74:5
    |
 LL | /     taking_multiple_units(
 LL | |         {
@@ -140,7 +140,7 @@ LL +         foo(2);
  ...
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:84:13
+  --> $DIR/unit_arg.rs:85:13
    |
 LL |     None.or(Some(foo(2)));
    |             ^^^^^^^^^^^^
@@ -154,7 +154,7 @@ LL ~     });
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:87:5
+  --> $DIR/unit_arg.rs:88:5
    |
 LL |     foo(foo(()));
    |     ^^^^^^^^^^^^
@@ -166,7 +166,7 @@ LL ~     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:124:5
+  --> $DIR/unit_arg.rs:125:5
    |
 LL |     Some(foo(1))
    |     ^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/unit_hash.rs b/src/tools/clippy/tests/ui/unit_hash.rs
index 989916c239b..43eb54eff47 100644
--- a/src/tools/clippy/tests/ui/unit_hash.rs
+++ b/src/tools/clippy/tests/ui/unit_hash.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::unit_hash)]
+#![allow(clippy::let_unit_value)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::Hash;
diff --git a/src/tools/clippy/tests/ui/unit_hash.stderr b/src/tools/clippy/tests/ui/unit_hash.stderr
index da276296e02..050fa55a12b 100644
--- a/src/tools/clippy/tests/ui/unit_hash.stderr
+++ b/src/tools/clippy/tests/ui/unit_hash.stderr
@@ -1,5 +1,5 @@
 error: this call to `hash` on the unit type will do nothing
-  --> $DIR/unit_hash.rs:18:23
+  --> $DIR/unit_hash.rs:19:23
    |
 LL |         Foo::Empty => ().hash(&mut state),
    |                       ^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
@@ -8,7 +8,7 @@ LL |         Foo::Empty => ().hash(&mut state),
    = note: the implementation of `Hash` for `()` is a no-op
 
 error: this call to `hash` on the unit type will do nothing
-  --> $DIR/unit_hash.rs:23:5
+  --> $DIR/unit_hash.rs:24:5
    |
 LL |     res.hash(&mut state);
    |     ^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
@@ -16,7 +16,7 @@ LL |     res.hash(&mut state);
    = note: the implementation of `Hash` for `()` is a no-op
 
 error: this call to `hash` on the unit type will do nothing
-  --> $DIR/unit_hash.rs:26:5
+  --> $DIR/unit_hash.rs:27:5
    |
 LL |     do_nothing().hash(&mut state);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed
new file mode 100644
index 00000000000..f95f91329a2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.fixed
@@ -0,0 +1,22 @@
+// run-rustfix
+
+#![warn(clippy::unnecessary_owned_empty_strings)]
+
+fn ref_str_argument(_value: &str) {}
+
+#[allow(clippy::ptr_arg)]
+fn ref_string_argument(_value: &String) {}
+
+fn main() {
+    // should be linted
+    ref_str_argument("");
+
+    // should be linted
+    ref_str_argument("");
+
+    // should not be linted
+    ref_str_argument("");
+
+    // should not be linted
+    ref_string_argument(&String::new());
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs
new file mode 100644
index 00000000000..0cbdc151ed9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.rs
@@ -0,0 +1,22 @@
+// run-rustfix
+
+#![warn(clippy::unnecessary_owned_empty_strings)]
+
+fn ref_str_argument(_value: &str) {}
+
+#[allow(clippy::ptr_arg)]
+fn ref_string_argument(_value: &String) {}
+
+fn main() {
+    // should be linted
+    ref_str_argument(&String::new());
+
+    // should be linted
+    ref_str_argument(&String::from(""));
+
+    // should not be linted
+    ref_str_argument("");
+
+    // should not be linted
+    ref_string_argument(&String::new());
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr
new file mode 100644
index 00000000000..46bc4597b33
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_owned_empty_strings.stderr
@@ -0,0 +1,16 @@
+error: usage of `&String::new()` for a function expecting a `&str` argument
+  --> $DIR/unnecessary_owned_empty_strings.rs:12:22
+   |
+LL |     ref_str_argument(&String::new());
+   |                      ^^^^^^^^^^^^^^ help: try: `""`
+   |
+   = note: `-D clippy::unnecessary-owned-empty-strings` implied by `-D warnings`
+
+error: usage of `&String::from("")` for a function expecting a `&str` argument
+  --> $DIR/unnecessary_owned_empty_strings.rs:15:22
+   |
+LL |     ref_str_argument(&String::from(""));
+   |                      ^^^^^^^^^^^^^^^^^ help: try: `""`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index 38ba41ac54e..7455e22d49b 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -2,6 +2,7 @@
 
 #![allow(clippy::ptr_arg)]
 #![warn(clippy::unnecessary_to_owned)]
+#![feature(custom_inner_attributes)]
 
 use std::borrow::Cow;
 use std::ffi::{CStr, CString, OsStr, OsString};
@@ -213,6 +214,17 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
 
 fn require_string(_: &String) {}
 
+fn _msrv_1_35() {
+    #![clippy::msrv = "1.35"]
+    // `copied` was stabilized in 1.36, so clippy should use `cloned`.
+    let _ = &["x"][..].iter().cloned();
+}
+
+fn _msrv_1_36() {
+    #![clippy::msrv = "1.36"]
+    let _ = &["x"][..].iter().copied();
+}
+
 // https://github.com/rust-lang/rust-clippy/issues/8507
 mod issue_8507 {
     #![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index 15fb7ee83e3..bbcd00ad220 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -2,6 +2,7 @@
 
 #![allow(clippy::ptr_arg)]
 #![warn(clippy::unnecessary_to_owned)]
+#![feature(custom_inner_attributes)]
 
 use std::borrow::Cow;
 use std::ffi::{CStr, CString, OsStr, OsString};
@@ -213,6 +214,17 @@ fn get_file_path(_file_type: &FileType) -> Result<std::path::PathBuf, std::io::E
 
 fn require_string(_: &String) {}
 
+fn _msrv_1_35() {
+    #![clippy::msrv = "1.35"]
+    // `copied` was stabilized in 1.36, so clippy should use `cloned`.
+    let _ = &["x"][..].to_vec().into_iter();
+}
+
+fn _msrv_1_36() {
+    #![clippy::msrv = "1.36"]
+    let _ = &["x"][..].to_vec().into_iter();
+}
+
 // https://github.com/rust-lang/rust-clippy/issues/8507
 mod issue_8507 {
     #![allow(dead_code)]
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
index c53ce32be77..f9713559e4f 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.stderr
@@ -1,54 +1,54 @@
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:150:64
+  --> $DIR/unnecessary_to_owned.rs:151:64
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                                                                ^^^^^^^^^^^ help: remove this
    |
    = note: `-D clippy::redundant-clone` implied by `-D warnings`
 note: this value is dropped without further use
-  --> $DIR/unnecessary_to_owned.rs:150:20
+  --> $DIR/unnecessary_to_owned.rs:151:20
    |
 LL |     require_c_str(&CString::from_vec_with_nul(vec![0]).unwrap().to_owned());
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:151:40
+  --> $DIR/unnecessary_to_owned.rs:152:40
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                                        ^^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/unnecessary_to_owned.rs:151:21
+  --> $DIR/unnecessary_to_owned.rs:152:21
    |
 LL |     require_os_str(&OsString::from("x").to_os_string());
    |                     ^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:152:48
+  --> $DIR/unnecessary_to_owned.rs:153:48
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                                                ^^^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/unnecessary_to_owned.rs:152:19
+  --> $DIR/unnecessary_to_owned.rs:153:19
    |
 LL |     require_path(&std::path::PathBuf::from("x").to_path_buf());
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: redundant clone
-  --> $DIR/unnecessary_to_owned.rs:153:35
+  --> $DIR/unnecessary_to_owned.rs:154:35
    |
 LL |     require_str(&String::from("x").to_string());
    |                                   ^^^^^^^^^^^^ help: remove this
    |
 note: this value is dropped without further use
-  --> $DIR/unnecessary_to_owned.rs:153:18
+  --> $DIR/unnecessary_to_owned.rs:154:18
    |
 LL |     require_str(&String::from("x").to_string());
    |                  ^^^^^^^^^^^^^^^^^
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:59:36
+  --> $DIR/unnecessary_to_owned.rs:60:36
    |
 LL |     require_c_str(&Cow::from(c_str).into_owned());
    |                                    ^^^^^^^^^^^^^ help: remove this
@@ -56,427 +56,427 @@ LL |     require_c_str(&Cow::from(c_str).into_owned());
    = note: `-D clippy::unnecessary-to-owned` implied by `-D warnings`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:60:19
+  --> $DIR/unnecessary_to_owned.rs:61:19
    |
 LL |     require_c_str(&c_str.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_os_string`
-  --> $DIR/unnecessary_to_owned.rs:62:20
+  --> $DIR/unnecessary_to_owned.rs:63:20
    |
 LL |     require_os_str(&os_str.to_os_string());
    |                    ^^^^^^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:63:38
+  --> $DIR/unnecessary_to_owned.rs:64:38
    |
 LL |     require_os_str(&Cow::from(os_str).into_owned());
    |                                      ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:64:20
+  --> $DIR/unnecessary_to_owned.rs:65:20
    |
 LL |     require_os_str(&os_str.to_owned());
    |                    ^^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_path_buf`
-  --> $DIR/unnecessary_to_owned.rs:66:18
+  --> $DIR/unnecessary_to_owned.rs:67:18
    |
 LL |     require_path(&path.to_path_buf());
    |                  ^^^^^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:67:34
+  --> $DIR/unnecessary_to_owned.rs:68:34
    |
 LL |     require_path(&Cow::from(path).into_owned());
    |                                  ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:68:18
+  --> $DIR/unnecessary_to_owned.rs:69:18
    |
 LL |     require_path(&path.to_owned());
    |                  ^^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:70:17
+  --> $DIR/unnecessary_to_owned.rs:71:17
    |
 LL |     require_str(&s.to_string());
    |                 ^^^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:71:30
+  --> $DIR/unnecessary_to_owned.rs:72:30
    |
 LL |     require_str(&Cow::from(s).into_owned());
    |                              ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:72:17
+  --> $DIR/unnecessary_to_owned.rs:73:17
    |
 LL |     require_str(&s.to_owned());
    |                 ^^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:73:17
+  --> $DIR/unnecessary_to_owned.rs:74:17
    |
 LL |     require_str(&x_ref.to_string());
    |                 ^^^^^^^^^^^^^^^^^^ help: use: `x_ref.as_ref()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:75:19
+  --> $DIR/unnecessary_to_owned.rs:76:19
    |
 LL |     require_slice(&slice.to_vec());
    |                   ^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:76:36
+  --> $DIR/unnecessary_to_owned.rs:77:36
    |
 LL |     require_slice(&Cow::from(slice).into_owned());
    |                                    ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:77:19
+  --> $DIR/unnecessary_to_owned.rs:78:19
    |
 LL |     require_slice(&array.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `array.as_ref()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:78:19
+  --> $DIR/unnecessary_to_owned.rs:79:19
    |
 LL |     require_slice(&array_ref.to_owned());
    |                   ^^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref.as_ref()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:79:19
+  --> $DIR/unnecessary_to_owned.rs:80:19
    |
 LL |     require_slice(&slice.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:80:19
+  --> $DIR/unnecessary_to_owned.rs:81:19
    |
 LL |     require_slice(&x_ref.to_owned());
    |                   ^^^^^^^^^^^^^^^^^ help: use: `x_ref`
 
 error: unnecessary use of `into_owned`
-  --> $DIR/unnecessary_to_owned.rs:82:42
+  --> $DIR/unnecessary_to_owned.rs:83:42
    |
 LL |     require_x(&Cow::<X>::Owned(x.clone()).into_owned());
    |                                          ^^^^^^^^^^^^^ help: remove this
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:83:15
+  --> $DIR/unnecessary_to_owned.rs:84:15
    |
 LL |     require_x(&x_ref.to_owned());
    |               ^^^^^^^^^^^^^^^^^ help: use: `x_ref`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:85:25
+  --> $DIR/unnecessary_to_owned.rs:86:25
    |
 LL |     require_deref_c_str(c_str.to_owned());
    |                         ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:86:26
+  --> $DIR/unnecessary_to_owned.rs:87:26
    |
 LL |     require_deref_os_str(os_str.to_owned());
    |                          ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:87:24
+  --> $DIR/unnecessary_to_owned.rs:88:24
    |
 LL |     require_deref_path(path.to_owned());
    |                        ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:88:23
+  --> $DIR/unnecessary_to_owned.rs:89:23
    |
 LL |     require_deref_str(s.to_owned());
    |                       ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:89:25
+  --> $DIR/unnecessary_to_owned.rs:90:25
    |
 LL |     require_deref_slice(slice.to_owned());
    |                         ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:91:30
+  --> $DIR/unnecessary_to_owned.rs:92:30
    |
 LL |     require_impl_deref_c_str(c_str.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:92:31
+  --> $DIR/unnecessary_to_owned.rs:93:31
    |
 LL |     require_impl_deref_os_str(os_str.to_owned());
    |                               ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:93:29
+  --> $DIR/unnecessary_to_owned.rs:94:29
    |
 LL |     require_impl_deref_path(path.to_owned());
    |                             ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:94:28
+  --> $DIR/unnecessary_to_owned.rs:95:28
    |
 LL |     require_impl_deref_str(s.to_owned());
    |                            ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:95:30
+  --> $DIR/unnecessary_to_owned.rs:96:30
    |
 LL |     require_impl_deref_slice(slice.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:97:29
+  --> $DIR/unnecessary_to_owned.rs:98:29
    |
 LL |     require_deref_str_slice(s.to_owned(), slice.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:97:43
+  --> $DIR/unnecessary_to_owned.rs:98:43
    |
 LL |     require_deref_str_slice(s.to_owned(), slice.to_owned());
    |                                           ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:98:29
+  --> $DIR/unnecessary_to_owned.rs:99:29
    |
 LL |     require_deref_slice_str(slice.to_owned(), s.to_owned());
    |                             ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:98:47
+  --> $DIR/unnecessary_to_owned.rs:99:47
    |
 LL |     require_deref_slice_str(slice.to_owned(), s.to_owned());
    |                                               ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:100:26
+  --> $DIR/unnecessary_to_owned.rs:101:26
    |
 LL |     require_as_ref_c_str(c_str.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:101:27
+  --> $DIR/unnecessary_to_owned.rs:102:27
    |
 LL |     require_as_ref_os_str(os_str.to_owned());
    |                           ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:102:25
+  --> $DIR/unnecessary_to_owned.rs:103:25
    |
 LL |     require_as_ref_path(path.to_owned());
    |                         ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:103:24
+  --> $DIR/unnecessary_to_owned.rs:104:24
    |
 LL |     require_as_ref_str(s.to_owned());
    |                        ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:104:24
+  --> $DIR/unnecessary_to_owned.rs:105:24
    |
 LL |     require_as_ref_str(x.to_owned());
    |                        ^^^^^^^^^^^^ help: use: `&x`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:105:26
+  --> $DIR/unnecessary_to_owned.rs:106:26
    |
 LL |     require_as_ref_slice(array.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:106:26
+  --> $DIR/unnecessary_to_owned.rs:107:26
    |
 LL |     require_as_ref_slice(array_ref.to_owned());
    |                          ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:107:26
+  --> $DIR/unnecessary_to_owned.rs:108:26
    |
 LL |     require_as_ref_slice(slice.to_owned());
    |                          ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:109:31
+  --> $DIR/unnecessary_to_owned.rs:110:31
    |
 LL |     require_impl_as_ref_c_str(c_str.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `c_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:110:32
+  --> $DIR/unnecessary_to_owned.rs:111:32
    |
 LL |     require_impl_as_ref_os_str(os_str.to_owned());
    |                                ^^^^^^^^^^^^^^^^^ help: use: `os_str`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:111:30
+  --> $DIR/unnecessary_to_owned.rs:112:30
    |
 LL |     require_impl_as_ref_path(path.to_owned());
    |                              ^^^^^^^^^^^^^^^ help: use: `path`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:112:29
+  --> $DIR/unnecessary_to_owned.rs:113:29
    |
 LL |     require_impl_as_ref_str(s.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:113:29
+  --> $DIR/unnecessary_to_owned.rs:114:29
    |
 LL |     require_impl_as_ref_str(x.to_owned());
    |                             ^^^^^^^^^^^^ help: use: `&x`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:114:31
+  --> $DIR/unnecessary_to_owned.rs:115:31
    |
 LL |     require_impl_as_ref_slice(array.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:115:31
+  --> $DIR/unnecessary_to_owned.rs:116:31
    |
 LL |     require_impl_as_ref_slice(array_ref.to_owned());
    |                               ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:116:31
+  --> $DIR/unnecessary_to_owned.rs:117:31
    |
 LL |     require_impl_as_ref_slice(slice.to_owned());
    |                               ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:118:30
+  --> $DIR/unnecessary_to_owned.rs:119:30
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array.to_owned());
    |                              ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:118:44
+  --> $DIR/unnecessary_to_owned.rs:119:44
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array.to_owned());
    |                                            ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:119:30
+  --> $DIR/unnecessary_to_owned.rs:120:30
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
    |                              ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:119:44
+  --> $DIR/unnecessary_to_owned.rs:120:44
    |
 LL |     require_as_ref_str_slice(s.to_owned(), array_ref.to_owned());
    |                                            ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:120:30
+  --> $DIR/unnecessary_to_owned.rs:121:30
    |
 LL |     require_as_ref_str_slice(s.to_owned(), slice.to_owned());
    |                              ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:120:44
+  --> $DIR/unnecessary_to_owned.rs:121:44
    |
 LL |     require_as_ref_str_slice(s.to_owned(), slice.to_owned());
    |                                            ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:121:30
+  --> $DIR/unnecessary_to_owned.rs:122:30
    |
 LL |     require_as_ref_slice_str(array.to_owned(), s.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `array`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:121:48
+  --> $DIR/unnecessary_to_owned.rs:122:48
    |
 LL |     require_as_ref_slice_str(array.to_owned(), s.to_owned());
    |                                                ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:122:30
+  --> $DIR/unnecessary_to_owned.rs:123:30
    |
 LL |     require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
    |                              ^^^^^^^^^^^^^^^^^^^^ help: use: `array_ref`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:122:52
+  --> $DIR/unnecessary_to_owned.rs:123:52
    |
 LL |     require_as_ref_slice_str(array_ref.to_owned(), s.to_owned());
    |                                                    ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:123:30
+  --> $DIR/unnecessary_to_owned.rs:124:30
    |
 LL |     require_as_ref_slice_str(slice.to_owned(), s.to_owned());
    |                              ^^^^^^^^^^^^^^^^ help: use: `slice`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:123:48
+  --> $DIR/unnecessary_to_owned.rs:124:48
    |
 LL |     require_as_ref_slice_str(slice.to_owned(), s.to_owned());
    |                                                ^^^^^^^^^^^^ help: use: `s`
 
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:125:20
+  --> $DIR/unnecessary_to_owned.rs:126:20
    |
 LL |     let _ = x.join(&x_ref.to_string());
    |                    ^^^^^^^^^^^^^^^^^^ help: use: `x_ref`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:127:13
+  --> $DIR/unnecessary_to_owned.rs:128:13
    |
 LL |     let _ = slice.to_vec().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:128:13
+  --> $DIR/unnecessary_to_owned.rs:129:13
    |
 LL |     let _ = slice.to_owned().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:129:13
+  --> $DIR/unnecessary_to_owned.rs:130:13
    |
 LL |     let _ = [std::path::PathBuf::new()][..].to_vec().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:130:13
+  --> $DIR/unnecessary_to_owned.rs:131:13
    |
 LL |     let _ = [std::path::PathBuf::new()][..].to_owned().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:132:13
+  --> $DIR/unnecessary_to_owned.rs:133:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_vec());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:133:13
+  --> $DIR/unnecessary_to_owned.rs:134:13
    |
 LL |     let _ = IntoIterator::into_iter(slice.to_owned());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `slice.iter().copied()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:134:13
+  --> $DIR/unnecessary_to_owned.rs:135:13
    |
 LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_vec());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_owned`
-  --> $DIR/unnecessary_to_owned.rs:135:13
+  --> $DIR/unnecessary_to_owned.rs:136:13
    |
 LL |     let _ = IntoIterator::into_iter([std::path::PathBuf::new()][..].to_owned());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `[std::path::PathBuf::new()][..].iter().cloned()`
 
 error: unnecessary use of `to_vec`
-  --> $DIR/unnecessary_to_owned.rs:196:14
+  --> $DIR/unnecessary_to_owned.rs:197:14
    |
 LL |     for t in file_types.to_vec() {
    |              ^^^^^^^^^^^^^^^^^^^
@@ -491,11 +491,23 @@ LL -         let path = match get_file_path(&t) {
 LL +         let path = match get_file_path(t) {
    | 
 
+error: unnecessary use of `to_vec`
+  --> $DIR/unnecessary_to_owned.rs:220:14
+   |
+LL |     let _ = &["x"][..].to_vec().into_iter();
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().cloned()`
+
+error: unnecessary use of `to_vec`
+  --> $DIR/unnecessary_to_owned.rs:225:14
+   |
+LL |     let _ = &["x"][..].to_vec().into_iter();
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `["x"][..].iter().copied()`
+
 error: unnecessary use of `to_string`
-  --> $DIR/unnecessary_to_owned.rs:260:24
+  --> $DIR/unnecessary_to_owned.rs:272:24
    |
 LL |         Box::new(build(y.to_string()))
    |                        ^^^^^^^^^^^^^ help: use: `y`
 
-error: aborting due to 77 previous errors
+error: aborting due to 79 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
index 46463a29e9b..c223b5bc711 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.fixed
@@ -6,10 +6,13 @@
 #![allow(unreachable_patterns, irrefutable_let_patterns, unused_variables)]
 
 fn main() {
+    // Should be ignored by this lint, as nesting requires more characters.
+    if let &0 | &2 = &0 {}
+
     if let box (0 | 2) = Box::new(0) {}
     if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
-    const C0: &u8 = &1;
-    if let &(0 | 2) | C0 = &0 {}
+    const C0: Option<u8> = Some(1);
+    if let Some(1 | 2) | C0 = None {}
     if let &mut (0 | 2) = &mut 0 {}
     if let x @ (0 | 2) = 0 {}
     if let (0, 1 | 2 | 3) = (0, 0) {}
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.rs b/src/tools/clippy/tests/ui/unnested_or_patterns.rs
index 8ce0738bfc2..04cd11036e4 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.rs
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.rs
@@ -6,10 +6,13 @@
 #![allow(unreachable_patterns, irrefutable_let_patterns, unused_variables)]
 
 fn main() {
+    // Should be ignored by this lint, as nesting requires more characters.
+    if let &0 | &2 = &0 {}
+
     if let box 0 | box 2 = Box::new(0) {}
     if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}
-    const C0: &u8 = &1;
-    if let &0 | C0 | &2 = &0 {}
+    const C0: Option<u8> = Some(1);
+    if let Some(1) | C0 | Some(2) = None {}
     if let &mut 0 | &mut 2 = &mut 0 {}
     if let x @ 0 | x @ 2 = 0 {}
     if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}
diff --git a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
index de424c3fdb8..453c66cbba8 100644
--- a/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
+++ b/src/tools/clippy/tests/ui/unnested_or_patterns.stderr
@@ -1,5 +1,5 @@
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:9:12
+  --> $DIR/unnested_or_patterns.rs:12:12
    |
 LL |     if let box 0 | box 2 = Box::new(0) {}
    |            ^^^^^^^^^^^^^
@@ -11,7 +11,7 @@ LL |     if let box (0 | 2) = Box::new(0) {}
    |            ~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:10:12
+  --> $DIR/unnested_or_patterns.rs:13:12
    |
 LL |     if let box ((0 | 1)) | box (2 | 3) | box 4 = Box::new(0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -22,18 +22,18 @@ LL |     if let box (0 | 1 | 2 | 3 | 4) = Box::new(0) {}
    |            ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:12:12
+  --> $DIR/unnested_or_patterns.rs:15:12
    |
-LL |     if let &0 | C0 | &2 = &0 {}
-   |            ^^^^^^^^^^^^
+LL |     if let Some(1) | C0 | Some(2) = None {}
+   |            ^^^^^^^^^^^^^^^^^^^^^^
    |
 help: nest the patterns
    |
-LL |     if let &(0 | 2) | C0 = &0 {}
-   |            ~~~~~~~~~~~~~
+LL |     if let Some(1 | 2) | C0 = None {}
+   |            ~~~~~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:13:12
+  --> $DIR/unnested_or_patterns.rs:16:12
    |
 LL |     if let &mut 0 | &mut 2 = &mut 0 {}
    |            ^^^^^^^^^^^^^^^
@@ -44,7 +44,7 @@ LL |     if let &mut (0 | 2) = &mut 0 {}
    |            ~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:14:12
+  --> $DIR/unnested_or_patterns.rs:17:12
    |
 LL |     if let x @ 0 | x @ 2 = 0 {}
    |            ^^^^^^^^^^^^^
@@ -55,7 +55,7 @@ LL |     if let x @ (0 | 2) = 0 {}
    |            ~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:15:12
+  --> $DIR/unnested_or_patterns.rs:18:12
    |
 LL |     if let (0, 1) | (0, 2) | (0, 3) = (0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -66,7 +66,7 @@ LL |     if let (0, 1 | 2 | 3) = (0, 0) {}
    |            ~~~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:16:12
+  --> $DIR/unnested_or_patterns.rs:19:12
    |
 LL |     if let (1, 0) | (2, 0) | (3, 0) = (0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -77,7 +77,7 @@ LL |     if let (1 | 2 | 3, 0) = (0, 0) {}
    |            ~~~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:17:12
+  --> $DIR/unnested_or_patterns.rs:20:12
    |
 LL |     if let (x, ..) | (x, 1) | (x, 2) = (0, 1) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -88,7 +88,7 @@ LL |     if let (x, ..) | (x, 1 | 2) = (0, 1) {}
    |            ~~~~~~~~~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:18:12
+  --> $DIR/unnested_or_patterns.rs:21:12
    |
 LL |     if let [0] | [1] = [0] {}
    |            ^^^^^^^^^
@@ -99,7 +99,7 @@ LL |     if let [0 | 1] = [0] {}
    |            ~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:19:12
+  --> $DIR/unnested_or_patterns.rs:22:12
    |
 LL |     if let [x, 0] | [x, 1] = [0, 1] {}
    |            ^^^^^^^^^^^^^^^
@@ -110,7 +110,7 @@ LL |     if let [x, 0 | 1] = [0, 1] {}
    |            ~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:20:12
+  --> $DIR/unnested_or_patterns.rs:23:12
    |
 LL |     if let [x, 0] | [x, 1] | [x, 2] = [0, 1] {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -121,7 +121,7 @@ LL |     if let [x, 0 | 1 | 2] = [0, 1] {}
    |            ~~~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:21:12
+  --> $DIR/unnested_or_patterns.rs:24:12
    |
 LL |     if let [x, ..] | [x, 1] | [x, 2] = [0, 1] {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -132,7 +132,7 @@ LL |     if let [x, ..] | [x, 1 | 2] = [0, 1] {}
    |            ~~~~~~~~~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:23:12
+  --> $DIR/unnested_or_patterns.rs:26:12
    |
 LL |     if let TS(0, x) | TS(1, x) = TS(0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^
@@ -143,7 +143,7 @@ LL |     if let TS(0 | 1, x) = TS(0, 0) {}
    |            ~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:24:12
+  --> $DIR/unnested_or_patterns.rs:27:12
    |
 LL |     if let TS(1, 0) | TS(2, 0) | TS(3, 0) = TS(0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -154,7 +154,7 @@ LL |     if let TS(1 | 2 | 3, 0) = TS(0, 0) {}
    |            ~~~~~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:25:12
+  --> $DIR/unnested_or_patterns.rs:28:12
    |
 LL |     if let TS(x, ..) | TS(x, 1) | TS(x, 2) = TS(0, 0) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |     if let TS(x, ..) | TS(x, 1 | 2) = TS(0, 0) {}
    |            ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnested or-patterns
-  --> $DIR/unnested_or_patterns.rs:30:12
+  --> $DIR/unnested_or_patterns.rs:33:12
    |
 LL |     if let S { x: 0, y } | S { y, x: 1 } = (S { x: 0, y: 1 }) {}
    |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed
index ce58a80347b..c23231a99e9 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.fixed
+++ b/src/tools/clippy/tests/ui/useless_attribute.fixed
@@ -57,6 +57,12 @@ pub use std::io::prelude::*;
 #[allow(clippy::enum_glob_use)]
 pub use std::cmp::Ordering::*;
 
+// don't lint on clippy::redundant_pub_crate
+mod c {
+    #[allow(clippy::redundant_pub_crate)]
+    pub(crate) struct S;
+}
+
 fn test_indented_attr() {
     #![allow(clippy::almost_swapped)]
     use std::collections::HashSet;
diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs
index c82bb9ba07f..7a7b198ea60 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.rs
+++ b/src/tools/clippy/tests/ui/useless_attribute.rs
@@ -57,6 +57,12 @@ pub use std::io::prelude::*;
 #[allow(clippy::enum_glob_use)]
 pub use std::cmp::Ordering::*;
 
+// don't lint on clippy::redundant_pub_crate
+mod c {
+    #[allow(clippy::redundant_pub_crate)]
+    pub(crate) struct S;
+}
+
 fn test_indented_attr() {
     #[allow(clippy::almost_swapped)]
     use std::collections::HashSet;
diff --git a/src/tools/clippy/tests/ui/useless_attribute.stderr b/src/tools/clippy/tests/ui/useless_attribute.stderr
index d0194e4bbbe..255d2876355 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.stderr
+++ b/src/tools/clippy/tests/ui/useless_attribute.stderr
@@ -13,7 +13,7 @@ LL | #[cfg_attr(feature = "cargo-clippy", allow(dead_code))]
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![cfg_attr(feature = "cargo-clippy", allow(dead_code)`
 
 error: useless lint attribute
-  --> $DIR/useless_attribute.rs:61:5
+  --> $DIR/useless_attribute.rs:67:5
    |
 LL |     #[allow(clippy::almost_swapped)]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: if you just forgot a `!`, use: `#![allow(clippy::almost_swapped)]`
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.fixed b/src/tools/clippy/tests/ui/wildcard_imports.fixed
index 8402c33a4cd..b6f47ae906b 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports.fixed
@@ -8,8 +8,7 @@
 // FIXME: We should likely add another edition 2021 test case for this lint
 
 #![warn(clippy::wildcard_imports)]
-#![allow(unused)]
-#![allow(clippy::unnecessary_wraps)]
+#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]
 #![warn(unused_imports)]
 
 extern crate wildcard_imports_helper;
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.rs b/src/tools/clippy/tests/ui/wildcard_imports.rs
index faaeaade9b0..eb404b7a3de 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.rs
+++ b/src/tools/clippy/tests/ui/wildcard_imports.rs
@@ -8,8 +8,7 @@
 // FIXME: We should likely add another edition 2021 test case for this lint
 
 #![warn(clippy::wildcard_imports)]
-#![allow(unused)]
-#![allow(clippy::unnecessary_wraps)]
+#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]
 #![warn(unused_imports)]
 
 extern crate wildcard_imports_helper;
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.stderr b/src/tools/clippy/tests/ui/wildcard_imports.stderr
index 7534a65ec9b..626c1754fc8 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports.stderr
@@ -1,5 +1,5 @@
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:17:5
+  --> $DIR/wildcard_imports.rs:16:5
    |
 LL | use crate::fn_mod::*;
    |     ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
@@ -7,85 +7,85 @@ LL | use crate::fn_mod::*;
    = note: `-D clippy::wildcard-imports` implied by `-D warnings`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:18:5
+  --> $DIR/wildcard_imports.rs:17:5
    |
 LL | use crate::mod_mod::*;
    |     ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:19:5
+  --> $DIR/wildcard_imports.rs:18:5
    |
 LL | use crate::multi_fn_mod::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:21:5
+  --> $DIR/wildcard_imports.rs:20:5
    |
 LL | use crate::struct_mod::*;
    |     ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:25:5
+  --> $DIR/wildcard_imports.rs:24:5
    |
 LL | use wildcard_imports_helper::inner::inner_for_self_import::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:26:5
+  --> $DIR/wildcard_imports.rs:25:5
    |
 LL | use wildcard_imports_helper::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:97:13
+  --> $DIR/wildcard_imports.rs:96:13
    |
 LL |         use crate::fn_mod::*;
    |             ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:103:75
+  --> $DIR/wildcard_imports.rs:102:75
    |
 LL |         use wildcard_imports_helper::inner::inner_for_self_import::{self, *};
    |                                                                           ^ help: try: `inner_extern_foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:104:13
+  --> $DIR/wildcard_imports.rs:103:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:115:20
+  --> $DIR/wildcard_imports.rs:114:20
    |
 LL |         use self::{inner::*, inner2::*};
    |                    ^^^^^^^^ help: try: `inner::inner_foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:115:30
+  --> $DIR/wildcard_imports.rs:114:30
    |
 LL |         use self::{inner::*, inner2::*};
    |                              ^^^^^^^^^ help: try: `inner2::inner_bar`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:122:13
+  --> $DIR/wildcard_imports.rs:121:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:151:9
+  --> $DIR/wildcard_imports.rs:150:9
    |
 LL |     use crate::in_fn_test::*;
    |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:160:9
+  --> $DIR/wildcard_imports.rs:159:9
    |
 LL |     use crate:: in_fn_test::  * ;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:161:9
+  --> $DIR/wildcard_imports.rs:160:9
    |
 LL |       use crate:: fn_mod::
    |  _________^
@@ -93,37 +93,37 @@ LL | |         *;
    | |_________^ help: try: `crate:: fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:172:13
+  --> $DIR/wildcard_imports.rs:171:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:207:17
+  --> $DIR/wildcard_imports.rs:206:17
    |
 LL |             use super::*;
    |                 ^^^^^^^^ help: try: `super::insidefoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:215:13
+  --> $DIR/wildcard_imports.rs:214:13
    |
 LL |         use super_imports::*;
    |             ^^^^^^^^^^^^^^^^ help: try: `super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:224:17
+  --> $DIR/wildcard_imports.rs:223:17
    |
 LL |             use super::super::*;
    |                 ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:233:13
+  --> $DIR/wildcard_imports.rs:232:13
    |
 LL |         use super::super::super_imports::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:241:13
+  --> $DIR/wildcard_imports.rs:240:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention.rs b/src/tools/clippy/tests/ui/wrong_self_convention.rs
index f8fee4b3ab2..e3cc90ee222 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention.rs
+++ b/src/tools/clippy/tests/ui/wrong_self_convention.rs
@@ -193,11 +193,6 @@ pub mod issue8142 {
     struct S;
 
     impl S {
-        // Should lint: is_ methods should only take &self, or no self at all.
-        fn is_still_buggy(&mut self) -> bool {
-            false
-        }
-
         // Should not lint: "no self at all" is allowed.
         fn is_forty_two(x: u32) -> bool {
             x == 42
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention.stderr b/src/tools/clippy/tests/ui/wrong_self_convention.stderr
index 5493a99572e..2e7ee51d7e1 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention.stderr
+++ b/src/tools/clippy/tests/ui/wrong_self_convention.stderr
@@ -31,7 +31,7 @@ LL |     fn into_i32(&self) {}
    |
    = help: consider choosing a less ambiguous name
 
-error: methods called `is_*` usually take `self` by reference or no `self`
+error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`
   --> $DIR/wrong_self_convention.rs:38:15
    |
 LL |     fn is_i32(self) {}
@@ -71,7 +71,7 @@ LL |     pub fn into_i64(&self) {}
    |
    = help: consider choosing a less ambiguous name
 
-error: methods called `is_*` usually take `self` by reference or no `self`
+error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`
   --> $DIR/wrong_self_convention.rs:46:19
    |
 LL |     pub fn is_i64(self) {}
@@ -111,7 +111,7 @@ LL |         fn into_i32_ref(&self) {}
    |
    = help: consider choosing a less ambiguous name
 
-error: methods called `is_*` usually take `self` by reference or no `self`
+error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`
   --> $DIR/wrong_self_convention.rs:98:19
    |
 LL |         fn is_i32(self) {}
@@ -143,7 +143,7 @@ LL |         fn into_i32_ref(&self);
    |
    = help: consider choosing a less ambiguous name
 
-error: methods called `is_*` usually take `self` by reference or no `self`
+error: methods called `is_*` usually take `self` by mutable reference or `self` by reference or no `self`
   --> $DIR/wrong_self_convention.rs:122:19
    |
 LL |         fn is_i32(self);
@@ -191,13 +191,5 @@ LL |         fn to_u64(self) -> u64 {
    |
    = help: consider choosing a less ambiguous name
 
-error: methods called `is_*` usually take `self` by reference or no `self`
-  --> $DIR/wrong_self_convention.rs:197:27
-   |
-LL |         fn is_still_buggy(&mut self) -> bool {
-   |                           ^^^^^^^^^
-   |
-   = help: consider choosing a less ambiguous name
-
-error: aborting due to 25 previous errors
+error: aborting due to 24 previous errors
 
diff --git a/src/tools/clippy/tests/ui/wrong_self_convention2.rs b/src/tools/clippy/tests/ui/wrong_self_convention2.rs
index a8fe8331133..0dcf4743e8b 100644
--- a/src/tools/clippy/tests/ui/wrong_self_convention2.rs
+++ b/src/tools/clippy/tests/ui/wrong_self_convention2.rs
@@ -104,3 +104,13 @@ mod issue4546 {
         pub fn to_other_thingy(self: Pin<&Self>) {}
     }
 }
+
+mod issue_8480_8513 {
+    struct Cat(String);
+
+    impl Cat {
+        fn is_animal(&mut self) -> bool {
+            todo!();
+        }
+    }
+}