about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2023-10-06 17:35:45 +0200
committerPhilipp Krones <hello@philkrones.com>2023-10-06 17:35:45 +0200
commit3c8c3ad6dfa95afcf4e70ccd692f976fc238e24c (patch)
treed28de3863205b3e59dc7141e69b30c5ad40c31f7
parent1bc0463b183392ad4e0ae9c5f7a76630d487230d (diff)
parentb105fb4c39bc1a010807a6c076193cef8d93c109 (diff)
downloadrust-3c8c3ad6dfa95afcf4e70ccd692f976fc238e24c.tar.gz
rust-3c8c3ad6dfa95afcf4e70ccd692f976fc238e24c.zip
Merge commit 'b105fb4c39bc1a010807a6c076193cef8d93c109' into clippyup
-rw-r--r--src/tools/clippy/CHANGELOG.md97
-rw-r--r--src/tools/clippy/Cargo.toml4
-rw-r--r--src/tools/clippy/book/src/development/adding_lints.md2
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md1
-rw-r--r--src/tools/clippy/clippy_dev/src/new_lint.rs63
-rw-r--r--src/tools/clippy/clippy_lints/Cargo.toml5
-rw-r--r--src/tools/clippy/clippy_lints/src/allow_attributes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_clike.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/error_impl_error.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/four_forward_slashes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_hasher.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/items_after_test_module.rs108
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs249
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_float_methods.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_hash_one.rs133
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_let_else.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_assert_message.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_canonical_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/raw_strings.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs43
-rw-r--r--src/tools/clippy/clippy_lints/src/wildcard_imports.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs142
-rw-r--r--src/tools/clippy/clippy_utils/Cargo.toml2
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs69
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs31
-rw-r--r--src/tools/clippy/clippy_utils/src/msrvs.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs44
-rw-r--r--src/tools/clippy/declare_clippy_lint/Cargo.toml2
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/src/driver.rs55
-rw-r--r--src/tools/clippy/src/main.rs63
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs28
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.fixed15
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.rs15
-rw-r--r--src/tools/clippy/tests/ui/ignored_unit_patterns.stderr24
-rw-r--r--src/tools/clippy/tests/ui/infinite_loop.rs2
-rw-r--r--src/tools/clippy/tests/ui/infinite_loop.stderr33
-rw-r--r--src/tools/clippy/tests/ui/into_iter_without_iter.rs124
-rw-r--r--src/tools/clippy/tests/ui/into_iter_without_iter.stderr114
-rw-r--r--src/tools/clippy/tests/ui/items_after_test_module/after_proc_macros.rs11
-rw-r--r--src/tools/clippy/tests/ui/items_after_test_module/auxiliary/submodule.rs4
-rw-r--r--src/tools/clippy/tests/ui/items_after_test_module/block_module.stderr2
-rw-r--r--src/tools/clippy/tests/ui/items_after_test_module/in_submodule.rs8
-rw-r--r--src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr14
-rw-r--r--src/tools/clippy/tests/ui/items_after_test_module/multiple_modules.rs11
-rw-r--r--src/tools/clippy/tests/ui/items_after_test_module/root_module.fixed (renamed from src/tools/clippy/tests/ui/items_after_test_module/block_module.rs)15
-rw-r--r--src/tools/clippy/tests/ui/items_after_test_module/root_module.rs22
-rw-r--r--src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr20
-rw-r--r--src/tools/clippy/tests/ui/iter_without_into_iter.rs120
-rw-r--r--src/tools/clippy/tests/ui/iter_without_into_iter.stderr150
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_future.rs2
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_future.stderr17
-rw-r--r--src/tools/clippy/tests/ui/manual_hash_one.fixed89
-rw-r--r--src/tools/clippy/tests/ui/manual_hash_one.rs89
-rw-r--r--src/tools/clippy/tests/ui/manual_hash_one.stderr56
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.fixed4
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.rs8
-rw-r--r--src/tools/clippy/tests/ui/manual_let_else_match.stderr12
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs3
-rw-r--r--src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr20
-rw-r--r--src/tools/clippy/tests/ui/mut_key.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_key.stderr41
-rw-r--r--src/tools/clippy/tests/ui/mut_reference.rs2
-rw-r--r--src/tools/clippy/tests/ui/mut_reference.stderr17
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs1
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr42
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string.fixed4
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string.rs4
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string.stderr46
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr30
-rw-r--r--src/tools/clippy/tests/ui/print_literal.fixed18
-rw-r--r--src/tools/clippy/tests/ui/print_literal.rs18
-rw-r--r--src/tools/clippy/tests/ui/print_literal.stderr124
-rw-r--r--src/tools/clippy/tests/ui/redundant_locals.rs37
-rw-r--r--src/tools/clippy/tests/ui/redundant_locals.stderr139
-rw-r--r--src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs2
-rw-r--r--src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr36
-rw-r--r--src/tools/clippy/tests/ui/slow_vector_initialization.rs2
-rw-r--r--src/tools/clippy/tests/ui/slow_vector_initialization.stderr11
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.fixed11
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.rs11
-rw-r--r--src/tools/clippy/tests/ui/std_instead_of_core.stderr22
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.fixed28
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.rs28
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports.stderr38
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed28
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr38
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed28
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr38
-rw-r--r--src/tools/clippy/tests/ui/wildcard_imports_2021.rs28
-rw-r--r--src/tools/clippy/tests/ui/write_literal.fixed14
-rw-r--r--src/tools/clippy/tests/ui/write_literal.rs14
-rw-r--r--src/tools/clippy/tests/ui/write_literal.stderr74
-rw-r--r--src/tools/clippy/tests/ui/write_literal_2.rs16
-rw-r--r--src/tools/clippy/tests/ui/write_literal_2.stderr82
108 files changed, 2637 insertions, 768 deletions
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 8c9ab1e2402..fef25ad8635 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -6,11 +6,101 @@ document.
 
 ## Unreleased / Beta / In Rust Nightly
 
-[37f4c172...master](https://github.com/rust-lang/rust-clippy/compare/37f4c172...master)
+[1e8fdf49...master](https://github.com/rust-lang/rust-clippy/compare/1e8fdf49...master)
+
+## Rust 1.73
+
+Current stable, released 2023-10-05
+
+[View all 103 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-07-02T12%3A24%3A40Z..2023-08-11T11%3A09%3A56Z+base%3Amaster)
+
+### New Lints
+
+* [`impossible_comparisons`]
+  [#10843](https://github.com/rust-lang/rust-clippy/pull/10843)
+* [`redundant_comparisons`]
+  [#10843](https://github.com/rust-lang/rust-clippy/pull/10843)
+* [`ignored_unit_patterns`]
+  [#11242](https://github.com/rust-lang/rust-clippy/pull/11242)
+* [`readonly_write_lock`]
+  [#11210](https://github.com/rust-lang/rust-clippy/pull/11210)
+* [`filter_map_bool_then`]
+  [#11115](https://github.com/rust-lang/rust-clippy/pull/11115)
+* [`needless_return_with_question_mark`]
+  [#11031](https://github.com/rust-lang/rust-clippy/pull/11031)
+* [`redundant_guards`]
+  [#10955](https://github.com/rust-lang/rust-clippy/pull/10955)
+* [`redundant_locals`]
+  [#10885](https://github.com/rust-lang/rust-clippy/pull/10885)
+* [`absolute_paths`]
+  [#11003](https://github.com/rust-lang/rust-clippy/pull/11003)
+* [`error_impl_error`]
+  [#11107](https://github.com/rust-lang/rust-clippy/pull/11107)
+* [`iter_skip_zero`]
+  [#11046](https://github.com/rust-lang/rust-clippy/pull/11046)
+* [`string_lit_chars_any`]
+  [#11052](https://github.com/rust-lang/rust-clippy/pull/11052)
+* [`four_forward_slashes`]
+  [#11140](https://github.com/rust-lang/rust-clippy/pull/11140)
+* [`format_collect`]
+  [#11116](https://github.com/rust-lang/rust-clippy/pull/11116)
+* [`needless_pass_by_ref_mut`]
+  [#10900](https://github.com/rust-lang/rust-clippy/pull/10900)
+* [`manual_is_infinite`]
+  [#11049](https://github.com/rust-lang/rust-clippy/pull/11049)
+* [`manual_is_finite`]
+  [#11049](https://github.com/rust-lang/rust-clippy/pull/11049)
+* [`incorrect_partial_ord_impl_on_ord_type`]
+  [#10788](https://github.com/rust-lang/rust-clippy/pull/10788)
+* [`read_line_without_trim`]
+  [#10970](https://github.com/rust-lang/rust-clippy/pull/10970)
+* [`type_id_on_box`]
+  [#10987](https://github.com/rust-lang/rust-clippy/pull/10987)
+
+### Moves and Deprecations
+
+* Renamed `unwrap_or_else_default` to [`unwrap_or_default`]
+  [#10120](https://github.com/rust-lang/rust-clippy/pull/10120)
+* Moved [`tuple_array_conversions`] to `pedantic` (Now allow-by-default)
+  [#11146](https://github.com/rust-lang/rust-clippy/pull/11146)
+* Moved [`arc_with_non_send_sync`] to `suspicious` (Now warn-by-default)
+  [#11104](https://github.com/rust-lang/rust-clippy/pull/11104)
+* Moved [`needless_raw_string_hashes`] to `pedantic` (Now allow-by-default)
+  [#11415](https://github.com/rust-lang/rust-clippy/pull/11415)
+
+### Enhancements
+
+* [`unwrap_used`]: No longer lints on the never-type or never-like enums
+  [#11252](https://github.com/rust-lang/rust-clippy/pull/11252)
+* [`expect_used`]: No longer lints on the never-type or never-like enums
+  [#11252](https://github.com/rust-lang/rust-clippy/pull/11252)
+
+### False Positive Fixes
+
+* [`panic_in_result_fn`]: No longer triggers on `todo!`, `unimplemented!`, `unreachable!`
+  [#11123](https://github.com/rust-lang/rust-clippy/pull/11123)
+
+### Suggestion Fixes/Improvements
+
+* [`semicolon_if_nothing_returned`]: The suggestion is now machine-applicable with rustfix
+  [#11083](https://github.com/rust-lang/rust-clippy/pull/11083)
+
+### ICE Fixes
+
+* [`filter_map_bool_then`]: No longer crashes on late-bound regions
+  [#11318](https://github.com/rust-lang/rust-clippy/pull/11318)
+* [`unwrap_or_default`]: No longer crashes on alias types for local items
+  [#11258](https://github.com/rust-lang/rust-clippy/pull/11258)
+* [`unnecessary_literal_unwrap`]: No longer crashes on `None.unwrap_or_default()`
+  [#11106](https://github.com/rust-lang/rust-clippy/pull/11106)
+* Fixed MIR-related ICE
+  [#11130](https://github.com/rust-lang/rust-clippy/pull/11130)
+* [`missing_fields_in_debug`]: No longer crashes on non-ADT self types
+  [#11069](https://github.com/rust-lang/rust-clippy/pull/11069)
 
 ## Rust 1.72
 
-Current stable, released 2023-08-24
+Released 2023-08-24
 
 [View all 131 merged pull requests](https://github.com/rust-lang/rust-clippy/pulls?q=merged%3A2023-05-22T14%3A53%3A59Z..2023-07-01T22%3A57%3A20Z+base%3Amaster)
 
@@ -5011,6 +5101,7 @@ Released 2018-09-13
 [`integer_division`]: https://rust-lang.github.io/rust-clippy/master/index.html#integer_division
 [`into_iter_on_array`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_array
 [`into_iter_on_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_on_ref
+[`into_iter_without_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#into_iter_without_iter
 [`invalid_atomic_ordering`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_atomic_ordering
 [`invalid_null_ptr_usage`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_null_ptr_usage
 [`invalid_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#invalid_ref
@@ -5036,6 +5127,7 @@ Released 2018-09-13
 [`iter_skip_next`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_next
 [`iter_skip_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_skip_zero
 [`iter_with_drain`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_with_drain
+[`iter_without_into_iter`]: https://rust-lang.github.io/rust-clippy/master/index.html#iter_without_into_iter
 [`iterator_step_by_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#iterator_step_by_zero
 [`just_underscores_and_digits`]: https://rust-lang.github.io/rust-clippy/master/index.html#just_underscores_and_digits
 [`large_const_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_const_arrays
@@ -5072,6 +5164,7 @@ Released 2018-09-13
 [`manual_find`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find
 [`manual_find_map`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_find_map
 [`manual_flatten`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_flatten
+[`manual_hash_one`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one
 [`manual_instant_elapsed`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_instant_elapsed
 [`manual_is_ascii_check`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_ascii_check
 [`manual_is_finite`]: https://rust-lang.github.io/rust-clippy/master/index.html#manual_is_finite
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 66786004f6e..cbcb42dad79 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy"
-version = "0.1.74"
+version = "0.1.75"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
@@ -25,6 +25,8 @@ clippy_lints = { path = "clippy_lints" }
 rustc_tools_util = "0.3.0"
 tempfile = { version = "3.2", optional = true }
 termize = "0.1"
+color-print = "0.3.4" # Sync version with Cargo
+anstream = "0.5.0"
 
 [dev-dependencies]
 ui_test = "0.20"
diff --git a/src/tools/clippy/book/src/development/adding_lints.md b/src/tools/clippy/book/src/development/adding_lints.md
index f6f0c95c729..e001197842b 100644
--- a/src/tools/clippy/book/src/development/adding_lints.md
+++ b/src/tools/clippy/book/src/development/adding_lints.md
@@ -261,7 +261,7 @@ impl EarlyLintPass for FooFunctions {}
 [declare_clippy_lint]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L60
 [example_lint_page]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
 [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
-[category_level_mapping]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L110
+[category_level_mapping]: ../index.html
 
 ## Lint registration
 
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index b980083f1f5..2c958ccbbc2 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -151,6 +151,7 @@ The minimum rust version that the project supports
 * [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)
 * [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)
 * [`manual_try_fold`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_try_fold)
+* [`manual_hash_one`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_hash_one)
 
 
 ## `cognitive-complexity-threshold`
diff --git a/src/tools/clippy/clippy_dev/src/new_lint.rs b/src/tools/clippy/clippy_dev/src/new_lint.rs
index e64cf2c8749..be2386bb1d2 100644
--- a/src/tools/clippy/clippy_dev/src/new_lint.rs
+++ b/src/tools/clippy/clippy_dev/src/new_lint.rs
@@ -58,7 +58,7 @@ pub fn create(
     };
 
     create_lint(&lint, msrv).context("Unable to create lint implementation")?;
-    create_test(&lint).context("Unable to create a test for the new lint")?;
+    create_test(&lint, msrv).context("Unable to create a test for the new lint")?;
 
     if lint.ty.is_none() {
         add_lint(&lint, msrv).context("Unable to add lint to clippy_lints/src/lib.rs")?;
@@ -88,15 +88,21 @@ fn create_lint(lint: &LintData<'_>, enable_msrv: bool) -> io::Result<()> {
     }
 }
 
-fn create_test(lint: &LintData<'_>) -> io::Result<()> {
-    fn create_project_layout<P: Into<PathBuf>>(lint_name: &str, location: P, case: &str, hint: &str) -> io::Result<()> {
+fn create_test(lint: &LintData<'_>, msrv: bool) -> io::Result<()> {
+    fn create_project_layout<P: Into<PathBuf>>(
+        lint_name: &str,
+        location: P,
+        case: &str,
+        hint: &str,
+        msrv: bool,
+    ) -> io::Result<()> {
         let mut path = location.into().join(case);
         fs::create_dir(&path)?;
         write_file(path.join("Cargo.toml"), get_manifest_contents(lint_name, hint))?;
 
         path.push("src");
         fs::create_dir(&path)?;
-        write_file(path.join("main.rs"), get_test_file_contents(lint_name))?;
+        write_file(path.join("main.rs"), get_test_file_contents(lint_name, msrv))?;
 
         Ok(())
     }
@@ -106,13 +112,25 @@ fn create_test(lint: &LintData<'_>) -> io::Result<()> {
         let test_dir = lint.project_root.join(&relative_test_dir);
         fs::create_dir(&test_dir)?;
 
-        create_project_layout(lint.name, &test_dir, "fail", "Content that triggers the lint goes here")?;
-        create_project_layout(lint.name, &test_dir, "pass", "This file should not trigger the lint")?;
+        create_project_layout(
+            lint.name,
+            &test_dir,
+            "fail",
+            "Content that triggers the lint goes here",
+            msrv,
+        )?;
+        create_project_layout(
+            lint.name,
+            &test_dir,
+            "pass",
+            "This file should not trigger the lint",
+            false,
+        )?;
 
         println!("Generated test directories: `{relative_test_dir}/pass`, `{relative_test_dir}/fail`");
     } else {
         let test_path = format!("tests/ui/{}.rs", lint.name);
-        let test_contents = get_test_file_contents(lint.name);
+        let test_contents = get_test_file_contents(lint.name, msrv);
         write_file(lint.project_root.join(&test_path), test_contents)?;
 
         println!("Generated test file: `{test_path}`");
@@ -194,8 +212,8 @@ pub(crate) fn get_stabilization_version() -> String {
     parse_manifest(&contents).expect("Unable to find package version in `Cargo.toml`")
 }
 
-fn get_test_file_contents(lint_name: &str) -> String {
-    formatdoc!(
+fn get_test_file_contents(lint_name: &str, msrv: bool) -> String {
+    let mut test = formatdoc!(
         r#"
         #![warn(clippy::{lint_name})]
 
@@ -203,7 +221,29 @@ fn get_test_file_contents(lint_name: &str) -> String {
             // test code goes here
         }}
     "#
-    )
+    );
+
+    if msrv {
+        let _ = writedoc!(
+            test,
+            r#"
+
+                // TODO: set xx to the version one below the MSRV used by the lint, and yy to
+                // the version used by the lint
+                #[clippy::msrv = "1.xx"]
+                fn msrv_1_xx() {{
+                    // a simple example that would trigger the lint if the MSRV were met
+                }}
+
+                #[clippy::msrv = "1.yy"]
+                fn msrv_1_yy() {{
+                    // the same example as above
+                }}
+            "#
+        );
+    }
+
+    test
 }
 
 fn get_manifest_contents(lint_name: &str, hint: &str) -> String {
@@ -258,7 +298,7 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
         )
     });
 
-    let _: fmt::Result = write!(result, "{}", get_lint_declaration(&name_upper, category));
+    let _: fmt::Result = writeln!(result, "{}", get_lint_declaration(&name_upper, category));
 
     result.push_str(&if enable_msrv {
         formatdoc!(
@@ -281,7 +321,6 @@ fn get_lint_file_contents(lint: &LintData<'_>, enable_msrv: bool) -> String {
             }}
 
             // TODO: Add MSRV level to `clippy_utils/src/msrvs.rs` if needed.
-            // TODO: Add MSRV test to `tests/ui/min_rust_version_attr.rs`.
             // TODO: Update msrv config comment in `clippy_lints/src/utils/conf.rs`
         "#
         )
diff --git a/src/tools/clippy/clippy_lints/Cargo.toml b/src/tools/clippy/clippy_lints/Cargo.toml
index dcd9a4adcbd..4d5b3bf8a94 100644
--- a/src/tools/clippy/clippy_lints/Cargo.toml
+++ b/src/tools/clippy/clippy_lints/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_lints"
-version = "0.1.74"
+version = "0.1.75"
 description = "A bunch of helpful lints to avoid common pitfalls in Rust"
 repository = "https://github.com/rust-lang/rust-clippy"
 readme = "README.md"
@@ -28,6 +28,9 @@ semver = "1.0"
 rustc-semver = "1.1"
 url = "2.2"
 
+[dev-dependencies]
+walkdir = "2.3"
+
 [features]
 deny-warnings = ["clippy_utils/deny-warnings"]
 # build clippy with internal lints enabled, off by default
diff --git a/src/tools/clippy/clippy_lints/src/allow_attributes.rs b/src/tools/clippy/clippy_lints/src/allow_attributes.rs
index e1ef514edfd..e3f4cf79d31 100644
--- a/src/tools/clippy/clippy_lints/src/allow_attributes.rs
+++ b/src/tools/clippy/clippy_lints/src/allow_attributes.rs
@@ -8,6 +8,7 @@ use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
 declare_clippy_lint! {
+    /// ### What it does
     /// Checks for usage of the `#[allow]` attribute and suggests replacing it with
     /// the `#[expect]` (See [RFC 2383](https://rust-lang.github.io/rfcs/2383-lint-reasons.html))
     ///
@@ -19,7 +20,6 @@ declare_clippy_lint! {
     /// (`#![allow]`) are usually used to enable or disable lints on a global scale.
     ///
     /// ### Why is this bad?
-    ///
     /// `#[expect]` attributes suppress the lint emission, but emit a warning, if
     /// the expectation is unfulfilled. This can be useful to be notified when the
     /// lint is no longer triggered.
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index 4d1281ec1e7..481c44031cf 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -229,6 +229,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::items_after_statements::ITEMS_AFTER_STATEMENTS_INFO,
     crate::items_after_test_module::ITEMS_AFTER_TEST_MODULE_INFO,
     crate::iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR_INFO,
+    crate::iter_without_into_iter::INTO_ITER_WITHOUT_ITER_INFO,
+    crate::iter_without_into_iter::ITER_WITHOUT_INTO_ITER_INFO,
     crate::large_const_arrays::LARGE_CONST_ARRAYS_INFO,
     crate::large_enum_variant::LARGE_ENUM_VARIANT_INFO,
     crate::large_futures::LARGE_FUTURES_INFO,
@@ -280,6 +282,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::manual_clamp::MANUAL_CLAMP_INFO,
     crate::manual_float_methods::MANUAL_IS_FINITE_INFO,
     crate::manual_float_methods::MANUAL_IS_INFINITE_INFO,
+    crate::manual_hash_one::MANUAL_HASH_ONE_INFO,
     crate::manual_is_ascii_check::MANUAL_IS_ASCII_CHECK_INFO,
     crate::manual_let_else::MANUAL_LET_ELSE_INFO,
     crate::manual_main_separator_str::MANUAL_MAIN_SEPARATOR_STR_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs
index 3f60e5a7c4d..646767868e2 100644
--- a/src/tools/clippy/clippy_lints/src/enum_clike.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs
@@ -1,7 +1,7 @@
 //! lint on C-like enums that are `repr(isize/usize)` and have values that
 //! don't fit into an `i32`
 
-use clippy_utils::consts::{miri_to_const, Constant};
+use clippy_utils::consts::{mir_to_const, Constant};
 use clippy_utils::diagnostics::span_lint;
 use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -51,7 +51,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant {
                         .const_eval_poly(def_id.to_def_id())
                         .ok()
                         .map(|val| rustc_middle::mir::Const::from_value(val, ty));
-                    if let Some(Constant::Int(val)) = constant.and_then(|c| miri_to_const(cx, c)) {
+                    if let Some(Constant::Int(val)) = constant.and_then(|c| mir_to_const(cx, c)) {
                         if let ty::Adt(adt, _) = ty.kind() {
                             if adt.is_enum() {
                                 ty = adt.repr().discr_type().to_ty(cx.tcx);
diff --git a/src/tools/clippy/clippy_lints/src/error_impl_error.rs b/src/tools/clippy/clippy_lints/src/error_impl_error.rs
index f24577c7382..6d429fbd035 100644
--- a/src/tools/clippy/clippy_lints/src/error_impl_error.rs
+++ b/src/tools/clippy/clippy_lints/src/error_impl_error.rs
@@ -27,7 +27,7 @@ declare_clippy_lint! {
     ///
     /// impl std::error::Error for Error { ... }
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub ERROR_IMPL_ERROR,
     restriction,
     "exported types named `Error` that implement `Error`"
diff --git a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs
index 419c7734344..0ec52f89e71 100644
--- a/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs
+++ b/src/tools/clippy/clippy_lints/src/four_forward_slashes.rs
@@ -28,7 +28,7 @@ declare_clippy_lint! {
     ///     // ...
     /// }
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub FOUR_FORWARD_SLASHES,
     suspicious,
     "comments with 4 forward slashes (`////`) likely intended to be doc comments (`///`)"
diff --git a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
index d8ead1c9d9f..ef2a66d4a20 100644
--- a/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/ignored_unit_patterns.rs
@@ -37,6 +37,10 @@ declare_lint_pass!(IgnoredUnitPatterns => [IGNORED_UNIT_PATTERNS]);
 
 impl<'tcx> LateLintPass<'tcx> for IgnoredUnitPatterns {
     fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx hir::Pat<'tcx>) {
+        if pat.span.from_expansion() {
+            return;
+        }
+
         match cx.tcx.hir().get_parent(pat.hir_id) {
             Node::Param(param) if matches!(cx.tcx.hir().get_parent(param.hir_id), Node::Item(_)) => {
                 // Ignore function parameters
diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
index 64a4a3fa741..2b2ea156cd4 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
@@ -6,9 +6,8 @@ use rustc_hir as hir;
 use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor};
 use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
 use rustc_hir_analysis::hir_ty_to_ty;
-use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
-use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{Ty, TypeckResults};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::source_map::Span;
@@ -162,7 +161,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
                     vis.visit_ty(ty);
 
                     for target in &vis.found {
-                        if in_external_macro(cx.sess(), generics.span) {
+                        if generics.span.from_expansion() {
                             continue;
                         }
                         let generics_suggestion_span = generics.span.substitute_dummy({
diff --git a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs
index 55a43e91562..41477242bcc 100644
--- a/src/tools/clippy/clippy_lints/src/items_after_test_module.rs
+++ b/src/tools/clippy/clippy_lints/src/items_after_test_module.rs
@@ -1,10 +1,12 @@
-use clippy_utils::diagnostics::span_lint_and_help;
-use clippy_utils::{is_from_proc_macro, is_in_cfg_test};
-use rustc_hir::{HirId, ItemId, ItemKind, Mod};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
+use clippy_utils::diagnostics::span_lint_hir_and_then;
+use clippy_utils::source::snippet_opt;
+use clippy_utils::{fulfill_or_allowed, is_cfg_test, is_from_proc_macro};
+use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_hir::{HirId, Item, ItemKind, Mod};
+use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::{sym, Span};
+use rustc_span::hygiene::AstPass;
+use rustc_span::{sym, ExpnKind};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -41,46 +43,72 @@ declare_clippy_lint! {
 
 declare_lint_pass!(ItemsAfterTestModule => [ITEMS_AFTER_TEST_MODULE]);
 
-impl LateLintPass<'_> for ItemsAfterTestModule {
-    fn check_mod(&mut self, cx: &LateContext<'_>, _: &Mod<'_>, _: HirId) {
-        let mut was_test_mod_visited = false;
-        let mut test_mod_span: Option<Span> = None;
+fn cfg_test_module<'tcx>(cx: &LateContext<'tcx>, item: &Item<'tcx>) -> bool {
+    if let ItemKind::Mod(test_mod) = item.kind
+        && item.span.hi() == test_mod.spans.inner_span.hi()
+        && is_cfg_test(cx.tcx, item.hir_id())
+        && !item.span.from_expansion()
+        && !is_from_proc_macro(cx, item)
+    {
+        true
+    } else {
+        false
+    }
+}
 
-        let hir = cx.tcx.hir();
-        let items = hir.items().collect::<Vec<ItemId>>();
+impl LateLintPass<'_> for ItemsAfterTestModule {
+    fn check_mod(&mut self, cx: &LateContext<'_>, module: &Mod<'_>, _: HirId) {
+        let mut items = module.item_ids.iter().map(|&id| cx.tcx.hir().item(id));
 
-        for (i, itid) in items.iter().enumerate() {
-            let item = hir.item(*itid);
+        let Some((mod_pos, test_mod)) = items.by_ref().enumerate().find(|(_, item)| cfg_test_module(cx, item)) else {
+            return;
+        };
 
-            if_chain! {
-            if was_test_mod_visited;
-            if i == (items.len() - 3 /* Weird magic number (HIR-translation behaviour) */);
-            if cx.sess().source_map().lookup_char_pos(item.span.lo()).file.name_hash
-            == cx.sess().source_map().lookup_char_pos(test_mod_span.unwrap().lo()).file.name_hash; // Will never fail
-            if !matches!(item.kind, ItemKind::Mod(_));
-            if !is_in_cfg_test(cx.tcx, itid.hir_id()); // The item isn't in the testing module itself
-            if !in_external_macro(cx.sess(), item.span);
-            if !is_from_proc_macro(cx, item);
+        let after: Vec<_> = items
+            .filter(|item| {
+                // Ignore the generated test main function
+                !(item.ident.name == sym::main
+                    && item.span.ctxt().outer_expn_data().kind == ExpnKind::AstPass(AstPass::TestHarness))
+            })
+            .collect();
 
-            then {
-                span_lint_and_help(cx, ITEMS_AFTER_TEST_MODULE, test_mod_span.unwrap().with_hi(item.span.hi()), "items were found after the testing module", None, "move the items to before the testing module was defined");
-            }};
+        if let Some(last) = after.last()
+            && after.iter().all(|&item| {
+                !matches!(item.kind, ItemKind::Mod(_))
+                    && !item.span.from_expansion()
+                    && !is_from_proc_macro(cx, item)
+            })
+            && !fulfill_or_allowed(cx, ITEMS_AFTER_TEST_MODULE, after.iter().map(|item| item.hir_id()))
+        {
+            let def_spans: Vec<_> = std::iter::once(test_mod.owner_id)
+                .chain(after.iter().map(|item| item.owner_id))
+                .map(|id| cx.tcx.def_span(id))
+                .collect();
 
-            if let ItemKind::Mod(module) = item.kind && item.span.hi() == module.spans.inner_span.hi() {
-			// Check that it works the same way, the only I way I've found for #10713
-				for attr in cx.tcx.get_attrs(item.owner_id.to_def_id(), sym::cfg) {
-					if_chain! {
-						if attr.has_name(sym::cfg);
-                        if let Some(mitems) = attr.meta_item_list();
-                        if let [mitem] = &*mitems;
-                        if mitem.has_name(sym::test);
-                        then {
-							was_test_mod_visited = true;
-                            test_mod_span = Some(item.span);
-                        }
+            span_lint_hir_and_then(
+                cx,
+                ITEMS_AFTER_TEST_MODULE,
+                test_mod.hir_id(),
+                def_spans,
+                "items after a test module",
+                |diag| {
+                    if let Some(prev) = mod_pos.checked_sub(1)
+                        && let prev = cx.tcx.hir().item(module.item_ids[prev])
+                        && let items_span = last.span.with_lo(test_mod.span.hi())
+                        && let Some(items) = snippet_opt(cx, items_span)
+                    {
+                        diag.multipart_suggestion_with_style(
+                            "move the items to before the test module was defined",
+                            vec![
+                                (prev.span.shrink_to_hi(), items),
+                                (items_span, String::new())
+                            ],
+                            Applicability::MachineApplicable,
+                            SuggestionStyle::HideCodeAlways,
+                        );
                     }
-                }
-			}
+                },
+            );
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
new file mode 100644
index 00000000000..43e1b92c9b9
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
@@ -0,0 +1,249 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::get_parent_as_impl;
+use clippy_utils::source::snippet;
+use clippy_utils::ty::{implements_trait, make_normalized_projection};
+use rustc_ast::Mutability;
+use rustc_errors::Applicability;
+use rustc_hir::{FnRetTy, ImplItemKind, ImplicitSelfKind, ItemKind, TyKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::{self, Ty};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::{sym, Symbol};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Looks for `iter` and `iter_mut` methods without an associated `IntoIterator for (&|&mut) Type` implementation.
+    ///
+    /// ### Why is this bad?
+    /// It's not bad, but having them is idiomatic and allows the type to be used in for loops directly
+    /// (`for val in &iter {}`), without having to first call `iter()` or `iter_mut()`.
+    ///
+    /// ### Example
+    /// ```rust
+    /// struct MySlice<'a>(&'a [u8]);
+    /// impl<'a> MySlice<'a> {
+    ///     pub fn iter(&self) -> std::slice::Iter<'a, u8> {
+    ///         self.0.iter()
+    ///     }
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// struct MySlice<'a>(&'a [u8]);
+    /// impl<'a> MySlice<'a> {
+    ///     pub fn iter(&self) -> std::slice::Iter<'a, u8> {
+    ///         self.0.iter()
+    ///     }
+    /// }
+    /// impl<'a> IntoIterator for &MySlice<'a> {
+    ///     type Item = &'a u8;
+    ///     type IntoIter = std::slice::Iter<'a, u8>;
+    ///     fn into_iter(self) -> Self::IntoIter {
+    ///         self.iter()
+    ///     }
+    /// }
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub ITER_WITHOUT_INTO_ITER,
+    pedantic,
+    "implementing `iter(_mut)` without an associated `IntoIterator for (&|&mut) Type` impl"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// This is the opposite of the `iter_without_into_iter` lint.
+    /// It looks for `IntoIterator for (&|&mut) Type` implementations without an inherent `iter` or `iter_mut` method.
+    ///
+    /// ### Why is this bad?
+    /// It's not bad, but having them is idiomatic and allows the type to be used in iterator chains
+    /// by just calling `.iter()`, instead of the more awkward `<&Type>::into_iter` or `(&val).iter()` syntax
+    /// in case of ambiguity with another `Intoiterator` impl.
+    ///
+    /// ### Example
+    /// ```rust
+    /// struct MySlice<'a>(&'a [u8]);
+    /// impl<'a> IntoIterator for &MySlice<'a> {
+    ///     type Item = &'a u8;
+    ///     type IntoIter = std::slice::Iter<'a, u8>;
+    ///     fn into_iter(self) -> Self::IntoIter {
+    ///         self.0.iter()
+    ///     }
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// struct MySlice<'a>(&'a [u8]);
+    /// impl<'a> MySlice<'a> {
+    ///     pub fn iter(&self) -> std::slice::Iter<'a, u8> {
+    ///         self.into_iter()
+    ///     }
+    /// }
+    /// impl<'a> IntoIterator for &MySlice<'a> {
+    ///     type Item = &'a u8;
+    ///     type IntoIter = std::slice::Iter<'a, u8>;
+    ///     fn into_iter(self) -> Self::IntoIter {
+    ///         self.0.iter()
+    ///     }
+    /// }
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub INTO_ITER_WITHOUT_ITER,
+    pedantic,
+    "implementing `IntoIterator for (&|&mut) Type` without an inherent `iter(_mut)` method"
+}
+
+declare_lint_pass!(IterWithoutIntoIter => [ITER_WITHOUT_INTO_ITER, INTO_ITER_WITHOUT_ITER]);
+
+/// Checks if a given type is nameable in a trait (impl).
+/// RPIT is stable, but impl Trait in traits is not (yet), so when we have
+/// a function such as `fn iter(&self) -> impl IntoIterator`, we can't
+/// suggest `type IntoIter = impl IntoIterator`.
+fn is_nameable_in_impl_trait(ty: &rustc_hir::Ty<'_>) -> bool {
+    !matches!(ty.kind, TyKind::OpaqueDef(..))
+}
+
+fn type_has_inherent_method(cx: &LateContext<'_>, ty: Ty<'_>, method_name: Symbol) -> bool {
+    if let Some(ty_did) = ty.ty_adt_def().map(ty::AdtDef::did) {
+        cx.tcx.inherent_impls(ty_did).iter().any(|&did| {
+            cx.tcx
+                .associated_items(did)
+                .filter_by_name_unhygienic(method_name)
+                .next()
+                .is_some_and(|item| item.kind == ty::AssocKind::Fn)
+        })
+    } else {
+        false
+    }
+}
+
+impl LateLintPass<'_> for IterWithoutIntoIter {
+    fn check_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::Item<'_>) {
+        if let ItemKind::Impl(imp) = item.kind
+            && let TyKind::Ref(_, self_ty_without_ref) = &imp.self_ty.kind
+            && let Some(trait_ref) = imp.of_trait
+            && trait_ref.trait_def_id().is_some_and(|did| cx.tcx.is_diagnostic_item(sym::IntoIterator, did))
+            && let &ty::Ref(_, ty, mtbl) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
+            && let expected_method_name = match mtbl {
+                Mutability::Mut => sym::iter_mut,
+                Mutability::Not => sym::iter,
+            }
+            && !type_has_inherent_method(cx, ty, expected_method_name)
+            && let Some(iter_assoc_span) = imp.items.iter().find_map(|item| {
+                if item.ident.name == sym!(IntoIter) {
+                    Some(cx.tcx.hir().impl_item(item.id).expect_type().span)
+                } else {
+                    None
+                }
+            })
+        {
+            span_lint_and_then(
+                cx,
+                INTO_ITER_WITHOUT_ITER,
+                item.span,
+                &format!("`IntoIterator` implemented for a reference type without an `{expected_method_name}` method"),
+                |diag| {
+                    // The suggestion forwards to the `IntoIterator` impl and uses a form of UFCS
+                    // to avoid name ambiguities, as there might be an inherent into_iter method
+                    // that we don't want to call.
+                    let sugg = format!(
+"
+impl {self_ty_without_ref} {{
+    fn {expected_method_name}({ref_self}self) -> {iter_ty} {{
+        <{ref_self}Self as IntoIterator>::into_iter(self)
+    }}
+}}
+",
+                        self_ty_without_ref = snippet(cx, self_ty_without_ref.ty.span, ".."),
+                        ref_self = mtbl.ref_prefix_str(),
+                        iter_ty = snippet(cx, iter_assoc_span, ".."),
+                    );
+
+                    diag.span_suggestion_verbose(
+                        item.span.shrink_to_lo(),
+                        format!("consider implementing `{expected_method_name}`"),
+                        sugg,
+                        // Just like iter_without_into_iter, this suggestion is on a best effort basis
+                        // and requires potentially adding lifetimes or moving them around.
+                        Applicability::Unspecified
+                    );
+                }
+            );
+        }
+    }
+
+    fn check_impl_item(&mut self, cx: &LateContext<'_>, item: &rustc_hir::ImplItem<'_>) {
+        let item_did = item.owner_id.to_def_id();
+        let (borrow_prefix, expected_implicit_self) = match item.ident.name {
+            sym::iter => ("&", ImplicitSelfKind::ImmRef),
+            sym::iter_mut => ("&mut ", ImplicitSelfKind::MutRef),
+            _ => return,
+        };
+
+        if let ImplItemKind::Fn(sig, _) = item.kind
+            && let FnRetTy::Return(ret) = sig.decl.output
+            && is_nameable_in_impl_trait(ret)
+            && cx.tcx.generics_of(item_did).params.is_empty()
+            && sig.decl.implicit_self == expected_implicit_self
+            && sig.decl.inputs.len() == 1
+            && let Some(imp) = get_parent_as_impl(cx.tcx, item.hir_id())
+            && imp.of_trait.is_none()
+            && let sig = cx.tcx.liberate_late_bound_regions(
+                item_did,
+                cx.tcx.fn_sig(item_did).instantiate_identity()
+            )
+            && let ref_ty = sig.inputs()[0]
+            && let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
+            && let Some(iterator_did) = cx.tcx.get_diagnostic_item(sym::Iterator)
+            && let ret_ty = sig.output()
+            // Order is important here, we need to check that the `fn iter` return type actually implements `IntoIterator`
+            // *before* normalizing `<_ as IntoIterator>::Item` (otherwise make_normalized_projection ICEs)
+            && implements_trait(cx, ret_ty, iterator_did, &[])
+            && let Some(iter_ty) = make_normalized_projection(
+                cx.tcx,
+                cx.param_env,
+                iterator_did,
+                sym!(Item),
+                [ret_ty],
+            )
+            // Only lint if the `IntoIterator` impl doesn't actually exist
+            && !implements_trait(cx, ref_ty, into_iter_did, &[])
+        {
+            let self_ty_snippet = format!("{borrow_prefix}{}", snippet(cx, imp.self_ty.span, ".."));
+
+            span_lint_and_then(
+                cx,
+                ITER_WITHOUT_INTO_ITER,
+                item.span,
+                &format!("`{}` method without an `IntoIterator` impl for `{self_ty_snippet}`", item.ident),
+                |diag| {
+                    // Get the lower span of the `impl` block, and insert the suggestion right before it:
+                    // impl X {
+                    // ^   fn iter(&self) -> impl IntoIterator { ... }
+                    // }
+                    let span_behind_impl = cx.tcx
+                        .def_span(cx.tcx.hir().parent_id(item.hir_id()).owner.def_id)
+                        .shrink_to_lo();
+
+                    let sugg = format!(
+"
+impl IntoIterator for {self_ty_snippet} {{
+    type IntoIter = {ret_ty};
+    type Iter = {iter_ty};
+    fn into_iter() -> Self::IntoIter {{
+        self.iter()
+    }}
+}}
+"
+                    );
+                    diag.span_suggestion_verbose(
+                        span_behind_impl,
+                        format!("consider implementing `IntoIterator` for `{self_ty_snippet}`"),
+                        sugg,
+                        // Suggestion is on a best effort basis, might need some adjustments by the user
+                        // such as adding some lifetimes in the associated types, or importing types.
+                        Applicability::Unspecified,
+                    );
+            });
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 1271be2fd93..0f35ec27665 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -169,6 +169,7 @@ mod invalid_upcast_comparisons;
 mod items_after_statements;
 mod items_after_test_module;
 mod iter_not_returning_iterator;
+mod iter_without_into_iter;
 mod large_const_arrays;
 mod large_enum_variant;
 mod large_futures;
@@ -190,6 +191,7 @@ mod manual_async_fn;
 mod manual_bits;
 mod manual_clamp;
 mod manual_float_methods;
+mod manual_hash_one;
 mod manual_is_ascii_check;
 mod manual_let_else;
 mod manual_main_separator_str;
@@ -1119,6 +1121,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
             msrv(),
         ))
     });
+    store.register_late_pass(move |_| Box::new(manual_hash_one::ManualHashOne::new(msrv())));
+    store.register_late_pass(|_| Box::new(iter_without_into_iter::IterWithoutIntoIter));
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
index 88db7ae6aec..ed9189a1804 100644
--- a/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_float_methods.rs
@@ -26,7 +26,7 @@ declare_clippy_lint! {
     /// # let x = 1.0f32;
     /// if x.is_infinite() {}
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub MANUAL_IS_INFINITE,
     style,
     "use dedicated method to check if a float is infinite"
@@ -51,7 +51,7 @@ declare_clippy_lint! {
     /// if x.is_finite() {}
     /// if x.is_finite() {}
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub MANUAL_IS_FINITE,
     style,
     "use dedicated method to check if a float is finite"
diff --git a/src/tools/clippy/clippy_lints/src/manual_hash_one.rs b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
new file mode 100644
index 00000000000..ea911335450
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/manual_hash_one.rs
@@ -0,0 +1,133 @@
+use clippy_utils::diagnostics::span_lint_hir_and_then;
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::source::snippet_opt;
+use clippy_utils::visitors::{is_local_used, local_used_once};
+use clippy_utils::{is_trait_method, path_to_local_id};
+use rustc_errors::Applicability;
+use rustc_hir::{BindingAnnotation, ExprKind, Local, Node, PatKind, StmtKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for cases where [`BuildHasher::hash_one`] can be used.
+    ///
+    /// [`BuildHasher::hash_one`]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html#method.hash_one
+    ///
+    /// ### Why is this bad?
+    /// It is more concise to use the `hash_one` method.
+    ///
+    /// ### Example
+    /// ```rust
+    /// use std::hash::{BuildHasher, Hash, Hasher};
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let value = vec![1, 2, 3];
+    ///
+    /// let mut hasher = s.build_hasher();
+    /// value.hash(&mut hasher);
+    /// let hash = hasher.finish();
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// use std::hash::BuildHasher;
+    /// use std::collections::hash_map::RandomState;
+    ///
+    /// let s = RandomState::new();
+    /// let value = vec![1, 2, 3];
+    ///
+    /// let hash = s.hash_one(&value);
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub MANUAL_HASH_ONE,
+    complexity,
+    "manual implementations of `BuildHasher::hash_one`"
+}
+
+pub struct ManualHashOne {
+    msrv: Msrv,
+}
+
+impl ManualHashOne {
+    #[must_use]
+    pub fn new(msrv: Msrv) -> Self {
+        Self { msrv }
+    }
+}
+
+impl_lint_pass!(ManualHashOne => [MANUAL_HASH_ONE]);
+
+impl LateLintPass<'_> for ManualHashOne {
+    fn check_local(&mut self, cx: &LateContext<'_>, local: &Local<'_>) {
+        // `let mut hasher = seg.build_hasher();`
+        if let PatKind::Binding(BindingAnnotation::MUT, hasher, _, None) = local.pat.kind
+            && let Some(init) = local.init
+            && !init.span.from_expansion()
+            && let ExprKind::MethodCall(seg, build_hasher, [], _) = init.kind
+            && seg.ident.name == sym!(build_hasher)
+
+            && let Node::Stmt(local_stmt) = cx.tcx.hir().get_parent(local.hir_id)
+            && let Node::Block(block) = cx.tcx.hir().get_parent(local_stmt.hir_id)
+
+            && let mut stmts = block.stmts.iter()
+                .skip_while(|stmt| stmt.hir_id != local_stmt.hir_id)
+                .skip(1)
+                .filter(|&stmt| is_local_used(cx, stmt, hasher))
+
+            // `hashed_value.hash(&mut hasher);`
+            && let Some(hash_stmt) = stmts.next()
+            && let StmtKind::Semi(hash_expr) = hash_stmt.kind
+            && !hash_expr.span.from_expansion()
+            && let ExprKind::MethodCall(seg, hashed_value, [ref_to_hasher], _) = hash_expr.kind
+            && seg.ident.name == sym::hash
+            && is_trait_method(cx, hash_expr, sym::Hash)
+            && path_to_local_id(ref_to_hasher.peel_borrows(), hasher)
+
+            && let maybe_finish_stmt = stmts.next()
+            // There should be no more statements referencing `hasher`
+            && stmts.next().is_none()
+
+            // `hasher.finish()`, may be anywhere in a statement or the trailing expr of the block
+            && let Some(path_expr) = local_used_once(cx, (maybe_finish_stmt, block.expr), hasher)
+            && let Node::Expr(finish_expr) = cx.tcx.hir().get_parent(path_expr.hir_id)
+            && !finish_expr.span.from_expansion()
+            && let ExprKind::MethodCall(seg, _, [], _) = finish_expr.kind
+            && seg.ident.name == sym!(finish)
+
+            && self.msrv.meets(msrvs::BUILD_HASHER_HASH_ONE)
+        {
+            span_lint_hir_and_then(
+                cx,
+                MANUAL_HASH_ONE,
+                finish_expr.hir_id,
+                finish_expr.span,
+                "manual implementation of `BuildHasher::hash_one`",
+                |diag| {
+                    if let Some(build_hasher) = snippet_opt(cx, build_hasher.span)
+                        && let Some(hashed_value) = snippet_opt(cx, hashed_value.span)
+                    {
+                        diag.multipart_suggestion(
+                            "try",
+                            vec![
+                                (local_stmt.span, String::new()),
+                                (hash_stmt.span, String::new()),
+                                (
+                                    finish_expr.span,
+                                    // `needless_borrows_for_generic_args` will take care of
+                                    // removing the `&` when it isn't needed
+                                    format!("{build_hasher}.hash_one(&{hashed_value})")
+                                )
+                            ],
+                            Applicability::MachineApplicable,
+                        );
+
+                    }
+                },
+            );
+        }
+    }
+
+    extract_msrv_attr!(LateContext);
+}
diff --git a/src/tools/clippy/clippy_lints/src/manual_let_else.rs b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
index c531137b785..2117308cd40 100644
--- a/src/tools/clippy/clippy_lints/src/manual_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_let_else.rs
@@ -136,9 +136,9 @@ fn emit_manual_let_else(
             // for this to be machine applicable.
             let mut app = Applicability::HasPlaceholders;
             let (sn_expr, _) = snippet_with_context(cx, expr.span, span.ctxt(), "", &mut app);
-            let (sn_else, _) = snippet_with_context(cx, else_body.span, span.ctxt(), "", &mut app);
+            let (sn_else, else_is_mac_call) = snippet_with_context(cx, else_body.span, span.ctxt(), "", &mut app);
 
-            let else_bl = if matches!(else_body.kind, ExprKind::Block(..)) {
+            let else_bl = if matches!(else_body.kind, ExprKind::Block(..)) && !else_is_mac_call {
                 sn_else.into_owned()
             } else {
                 format!("{{ {sn_else} }}")
diff --git a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
index 0e22485db2c..c12727c4a28 100644
--- a/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_non_exhaustive.rs
@@ -3,6 +3,7 @@ use clippy_utils::is_doc_hidden;
 use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::snippet_opt;
 use rustc_ast::ast::{self, VisibilityKind};
+use rustc_ast::attr;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::Applicability;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@@ -158,7 +159,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
             let mut iter = def.variants.iter().filter_map(|v| {
                 (matches!(v.data, hir::VariantData::Unit(_, _))
                     && v.ident.as_str().starts_with('_')
-                    && is_doc_hidden(cx.tcx.hir().attrs(v.hir_id)))
+                    && is_doc_hidden(cx.tcx.hir().attrs(v.hir_id))
+                    && !attr::contains_name(cx.tcx.hir().attrs(item.hir_id()), sym::non_exhaustive))
                 .then_some((v.def_id, v.span))
             });
             if let Some((id, span)) = iter.next()
@@ -198,16 +200,14 @@ impl<'tcx> LateLintPass<'tcx> for ManualNonExhaustiveEnum {
                 enum_span,
                 "this seems like a manual implementation of the non-exhaustive pattern",
                 |diag| {
-                    if !cx.tcx.adt_def(enum_id).is_variant_list_non_exhaustive()
-                        && let header_span = cx.sess().source_map().span_until_char(enum_span, '{')
-                        && let Some(snippet) = snippet_opt(cx, header_span)
-                    {
-                            diag.span_suggestion(
-                                header_span,
-                                "add the attribute",
-                                format!("#[non_exhaustive] {snippet}"),
-                                Applicability::Unspecified,
-                            );
+                    let header_span = cx.sess().source_map().span_until_char(enum_span, '{');
+                    if let Some(snippet) = snippet_opt(cx, header_span) {
+                        diag.span_suggestion(
+                            header_span,
+                            "add the attribute",
+                            format!("#[non_exhaustive] {snippet}"),
+                            Applicability::Unspecified,
+                        );
                     }
                     diag.span_help(variant_span, "remove this variant");
                 },
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index 930386a60aa..a23000e5fe1 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -961,7 +961,7 @@ declare_clippy_lint! {
     ///     _ => todo!(),
     /// }
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub REDUNDANT_GUARDS,
     complexity,
     "checks for unnecessary guards in match expressions"
diff --git a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
index 7c0485914b8..8f0083f812c 100644
--- a/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/overlapping_arms.rs
@@ -1,4 +1,4 @@
-use clippy_utils::consts::{constant, constant_full_int, miri_to_const, FullInt};
+use clippy_utils::consts::{constant, constant_full_int, mir_to_const, FullInt};
 use clippy_utils::diagnostics::span_lint_and_note;
 use core::cmp::Ordering;
 use rustc_hir::{Arm, Expr, PatKind, RangeEnd};
@@ -37,14 +37,14 @@ fn all_ranges<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'_>], ty: Ty<'tcx>)
                         Some(lhs) => constant(cx, cx.typeck_results(), lhs)?,
                         None => {
                             let min_val_const = ty.numeric_min_val(cx.tcx)?;
-                            miri_to_const(cx, mir::Const::from_ty_const(min_val_const, cx.tcx))?
+                            mir_to_const(cx, mir::Const::from_ty_const(min_val_const, cx.tcx))?
                         },
                     };
                     let rhs_const = match rhs {
                         Some(rhs) => constant(cx, cx.typeck_results(), rhs)?,
                         None => {
                             let max_val_const = ty.numeric_max_val(cx.tcx)?;
-                            miri_to_const(cx, mir::Const::from_ty_const(max_val_const, cx.tcx))?
+                            mir_to_const(cx, mir::Const::from_ty_const(max_val_const, cx.tcx))?
                         },
                     };
                     let lhs_val = lhs_const.int_value(cx, ty)?;
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index e7fcef9e9de..a935aea5075 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -2970,7 +2970,7 @@ declare_clippy_lint! {
     /// assert_eq!((*any_box).type_id(), TypeId::of::<i32>());
     /// //          ^ dereference first, to call `type_id` on `dyn Any`
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub TYPE_ID_ON_BOX,
     suspicious,
     "calling `.type_id()` on `Box<dyn Any>`"
@@ -3368,6 +3368,7 @@ declare_clippy_lint! {
 }
 
 declare_clippy_lint! {
+    /// ### What it does
     /// Looks for calls to [`Stdin::read_line`] to read a line from the standard input
     /// into a string, then later attempting to parse this string into a type without first trimming it, which will
     /// always fail because the string has a trailing newline in it.
@@ -3390,7 +3391,7 @@ declare_clippy_lint! {
     /// //                  ^^^^^^^^^^^ remove the trailing newline
     /// assert_eq!(num, 42);
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub READ_LINE_WITHOUT_TRIM,
     correctness,
     "calling `Stdin::read_line`, then trying to parse it without first trimming"
@@ -3418,7 +3419,7 @@ declare_clippy_lint! {
     /// # let c = 'c';
     /// matches!(c, '\\' | '.' | '+' | '*' | '(' | ')' | '|' | '[' | ']' | '{' | '}' | '^' | '$' | '#' | '&' | '-' | '~');
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub STRING_LIT_CHARS_ANY,
     restriction,
     "checks for `<string_lit>.chars().any(|i| i == c)`"
@@ -3453,7 +3454,7 @@ declare_clippy_lint! {
     ///     })
     /// }
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub FORMAT_COLLECT,
     perf,
     "`format!`ing every element in a collection, then collecting the strings into a new `String`"
@@ -3474,7 +3475,7 @@ declare_clippy_lint! {
     /// let y = v.iter().collect::<Vec<_>>();
     /// assert_eq!(x, y);
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub ITER_SKIP_ZERO,
     correctness,
     "disallows `.skip(0)`"
@@ -3505,7 +3506,7 @@ declare_clippy_lint! {
     /// # let v = vec![];
     /// _ = v.into_iter().filter(|i| i % 2 == 0).map(|i| really_expensive_fn(i));
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub FILTER_MAP_BOOL_THEN,
     style,
     "checks for usage of `bool::then` in `Iterator::filter_map`"
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
index 24c0ea3f60a..3e19d72ec91 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
@@ -24,7 +24,6 @@ fn get_ty_from_args<'a>(args: Option<&'a [hir::GenericArg<'a>]>, index: usize) -
     }
 }
 
-#[expect(clippy::too_many_lines)]
 pub(super) fn check(
     cx: &LateContext<'_>,
     expr: &hir::Expr<'_>,
@@ -101,11 +100,11 @@ pub(super) fn check(
                 (expr.span.with_lo(args[0].span.hi()), String::new()),
             ]),
             ("None", "unwrap_or_else", _) => match args[0].kind {
-                hir::ExprKind::Closure(hir::Closure {
-                    body,
-                    ..
-                }) => Some(vec![
-                    (expr.span.with_hi(cx.tcx.hir().body(*body).value.span.lo()), String::new()),
+                hir::ExprKind::Closure(hir::Closure { body, .. }) => Some(vec![
+                    (
+                        expr.span.with_hi(cx.tcx.hir().body(*body).value.span.lo()),
+                        String::new(),
+                    ),
                     (expr.span.with_lo(args[0].span.hi()), String::new()),
                 ]),
                 _ => None,
diff --git a/src/tools/clippy/clippy_lints/src/missing_assert_message.rs b/src/tools/clippy/clippy_lints/src/missing_assert_message.rs
index c17f00c4275..136947a2c8c 100644
--- a/src/tools/clippy/clippy_lints/src/missing_assert_message.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_assert_message.rs
@@ -15,6 +15,10 @@ declare_clippy_lint! {
     /// A good custom message should be more about why the failure of the assertion is problematic
     /// and not what is failed because the assertion already conveys that.
     ///
+    /// Although the same reasoning applies to testing functions, this lint ignores them as they would be too noisy.
+    /// Also, in most cases understanding the test failure would be easier
+    /// compared to understanding a complex invariant distributed around the codebase.
+    ///
     /// ### Known problems
     /// This lint cannot check the quality of the custom panic messages.
     /// Hence, you can suppress this lint simply by adding placeholder messages
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index ea6a9bc5657..e87aea263d4 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -135,10 +135,7 @@ impl<'a, 'tcx> DivergenceVisitor<'a, 'tcx> {
 }
 
 fn stmt_might_diverge(stmt: &Stmt<'_>) -> bool {
-    match stmt.kind {
-        StmtKind::Item(..) => false,
-        _ => true,
-    }
+    !matches!(stmt.kind, StmtKind::Item(..))
 }
 
 impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
@@ -148,7 +145,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
             ExprKind::Block(block, ..) => match (block.stmts, block.expr) {
                 (stmts, Some(e)) => {
                     if stmts.iter().all(|stmt| !stmt_might_diverge(stmt)) {
-                        self.visit_expr(e)
+                        self.visit_expr(e);
                     }
                 },
                 ([first @ .., stmt], None) => {
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index 57652e5ff54..212d6234bdb 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -47,9 +47,9 @@ declare_clippy_lint! {
     ///     12 + *y
     /// }
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub NEEDLESS_PASS_BY_REF_MUT,
-    suspicious,
+    nursery,
     "using a `&mut` argument when it's not mutated"
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
index 4be140647fc..0e4b6aa1b7d 100644
--- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
@@ -102,7 +102,7 @@ declare_clippy_lint! {
     ///     }
     /// }
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub NON_CANONICAL_PARTIAL_ORD_IMPL,
     suspicious,
     "non-canonical implementation of `PartialOrd` on an `Ord` type"
diff --git a/src/tools/clippy/clippy_lints/src/operators/mod.rs b/src/tools/clippy/clippy_lints/src/operators/mod.rs
index 4635e1164cd..6b247cf5f6a 100644
--- a/src/tools/clippy/clippy_lints/src/operators/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/mod.rs
@@ -312,7 +312,7 @@ declare_clippy_lint! {
     /// # let status_code = 200;
     /// if status_code <= 400 && status_code > 500 {}
     /// ```
-    #[clippy::version = "1.71.0"]
+    #[clippy::version = "1.73.0"]
     pub IMPOSSIBLE_COMPARISONS,
     correctness,
     "double comparisons that will never evaluate to `true`"
@@ -332,7 +332,7 @@ declare_clippy_lint! {
     /// # let status_code = 200;
     /// if status_code <= 400 && status_code < 500 {}
     /// ```
-    #[clippy::version = "1.71.0"]
+    #[clippy::version = "1.73.0"]
     pub REDUNDANT_COMPARISONS,
     correctness,
     "double comparisons where one of them can be removed"
diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs
index 8a7e4874666..c951d9a4a09 100644
--- a/src/tools/clippy/clippy_lints/src/raw_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs
@@ -75,6 +75,7 @@ impl EarlyLintPass for RawStrings {
             if !snippet(cx, expr.span, prefix).trim().starts_with(prefix) {
                 return;
             }
+            let descr = lit.kind.descr();
 
             if !str.contains(['\\', '"']) {
                 span_lint_and_then(
@@ -89,20 +90,17 @@ impl EarlyLintPass for RawStrings {
                         let r_pos = expr.span.lo() + BytePos::from_usize(prefix.len() - 1);
                         let start = start.with_lo(r_pos);
 
-                        if end.is_empty() {
-                            diag.span_suggestion(
-                                start,
-                                "use a string literal instead",
-                                format!("\"{str}\""),
-                                Applicability::MachineApplicable,
-                            );
-                        } else {
-                            diag.multipart_suggestion(
-                                "try",
-                                vec![(start, String::new()), (end, String::new())],
-                                Applicability::MachineApplicable,
-                            );
+                        let mut remove = vec![(start, String::new())];
+                        // avoid debug ICE from empty suggestions
+                        if !end.is_empty() {
+                            remove.push((end, String::new()));
                         }
+
+                        diag.multipart_suggestion_verbose(
+                            format!("use a plain {descr} literal instead"),
+                            remove,
+                            Applicability::MachineApplicable,
+                        );
                     },
                 );
                 if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS), rustc_lint::Allow) {
@@ -149,9 +147,9 @@ impl EarlyLintPass for RawStrings {
                         let (start, end) = hash_spans(expr.span, prefix, req, max);
 
                         let message = match max - req {
-                            _ if req == 0 => "remove all the hashes around the literal".to_string(),
-                            1 => "remove one hash from both sides of the literal".to_string(),
-                            n => format!("remove {n} hashes from both sides of the literal"),
+                            _ if req == 0 => format!("remove all the hashes around the {descr} literal"),
+                            1 => format!("remove one hash from both sides of the {descr} literal"),
+                            n => format!("remove {n} hashes from both sides of the {descr} literal"),
                         };
 
                         diag.multipart_suggestion(
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index 0c89c7ee47d..197742b5dd4 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -3,11 +3,9 @@ use clippy_utils::is_from_proc_macro;
 use clippy_utils::ty::needs_ordered_drop;
 use rustc_ast::Mutability;
 use rustc_hir::def::Res;
-use rustc_hir::{
-    BindingAnnotation, ByRef, Expr, ExprKind, HirId, Local, Node, Pat, PatKind, QPath,
-};
+use rustc_hir::{BindingAnnotation, ByRef, ExprKind, HirId, Local, Node, Pat, PatKind, QPath};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::{in_external_macro, is_from_async_await};
+use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::Ident;
 use rustc_span::DesugaringKind;
@@ -39,7 +37,7 @@ declare_clippy_lint! {
     ///   // no redefinition with the same name
     /// }
     /// ```
-    #[clippy::version = "1.72.0"]
+    #[clippy::version = "1.73.0"]
     pub REDUNDANT_LOCALS,
     correctness,
     "redundant redefinition of a local binding"
@@ -68,21 +66,18 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
             // the local does not change the effect of assignments to the binding. see #11290
             if !affects_assignments(cx, mutability, binding_id, local.hir_id);
             // the local does not affect the code's drop behavior
-            if !affects_drop_behavior(cx, binding_id, local.hir_id, expr);
+            if !needs_ordered_drop(cx, cx.typeck_results().expr_ty(expr));
             // the local is user-controlled
             if !in_external_macro(cx.sess(), local.span);
             if !is_from_proc_macro(cx, expr);
-            // Async function parameters are lowered into the closure body, so we can't lint them.
-            // see `lower_maybe_async_body` in `rust_ast_lowering`
-            if !is_from_async_await(local.span);
             then {
                 span_lint_and_help(
                     cx,
                     REDUNDANT_LOCALS,
-                    vec![binding_pat.span, local.span],
-                    "redundant redefinition of a binding",
-                    None,
-                    &format!("remove the redefinition of `{ident}`"),
+                    local.span,
+                    &format!("redundant redefinition of a binding `{ident}`"),
+                    Some(binding_pat.span),
+                    &format!("`{ident}` is initially defined here"),
                 );
             }
         }
@@ -109,18 +104,3 @@ fn affects_assignments(cx: &LateContext<'_>, mutability: Mutability, bind: HirId
     // the binding is mutable and the rebinding is in a different scope than the original binding
     mutability == Mutability::Mut && hir.get_enclosing_scope(bind) != hir.get_enclosing_scope(rebind)
 }
-
-/// Check if a rebinding of a local affects the code's drop behavior.
-fn affects_drop_behavior<'tcx>(
-    cx: &LateContext<'tcx>,
-    bind: HirId,
-    rebind: HirId,
-    rebind_expr: &Expr<'tcx>,
-) -> bool {
-    let hir = cx.tcx.hir();
-
-    // the rebinding is in a different scope than the original binding
-    // and the type of the binding cares about drop order
-    hir.get_enclosing_scope(bind) != hir.get_enclosing_scope(rebind)
-        && needs_ordered_drop(cx, cx.typeck_results().expr_ty(rebind_expr))
-}
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index 5f54a10d1c4..b7396535eed 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -1,9 +1,11 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::is_from_proc_macro;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{HirId, Path, PathSegment};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::kw;
 use rustc_span::{sym, Span};
@@ -99,6 +101,8 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
         if let Res::Def(_, def_id) = path.res
             && let Some(first_segment) = get_first_segment(path)
             && is_stable(cx, def_id)
+            && !in_external_macro(cx.sess(), path.span)
+            && !is_from_proc_macro(cx, &first_segment.ident)
         {
             let (lint, used_mod, replace_with) = match first_segment.ident.name {
                 sym::std => match cx.tcx.crate_name(def_id.krate) {
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 75c3c7a958a..23da1de7730 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -294,7 +294,7 @@ define_Conf! {
     ///
     /// Suppress lints whenever the suggested change would cause breakage for other crates.
     (avoid_breaking_exported_api: bool = true),
-    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD.
+    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE.
     ///
     /// The minimum rust version that the project supports
     (msrv: Option<String> = None),
@@ -744,3 +744,44 @@ fn calculate_dimensions(fields: &[&str]) -> (usize, Vec<usize>) {
 
     (rows, column_widths)
 }
+
+#[cfg(test)]
+mod tests {
+    use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+    use serde::de::IgnoredAny;
+    use std::fs;
+    use walkdir::WalkDir;
+
+    #[test]
+    fn configs_are_tested() {
+        let mut names: FxHashSet<String> = super::metadata::get_configuration_metadata()
+            .into_iter()
+            .map(|meta| meta.name.replace('_', "-"))
+            .collect();
+
+        let toml_files = WalkDir::new("../tests")
+            .into_iter()
+            .map(Result::unwrap)
+            .filter(|entry| entry.file_name() == "clippy.toml");
+
+        for entry in toml_files {
+            let file = fs::read_to_string(entry.path()).unwrap();
+            #[allow(clippy::zero_sized_map_values)]
+            if let Ok(map) = toml::from_str::<FxHashMap<String, IgnoredAny>>(&file) {
+                for name in map.keys() {
+                    names.remove(name.as_str());
+                }
+            }
+        }
+
+        assert!(
+            names.remove("allow-one-hash-in-raw-strings"),
+            "remove this when #11481 is fixed"
+        );
+
+        assert!(
+            names.is_empty(),
+            "Configuration variable lacks test: {names:?}\nAdd a test to `tests/ui-toml`"
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
index d09d02a7dfd..70b83149ce1 100644
--- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
+++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs
@@ -132,6 +132,7 @@ impl LateLintPass<'_> for WildcardImports {
             if self.warn_on_all || !self.check_exceptions(item, use_path.segments);
             let used_imports = cx.tcx.names_imported_by_glob_use(item.owner_id.def_id);
             if !used_imports.is_empty(); // Already handled by `unused_imports`
+            if !used_imports.contains(&kw::Underscore);
             then {
                 let mut applicability = Applicability::MachineApplicable;
                 let import_source_snippet = snippet_with_applicability(cx, use_path.span, "..", &mut applicability);
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index da083fb14aa..855aefa70cb 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -3,12 +3,15 @@ use clippy_utils::macros::{find_format_args, format_arg_removal_span, root_macro
 use clippy_utils::source::{expand_past_previous_comma, snippet_opt};
 use clippy_utils::{is_in_cfg_test, is_in_test_function};
 use rustc_ast::token::LitKind;
-use rustc_ast::{FormatArgPosition, FormatArgs, FormatArgsPiece, FormatOptions, FormatPlaceholder, FormatTrait};
+use rustc_ast::{
+    FormatArgPosition, FormatArgPositionKind, FormatArgs, FormatArgsPiece, FormatOptions, FormatPlaceholder,
+    FormatTrait,
+};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Impl, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
-use rustc_span::{sym, BytePos};
+use rustc_span::{sym, BytePos, Span};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -450,6 +453,12 @@ fn check_empty_string(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call
 fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
     let arg_index = |argument: &FormatArgPosition| argument.index.unwrap_or_else(|pos| pos);
 
+    let lint_name = if name.starts_with("write") {
+        WRITE_LITERAL
+    } else {
+        PRINT_LITERAL
+    };
+
     let mut counts = vec![0u32; format_args.arguments.all_args().len()];
     for piece in &format_args.template {
         if let FormatArgsPiece::Placeholder(placeholder) = piece {
@@ -457,6 +466,12 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
         }
     }
 
+    let mut suggestion: Vec<(Span, String)> = vec![];
+    // holds index of replaced positional arguments; used to decrement the index of the remaining
+    // positional arguments.
+    let mut replaced_position: Vec<usize> = vec![];
+    let mut sug_span: Option<Span> = None;
+
     for piece in &format_args.template {
         if let FormatArgsPiece::Placeholder(FormatPlaceholder {
             argument,
@@ -471,9 +486,9 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
             && let rustc_ast::ExprKind::Lit(lit) = &arg.expr.kind
             && !arg.expr.span.from_expansion()
             && let Some(value_string) = snippet_opt(cx, arg.expr.span)
-    {
+        {
             let (replacement, replace_raw) = match lit.kind {
-                LitKind::Str | LitKind::StrRaw(_)  => match extract_str_literal(&value_string) {
+                LitKind::Str | LitKind::StrRaw(_) => match extract_str_literal(&value_string) {
                     Some(extracted) => extracted,
                     None => return,
                 },
@@ -493,12 +508,6 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
                 _ => continue,
             };
 
-            let lint = if name.starts_with("write") {
-                WRITE_LITERAL
-            } else {
-                PRINT_LITERAL
-            };
-
             let Some(format_string_snippet) = snippet_opt(cx, format_args.span) else { continue };
             let format_string_is_raw = format_string_snippet.starts_with('r');
 
@@ -519,29 +528,58 @@ fn check_literal(cx: &LateContext<'_>, format_args: &FormatArgs, name: &str) {
                 },
             };
 
-            span_lint_and_then(
-                cx,
-                lint,
-                arg.expr.span,
-                "literal with an empty format string",
-                |diag| {
-                    if let Some(replacement) = replacement
-                        // `format!("{}", "a")`, `format!("{named}", named = "b")
-                        //              ~~~~~                      ~~~~~~~~~~~~~
-                        && let Some(removal_span) = format_arg_removal_span(format_args, index)
-                    {
-                        let replacement = replacement.replace('{', "{{").replace('}', "}}");
-                        diag.multipart_suggestion(
-                            "try",
-                            vec![(*placeholder_span, replacement), (removal_span, String::new())],
-                            Applicability::MachineApplicable,
-                        );
-                    }
-                },
-            );
+            sug_span = Some(sug_span.unwrap_or(arg.expr.span).to(arg.expr.span));
+
+            if let Some((_, index)) = positional_arg_piece_span(piece) {
+                replaced_position.push(index);
+            }
+
+            if let Some(replacement) = replacement
+                // `format!("{}", "a")`, `format!("{named}", named = "b")
+                //              ~~~~~                      ~~~~~~~~~~~~~
+                && let Some(removal_span) = format_arg_removal_span(format_args, index) {
+                let replacement = escape_braces(&replacement, !format_string_is_raw && !replace_raw);
+                suggestion.push((*placeholder_span, replacement));
+                suggestion.push((removal_span, String::new()));
+            }
+        }
+    }
 
+    // Decrement the index of the remaining by the number of replaced positional arguments
+    if !suggestion.is_empty() {
+        for piece in &format_args.template {
+            if let Some((span, index)) = positional_arg_piece_span(piece)
+                && suggestion.iter().all(|(s, _)| *s != span) {
+                let decrement = replaced_position.iter().filter(|i| **i < index).count();
+                suggestion.push((span, format!("{{{}}}", index.saturating_sub(decrement))));
+            }
         }
     }
+
+    if let Some(span) = sug_span {
+        span_lint_and_then(cx, lint_name, span, "literal with an empty format string", |diag| {
+            if !suggestion.is_empty() {
+                diag.multipart_suggestion("try", suggestion, Applicability::MachineApplicable);
+            }
+        });
+    }
+}
+
+/// Extract Span and its index from the given `piece`, iff it's positional argument.
+fn positional_arg_piece_span(piece: &FormatArgsPiece) -> Option<(Span, usize)> {
+    match piece {
+        FormatArgsPiece::Placeholder(FormatPlaceholder {
+            argument:
+                FormatArgPosition {
+                    index: Ok(index),
+                    kind: FormatArgPositionKind::Number,
+                    ..
+                },
+            span: Some(span),
+            ..
+        }) => Some((*span, *index)),
+        _ => None,
+    }
 }
 
 /// Removes the raw marker, `#`s and quotes from a str, and returns if the literal is raw
@@ -593,3 +631,47 @@ fn conservative_unescape(literal: &str) -> Result<String, UnescapeErr> {
 
     if err { Err(UnescapeErr::Lint) } else { Ok(unescaped) }
 }
+
+/// Replaces `{` with `{{` and `}` with `}}`. If `preserve_unicode_escapes` is `true` the braces in
+/// `\u{xxxx}` are left unmodified
+#[expect(clippy::match_same_arms)]
+fn escape_braces(literal: &str, preserve_unicode_escapes: bool) -> String {
+    #[derive(Clone, Copy)]
+    enum State {
+        Normal,
+        Backslash,
+        UnicodeEscape,
+    }
+
+    let mut escaped = String::with_capacity(literal.len());
+    let mut state = State::Normal;
+
+    for ch in literal.chars() {
+        state = match (ch, state) {
+            // Escape braces outside of unicode escapes by doubling them up
+            ('{' | '}', State::Normal) => {
+                escaped.push(ch);
+                State::Normal
+            },
+            // If `preserve_unicode_escapes` isn't enabled stay in `State::Normal`, otherwise:
+            //
+            // \u{aaaa} \\ \x01
+            // ^        ^  ^
+            ('\\', State::Normal) if preserve_unicode_escapes => State::Backslash,
+            // \u{aaaa}
+            //  ^
+            ('u', State::Backslash) => State::UnicodeEscape,
+            // \xAA \\
+            //  ^    ^
+            (_, State::Backslash) => State::Normal,
+            // \u{aaaa}
+            //        ^
+            ('}', State::UnicodeEscape) => State::Normal,
+            _ => state,
+        };
+
+        escaped.push(ch);
+    }
+
+    escaped
+}
diff --git a/src/tools/clippy/clippy_utils/Cargo.toml b/src/tools/clippy/clippy_utils/Cargo.toml
index 1596bb77397..8522493f67b 100644
--- a/src/tools/clippy/clippy_utils/Cargo.toml
+++ b/src/tools/clippy/clippy_utils/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "clippy_utils"
-version = "0.1.74"
+version = "0.1.75"
 edition = "2021"
 publish = false
 
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index d596eed4b7c..0bae7056c4f 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -9,11 +9,12 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{BinOp, BinOpKind, Block, ConstBlock, Expr, ExprKind, HirId, Item, ItemKind, Node, QPath, UnOp};
 use rustc_lexer::tokenize;
 use rustc_lint::LateContext;
-use rustc_middle::mir::interpret::Scalar;
+use rustc_middle::mir::interpret::{alloc_range, Scalar};
 use rustc_middle::ty::{self, EarlyBinder, FloatTy, GenericArgsRef, List, ScalarInt, Ty, TyCtxt};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::SyntaxContext;
+use rustc_target::abi::Size;
 use std::cmp::Ordering::{self, Equal};
 use std::hash::{Hash, Hasher};
 use std::iter;
@@ -403,7 +404,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                     && adt_def.is_struct()
                     && let Some(desired_field) = field_of_struct(*adt_def, self.lcx, *constant, field)
                 {
-                    miri_to_const(self.lcx, desired_field)
+                    mir_to_const(self.lcx, desired_field)
                 }
                 else {
                     result
@@ -483,7 +484,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                     .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), None)
                     .ok()
                     .map(|val| rustc_middle::mir::Const::from_value(val, ty))?;
-                let result = miri_to_const(self.lcx, result)?;
+                let result = mir_to_const(self.lcx, result)?;
                 self.source = ConstantSource::Constant;
                 Some(result)
             },
@@ -655,10 +656,14 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
     }
 }
 
-pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> Option<Constant<'tcx>> {
+pub fn mir_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) -> Option<Constant<'tcx>> {
     use rustc_middle::mir::ConstValue;
-    match result {
-        mir::Const::Val(ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() {
+    let mir::Const::Val(val, _) = result else {
+        // We only work on evaluated consts.
+        return None;
+    };
+    match (val, result.ty().kind()) {
+        (ConstValue::Scalar(Scalar::Int(int)), _) => match result.ty().kind() {
             ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)),
             ty::Bool => Some(Constant::Bool(int == ScalarInt::TRUE)),
             ty::Uint(_) | ty::Int(_) => Some(Constant::Int(int.assert_bits(int.size()))),
@@ -671,42 +676,28 @@ pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) ->
             ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))),
             _ => None,
         },
-        mir::Const::Val(cv, _) if matches!(result.ty().kind(), ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Str)) =>
-        {
-            let data = cv.try_get_slice_bytes_for_diagnostics(lcx.tcx)?;
+        (_, ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Str) => {
+            let data = val.try_get_slice_bytes_for_diagnostics(lcx.tcx)?;
             String::from_utf8(data.to_owned()).ok().map(Constant::Str)
         },
-        mir::Const::Val(ConstValue::Indirect { alloc_id, offset: _ }, _) => {
-            let alloc = lcx.tcx.global_alloc(alloc_id).unwrap_memory();
-            match result.ty().kind() {
-                ty::Adt(adt_def, _) if adt_def.is_struct() => Some(Constant::Adt(result)),
-                ty::Array(sub_type, len) => match sub_type.kind() {
-                    ty::Float(FloatTy::F32) => match len.try_to_target_usize(lcx.tcx) {
-                        Some(len) => alloc
-                            .inner()
-                            .inspect_with_uninit_and_ptr_outside_interpreter(0..(4 * usize::try_from(len).unwrap()))
-                            .to_owned()
-                            .array_chunks::<4>()
-                            .map(|&chunk| Some(Constant::F32(f32::from_le_bytes(chunk))))
-                            .collect::<Option<Vec<Constant<'tcx>>>>()
-                            .map(Constant::Vec),
-                        _ => None,
-                    },
-                    ty::Float(FloatTy::F64) => match len.try_to_target_usize(lcx.tcx) {
-                        Some(len) => alloc
-                            .inner()
-                            .inspect_with_uninit_and_ptr_outside_interpreter(0..(8 * usize::try_from(len).unwrap()))
-                            .to_owned()
-                            .array_chunks::<8>()
-                            .map(|&chunk| Some(Constant::F64(f64::from_le_bytes(chunk))))
-                            .collect::<Option<Vec<Constant<'tcx>>>>()
-                            .map(Constant::Vec),
-                        _ => None,
-                    },
-                    _ => None,
-                },
-                _ => None,
+        (_, ty::Adt(adt_def, _)) if adt_def.is_struct() => Some(Constant::Adt(result)),
+        (ConstValue::Indirect { alloc_id, offset }, ty::Array(sub_type, len)) => {
+            let alloc = lcx.tcx.global_alloc(alloc_id).unwrap_memory().inner();
+            let len = len.try_to_target_usize(lcx.tcx)?;
+            let ty::Float(flt) = sub_type.kind() else {
+                return None;
+            };
+            let size = Size::from_bits(flt.bit_width());
+            let mut res = Vec::new();
+            for idx in 0..len {
+                let range = alloc_range(offset + size * idx, size);
+                let val = alloc.read_scalar(&lcx.tcx, range, /* read_provenance */ false).ok()?;
+                res.push(match flt {
+                    FloatTy::F32 => Constant::F32(f32::from_bits(val.to_u32().ok()?)),
+                    FloatTy::F64 => Constant::F64(f64::from_bits(val.to_u64().ok()?)),
+                });
             }
+            Some(Constant::Vec(res))
         },
         _ => None,
     }
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 64ca2ff7873..c2c97259d38 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -80,7 +80,6 @@ use std::sync::{Mutex, MutexGuard, OnceLock};
 use if_chain::if_chain;
 use itertools::Itertools;
 use rustc_ast::ast::{self, LitKind, RangeLimits};
-use rustc_ast::Attribute;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_hir::def::{DefKind, Res};
@@ -113,7 +112,7 @@ use rustc_span::{sym, Span};
 use rustc_target::abi::Integer;
 use visitors::Visitable;
 
-use crate::consts::{constant, miri_to_const, Constant};
+use crate::consts::{constant, mir_to_const, Constant};
 use crate::higher::Range;
 use crate::ty::{
     adt_and_variant_of_res, can_partially_move_ty, expr_sig, is_copy, is_recursively_primitive_type,
@@ -1509,9 +1508,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
             if let rustc_ty::Adt(_, subst) = ty.kind()
                 && let bnd_ty = subst.type_at(0)
                 && let Some(min_val) = bnd_ty.numeric_min_val(cx.tcx)
-                && let const_val = cx.tcx.valtree_to_const_val((bnd_ty, min_val.to_valtree()))
-                && let min_const_kind = Const::from_value(const_val, bnd_ty)
-                && let Some(min_const) = miri_to_const(cx, min_const_kind)
+                && let Some(min_const) = mir_to_const(cx, Const::from_ty_const(min_val, cx.tcx))
                 && let Some(start_const) = constant(cx, cx.typeck_results(), start)
             {
                 start_const == min_const
@@ -1525,9 +1522,7 @@ pub fn is_range_full(cx: &LateContext<'_>, expr: &Expr<'_>, container_path: Opti
                     if let rustc_ty::Adt(_, subst) = ty.kind()
                         && let bnd_ty = subst.type_at(0)
                         && let Some(max_val) = bnd_ty.numeric_max_val(cx.tcx)
-                        && let const_val = cx.tcx.valtree_to_const_val((bnd_ty, max_val.to_valtree()))
-                        && let max_const_kind = Const::from_value(const_val, bnd_ty)
-                        && let Some(max_const) = miri_to_const(cx, max_const_kind)
+                        && let Some(max_const) = mir_to_const(cx, Const::from_ty_const(max_val, cx.tcx))
                         && let Some(end_const) = constant(cx, cx.typeck_results(), end)
                     {
                         end_const == max_const
@@ -2456,11 +2451,12 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
     })
 }
 
-/// Checks if the item containing the given `HirId` has `#[cfg(test)]` attribute applied
+/// Checks if `id` has a `#[cfg(test)]` attribute applied
 ///
-/// Note: Add `//@compile-flags: --test` to UI tests with a `#[cfg(test)]` function
-pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
-    fn is_cfg_test(attr: &Attribute) -> bool {
+/// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent
+/// use [`is_in_cfg_test`]
+pub fn is_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
+    tcx.hir().attrs(id).iter().any(|attr| {
         if attr.has_name(sym::cfg)
             && let Some(items) = attr.meta_item_list()
             && let [item] = &*items
@@ -2470,11 +2466,14 @@ pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
         } else {
             false
         }
-    }
+    })
+}
+
+/// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied
+pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
     tcx.hir()
-        .parent_iter(id)
-        .flat_map(|(parent_id, _)| tcx.hir().attrs(parent_id))
-        .any(is_cfg_test)
+        .parent_id_iter(id)
+        .any(|parent_id| is_cfg_test(tcx, parent_id))
 }
 
 /// Checks if the item of any of its parents has `#[cfg(...)]` attribute applied.
diff --git a/src/tools/clippy/clippy_utils/src/msrvs.rs b/src/tools/clippy/clippy_utils/src/msrvs.rs
index 0faff05eb23..df839c2106f 100644
--- a/src/tools/clippy/clippy_utils/src/msrvs.rs
+++ b/src/tools/clippy/clippy_utils/src/msrvs.rs
@@ -19,7 +19,7 @@ macro_rules! msrv_aliases {
 
 // names may refer to stabilized feature flags or library items
 msrv_aliases! {
-    1,71,0 { TUPLE_ARRAY_CONVERSIONS }
+    1,71,0 { TUPLE_ARRAY_CONVERSIONS, BUILD_HASHER_HASH_ONE }
     1,70,0 { OPTION_IS_SOME_AND, BINARY_HEAP_RETAIN }
     1,68,0 { PATH_MAIN_SEPARATOR_STR }
     1,65,0 { LET_ELSE, POINTER_CAST_CONSTNESS }
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 3b47a451345..d752fe7d97e 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -62,6 +62,27 @@ where
         }
     }
 }
+impl<'tcx, A, B> Visitable<'tcx> for (A, B)
+where
+    A: Visitable<'tcx>,
+    B: Visitable<'tcx>,
+{
+    fn visit<V: Visitor<'tcx>>(self, visitor: &mut V) {
+        let (a, b) = self;
+        a.visit(visitor);
+        b.visit(visitor);
+    }
+}
+impl<'tcx, T> Visitable<'tcx> for Option<T>
+where
+    T: Visitable<'tcx>,
+{
+    fn visit<V: Visitor<'tcx>>(self, visitor: &mut V) {
+        if let Some(x) = self {
+            x.visit(visitor);
+        }
+    }
+}
 macro_rules! visitable_ref {
     ($t:ident, $f:ident) => {
         impl<'tcx> Visitable<'tcx> for &'tcx $t<'tcx> {
@@ -748,3 +769,26 @@ pub fn contains_break_or_continue(expr: &Expr<'_>) -> bool {
     })
     .is_some()
 }
+
+/// If the local is only used once in `visitable` returns the path expression referencing the given
+/// local
+pub fn local_used_once<'tcx>(
+    cx: &LateContext<'tcx>,
+    visitable: impl Visitable<'tcx>,
+    id: HirId,
+) -> Option<&'tcx Expr<'tcx>> {
+    let mut expr = None;
+
+    let cf = for_each_expr_with_closures(cx, visitable, |e| {
+        if path_to_local_id(e, id) && expr.replace(e).is_some() {
+            ControlFlow::Break(())
+        } else {
+            ControlFlow::Continue(())
+        }
+    });
+    if cf.is_some() {
+        return None;
+    }
+
+    expr
+}
diff --git a/src/tools/clippy/declare_clippy_lint/Cargo.toml b/src/tools/clippy/declare_clippy_lint/Cargo.toml
index 1470da61fac..beea9fd00e7 100644
--- a/src/tools/clippy/declare_clippy_lint/Cargo.toml
+++ b/src/tools/clippy/declare_clippy_lint/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "declare_clippy_lint"
-version = "0.1.74"
+version = "0.1.75"
 edition = "2021"
 publish = false
 
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 5ce22b65f00..fe2c77ab47f 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2023-09-25"
+channel = "nightly-2023-10-06"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs
index 1d89477dcc1..d47767faed9 100644
--- a/src/tools/clippy/src/driver.rs
+++ b/src/tools/clippy/src/driver.rs
@@ -26,6 +26,8 @@ use std::ops::Deref;
 use std::path::Path;
 use std::process::exit;
 
+use anstream::println;
+
 /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
 /// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
 fn arg_value<'a, T: Deref<Target = str>>(
@@ -162,39 +164,15 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
     }
 }
 
+#[allow(clippy::ignored_unit_patterns)]
 fn display_help() {
-    println!(
-        "\
-Checks a package to catch common mistakes and improve your Rust code.
-
-Usage:
-    cargo clippy [options] [--] [<opts>...]
-
-Common options:
-    -h, --help               Print this message
-        --rustc              Pass all args to rustc
-    -V, --version            Print version info and exit
-
-For the other options see `cargo check --help`.
-
-To allow or deny a lint from the command line you can use `cargo clippy --`
-with:
-
-    -W --warn OPT       Set lint warnings
-    -A --allow OPT      Set lint allowed
-    -D --deny OPT       Set lint denied
-    -F --forbid OPT     Set lint forbidden
-
-You can use tool lints to allow or deny lints from your code, eg.:
-
-    #[allow(clippy::needless_lifetimes)]
-"
-    );
+    println!("{}", help_message());
 }
 
 const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml";
 
 #[allow(clippy::too_many_lines)]
+#[allow(clippy::ignored_unit_patterns)]
 pub fn main() {
     let handler = EarlyErrorHandler::new(ErrorOutputType::default());
 
@@ -236,6 +214,7 @@ pub fn main() {
 
         if orig_args.iter().any(|a| a == "--version" || a == "-V") {
             let version_info = rustc_tools_util::get_version_info!();
+
             println!("{version_info}");
             exit(0);
         }
@@ -292,3 +271,25 @@ pub fn main() {
         }
     }))
 }
+
+#[must_use]
+fn help_message() -> &'static str {
+    color_print::cstr!(
+        "Checks a file to catch common mistakes and improve your Rust code.
+Run <cyan>clippy-driver</> with the same arguments you use for <cyan>rustc</>
+
+<green,bold>Usage</>:
+    <cyan,bold>clippy-driver</> <cyan>[OPTIONS] INPUT</>
+
+<green,bold>Common options:</>
+    <cyan,bold>-h</>, <cyan,bold>--help</>               Print this message
+    <cyan,bold>-V</>, <cyan,bold>--version</>            Print version info and exit
+    <cyan,bold>--rustc</>                  Pass all arguments to <cyan>rustc</>
+
+<green,bold>Allowing / Denying lints</>
+You can use tool lints to allow or deny lints from your code, e.g.:
+
+    <yellow,bold>#[allow(clippy::needless_lifetimes)]</>
+"
+    )
+}
diff --git a/src/tools/clippy/src/main.rs b/src/tools/clippy/src/main.rs
index 26b655076cf..bbf7d22c850 100644
--- a/src/tools/clippy/src/main.rs
+++ b/src/tools/clippy/src/main.rs
@@ -6,37 +6,14 @@ use std::env;
 use std::path::PathBuf;
 use std::process::{self, Command};
 
-const CARGO_CLIPPY_HELP: &str = "Checks a package to catch common mistakes and improve your Rust code.
-
-Usage:
-    cargo clippy [options] [--] [<opts>...]
-
-Common options:
-    --no-deps                Run Clippy only on the given crate, without linting the dependencies
-    --fix                    Automatically apply lint suggestions. This flag implies `--no-deps` and `--all-targets`
-    -h, --help               Print this message
-    -V, --version            Print version info and exit
-    --explain LINT           Print the documentation for a given lint
-
-For the other options see `cargo check --help`.
-
-To allow or deny a lint from the command line you can use `cargo clippy --`
-with:
-
-    -W --warn OPT       Set lint warnings
-    -A --allow OPT      Set lint allowed
-    -D --deny OPT       Set lint denied
-    -F --forbid OPT     Set lint forbidden
-
-You can use tool lints to allow or deny lints from your code, e.g.:
-
-    #[allow(clippy::needless_lifetimes)]
-";
+use anstream::println;
 
+#[allow(clippy::ignored_unit_patterns)]
 fn show_help() {
-    println!("{CARGO_CLIPPY_HELP}");
+    println!("{}", help_message());
 }
 
+#[allow(clippy::ignored_unit_patterns)]
 fn show_version() {
     let version_info = rustc_tools_util::get_version_info!();
     println!("{version_info}");
@@ -168,6 +145,38 @@ where
     }
 }
 
+#[must_use]
+pub fn help_message() -> &'static str {
+    color_print::cstr!(
+"Checks a package to catch common mistakes and improve your Rust code.
+
+<green,bold>Usage</>:
+    <cyan,bold>cargo clippy</> <cyan>[OPTIONS] [--] [<<ARGS>>...]</>
+
+<green,bold>Common options:</>
+    <cyan,bold>--no-deps</>                Run Clippy only on the given crate, without linting the dependencies
+    <cyan,bold>--fix</>                    Automatically apply lint suggestions. This flag implies <cyan>--no-deps</> and <cyan>--all-targets</>
+    <cyan,bold>-h</>, <cyan,bold>--help</>               Print this message
+    <cyan,bold>-V</>, <cyan,bold>--version</>            Print version info and exit
+    <cyan,bold>--explain [LINT]</>         Print the documentation for a given lint
+
+See all options with <cyan,bold>cargo check --help</>.
+
+<green,bold>Allowing / Denying lints</>
+
+To allow or deny a lint from the command line you can use <cyan,bold>cargo clippy --</> with:
+
+    <cyan,bold>-W</> / <cyan,bold>--warn</> <cyan>[LINT]</>       Set lint warnings
+    <cyan,bold>-A</> / <cyan,bold>--allow</> <cyan>[LINT]</>      Set lint allowed
+    <cyan,bold>-D</> / <cyan,bold>--deny</> <cyan>[LINT]</>       Set lint denied
+    <cyan,bold>-F</> / <cyan,bold>--forbid</> <cyan>[LINT]</>     Set lint forbidden
+
+You can use tool lints to allow or deny lints from your code, e.g.:
+
+    <yellow,bold>#[allow(clippy::needless_lifetimes)]</>
+"
+    )
+}
 #[cfg(test)]
 mod tests {
     use super::ClippyCmd;
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 37f0ec2b37d..79a95d775b1 100644
--- a/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_derive.rs
@@ -21,6 +21,18 @@ pub fn derive(_: TokenStream) -> TokenStream {
     output
 }
 
+#[proc_macro_derive(ImplStructWithStdDisplay)]
+pub fn derive_std(_: TokenStream) -> TokenStream {
+    quote! {
+        struct A {}
+        impl ::std::fmt::Display for A {
+            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+                write!(f, "A")
+            }
+        }
+    }
+}
+
 #[proc_macro_derive(FieldReassignWithDefault)]
 pub fn derive_foo(_input: TokenStream) -> TokenStream {
     quote! {
@@ -141,3 +153,19 @@ pub fn shadow_derive(_: TokenStream) -> TokenStream {
         .into(),
     ])
 }
+
+#[proc_macro_derive(StructIgnoredUnitPattern)]
+pub fn derive_ignored_unit_pattern(_: TokenStream) -> TokenStream {
+    quote! {
+        struct A;
+        impl A {
+            fn a(&self) -> Result<(), ()> {
+                unimplemented!()
+            }
+
+            pub fn b(&self) {
+                let _ = self.a().unwrap();
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
index 6c6f21fee16..15eaf1f659a 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.fixed
@@ -1,3 +1,4 @@
+//@aux-build:proc_macro_derive.rs
 #![warn(clippy::ignored_unit_patterns)]
 #![allow(clippy::let_unit_value, clippy::redundant_pattern_matching, clippy::single_match)]
 
@@ -14,8 +15,22 @@ fn main() {
     //~^ ERROR: matching over `()` is more explicit
     let _ = foo().map_err(|()| todo!());
     //~^ ERROR: matching over `()` is more explicit
+
+    println!(
+        "{:?}",
+        match foo() {
+            Ok(()) => {},
+            //~^ ERROR: matching over `()` is more explicit
+            Err(()) => {},
+            //~^ ERROR: matching over `()` is more explicit
+        }
+    );
 }
 
+// ignored_unit_patterns in derive macro should be ok
+#[derive(proc_macro_derive::StructIgnoredUnitPattern)]
+pub struct B;
+
 #[allow(unused)]
 pub fn moo(_: ()) {
     let () = foo().unwrap();
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
index 5e8c2e03ba2..9cac3a440ab 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.rs
@@ -1,3 +1,4 @@
+//@aux-build:proc_macro_derive.rs
 #![warn(clippy::ignored_unit_patterns)]
 #![allow(clippy::let_unit_value, clippy::redundant_pattern_matching, clippy::single_match)]
 
@@ -14,8 +15,22 @@ fn main() {
     //~^ ERROR: matching over `()` is more explicit
     let _ = foo().map_err(|_| todo!());
     //~^ ERROR: matching over `()` is more explicit
+
+    println!(
+        "{:?}",
+        match foo() {
+            Ok(_) => {},
+            //~^ ERROR: matching over `()` is more explicit
+            Err(_) => {},
+            //~^ ERROR: matching over `()` is more explicit
+        }
+    );
 }
 
+// ignored_unit_patterns in derive macro should be ok
+#[derive(proc_macro_derive::StructIgnoredUnitPattern)]
+pub struct B;
+
 #[allow(unused)]
 pub fn moo(_: ()) {
     let _ = foo().unwrap();
diff --git a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
index df5e1d89e90..cac01a87dba 100644
--- a/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
+++ b/src/tools/clippy/tests/ui/ignored_unit_patterns.stderr
@@ -1,5 +1,5 @@
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:10:12
+  --> $DIR/ignored_unit_patterns.rs:11:12
    |
 LL |         Ok(_) => {},
    |            ^ help: use `()` instead of `_`: `()`
@@ -8,28 +8,40 @@ LL |         Ok(_) => {},
    = help: to override `-D warnings` add `#[allow(clippy::ignored_unit_patterns)]`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:11:13
+  --> $DIR/ignored_unit_patterns.rs:12:13
    |
 LL |         Err(_) => {},
    |             ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:13:15
+  --> $DIR/ignored_unit_patterns.rs:14:15
    |
 LL |     if let Ok(_) = foo() {}
    |               ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:15:28
+  --> $DIR/ignored_unit_patterns.rs:16:28
    |
 LL |     let _ = foo().map_err(|_| todo!());
    |                            ^ help: use `()` instead of `_`: `()`
 
 error: matching over `()` is more explicit
-  --> $DIR/ignored_unit_patterns.rs:21:9
+  --> $DIR/ignored_unit_patterns.rs:22:16
+   |
+LL |             Ok(_) => {},
+   |                ^ help: use `()` instead of `_`: `()`
+
+error: matching over `()` is more explicit
+  --> $DIR/ignored_unit_patterns.rs:24:17
+   |
+LL |             Err(_) => {},
+   |                 ^ help: use `()` instead of `_`: `()`
+
+error: matching over `()` is more explicit
+  --> $DIR/ignored_unit_patterns.rs:36:9
    |
 LL |     let _ = foo().unwrap();
    |         ^ help: use `()` instead of `_`: `()`
 
-error: aborting due to 5 previous errors
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/infinite_loop.rs b/src/tools/clippy/tests/ui/infinite_loop.rs
index 281e12c7b93..765c6701147 100644
--- a/src/tools/clippy/tests/ui/infinite_loop.rs
+++ b/src/tools/clippy/tests/ui/infinite_loop.rs
@@ -7,8 +7,6 @@ fn fn_constref(i: &i32) -> i32 {
     unimplemented!()
 }
 fn fn_mutref(i: &mut i32) {
-    //~^ ERROR: this argument is a mutable reference, but not used mutably
-    //~| NOTE: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
     unimplemented!()
 }
 fn fooi() -> i32 {
diff --git a/src/tools/clippy/tests/ui/infinite_loop.stderr b/src/tools/clippy/tests/ui/infinite_loop.stderr
index c32b5e323c0..a78e47d0229 100644
--- a/src/tools/clippy/tests/ui/infinite_loop.stderr
+++ b/src/tools/clippy/tests/ui/infinite_loop.stderr
@@ -1,5 +1,5 @@
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:24:11
+  --> $DIR/infinite_loop.rs:22:11
    |
 LL |     while y < 10 {
    |           ^^^^^^
@@ -8,7 +8,7 @@ LL |     while y < 10 {
    = note: `#[deny(clippy::while_immutable_condition)]` on by default
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:31:11
+  --> $DIR/infinite_loop.rs:29:11
    |
 LL |     while y < 10 && x < 3 {
    |           ^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL |     while y < 10 && x < 3 {
    = note: this may lead to an infinite or to a never running loop
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:40:11
+  --> $DIR/infinite_loop.rs:38:11
    |
 LL |     while !cond {
    |           ^^^^^
@@ -24,7 +24,7 @@ LL |     while !cond {
    = note: this may lead to an infinite or to a never running loop
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:86:11
+  --> $DIR/infinite_loop.rs:84:11
    |
 LL |     while i < 3 {
    |           ^^^^^
@@ -32,7 +32,7 @@ LL |     while i < 3 {
    = note: this may lead to an infinite or to a never running loop
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:93:11
+  --> $DIR/infinite_loop.rs:91:11
    |
 LL |     while i < 3 && j > 0 {
    |           ^^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     while i < 3 && j > 0 {
    = note: this may lead to an infinite or to a never running loop
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:99:11
+  --> $DIR/infinite_loop.rs:97:11
    |
 LL |     while i < 3 {
    |           ^^^^^
@@ -48,7 +48,7 @@ LL |     while i < 3 {
    = note: this may lead to an infinite or to a never running loop
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:116:11
+  --> $DIR/infinite_loop.rs:114:11
    |
 LL |     while i < 3 {
    |           ^^^^^
@@ -56,7 +56,7 @@ LL |     while i < 3 {
    = note: this may lead to an infinite or to a never running loop
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:123:11
+  --> $DIR/infinite_loop.rs:121:11
    |
 LL |     while i < 3 {
    |           ^^^^^
@@ -64,7 +64,7 @@ LL |     while i < 3 {
    = note: this may lead to an infinite or to a never running loop
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:191:15
+  --> $DIR/infinite_loop.rs:189:15
    |
 LL |         while self.count < n {
    |               ^^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |         while self.count < n {
    = note: this may lead to an infinite or to a never running loop
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:201:11
+  --> $DIR/infinite_loop.rs:199:11
    |
 LL |     while y < 10 {
    |           ^^^^^^
@@ -82,7 +82,7 @@ LL |     while y < 10 {
    = help: rewrite it as `if cond { loop { } }`
 
 error: variables in the condition are not mutated in the loop body
-  --> $DIR/infinite_loop.rs:210:11
+  --> $DIR/infinite_loop.rs:208:11
    |
 LL |     while y < 10 {
    |           ^^^^^^
@@ -91,14 +91,5 @@ LL |     while y < 10 {
    = note: this loop contains `return`s or `break`s
    = help: rewrite it as `if cond { loop { } }`
 
-error: this argument is a mutable reference, but not used mutably
-  --> $DIR/infinite_loop.rs:9:17
-   |
-LL | fn fn_mutref(i: &mut i32) {
-   |                 ^^^^^^^^ help: consider changing to: `&i32`
-   |
-   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
-
-error: aborting due to 12 previous errors
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/into_iter_without_iter.rs b/src/tools/clippy/tests/ui/into_iter_without_iter.rs
new file mode 100644
index 00000000000..6be3bb8abdd
--- /dev/null
+++ b/src/tools/clippy/tests/ui/into_iter_without_iter.rs
@@ -0,0 +1,124 @@
+//@no-rustfix
+#![warn(clippy::into_iter_without_iter)]
+
+use std::iter::IntoIterator;
+
+fn main() {
+    {
+        struct S;
+
+        impl<'a> IntoIterator for &'a S {
+            //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method
+            type IntoIter = std::slice::Iter<'a, u8>;
+            type Item = &'a u8;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+        impl<'a> IntoIterator for &'a mut S {
+            //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method
+            type IntoIter = std::slice::IterMut<'a, u8>;
+            type Item = &'a mut u8;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+    }
+    {
+        struct S<T>(T);
+        impl<'a, T> IntoIterator for &'a S<T> {
+            //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter` method
+            type IntoIter = std::slice::Iter<'a, T>;
+            type Item = &'a T;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+        impl<'a, T> IntoIterator for &'a mut S<T> {
+            //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method
+            type IntoIter = std::slice::IterMut<'a, T>;
+            type Item = &'a mut T;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+    }
+    {
+        // Both iter and iter_mut methods exist, don't lint
+        struct S<'a, T>(&'a T);
+
+        impl<'a, T> S<'a, T> {
+            fn iter(&self) -> std::slice::Iter<'a, T> {
+                todo!()
+            }
+            fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {
+                todo!()
+            }
+        }
+
+        impl<'a, T> IntoIterator for &S<'a, T> {
+            type IntoIter = std::slice::Iter<'a, T>;
+            type Item = &'a T;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+
+        impl<'a, T> IntoIterator for &mut S<'a, T> {
+            type IntoIter = std::slice::IterMut<'a, T>;
+            type Item = &'a mut T;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+    }
+    {
+        // Only `iter` exists, no `iter_mut`
+        struct S<'a, T>(&'a T);
+
+        impl<'a, T> S<'a, T> {
+            fn iter(&self) -> std::slice::Iter<'a, T> {
+                todo!()
+            }
+        }
+
+        impl<'a, T> IntoIterator for &S<'a, T> {
+            type IntoIter = std::slice::Iter<'a, T>;
+            type Item = &'a T;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+
+        impl<'a, T> IntoIterator for &mut S<'a, T> {
+            //~^ ERROR: `IntoIterator` implemented for a reference type without an `iter_mut` method
+            type IntoIter = std::slice::IterMut<'a, T>;
+            type Item = &'a mut T;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+    }
+    {
+        // `iter` exists, but `IntoIterator` is implemented for an alias. inherent_impls doesn't "normalize"
+        // aliases so that `inherent_impls(Alias)` where `type Alias = S` returns nothing, so this can lead
+        // to fun FPs. Make sure it doesn't happen here (we're using type_of, which should skip the alias).
+        struct S;
+
+        impl S {
+            fn iter(&self) -> std::slice::Iter<'static, u8> {
+                todo!()
+            }
+        }
+
+        type Alias = S;
+
+        impl IntoIterator for &Alias {
+            type IntoIter = std::slice::Iter<'static, u8>;
+            type Item = &'static u8;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/into_iter_without_iter.stderr b/src/tools/clippy/tests/ui/into_iter_without_iter.stderr
new file mode 100644
index 00000000000..f543d1d8e86
--- /dev/null
+++ b/src/tools/clippy/tests/ui/into_iter_without_iter.stderr
@@ -0,0 +1,114 @@
+error: `IntoIterator` implemented for a reference type without an `iter` method
+  --> $DIR/into_iter_without_iter.rs:10:9
+   |
+LL | /         impl<'a> IntoIterator for &'a S {
+LL | |
+LL | |             type IntoIter = std::slice::Iter<'a, u8>;
+LL | |             type Item = &'a u8;
+...  |
+LL | |             }
+LL | |         }
+   | |_________^
+   |
+   = note: `-D clippy::into-iter-without-iter` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::into_iter_without_iter)]`
+help: consider implementing `iter`
+   |
+LL ~         
+LL + impl S {
+LL +     fn iter(&self) -> std::slice::Iter<'a, u8> {
+LL +         <&Self as IntoIterator>::into_iter(self)
+LL +     }
+LL + }
+   |
+
+error: `IntoIterator` implemented for a reference type without an `iter_mut` method
+  --> $DIR/into_iter_without_iter.rs:18:9
+   |
+LL | /         impl<'a> IntoIterator for &'a mut S {
+LL | |
+LL | |             type IntoIter = std::slice::IterMut<'a, u8>;
+LL | |             type Item = &'a mut u8;
+...  |
+LL | |             }
+LL | |         }
+   | |_________^
+   |
+help: consider implementing `iter_mut`
+   |
+LL ~         
+LL + impl S {
+LL +     fn iter_mut(&mut self) -> std::slice::IterMut<'a, u8> {
+LL +         <&mut Self as IntoIterator>::into_iter(self)
+LL +     }
+LL + }
+   |
+
+error: `IntoIterator` implemented for a reference type without an `iter` method
+  --> $DIR/into_iter_without_iter.rs:29:9
+   |
+LL | /         impl<'a, T> IntoIterator for &'a S<T> {
+LL | |
+LL | |             type IntoIter = std::slice::Iter<'a, T>;
+LL | |             type Item = &'a T;
+...  |
+LL | |             }
+LL | |         }
+   | |_________^
+   |
+help: consider implementing `iter`
+   |
+LL ~         
+LL + impl S<T> {
+LL +     fn iter(&self) -> std::slice::Iter<'a, T> {
+LL +         <&Self as IntoIterator>::into_iter(self)
+LL +     }
+LL + }
+   |
+
+error: `IntoIterator` implemented for a reference type without an `iter_mut` method
+  --> $DIR/into_iter_without_iter.rs:37:9
+   |
+LL | /         impl<'a, T> IntoIterator for &'a mut S<T> {
+LL | |
+LL | |             type IntoIter = std::slice::IterMut<'a, T>;
+LL | |             type Item = &'a mut T;
+...  |
+LL | |             }
+LL | |         }
+   | |_________^
+   |
+help: consider implementing `iter_mut`
+   |
+LL ~         
+LL + impl S<T> {
+LL +     fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {
+LL +         <&mut Self as IntoIterator>::into_iter(self)
+LL +     }
+LL + }
+   |
+
+error: `IntoIterator` implemented for a reference type without an `iter_mut` method
+  --> $DIR/into_iter_without_iter.rs:93:9
+   |
+LL | /         impl<'a, T> IntoIterator for &mut S<'a, T> {
+LL | |
+LL | |             type IntoIter = std::slice::IterMut<'a, T>;
+LL | |             type Item = &'a mut T;
+...  |
+LL | |             }
+LL | |         }
+   | |_________^
+   |
+help: consider implementing `iter_mut`
+   |
+LL ~         
+LL + impl S<'a, T> {
+LL +     fn iter_mut(&mut self) -> std::slice::IterMut<'a, T> {
+LL +         <&mut Self as IntoIterator>::into_iter(self)
+LL +     }
+LL + }
+   |
+
+error: aborting due to 5 previous errors
+
diff --git a/src/tools/clippy/tests/ui/items_after_test_module/after_proc_macros.rs b/src/tools/clippy/tests/ui/items_after_test_module/after_proc_macros.rs
new file mode 100644
index 00000000000..d9c0aef88c8
--- /dev/null
+++ b/src/tools/clippy/tests/ui/items_after_test_module/after_proc_macros.rs
@@ -0,0 +1,11 @@
+//@aux-build:../auxiliary/proc_macros.rs
+extern crate proc_macros;
+
+proc_macros::with_span! {
+    span
+    #[cfg(test)]
+    mod tests {}
+}
+
+#[test]
+fn f() {}
diff --git a/src/tools/clippy/tests/ui/items_after_test_module/auxiliary/submodule.rs b/src/tools/clippy/tests/ui/items_after_test_module/auxiliary/submodule.rs
new file mode 100644
index 00000000000..69d61790121
--- /dev/null
+++ b/src/tools/clippy/tests/ui/items_after_test_module/auxiliary/submodule.rs
@@ -0,0 +1,4 @@
+#[cfg(test)]
+mod tests {}
+
+fn in_submodule() {}
diff --git a/src/tools/clippy/tests/ui/items_after_test_module/block_module.stderr b/src/tools/clippy/tests/ui/items_after_test_module/block_module.stderr
deleted file mode 100644
index 1b625747161..00000000000
--- a/src/tools/clippy/tests/ui/items_after_test_module/block_module.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-error: Option 'test' given more than once
-
diff --git a/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.rs b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.rs
new file mode 100644
index 00000000000..7132e71764e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.rs
@@ -0,0 +1,8 @@
+#[path = "auxiliary/submodule.rs"]
+mod submodule;
+
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn t() {}
+}
diff --git a/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr
new file mode 100644
index 00000000000..4e99876365c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/items_after_test_module/in_submodule.stderr
@@ -0,0 +1,14 @@
+error: items after a test module
+  --> $DIR/auxiliary/submodule.rs:2:1
+   |
+LL | mod tests {}
+   | ^^^^^^^^^
+LL |
+LL | fn in_submodule() {}
+   | ^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::items-after-test-module` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::items_after_test_module)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/items_after_test_module/multiple_modules.rs b/src/tools/clippy/tests/ui/items_after_test_module/multiple_modules.rs
new file mode 100644
index 00000000000..8ab9e8200f1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/items_after_test_module/multiple_modules.rs
@@ -0,0 +1,11 @@
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn f() {}
+}
+
+#[cfg(test)]
+mod more_tests {
+    #[test]
+    fn g() {}
+}
diff --git a/src/tools/clippy/tests/ui/items_after_test_module/block_module.rs b/src/tools/clippy/tests/ui/items_after_test_module/root_module.fixed
index 5136b2557ec..d444100a76b 100644
--- a/src/tools/clippy/tests/ui/items_after_test_module/block_module.rs
+++ b/src/tools/clippy/tests/ui/items_after_test_module/root_module.fixed
@@ -1,4 +1,3 @@
-//@compile-flags: --test
 #![allow(unused)]
 #![warn(clippy::items_after_test_module)]
 
@@ -6,6 +5,13 @@ fn main() {}
 
 fn should_not_lint() {}
 
+fn should_lint() {}
+
+const SHOULD_ALSO_LINT: usize = 1;
+macro_rules! should_lint {
+    () => {};
+}
+
 #[allow(dead_code)]
 #[allow(unused)] // Some attributes to check that span replacement is good enough
 #[allow(clippy::allow_attributes)]
@@ -14,10 +20,3 @@ mod tests {
     #[test]
     fn hi() {}
 }
-
-fn should_lint() {}
-
-const SHOULD_ALSO_LINT: usize = 1;
-macro_rules! should_not_lint {
-    () => {};
-}
diff --git a/src/tools/clippy/tests/ui/items_after_test_module/root_module.rs b/src/tools/clippy/tests/ui/items_after_test_module/root_module.rs
new file mode 100644
index 00000000000..57da01639cc
--- /dev/null
+++ b/src/tools/clippy/tests/ui/items_after_test_module/root_module.rs
@@ -0,0 +1,22 @@
+#![allow(unused)]
+#![warn(clippy::items_after_test_module)]
+
+fn main() {}
+
+fn should_not_lint() {}
+
+#[allow(dead_code)]
+#[allow(unused)] // Some attributes to check that span replacement is good enough
+#[allow(clippy::allow_attributes)]
+#[cfg(test)]
+mod tests {
+    #[test]
+    fn hi() {}
+}
+
+fn should_lint() {}
+
+const SHOULD_ALSO_LINT: usize = 1;
+macro_rules! should_lint {
+    () => {};
+}
diff --git a/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr b/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr
new file mode 100644
index 00000000000..67bc82ebff9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/items_after_test_module/root_module.stderr
@@ -0,0 +1,20 @@
+error: items after a test module
+  --> $DIR/root_module.rs:12:1
+   |
+LL | mod tests {
+   | ^^^^^^^^^
+...
+LL | fn should_lint() {}
+   | ^^^^^^^^^^^^^^^^
+LL |
+LL | const SHOULD_ALSO_LINT: usize = 1;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | macro_rules! should_lint {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::items-after-test-module` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::items_after_test_module)]`
+   = help: move the items to before the test module was defined
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/iter_without_into_iter.rs b/src/tools/clippy/tests/ui/iter_without_into_iter.rs
new file mode 100644
index 00000000000..cedb756c79d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_without_into_iter.rs
@@ -0,0 +1,120 @@
+//@no-rustfix
+#![warn(clippy::iter_without_into_iter)]
+
+fn main() {
+    {
+        struct S;
+        impl S {
+            pub fn iter(&self) -> std::slice::Iter<'_, u8> {
+                //~^ ERROR: `iter` method without an `IntoIterator` impl
+                [].iter()
+            }
+            pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
+                //~^ ERROR: `iter_mut` method without an `IntoIterator` impl
+                [].iter_mut()
+            }
+        }
+    }
+    {
+        struct S;
+        impl S {
+            pub fn iter(&self) -> impl Iterator<Item = &u8> {
+                // RPITIT is not stable, so we can't generally suggest it here yet
+                [].iter()
+            }
+        }
+    }
+    {
+        struct S<'a>(&'a mut [u8]);
+        impl<'a> S<'a> {
+            pub fn iter(&self) -> std::slice::Iter<'_, u8> {
+                //~^ ERROR: `iter` method without an `IntoIterator` impl
+                self.0.iter()
+            }
+            pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
+                //~^ ERROR: `iter_mut` method without an `IntoIterator` impl
+                self.0.iter_mut()
+            }
+        }
+    }
+    {
+        // Incompatible signatures
+        struct S;
+        impl S {
+            pub fn iter(self) -> std::slice::Iter<'static, u8> {
+                todo!()
+            }
+        }
+        struct S2;
+        impl S2 {
+            pub async fn iter(&self) -> std::slice::Iter<'static, u8> {
+                todo!()
+            }
+        }
+        struct S3;
+        impl S3 {
+            pub fn iter(&self, _additional_param: ()) -> std::slice::Iter<'static, u8> {
+                todo!()
+            }
+        }
+        struct S4<T>(T);
+        impl<T> S4<T> {
+            pub fn iter<U>(&self) -> std::slice::Iter<'static, (T, U)> {
+                todo!()
+            }
+        }
+        struct S5<T>(T);
+        impl<T> S5<T> {
+            pub fn iter(&self) -> std::slice::Iter<'static, T> {
+                todo!()
+            }
+        }
+    }
+    {
+        struct S<T>(T);
+        impl<T> S<T> {
+            pub fn iter(&self) -> std::slice::Iter<'_, T> {
+                //~^ ERROR: `iter` method without an `IntoIterator` impl
+                todo!()
+            }
+            pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
+                //~^ ERROR: `iter_mut` method without an `IntoIterator` impl
+                todo!()
+            }
+        }
+    }
+    {
+        struct S<T>(T);
+        impl<T> S<T> {
+            pub fn iter(&self) -> std::slice::Iter<'_, T> {
+                // Don't lint, there's an existing (wrong) IntoIterator impl
+                todo!()
+            }
+        }
+
+        impl<'a, T> IntoIterator for &'a S<T> {
+            type Item = &'a String;
+            type IntoIter = std::slice::Iter<'a, String>;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+    }
+    {
+        struct S<T>(T);
+        impl<T> S<T> {
+            pub fn iter_mut(&self) -> std::slice::IterMut<'_, T> {
+                // Don't lint, there's an existing (wrong) IntoIterator impl
+                todo!()
+            }
+        }
+
+        impl<'a, T> IntoIterator for &'a mut S<T> {
+            type Item = &'a mut String;
+            type IntoIter = std::slice::IterMut<'a, String>;
+            fn into_iter(self) -> Self::IntoIter {
+                todo!()
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/iter_without_into_iter.stderr b/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
new file mode 100644
index 00000000000..9d0b99415a5
--- /dev/null
+++ b/src/tools/clippy/tests/ui/iter_without_into_iter.stderr
@@ -0,0 +1,150 @@
+error: `iter` method without an `IntoIterator` impl for `&S`
+  --> $DIR/iter_without_into_iter.rs:8:13
+   |
+LL | /             pub fn iter(&self) -> std::slice::Iter<'_, u8> {
+LL | |
+LL | |                 [].iter()
+LL | |             }
+   | |_____________^
+   |
+   = note: `-D clippy::iter-without-into-iter` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::iter_without_into_iter)]`
+help: consider implementing `IntoIterator` for `&S`
+   |
+LL ~         
+LL + impl IntoIterator for &S {
+LL +     type IntoIter = std::slice::Iter<'_, u8>;
+LL +     type Iter = &u8;
+LL +     fn into_iter() -> Self::IntoIter {
+LL +         self.iter()
+LL +     }
+LL + }
+   |
+
+error: `iter_mut` method without an `IntoIterator` impl for `&mut S`
+  --> $DIR/iter_without_into_iter.rs:12:13
+   |
+LL | /             pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
+LL | |
+LL | |                 [].iter_mut()
+LL | |             }
+   | |_____________^
+   |
+help: consider implementing `IntoIterator` for `&mut S`
+   |
+LL ~         
+LL + impl IntoIterator for &mut S {
+LL +     type IntoIter = std::slice::IterMut<'_, u8>;
+LL +     type Iter = &mut u8;
+LL +     fn into_iter() -> Self::IntoIter {
+LL +         self.iter()
+LL +     }
+LL + }
+   |
+
+error: `iter` method without an `IntoIterator` impl for `&S<'a>`
+  --> $DIR/iter_without_into_iter.rs:30:13
+   |
+LL | /             pub fn iter(&self) -> std::slice::Iter<'_, u8> {
+LL | |
+LL | |                 self.0.iter()
+LL | |             }
+   | |_____________^
+   |
+help: consider implementing `IntoIterator` for `&S<'a>`
+   |
+LL ~         
+LL + impl IntoIterator for &S<'a> {
+LL +     type IntoIter = std::slice::Iter<'_, u8>;
+LL +     type Iter = &u8;
+LL +     fn into_iter() -> Self::IntoIter {
+LL +         self.iter()
+LL +     }
+LL + }
+   |
+
+error: `iter_mut` method without an `IntoIterator` impl for `&mut S<'a>`
+  --> $DIR/iter_without_into_iter.rs:34:13
+   |
+LL | /             pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, u8> {
+LL | |
+LL | |                 self.0.iter_mut()
+LL | |             }
+   | |_____________^
+   |
+help: consider implementing `IntoIterator` for `&mut S<'a>`
+   |
+LL ~         
+LL + impl IntoIterator for &mut S<'a> {
+LL +     type IntoIter = std::slice::IterMut<'_, u8>;
+LL +     type Iter = &mut u8;
+LL +     fn into_iter() -> Self::IntoIter {
+LL +         self.iter()
+LL +     }
+LL + }
+   |
+
+error: `iter` method without an `IntoIterator` impl for `&S5<T>`
+  --> $DIR/iter_without_into_iter.rs:68:13
+   |
+LL | /             pub fn iter(&self) -> std::slice::Iter<'static, T> {
+LL | |                 todo!()
+LL | |             }
+   | |_____________^
+   |
+help: consider implementing `IntoIterator` for `&S5<T>`
+   |
+LL ~         
+LL + impl IntoIterator for &S5<T> {
+LL +     type IntoIter = std::slice::Iter<'static, T>;
+LL +     type Iter = &T;
+LL +     fn into_iter() -> Self::IntoIter {
+LL +         self.iter()
+LL +     }
+LL + }
+   |
+
+error: `iter` method without an `IntoIterator` impl for `&S<T>`
+  --> $DIR/iter_without_into_iter.rs:76:13
+   |
+LL | /             pub fn iter(&self) -> std::slice::Iter<'_, T> {
+LL | |
+LL | |                 todo!()
+LL | |             }
+   | |_____________^
+   |
+help: consider implementing `IntoIterator` for `&S<T>`
+   |
+LL ~         
+LL + impl IntoIterator for &S<T> {
+LL +     type IntoIter = std::slice::Iter<'_, T>;
+LL +     type Iter = &T;
+LL +     fn into_iter() -> Self::IntoIter {
+LL +         self.iter()
+LL +     }
+LL + }
+   |
+
+error: `iter_mut` method without an `IntoIterator` impl for `&mut S<T>`
+  --> $DIR/iter_without_into_iter.rs:80:13
+   |
+LL | /             pub fn iter_mut(&mut self) -> std::slice::IterMut<'_, T> {
+LL | |
+LL | |                 todo!()
+LL | |             }
+   | |_____________^
+   |
+help: consider implementing `IntoIterator` for `&mut S<T>`
+   |
+LL ~         
+LL + impl IntoIterator for &mut S<T> {
+LL +     type IntoIter = std::slice::IterMut<'_, T>;
+LL +     type Iter = &mut T;
+LL +     fn into_iter() -> Self::IntoIter {
+LL +         self.iter()
+LL +     }
+LL + }
+   |
+
+error: aborting due to 7 previous errors
+
diff --git a/src/tools/clippy/tests/ui/let_underscore_future.rs b/src/tools/clippy/tests/ui/let_underscore_future.rs
index 873ae667ab7..c2185e9785d 100644
--- a/src/tools/clippy/tests/ui/let_underscore_future.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_future.rs
@@ -9,8 +9,6 @@ fn custom() -> impl Future<Output = ()> {
 }
 
 fn do_something_to_future(future: &mut impl Future<Output = ()>) {}
-//~^ ERROR: this argument is a mutable reference, but not used mutably
-//~| NOTE: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
 
 fn main() {
     let _ = some_async_fn();
diff --git a/src/tools/clippy/tests/ui/let_underscore_future.stderr b/src/tools/clippy/tests/ui/let_underscore_future.stderr
index 3ba99c6377b..ef927a8083b 100644
--- a/src/tools/clippy/tests/ui/let_underscore_future.stderr
+++ b/src/tools/clippy/tests/ui/let_underscore_future.stderr
@@ -1,5 +1,5 @@
 error: non-binding `let` on a future
-  --> $DIR/let_underscore_future.rs:16:5
+  --> $DIR/let_underscore_future.rs:14:5
    |
 LL |     let _ = some_async_fn();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     let _ = some_async_fn();
    = help: to override `-D warnings` add `#[allow(clippy::let_underscore_future)]`
 
 error: non-binding `let` on a future
-  --> $DIR/let_underscore_future.rs:18:5
+  --> $DIR/let_underscore_future.rs:16:5
    |
 LL |     let _ = custom();
    |     ^^^^^^^^^^^^^^^^^
@@ -17,21 +17,12 @@ LL |     let _ = custom();
    = help: consider awaiting the future or dropping explicitly with `std::mem::drop`
 
 error: non-binding `let` on a future
-  --> $DIR/let_underscore_future.rs:23:5
+  --> $DIR/let_underscore_future.rs:21:5
    |
 LL |     let _ = future;
    |     ^^^^^^^^^^^^^^^
    |
    = help: consider awaiting the future or dropping explicitly with `std::mem::drop`
 
-error: this argument is a mutable reference, but not used mutably
-  --> $DIR/let_underscore_future.rs:11:35
-   |
-LL | fn do_something_to_future(future: &mut impl Future<Output = ()>) {}
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&impl Future<Output = ()>`
-   |
-   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_hash_one.fixed b/src/tools/clippy/tests/ui/manual_hash_one.fixed
new file mode 100644
index 00000000000..edfd9c4a47b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_hash_one.fixed
@@ -0,0 +1,89 @@
+#![warn(clippy::manual_hash_one)]
+#![allow(clippy::needless_borrows_for_generic_args)]
+
+use std::hash::{BuildHasher, Hash, Hasher};
+
+fn returned(b: impl BuildHasher) -> u64 {
+    
+    
+    b.hash_one(&true)
+}
+
+fn unsized_receiver(b: impl BuildHasher, s: &str) {
+    
+    
+    let _ = b.hash_one(&s[4..10]);
+}
+
+fn owned_value(b: impl BuildHasher, v: Vec<u32>) -> Vec<u32> {
+    
+    
+    let _ = b.hash_one(&v);
+    v
+}
+
+fn reused_hasher(b: impl BuildHasher) {
+    let mut hasher = b.build_hasher();
+    true.hash(&mut hasher);
+    let _ = hasher.finish();
+    let _ = hasher.finish();
+}
+
+fn reused_hasher_in_return(b: impl BuildHasher) -> u64 {
+    let mut hasher = b.build_hasher();
+    true.hash(&mut hasher);
+    let _ = hasher.finish();
+    hasher.finish()
+}
+
+fn no_hash(b: impl BuildHasher) {
+    let mut hasher = b.build_hasher();
+    let _ = hasher.finish();
+}
+
+fn hash_twice(b: impl BuildHasher) {
+    let mut hasher = b.build_hasher();
+    true.hash(&mut hasher);
+    true.hash(&mut hasher);
+    let _ = hasher.finish();
+}
+
+fn other_hasher(b: impl BuildHasher) {
+    let mut other_hasher = b.build_hasher();
+
+    let mut hasher = b.build_hasher();
+    true.hash(&mut other_hasher);
+    let _ = hasher.finish();
+}
+
+fn finish_then_hash(b: impl BuildHasher) {
+    let mut hasher = b.build_hasher();
+    let _ = hasher.finish();
+    true.hash(&mut hasher);
+}
+
+fn in_macro(b: impl BuildHasher) {
+    macro_rules! m {
+        ($b:expr) => {{
+            let mut hasher = $b.build_hasher();
+            true.hash(&mut hasher);
+            let _ = hasher.finish();
+        }};
+    }
+
+    m!(b);
+}
+
+#[clippy::msrv = "1.70"]
+fn msrv_1_70(b: impl BuildHasher, v: impl Hash) {
+    let mut hasher = b.build_hasher();
+    v.hash(&mut hasher);
+    let _ = hasher.finish();
+}
+
+#[clippy::msrv = "1.71"]
+fn msrv_1_71(b: impl BuildHasher, v: impl Hash) {
+    
+    
+    let _ = b.hash_one(&v);
+}
diff --git a/src/tools/clippy/tests/ui/manual_hash_one.rs b/src/tools/clippy/tests/ui/manual_hash_one.rs
new file mode 100644
index 00000000000..ee61522853f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_hash_one.rs
@@ -0,0 +1,89 @@
+#![warn(clippy::manual_hash_one)]
+#![allow(clippy::needless_borrows_for_generic_args)]
+
+use std::hash::{BuildHasher, Hash, Hasher};
+
+fn returned(b: impl BuildHasher) -> u64 {
+    let mut hasher = b.build_hasher();
+    true.hash(&mut hasher);
+    hasher.finish()
+}
+
+fn unsized_receiver(b: impl BuildHasher, s: &str) {
+    let mut hasher = b.build_hasher();
+    s[4..10].hash(&mut hasher);
+    let _ = hasher.finish();
+}
+
+fn owned_value(b: impl BuildHasher, v: Vec<u32>) -> Vec<u32> {
+    let mut hasher = b.build_hasher();
+    v.hash(&mut hasher);
+    let _ = hasher.finish();
+    v
+}
+
+fn reused_hasher(b: impl BuildHasher) {
+    let mut hasher = b.build_hasher();
+    true.hash(&mut hasher);
+    let _ = hasher.finish();
+    let _ = hasher.finish();
+}
+
+fn reused_hasher_in_return(b: impl BuildHasher) -> u64 {
+    let mut hasher = b.build_hasher();
+    true.hash(&mut hasher);
+    let _ = hasher.finish();
+    hasher.finish()
+}
+
+fn no_hash(b: impl BuildHasher) {
+    let mut hasher = b.build_hasher();
+    let _ = hasher.finish();
+}
+
+fn hash_twice(b: impl BuildHasher) {
+    let mut hasher = b.build_hasher();
+    true.hash(&mut hasher);
+    true.hash(&mut hasher);
+    let _ = hasher.finish();
+}
+
+fn other_hasher(b: impl BuildHasher) {
+    let mut other_hasher = b.build_hasher();
+
+    let mut hasher = b.build_hasher();
+    true.hash(&mut other_hasher);
+    let _ = hasher.finish();
+}
+
+fn finish_then_hash(b: impl BuildHasher) {
+    let mut hasher = b.build_hasher();
+    let _ = hasher.finish();
+    true.hash(&mut hasher);
+}
+
+fn in_macro(b: impl BuildHasher) {
+    macro_rules! m {
+        ($b:expr) => {{
+            let mut hasher = $b.build_hasher();
+            true.hash(&mut hasher);
+            let _ = hasher.finish();
+        }};
+    }
+
+    m!(b);
+}
+
+#[clippy::msrv = "1.70"]
+fn msrv_1_70(b: impl BuildHasher, v: impl Hash) {
+    let mut hasher = b.build_hasher();
+    v.hash(&mut hasher);
+    let _ = hasher.finish();
+}
+
+#[clippy::msrv = "1.71"]
+fn msrv_1_71(b: impl BuildHasher, v: impl Hash) {
+    let mut hasher = b.build_hasher();
+    v.hash(&mut hasher);
+    let _ = hasher.finish();
+}
diff --git a/src/tools/clippy/tests/ui/manual_hash_one.stderr b/src/tools/clippy/tests/ui/manual_hash_one.stderr
new file mode 100644
index 00000000000..3ce6f41e1f9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_hash_one.stderr
@@ -0,0 +1,56 @@
+error: manual implementation of `BuildHasher::hash_one`
+  --> $DIR/manual_hash_one.rs:9:5
+   |
+LL |     hasher.finish()
+   |     ^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::manual-hash-one` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_hash_one)]`
+help: try
+   |
+LL ~     
+LL ~     
+LL ~     b.hash_one(&true)
+   |
+
+error: manual implementation of `BuildHasher::hash_one`
+  --> $DIR/manual_hash_one.rs:15:13
+   |
+LL |     let _ = hasher.finish();
+   |             ^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~     
+LL ~     
+LL ~     let _ = b.hash_one(&s[4..10]);
+   |
+
+error: manual implementation of `BuildHasher::hash_one`
+  --> $DIR/manual_hash_one.rs:21:13
+   |
+LL |     let _ = hasher.finish();
+   |             ^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~     
+LL ~     
+LL ~     let _ = b.hash_one(&v);
+   |
+
+error: manual implementation of `BuildHasher::hash_one`
+  --> $DIR/manual_hash_one.rs:88:13
+   |
+LL |     let _ = hasher.finish();
+   |             ^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL ~     
+LL ~     
+LL ~     let _ = b.hash_one(&v);
+   |
+
+error: aborting due to 4 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.fixed b/src/tools/clippy/tests/ui/manual_let_else_match.fixed
index 09b713f0410..588ba5edd8f 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.fixed
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.fixed
@@ -133,3 +133,7 @@ fn not_fire() {
         [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ ..] => data,
     };
 }
+
+fn issue11579() {
+    let Some(msg) = Some("hi") else { unreachable!("can't happen") };
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.rs b/src/tools/clippy/tests/ui/manual_let_else_match.rs
index e6af4738420..c37b5613ff7 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.rs
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.rs
@@ -170,3 +170,11 @@ fn not_fire() {
         [data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ ..] => data,
     };
 }
+
+fn issue11579() {
+    let msg = match Some("hi") {
+        //~^ ERROR: this could be rewritten as `let...else`
+        Some(m) => m,
+        _ => unreachable!("can't happen"),
+    };
+}
diff --git a/src/tools/clippy/tests/ui/manual_let_else_match.stderr b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
index 8ca2c84072d..18bfe324ba7 100644
--- a/src/tools/clippy/tests/ui/manual_let_else_match.stderr
+++ b/src/tools/clippy/tests/ui/manual_let_else_match.stderr
@@ -92,5 +92,15 @@ LL | |         _ => return,
 LL | |     };
    | |______^ help: consider writing: `let ([data @ .., 0, 0, 0, 0] | [data @ .., 0, 0] | [data @ .., 0]) = data.as_slice() else { return };`
 
-error: aborting due to 9 previous errors
+error: this could be rewritten as `let...else`
+  --> $DIR/manual_let_else_match.rs:175:5
+   |
+LL | /     let msg = match Some("hi") {
+LL | |
+LL | |         Some(m) => m,
+LL | |         _ => unreachable!("can't happen"),
+LL | |     };
+   | |______^ help: consider writing: `let Some(msg) = Some("hi") else { unreachable!("can't happen") };`
+
+error: aborting due to 10 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
index 0e439dabfd6..e32ba863176 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.rs
@@ -10,10 +10,9 @@ enum E {
     _C,
 }
 
-// user forgot to remove the marker
+// if the user explicitly marks as nonexhaustive we shouldn't warn them
 #[non_exhaustive]
 enum Ep {
-    //~^ ERROR: this seems like a manual implementation of the non-exhaustive pattern
     A,
     B,
     #[doc(hidden)]
diff --git a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
index ce7e21c94bb..7361a4a2cbb 100644
--- a/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
+++ b/src/tools/clippy/tests/ui/manual_non_exhaustive_enum.stderr
@@ -22,23 +22,5 @@ LL |     _C,
    = note: `-D clippy::manual-non-exhaustive` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::manual_non_exhaustive)]`
 
-error: this seems like a manual implementation of the non-exhaustive pattern
-  --> $DIR/manual_non_exhaustive_enum.rs:15:1
-   |
-LL | / enum Ep {
-LL | |
-LL | |     A,
-LL | |     B,
-LL | |     #[doc(hidden)]
-LL | |     _C,
-LL | | }
-   | |_^
-   |
-help: remove this variant
-  --> $DIR/manual_non_exhaustive_enum.rs:20:5
-   |
-LL |     _C,
-   |     ^^
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/mut_key.rs b/src/tools/clippy/tests/ui/mut_key.rs
index 80692132176..2d70bfd4c77 100644
--- a/src/tools/clippy/tests/ui/mut_key.rs
+++ b/src/tools/clippy/tests/ui/mut_key.rs
@@ -32,8 +32,6 @@ fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> HashSet<K
     //~^ ERROR: mutable key type
     //~| NOTE: `-D clippy::mutable-key-type` implied by `-D warnings`
     //~| ERROR: mutable key type
-    //~| ERROR: this argument is a mutable reference, but not used mutably
-    //~| NOTE: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
     let _other: HashMap<Key, bool> = HashMap::new();
     //~^ ERROR: mutable key type
     m.keys().cloned().collect()
diff --git a/src/tools/clippy/tests/ui/mut_key.stderr b/src/tools/clippy/tests/ui/mut_key.stderr
index 3701769a9ca..48eeaff78a7 100644
--- a/src/tools/clippy/tests/ui/mut_key.stderr
+++ b/src/tools/clippy/tests/ui/mut_key.stderr
@@ -14,103 +14,94 @@ LL | fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> Hash
    |                                                                        ^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:37:5
+  --> $DIR/mut_key.rs:35:5
    |
 LL |     let _other: HashMap<Key, bool> = HashMap::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:65:22
+  --> $DIR/mut_key.rs:63:22
    |
 LL | fn tuples_bad<U>(_m: &mut HashMap<(Key, U), bool>) {}
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:78:5
+  --> $DIR/mut_key.rs:76:5
    |
 LL |     let _map = HashMap::<Cell<usize>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:80:5
+  --> $DIR/mut_key.rs:78:5
    |
 LL |     let _map = HashMap::<&mut Cell<usize>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:82:5
+  --> $DIR/mut_key.rs:80:5
    |
 LL |     let _map = HashMap::<&mut usize, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:85:5
+  --> $DIR/mut_key.rs:83:5
    |
 LL |     let _map = HashMap::<Vec<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:87:5
+  --> $DIR/mut_key.rs:85:5
    |
 LL |     let _map = HashMap::<BTreeMap<Cell<usize>, ()>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:89:5
+  --> $DIR/mut_key.rs:87:5
    |
 LL |     let _map = HashMap::<BTreeMap<(), Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:91:5
+  --> $DIR/mut_key.rs:89:5
    |
 LL |     let _map = HashMap::<BTreeSet<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:93:5
+  --> $DIR/mut_key.rs:91:5
    |
 LL |     let _map = HashMap::<Option<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:95:5
+  --> $DIR/mut_key.rs:93:5
    |
 LL |     let _map = HashMap::<Option<Vec<Cell<usize>>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:97:5
+  --> $DIR/mut_key.rs:95:5
    |
 LL |     let _map = HashMap::<Result<&mut usize, ()>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:100:5
+  --> $DIR/mut_key.rs:98:5
    |
 LL |     let _map = HashMap::<Box<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:102:5
+  --> $DIR/mut_key.rs:100:5
    |
 LL |     let _map = HashMap::<Rc<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: mutable key type
-  --> $DIR/mut_key.rs:104:5
+  --> $DIR/mut_key.rs:102:5
    |
 LL |     let _map = HashMap::<Arc<Cell<usize>>, usize>::new();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: this argument is a mutable reference, but not used mutably
-  --> $DIR/mut_key.rs:31:32
-   |
-LL | fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> HashSet<Key> {
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing to: `&HashMap<Key, usize>`
-   |
-   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
-
-error: aborting due to 18 previous errors
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/mut_reference.rs b/src/tools/clippy/tests/ui/mut_reference.rs
index f3db226e4e7..1d7faaa5e75 100644
--- a/src/tools/clippy/tests/ui/mut_reference.rs
+++ b/src/tools/clippy/tests/ui/mut_reference.rs
@@ -22,8 +22,6 @@ impl MyStruct {
     fn takes_an_immutable_reference(&self, a: &i32) {}
 
     fn takes_a_mutable_reference(&self, a: &mut i32) {}
-    //~^ ERROR: this argument is a mutable reference, but not used mutably
-    //~| NOTE: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
 }
 
 #[warn(clippy::unnecessary_mut_passed)]
diff --git a/src/tools/clippy/tests/ui/mut_reference.stderr b/src/tools/clippy/tests/ui/mut_reference.stderr
index d7a0d0c2252..87db08e2a74 100644
--- a/src/tools/clippy/tests/ui/mut_reference.stderr
+++ b/src/tools/clippy/tests/ui/mut_reference.stderr
@@ -1,5 +1,5 @@
 error: the function `takes_an_immutable_reference` doesn't need a mutable reference
-  --> $DIR/mut_reference.rs:32:34
+  --> $DIR/mut_reference.rs:30:34
    |
 LL |     takes_an_immutable_reference(&mut 42);
    |                                  ^^^^^^^
@@ -8,25 +8,16 @@ LL |     takes_an_immutable_reference(&mut 42);
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_mut_passed)]`
 
 error: the function `as_ptr` doesn't need a mutable reference
-  --> $DIR/mut_reference.rs:36:12
+  --> $DIR/mut_reference.rs:34:12
    |
 LL |     as_ptr(&mut 42);
    |            ^^^^^^^
 
 error: the method `takes_an_immutable_reference` doesn't need a mutable reference
-  --> $DIR/mut_reference.rs:41:44
+  --> $DIR/mut_reference.rs:39:44
    |
 LL |     my_struct.takes_an_immutable_reference(&mut 42);
    |                                            ^^^^^^^
 
-error: this argument is a mutable reference, but not used mutably
-  --> $DIR/mut_reference.rs:24:44
-   |
-LL |     fn takes_a_mutable_reference(&self, a: &mut i32) {}
-   |                                            ^^^^^^^^ help: consider changing to: `&i32`
-   |
-   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
-
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
index 9cddcb3df23..39d76f99900 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
@@ -1,4 +1,5 @@
 #![allow(clippy::if_same_then_else, clippy::no_effect, clippy::redundant_closure_call)]
+#![warn(clippy::needless_pass_by_ref_mut)]
 #![feature(lint_reasons)]
 //@no-rustfix
 use std::ptr::NonNull;
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
index 0c7fbd5df6d..aa937c3f6af 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
@@ -1,5 +1,5 @@
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:6:11
+  --> $DIR/needless_pass_by_ref_mut.rs:7:11
    |
 LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
    |           ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
@@ -8,79 +8,79 @@ LL | fn foo(s: &mut Vec<u32>, b: &u32, x: &mut u32) {
    = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:31:12
+  --> $DIR/needless_pass_by_ref_mut.rs:32:12
    |
 LL | fn foo6(s: &mut Vec<u32>) {
    |            ^^^^^^^^^^^^^ help: consider changing to: `&Vec<u32>`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:44:29
+  --> $DIR/needless_pass_by_ref_mut.rs:45:29
    |
 LL |     fn mushroom(&self, vec: &mut Vec<i32>) -> usize {
    |                             ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:49:31
+  --> $DIR/needless_pass_by_ref_mut.rs:50:31
    |
 LL |     fn badger(&mut self, vec: &mut Vec<i32>) -> usize {
    |                               ^^^^^^^^^^^^^ help: consider changing to: `&Vec<i32>`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:126:16
+  --> $DIR/needless_pass_by_ref_mut.rs:127:16
    |
 LL | async fn a1(x: &mut i32) {
    |                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:130:16
+  --> $DIR/needless_pass_by_ref_mut.rs:131:16
    |
 LL | async fn a2(x: &mut i32, y: String) {
    |                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:134:16
+  --> $DIR/needless_pass_by_ref_mut.rs:135:16
    |
 LL | async fn a3(x: &mut i32, y: String, z: String) {
    |                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:138:16
+  --> $DIR/needless_pass_by_ref_mut.rs:139:16
    |
 LL | async fn a4(x: &mut i32, y: i32) {
    |                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:142:24
+  --> $DIR/needless_pass_by_ref_mut.rs:143:24
    |
 LL | async fn a5(x: i32, y: &mut i32) {
    |                        ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:146:24
+  --> $DIR/needless_pass_by_ref_mut.rs:147:24
    |
 LL | async fn a6(x: i32, y: &mut i32) {
    |                        ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:150:32
+  --> $DIR/needless_pass_by_ref_mut.rs:151:32
    |
 LL | async fn a7(x: i32, y: i32, z: &mut i32) {
    |                                ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:154:24
+  --> $DIR/needless_pass_by_ref_mut.rs:155:24
    |
 LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
    |                        ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:154:45
+  --> $DIR/needless_pass_by_ref_mut.rs:155:45
    |
 LL | async fn a8(x: i32, a: &mut i32, y: i32, z: &mut i32) {
    |                                             ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:188:16
+  --> $DIR/needless_pass_by_ref_mut.rs:189:16
    |
 LL | fn cfg_warn(s: &mut u32) {}
    |                ^^^^^^^^ help: consider changing to: `&u32`
@@ -88,7 +88,7 @@ LL | fn cfg_warn(s: &mut u32) {}
    = note: this is cfg-gated and may require further changes
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:194:20
+  --> $DIR/needless_pass_by_ref_mut.rs:195:20
    |
 LL |     fn cfg_warn(s: &mut u32) {}
    |                    ^^^^^^^^ help: consider changing to: `&u32`
@@ -96,19 +96,19 @@ LL |     fn cfg_warn(s: &mut u32) {}
    = note: this is cfg-gated and may require further changes
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:208:39
+  --> $DIR/needless_pass_by_ref_mut.rs:209:39
    |
 LL | async fn inner_async2(x: &mut i32, y: &mut u32) {
    |                                       ^^^^^^^^ help: consider changing to: `&u32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:216:26
+  --> $DIR/needless_pass_by_ref_mut.rs:217:26
    |
 LL | async fn inner_async3(x: &mut i32, y: &mut u32) {
    |                          ^^^^^^^^ help: consider changing to: `&i32`
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:235:34
+  --> $DIR/needless_pass_by_ref_mut.rs:236:34
    |
 LL | pub async fn call_in_closure1(n: &mut str) {
    |                                  ^^^^^^^^ help: consider changing to: `&str`
@@ -116,7 +116,7 @@ LL | pub async fn call_in_closure1(n: &mut str) {
    = warning: changing this function will impact semver compatibility
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:247:25
+  --> $DIR/needless_pass_by_ref_mut.rs:248:25
    |
 LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
    |                         ^^^^^^^^^^ help: consider changing to: `&usize`
@@ -124,7 +124,7 @@ LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
    = warning: changing this function will impact semver compatibility
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:254:20
+  --> $DIR/needless_pass_by_ref_mut.rs:255:20
    |
 LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
    |                    ^^^^^^^^^^ help: consider changing to: `&usize`
@@ -132,7 +132,7 @@ LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
    = warning: changing this function will impact semver compatibility
 
 error: this argument is a mutable reference, but not used mutably
-  --> $DIR/needless_pass_by_ref_mut.rs:265:26
+  --> $DIR/needless_pass_by_ref_mut.rs:266:26
    |
 LL | pub async fn closure4(n: &mut usize) {
    |                          ^^^^^^^^^^ help: consider changing to: `&usize`
diff --git a/src/tools/clippy/tests/ui/needless_raw_string.fixed b/src/tools/clippy/tests/ui/needless_raw_string.fixed
index 85549810513..4ea711fd67a 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string.fixed
+++ b/src/tools/clippy/tests/ui/needless_raw_string.fixed
@@ -18,4 +18,8 @@ fn main() {
         multiline
         string
     ";
+
+    "no hashes";
+    b"no hashes";
+    c"no hashes";
 }
diff --git a/src/tools/clippy/tests/ui/needless_raw_string.rs b/src/tools/clippy/tests/ui/needless_raw_string.rs
index 06d49730387..b6239f9b1f0 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string.rs
+++ b/src/tools/clippy/tests/ui/needless_raw_string.rs
@@ -18,4 +18,8 @@ fn main() {
         multiline
         string
     "#;
+
+    r"no hashes";
+    br"no hashes";
+    cr"no hashes";
 }
diff --git a/src/tools/clippy/tests/ui/needless_raw_string.stderr b/src/tools/clippy/tests/ui/needless_raw_string.stderr
index e6806b31b1d..276bc84c6c3 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string.stderr
+++ b/src/tools/clippy/tests/ui/needless_raw_string.stderr
@@ -6,7 +6,7 @@ LL |     r#"aaa"#;
    |
    = note: `-D clippy::needless-raw-strings` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::needless_raw_strings)]`
-help: try
+help: use a plain string literal instead
    |
 LL -     r#"aaa"#;
 LL +     "aaa";
@@ -18,7 +18,7 @@ error: unnecessary raw string literal
 LL |     br#"aaa"#;
    |     ^^^^^^^^^
    |
-help: try
+help: use a plain byte string literal instead
    |
 LL -     br#"aaa"#;
 LL +     b"aaa";
@@ -30,7 +30,7 @@ error: unnecessary raw string literal
 LL |     cr#"aaa"#;
    |     ^^^^^^^^^
    |
-help: try
+help: use a plain C string literal instead
    |
 LL -     cr#"aaa"#;
 LL +     c"aaa";
@@ -46,7 +46,7 @@ LL | |         string
 LL | |     "#;
    | |______^
    |
-help: try
+help: use a plain string literal instead
    |
 LL ~     "
 LL |         a
@@ -55,5 +55,41 @@ LL |         string
 LL ~     ";
    |
 
-error: aborting due to 4 previous errors
+error: unnecessary raw string literal
+  --> $DIR/needless_raw_string.rs:22:5
+   |
+LL |     r"no hashes";
+   |     ^^^^^^^^^^^^
+   |
+help: use a plain string literal instead
+   |
+LL -     r"no hashes";
+LL +     "no hashes";
+   |
+
+error: unnecessary raw string literal
+  --> $DIR/needless_raw_string.rs:23:5
+   |
+LL |     br"no hashes";
+   |     ^^^^^^^^^^^^^
+   |
+help: use a plain byte string literal instead
+   |
+LL -     br"no hashes";
+LL +     b"no hashes";
+   |
+
+error: unnecessary raw string literal
+  --> $DIR/needless_raw_string.rs:24:5
+   |
+LL |     cr"no hashes";
+   |     ^^^^^^^^^^^^^
+   |
+help: use a plain C string literal instead
+   |
+LL -     cr"no hashes";
+LL +     c"no hashes";
+   |
+
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
index 4399c6555c2..017160b1a42 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
@@ -6,7 +6,7 @@ LL |     r#"\aaa"#;
    |
    = note: `-D clippy::needless-raw-string-hashes` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::needless_raw_string_hashes)]`
-help: remove all the hashes around the literal
+help: remove all the hashes around the string literal
    |
 LL -     r#"\aaa"#;
 LL +     r"\aaa";
@@ -18,7 +18,7 @@ error: unnecessary hashes around raw string literal
 LL |     r##"Hello "world"!"##;
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
-help: remove one hash from both sides of the literal
+help: remove one hash from both sides of the string literal
    |
 LL -     r##"Hello "world"!"##;
 LL +     r#"Hello "world"!"#;
@@ -30,7 +30,7 @@ error: unnecessary hashes around raw string literal
 LL |     r######" "### "## "# "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: remove 2 hashes from both sides of the literal
+help: remove 2 hashes from both sides of the string literal
    |
 LL -     r######" "### "## "# "######;
 LL +     r####" "### "## "# "####;
@@ -42,7 +42,7 @@ error: unnecessary hashes around raw string literal
 LL |     r######" "aa" "# "## "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: remove 3 hashes from both sides of the literal
+help: remove 3 hashes from both sides of the string literal
    |
 LL -     r######" "aa" "# "## "######;
 LL +     r###" "aa" "# "## "###;
@@ -54,7 +54,7 @@ error: unnecessary hashes around raw string literal
 LL |     br#"\aaa"#;
    |     ^^^^^^^^^^
    |
-help: remove all the hashes around the literal
+help: remove all the hashes around the byte string literal
    |
 LL -     br#"\aaa"#;
 LL +     br"\aaa";
@@ -66,7 +66,7 @@ error: unnecessary hashes around raw string literal
 LL |     br##"Hello "world"!"##;
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
-help: remove one hash from both sides of the literal
+help: remove one hash from both sides of the byte string literal
    |
 LL -     br##"Hello "world"!"##;
 LL +     br#"Hello "world"!"#;
@@ -78,7 +78,7 @@ error: unnecessary hashes around raw string literal
 LL |     br######" "### "## "# "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: remove 2 hashes from both sides of the literal
+help: remove 2 hashes from both sides of the byte string literal
    |
 LL -     br######" "### "## "# "######;
 LL +     br####" "### "## "# "####;
@@ -90,7 +90,7 @@ error: unnecessary hashes around raw string literal
 LL |     br######" "aa" "# "## "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: remove 3 hashes from both sides of the literal
+help: remove 3 hashes from both sides of the byte string literal
    |
 LL -     br######" "aa" "# "## "######;
 LL +     br###" "aa" "# "## "###;
@@ -102,7 +102,7 @@ error: unnecessary hashes around raw string literal
 LL |     cr#"\aaa"#;
    |     ^^^^^^^^^^
    |
-help: remove all the hashes around the literal
+help: remove all the hashes around the C string literal
    |
 LL -     cr#"\aaa"#;
 LL +     cr"\aaa";
@@ -114,7 +114,7 @@ error: unnecessary hashes around raw string literal
 LL |     cr##"Hello "world"!"##;
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
-help: remove one hash from both sides of the literal
+help: remove one hash from both sides of the C string literal
    |
 LL -     cr##"Hello "world"!"##;
 LL +     cr#"Hello "world"!"#;
@@ -126,7 +126,7 @@ error: unnecessary hashes around raw string literal
 LL |     cr######" "### "## "# "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: remove 2 hashes from both sides of the literal
+help: remove 2 hashes from both sides of the C string literal
    |
 LL -     cr######" "### "## "# "######;
 LL +     cr####" "### "## "# "####;
@@ -138,7 +138,7 @@ error: unnecessary hashes around raw string literal
 LL |     cr######" "aa" "# "## "######;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: remove 3 hashes from both sides of the literal
+help: remove 3 hashes from both sides of the C string literal
    |
 LL -     cr######" "aa" "# "## "######;
 LL +     cr###" "aa" "# "## "###;
@@ -154,7 +154,7 @@ LL | |         string
 LL | |     "#;
    | |______^
    |
-help: remove all the hashes around the literal
+help: remove all the hashes around the string literal
    |
 LL ~     r"
 LL |         \a
@@ -169,7 +169,7 @@ error: unnecessary hashes around raw string literal
 LL |     r###"rust"###;
    |     ^^^^^^^^^^^^^
    |
-help: remove all the hashes around the literal
+help: remove all the hashes around the string literal
    |
 LL -     r###"rust"###;
 LL +     r"rust";
@@ -181,7 +181,7 @@ error: unnecessary hashes around raw string literal
 LL |     r#"hello world"#;
    |     ^^^^^^^^^^^^^^^^
    |
-help: remove all the hashes around the literal
+help: remove all the hashes around the string literal
    |
 LL -     r#"hello world"#;
 LL +     r"hello world";
diff --git a/src/tools/clippy/tests/ui/print_literal.fixed b/src/tools/clippy/tests/ui/print_literal.fixed
index 88cd3a54b41..a7157c07f8a 100644
--- a/src/tools/clippy/tests/ui/print_literal.fixed
+++ b/src/tools/clippy/tests/ui/print_literal.fixed
@@ -39,20 +39,30 @@ fn main() {
     // throw a warning
     println!("hello world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
     println!("world hello");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
 
     // named args shouldn't change anything either
     println!("hello world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
     println!("world hello");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
 
     // The string literal from `file!()` has a callsite span that isn't marked as coming from an
     // expansion
     println!("file: {}", file!());
+
+    // Braces in unicode escapes should not be escaped
+    println!("{{}} \x00 \u{ab123} \\\u{ab123} {{:?}}");
+    println!("\\\u{1234}");
+    // This does not lint because it would have to suggest unescaping the character
+    println!(r"{}", "\u{ab123}");
+    // These are not unicode escapes
+    println!("\\u{{ab123}} \\u{{{{");
+    println!(r"\u{{ab123}} \u{{{{");
+    println!("\\{{ab123}} \\u{{{{");
+    println!("\\u{{ab123}}");
+    println!("\\\\u{{1234}}");
+
+    println!("mixed: {{hello}} {world}");
 }
diff --git a/src/tools/clippy/tests/ui/print_literal.rs b/src/tools/clippy/tests/ui/print_literal.rs
index bd7444c9606..4b04b42744c 100644
--- a/src/tools/clippy/tests/ui/print_literal.rs
+++ b/src/tools/clippy/tests/ui/print_literal.rs
@@ -39,20 +39,30 @@ fn main() {
     // throw a warning
     println!("{0} {1}", "hello", "world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
     println!("{1} {0}", "hello", "world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
 
     // named args shouldn't change anything either
     println!("{foo} {bar}", foo = "hello", bar = "world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
     println!("{bar} {foo}", foo = "hello", bar = "world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
 
     // The string literal from `file!()` has a callsite span that isn't marked as coming from an
     // expansion
     println!("file: {}", file!());
+
+    // Braces in unicode escapes should not be escaped
+    println!("{}", "{} \x00 \u{ab123} \\\u{ab123} {:?}");
+    println!("{}", "\\\u{1234}");
+    // This does not lint because it would have to suggest unescaping the character
+    println!(r"{}", "\u{ab123}");
+    // These are not unicode escapes
+    println!("{}", r"\u{ab123} \u{{");
+    println!(r"{}", r"\u{ab123} \u{{");
+    println!("{}", r"\{ab123} \u{{");
+    println!("{}", "\\u{ab123}");
+    println!("{}", "\\\\u{1234}");
+
+    println!("mixed: {} {world}", "{hello}");
 }
diff --git a/src/tools/clippy/tests/ui/print_literal.stderr b/src/tools/clippy/tests/ui/print_literal.stderr
index 1d9751b92e9..8c011d7bc0a 100644
--- a/src/tools/clippy/tests/ui/print_literal.stderr
+++ b/src/tools/clippy/tests/ui/print_literal.stderr
@@ -52,97 +52,145 @@ error: literal with an empty format string
   --> $DIR/print_literal.rs:40:25
    |
 LL |     println!("{0} {1}", "hello", "world");
-   |                         ^^^^^^^
+   |                         ^^^^^^^^^^^^^^^^
    |
 help: try
    |
 LL -     println!("{0} {1}", "hello", "world");
-LL +     println!("hello {1}", "world");
+LL +     println!("hello world");
    |
 
 error: literal with an empty format string
-  --> $DIR/print_literal.rs:40:34
+  --> $DIR/print_literal.rs:42:25
    |
-LL |     println!("{0} {1}", "hello", "world");
-   |                                  ^^^^^^^
+LL |     println!("{1} {0}", "hello", "world");
+   |                         ^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     println!("{0} {1}", "hello", "world");
-LL +     println!("{0} world", "hello");
+LL -     println!("{1} {0}", "hello", "world");
+LL +     println!("world hello");
    |
 
 error: literal with an empty format string
-  --> $DIR/print_literal.rs:43:34
+  --> $DIR/print_literal.rs:46:35
    |
-LL |     println!("{1} {0}", "hello", "world");
-   |                                  ^^^^^^^
+LL |     println!("{foo} {bar}", foo = "hello", bar = "world");
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     println!("{1} {0}", "hello", "world");
-LL +     println!("world {0}", "hello");
+LL -     println!("{foo} {bar}", foo = "hello", bar = "world");
+LL +     println!("hello world");
    |
 
 error: literal with an empty format string
-  --> $DIR/print_literal.rs:43:25
+  --> $DIR/print_literal.rs:48:35
    |
-LL |     println!("{1} {0}", "hello", "world");
-   |                         ^^^^^^^
+LL |     println!("{bar} {foo}", foo = "hello", bar = "world");
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     println!("{1} {0}", "hello", "world");
-LL +     println!("{1} hello", "world");
+LL -     println!("{bar} {foo}", foo = "hello", bar = "world");
+LL +     println!("world hello");
    |
 
 error: literal with an empty format string
-  --> $DIR/print_literal.rs:48:35
+  --> $DIR/print_literal.rs:56:20
    |
-LL |     println!("{foo} {bar}", foo = "hello", bar = "world");
-   |                                   ^^^^^^^
+LL |     println!("{}", "{} \x00 \u{ab123} \\\u{ab123} {:?}");
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     println!("{foo} {bar}", foo = "hello", bar = "world");
-LL +     println!("hello {bar}", bar = "world");
+LL -     println!("{}", "{} \x00 \u{ab123} \\\u{ab123} {:?}");
+LL +     println!("{{}} \x00 \u{ab123} \\\u{ab123} {{:?}}");
    |
 
 error: literal with an empty format string
-  --> $DIR/print_literal.rs:48:50
+  --> $DIR/print_literal.rs:57:20
    |
-LL |     println!("{foo} {bar}", foo = "hello", bar = "world");
-   |                                                  ^^^^^^^
+LL |     println!("{}", "\\\u{1234}");
+   |                    ^^^^^^^^^^^^
    |
 help: try
    |
-LL -     println!("{foo} {bar}", foo = "hello", bar = "world");
-LL +     println!("{foo} world", foo = "hello");
+LL -     println!("{}", "\\\u{1234}");
+LL +     println!("\\\u{1234}");
    |
 
 error: literal with an empty format string
-  --> $DIR/print_literal.rs:51:50
+  --> $DIR/print_literal.rs:61:20
    |
-LL |     println!("{bar} {foo}", foo = "hello", bar = "world");
-   |                                                  ^^^^^^^
+LL |     println!("{}", r"\u{ab123} \u{{");
+   |                    ^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     println!("{bar} {foo}", foo = "hello", bar = "world");
-LL +     println!("world {foo}", foo = "hello");
+LL -     println!("{}", r"\u{ab123} \u{{");
+LL +     println!("\\u{{ab123}} \\u{{{{");
    |
 
 error: literal with an empty format string
-  --> $DIR/print_literal.rs:51:35
+  --> $DIR/print_literal.rs:62:21
    |
-LL |     println!("{bar} {foo}", foo = "hello", bar = "world");
-   |                                   ^^^^^^^
+LL |     println!(r"{}", r"\u{ab123} \u{{");
+   |                     ^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     println!("{bar} {foo}", foo = "hello", bar = "world");
-LL +     println!("{bar} hello", bar = "world");
+LL -     println!(r"{}", r"\u{ab123} \u{{");
+LL +     println!(r"\u{{ab123}} \u{{{{");
+   |
+
+error: literal with an empty format string
+  --> $DIR/print_literal.rs:63:20
+   |
+LL |     println!("{}", r"\{ab123} \u{{");
+   |                    ^^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -     println!("{}", r"\{ab123} \u{{");
+LL +     println!("\\{{ab123}} \\u{{{{");
+   |
+
+error: literal with an empty format string
+  --> $DIR/print_literal.rs:64:20
+   |
+LL |     println!("{}", "\\u{ab123}");
+   |                    ^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -     println!("{}", "\\u{ab123}");
+LL +     println!("\\u{{ab123}}");
+   |
+
+error: literal with an empty format string
+  --> $DIR/print_literal.rs:65:20
+   |
+LL |     println!("{}", "\\\\u{1234}");
+   |                    ^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -     println!("{}", "\\\\u{1234}");
+LL +     println!("\\\\u{{1234}}");
+   |
+
+error: literal with an empty format string
+  --> $DIR/print_literal.rs:67:35
+   |
+LL |     println!("mixed: {} {world}", "{hello}");
+   |                                   ^^^^^^^^^
+   |
+help: try
+   |
+LL -     println!("mixed: {} {world}", "{hello}");
+LL +     println!("mixed: {{hello}} {world}");
    |
 
-error: aborting due to 12 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/redundant_locals.rs b/src/tools/clippy/tests/ui/redundant_locals.rs
index c5d93e4365d..e81db300f15 100644
--- a/src/tools/clippy/tests/ui/redundant_locals.rs
+++ b/src/tools/clippy/tests/ui/redundant_locals.rs
@@ -118,3 +118,40 @@ fn macros() {
         let x = x;
     }
 }
+
+struct WithDrop(usize);
+impl Drop for WithDrop {
+    fn drop(&mut self) {}
+}
+
+struct InnerDrop(WithDrop);
+
+struct ComposeDrop {
+    d: WithDrop,
+}
+
+struct WithoutDrop(usize);
+
+fn drop_trait() {
+    let a = WithDrop(1);
+    let b = WithDrop(2);
+    let a = a;
+}
+
+fn without_drop() {
+    let a = WithoutDrop(1);
+    let b = WithoutDrop(2);
+    let a = a;
+}
+
+fn drop_inner() {
+    let a = InnerDrop(WithDrop(1));
+    let b = InnerDrop(WithDrop(2));
+    let a = a;
+}
+
+fn drop_compose() {
+    let a = ComposeDrop { d: WithDrop(1) };
+    let b = ComposeDrop { d: WithDrop(1) };
+    let a = a;
+}
diff --git a/src/tools/clippy/tests/ui/redundant_locals.stderr b/src/tools/clippy/tests/ui/redundant_locals.stderr
index 13b872e9576..d794a87fe7d 100644
--- a/src/tools/clippy/tests/ui/redundant_locals.stderr
+++ b/src/tools/clippy/tests/ui/redundant_locals.stderr
@@ -1,137 +1,172 @@
-error: redundant redefinition of a binding
-  --> $DIR/redundant_locals.rs:11:9
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:12:5
    |
-LL |     let x = 1;
-   |         ^
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
+help: `x` is initially defined here
+  --> $DIR/redundant_locals.rs:11:9
+   |
+LL |     let x = 1;
+   |         ^
    = note: `-D clippy::redundant-locals` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::redundant_locals)]`
 
-error: redundant redefinition of a binding
-  --> $DIR/redundant_locals.rs:16:9
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:17:5
    |
-LL |     let mut x = 1;
-   |         ^^^^^
 LL |     let mut x = x;
    |     ^^^^^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
+help: `x` is initially defined here
+  --> $DIR/redundant_locals.rs:16:9
+   |
+LL |     let mut x = 1;
+   |         ^^^^^
 
-error: redundant redefinition of a binding
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:47:5
+   |
+LL |     let x = x;
+   |     ^^^^^^^^^^
+   |
+help: `x` is initially defined here
   --> $DIR/redundant_locals.rs:46:14
    |
 LL | fn parameter(x: i32) {
    |              ^
+
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:52:5
+   |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
-
-error: redundant redefinition of a binding
+help: `x` is initially defined here
   --> $DIR/redundant_locals.rs:51:9
    |
 LL |     let x = 1;
    |         ^
+
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:53:5
+   |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
-
-error: redundant redefinition of a binding
+help: `x` is initially defined here
   --> $DIR/redundant_locals.rs:52:9
    |
 LL |     let x = x;
    |         ^
+
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:54:5
+   |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
-
-error: redundant redefinition of a binding
+help: `x` is initially defined here
   --> $DIR/redundant_locals.rs:53:9
    |
 LL |     let x = x;
    |         ^
+
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:55:5
+   |
 LL |     let x = x;
    |     ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
-
-error: redundant redefinition of a binding
+help: `x` is initially defined here
   --> $DIR/redundant_locals.rs:54:9
    |
 LL |     let x = x;
    |         ^
-LL |     let x = x;
+
+error: redundant redefinition of a binding `a`
+  --> $DIR/redundant_locals.rs:61:5
+   |
+LL |     let a = a;
    |     ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
-
-error: redundant redefinition of a binding
+help: `a` is initially defined here
   --> $DIR/redundant_locals.rs:59:9
    |
 LL |     let a = 1;
    |         ^
-LL |     let b = 2;
-LL |     let a = a;
+
+error: redundant redefinition of a binding `b`
+  --> $DIR/redundant_locals.rs:62:5
+   |
+LL |     let b = b;
    |     ^^^^^^^^^^
    |
-   = help: remove the redefinition of `a`
-
-error: redundant redefinition of a binding
+help: `b` is initially defined here
   --> $DIR/redundant_locals.rs:60:9
    |
 LL |     let b = 2;
    |         ^
-LL |     let a = a;
-LL |     let b = b;
-   |     ^^^^^^^^^^
-   |
-   = help: remove the redefinition of `b`
 
-error: redundant redefinition of a binding
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:68:9
+   |
+LL |         let x = x;
+   |         ^^^^^^^^^^
+   |
+help: `x` is initially defined here
   --> $DIR/redundant_locals.rs:67:13
    |
 LL |         let x = 1;
    |             ^
+
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:75:9
+   |
 LL |         let x = x;
    |         ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
-
-error: redundant redefinition of a binding
+help: `x` is initially defined here
   --> $DIR/redundant_locals.rs:74:13
    |
 LL |         let x = 1;
    |             ^
+
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:78:9
+   |
 LL |         let x = x;
    |         ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
-
-error: redundant redefinition of a binding
+help: `x` is initially defined here
   --> $DIR/redundant_locals.rs:77:6
    |
 LL |     |x: i32| {
    |      ^
+
+error: redundant redefinition of a binding `x`
+  --> $DIR/redundant_locals.rs:97:9
+   |
 LL |         let x = x;
    |         ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
-
-error: redundant redefinition of a binding
+help: `x` is initially defined here
   --> $DIR/redundant_locals.rs:94:9
    |
 LL |     let x = 1;
    |         ^
-...
-LL |         let x = x;
-   |         ^^^^^^^^^^
+
+error: redundant redefinition of a binding `a`
+  --> $DIR/redundant_locals.rs:144:5
+   |
+LL |     let a = a;
+   |     ^^^^^^^^^^
    |
-   = help: remove the redefinition of `x`
+help: `a` is initially defined here
+  --> $DIR/redundant_locals.rs:142:9
+   |
+LL |     let a = WithoutDrop(1);
+   |         ^
 
-error: aborting due to 13 previous errors
+error: aborting due to 14 previous errors
 
diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs
index 550ec007268..33211b32d74 100644
--- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs
+++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.rs
@@ -40,8 +40,6 @@ impl T {
 
     pub fn hash(&self, state: &mut T) {
         //~^ ERROR: method `hash` can be confused for the standard trait method `std::hash::Ha
-        //~| ERROR: this argument is a mutable reference, but not used mutably
-        //~| NOTE: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
         unimplemented!()
     }
 
diff --git a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
index 79afddea247..c257f411342 100644
--- a/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
+++ b/src/tools/clippy/tests/ui/should_impl_trait/method_list_2.stderr
@@ -38,8 +38,6 @@ error: method `hash` can be confused for the standard trait method `std::hash::H
    |
 LL | /     pub fn hash(&self, state: &mut T) {
 LL | |
-LL | |
-LL | |
 LL | |         unimplemented!()
 LL | |     }
    | |_____^
@@ -47,7 +45,7 @@ LL | |     }
    = help: consider implementing the trait `std::hash::Hash` or choosing a less ambiguous method name
 
 error: method `index` can be confused for the standard trait method `std::ops::Index::index`
-  --> $DIR/method_list_2.rs:48:5
+  --> $DIR/method_list_2.rs:46:5
    |
 LL | /     pub fn index(&self, index: usize) -> &Self {
 LL | |
@@ -58,7 +56,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Index` or choosing a less ambiguous method name
 
 error: method `index_mut` can be confused for the standard trait method `std::ops::IndexMut::index_mut`
-  --> $DIR/method_list_2.rs:53:5
+  --> $DIR/method_list_2.rs:51:5
    |
 LL | /     pub fn index_mut(&mut self, index: usize) -> &mut Self {
 LL | |
@@ -69,7 +67,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::IndexMut` or choosing a less ambiguous method name
 
 error: method `into_iter` can be confused for the standard trait method `std::iter::IntoIterator::into_iter`
-  --> $DIR/method_list_2.rs:58:5
+  --> $DIR/method_list_2.rs:56:5
    |
 LL | /     pub fn into_iter(self) -> Self {
 LL | |
@@ -80,7 +78,7 @@ LL | |     }
    = help: consider implementing the trait `std::iter::IntoIterator` or choosing a less ambiguous method name
 
 error: method `mul` can be confused for the standard trait method `std::ops::Mul::mul`
-  --> $DIR/method_list_2.rs:63:5
+  --> $DIR/method_list_2.rs:61:5
    |
 LL | /     pub fn mul(self, rhs: Self) -> Self {
 LL | |
@@ -91,7 +89,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Mul` or choosing a less ambiguous method name
 
 error: method `neg` can be confused for the standard trait method `std::ops::Neg::neg`
-  --> $DIR/method_list_2.rs:68:5
+  --> $DIR/method_list_2.rs:66:5
    |
 LL | /     pub fn neg(self) -> Self {
 LL | |
@@ -102,7 +100,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Neg` or choosing a less ambiguous method name
 
 error: method `next` can be confused for the standard trait method `std::iter::Iterator::next`
-  --> $DIR/method_list_2.rs:73:5
+  --> $DIR/method_list_2.rs:71:5
    |
 LL | /     pub fn next(&mut self) -> Option<Self> {
 LL | |
@@ -113,7 +111,7 @@ LL | |     }
    = help: consider implementing the trait `std::iter::Iterator` or choosing a less ambiguous method name
 
 error: method `not` can be confused for the standard trait method `std::ops::Not::not`
-  --> $DIR/method_list_2.rs:78:5
+  --> $DIR/method_list_2.rs:76:5
    |
 LL | /     pub fn not(self) -> Self {
 LL | |
@@ -124,7 +122,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Not` or choosing a less ambiguous method name
 
 error: method `rem` can be confused for the standard trait method `std::ops::Rem::rem`
-  --> $DIR/method_list_2.rs:83:5
+  --> $DIR/method_list_2.rs:81:5
    |
 LL | /     pub fn rem(self, rhs: Self) -> Self {
 LL | |
@@ -135,7 +133,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Rem` or choosing a less ambiguous method name
 
 error: method `shl` can be confused for the standard trait method `std::ops::Shl::shl`
-  --> $DIR/method_list_2.rs:88:5
+  --> $DIR/method_list_2.rs:86:5
    |
 LL | /     pub fn shl(self, rhs: Self) -> Self {
 LL | |
@@ -146,7 +144,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Shl` or choosing a less ambiguous method name
 
 error: method `shr` can be confused for the standard trait method `std::ops::Shr::shr`
-  --> $DIR/method_list_2.rs:93:5
+  --> $DIR/method_list_2.rs:91:5
    |
 LL | /     pub fn shr(self, rhs: Self) -> Self {
 LL | |
@@ -157,7 +155,7 @@ LL | |     }
    = help: consider implementing the trait `std::ops::Shr` or choosing a less ambiguous method name
 
 error: method `sub` can be confused for the standard trait method `std::ops::Sub::sub`
-  --> $DIR/method_list_2.rs:98:5
+  --> $DIR/method_list_2.rs:96:5
    |
 LL | /     pub fn sub(self, rhs: Self) -> Self {
 LL | |
@@ -167,15 +165,5 @@ LL | |     }
    |
    = help: consider implementing the trait `std::ops::Sub` or choosing a less ambiguous method name
 
-error: this argument is a mutable reference, but not used mutably
-  --> $DIR/method_list_2.rs:41:31
-   |
-LL |     pub fn hash(&self, state: &mut T) {
-   |                               ^^^^^^ help: consider changing to: `&T`
-   |
-   = warning: changing this function will impact semver compatibility
-   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
-
-error: aborting due to 16 previous errors
+error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/slow_vector_initialization.rs b/src/tools/clippy/tests/ui/slow_vector_initialization.rs
index 5c3086c9d69..16f81019574 100644
--- a/src/tools/clippy/tests/ui/slow_vector_initialization.rs
+++ b/src/tools/clippy/tests/ui/slow_vector_initialization.rs
@@ -103,8 +103,6 @@ fn from_empty_vec() {
 }
 
 fn do_stuff(vec: &mut [u8]) {}
-//~^ ERROR: this argument is a mutable reference, but not used mutably
-//~| NOTE: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
 
 fn extend_vector_with_manipulations_between() {
     let len = 300;
diff --git a/src/tools/clippy/tests/ui/slow_vector_initialization.stderr b/src/tools/clippy/tests/ui/slow_vector_initialization.stderr
index 4d24400ecb5..16a7057653c 100644
--- a/src/tools/clippy/tests/ui/slow_vector_initialization.stderr
+++ b/src/tools/clippy/tests/ui/slow_vector_initialization.stderr
@@ -105,14 +105,5 @@ LL |     vec1 = vec![];
 LL |     vec1.resize(10, 0);
    |     ^^^^^^^^^^^^^^^^^^
 
-error: this argument is a mutable reference, but not used mutably
-  --> $DIR/slow_vector_initialization.rs:105:18
-   |
-LL | fn do_stuff(vec: &mut [u8]) {}
-   |                  ^^^^^^^^^ help: consider changing to: `&[u8]`
-   |
-   = note: `-D clippy::needless-pass-by-ref-mut` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::needless_pass_by_ref_mut)]`
-
-error: aborting due to 14 previous errors
+error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.fixed b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
index 8027c053fb5..a7555704fbe 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.fixed
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.fixed
@@ -1,8 +1,12 @@
+//@aux-build:proc_macro_derive.rs
 #![warn(clippy::std_instead_of_core)]
 #![allow(unused_imports)]
 
 extern crate alloc;
 
+#[macro_use]
+extern crate proc_macro_derive;
+
 #[warn(clippy::std_instead_of_core)]
 fn std_instead_of_core() {
     // Regular import
@@ -55,6 +59,13 @@ fn alloc_instead_of_core() {
     //~^ ERROR: used import from `alloc` instead of `core`
 }
 
+mod std_in_proc_macro_derive {
+    #[warn(clippy::alloc_instead_of_core)]
+    #[allow(unused)]
+    #[derive(ImplStructWithStdDisplay)]
+    struct B {}
+}
+
 fn main() {
     std_instead_of_core();
     std_instead_of_alloc();
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.rs b/src/tools/clippy/tests/ui/std_instead_of_core.rs
index 63a096384d7..af7f3399f49 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.rs
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.rs
@@ -1,8 +1,12 @@
+//@aux-build:proc_macro_derive.rs
 #![warn(clippy::std_instead_of_core)]
 #![allow(unused_imports)]
 
 extern crate alloc;
 
+#[macro_use]
+extern crate proc_macro_derive;
+
 #[warn(clippy::std_instead_of_core)]
 fn std_instead_of_core() {
     // Regular import
@@ -55,6 +59,13 @@ fn alloc_instead_of_core() {
     //~^ ERROR: used import from `alloc` instead of `core`
 }
 
+mod std_in_proc_macro_derive {
+    #[warn(clippy::alloc_instead_of_core)]
+    #[allow(unused)]
+    #[derive(ImplStructWithStdDisplay)]
+    struct B {}
+}
+
 fn main() {
     std_instead_of_core();
     std_instead_of_alloc();
diff --git a/src/tools/clippy/tests/ui/std_instead_of_core.stderr b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
index ca26f77bd37..4f7bdc4045e 100644
--- a/src/tools/clippy/tests/ui/std_instead_of_core.stderr
+++ b/src/tools/clippy/tests/ui/std_instead_of_core.stderr
@@ -1,5 +1,5 @@
 error: used import from `std` instead of `core`
-  --> $DIR/std_instead_of_core.rs:9:9
+  --> $DIR/std_instead_of_core.rs:13:9
    |
 LL |     use std::hash::Hasher;
    |         ^^^ help: consider importing the item from `core`: `core`
@@ -8,49 +8,49 @@ LL |     use std::hash::Hasher;
    = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_core)]`
 
 error: used import from `std` instead of `core`
-  --> $DIR/std_instead_of_core.rs:12:11
+  --> $DIR/std_instead_of_core.rs:16:11
    |
 LL |     use ::std::hash::Hash;
    |           ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> $DIR/std_instead_of_core.rs:18:9
+  --> $DIR/std_instead_of_core.rs:22:9
    |
 LL |     use std::fmt::{Debug, Result};
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> $DIR/std_instead_of_core.rs:22:15
+  --> $DIR/std_instead_of_core.rs:26:15
    |
 LL |     let ptr = std::ptr::null::<u32>();
    |               ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> $DIR/std_instead_of_core.rs:24:21
+  --> $DIR/std_instead_of_core.rs:28:21
    |
 LL |     let ptr_mut = ::std::ptr::null_mut::<usize>();
    |                     ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> $DIR/std_instead_of_core.rs:28:16
+  --> $DIR/std_instead_of_core.rs:32:16
    |
 LL |     let cell = std::cell::Cell::new(8u32);
    |                ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> $DIR/std_instead_of_core.rs:30:27
+  --> $DIR/std_instead_of_core.rs:34:27
    |
 LL |     let cell_absolute = ::std::cell::Cell::new(8u32);
    |                           ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `core`
-  --> $DIR/std_instead_of_core.rs:39:9
+  --> $DIR/std_instead_of_core.rs:43:9
    |
 LL |     use std::iter::Iterator;
    |         ^^^ help: consider importing the item from `core`: `core`
 
 error: used import from `std` instead of `alloc`
-  --> $DIR/std_instead_of_core.rs:46:9
+  --> $DIR/std_instead_of_core.rs:50:9
    |
 LL |     use std::vec;
    |         ^^^ help: consider importing the item from `alloc`: `alloc`
@@ -59,13 +59,13 @@ LL |     use std::vec;
    = help: to override `-D warnings` add `#[allow(clippy::std_instead_of_alloc)]`
 
 error: used import from `std` instead of `alloc`
-  --> $DIR/std_instead_of_core.rs:48:9
+  --> $DIR/std_instead_of_core.rs:52:9
    |
 LL |     use std::vec::Vec;
    |         ^^^ help: consider importing the item from `alloc`: `alloc`
 
 error: used import from `alloc` instead of `core`
-  --> $DIR/std_instead_of_core.rs:54:9
+  --> $DIR/std_instead_of_core.rs:58:9
    |
 LL |     use alloc::slice::from_ref;
    |         ^^^^^ help: consider importing the item from `core`: `core`
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.fixed b/src/tools/clippy/tests/ui/wildcard_imports.fixed
index 2828f9d048e..6fdd728b9b7 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports.fixed
@@ -69,6 +69,34 @@ mod struct_mod {
     }
 }
 
+// issue 9942
+mod underscore_mod {
+    // allow use of `deref` so that `clippy --fix` includes `Deref`.
+    #![allow(noop_method_call)]
+
+    mod exports_underscore {
+        pub use std::ops::Deref as _;
+        pub fn dummy() {}
+    }
+
+    mod exports_underscore_ish {
+        pub use std::ops::Deref as _Deref;
+        pub fn dummy() {}
+    }
+
+    fn does_not_lint() {
+        use self::exports_underscore::*;
+        let _ = (&0).deref();
+        dummy();
+    }
+
+    fn does_lint() {
+        use self::exports_underscore_ish::{_Deref, dummy};
+        let _ = (&0).deref();
+        dummy();
+    }
+}
+
 fn main() {
     foo();
     multi_foo();
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.rs b/src/tools/clippy/tests/ui/wildcard_imports.rs
index cbe70e505d8..20e06d4b366 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.rs
+++ b/src/tools/clippy/tests/ui/wildcard_imports.rs
@@ -69,6 +69,34 @@ mod struct_mod {
     }
 }
 
+// issue 9942
+mod underscore_mod {
+    // allow use of `deref` so that `clippy --fix` includes `Deref`.
+    #![allow(noop_method_call)]
+
+    mod exports_underscore {
+        pub use std::ops::Deref as _;
+        pub fn dummy() {}
+    }
+
+    mod exports_underscore_ish {
+        pub use std::ops::Deref as _Deref;
+        pub fn dummy() {}
+    }
+
+    fn does_not_lint() {
+        use self::exports_underscore::*;
+        let _ = (&0).deref();
+        dummy();
+    }
+
+    fn does_lint() {
+        use self::exports_underscore_ish::*;
+        let _ = (&0).deref();
+        dummy();
+    }
+}
+
 fn main() {
     foo();
     multi_foo();
diff --git a/src/tools/clippy/tests/ui/wildcard_imports.stderr b/src/tools/clippy/tests/ui/wildcard_imports.stderr
index 3c750815baf..01a5414778c 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports.stderr
@@ -38,55 +38,61 @@ 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:94:13
+   |
+LL |         use self::exports_underscore_ish::*;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `self::exports_underscore_ish::{_Deref, dummy}`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:125: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:131: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:132:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:116:20
+  --> $DIR/wildcard_imports.rs:144:20
    |
 LL |         use self::{inner::*, inner2::*};
    |                    ^^^^^^^^ help: try: `inner::inner_foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:116:30
+  --> $DIR/wildcard_imports.rs:144:30
    |
 LL |         use self::{inner::*, inner2::*};
    |                              ^^^^^^^^^ help: try: `inner2::inner_bar`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:123:13
+  --> $DIR/wildcard_imports.rs:151:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:152:9
+  --> $DIR/wildcard_imports.rs:180: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:161:9
+  --> $DIR/wildcard_imports.rs:189:9
    |
 LL |     use crate:: in_fn_test::  * ;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:162:9
+  --> $DIR/wildcard_imports.rs:190:9
    |
 LL |       use crate:: fn_mod::
    |  _________^
@@ -94,40 +100,40 @@ LL | |         *;
    | |_________^ help: try: `crate:: fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:173:13
+  --> $DIR/wildcard_imports.rs:201:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:208:17
+  --> $DIR/wildcard_imports.rs:236:17
    |
 LL |             use super::*;
    |                 ^^^^^^^^ help: try: `super::insidefoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:216:13
+  --> $DIR/wildcard_imports.rs:244:13
    |
 LL |         use crate::super_imports::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:225:17
+  --> $DIR/wildcard_imports.rs:253:17
    |
 LL |             use super::super::*;
    |                 ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:234:13
+  --> $DIR/wildcard_imports.rs:262:13
    |
 LL |         use super::super::super_imports::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:242:13
+  --> $DIR/wildcard_imports.rs:270:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
 
-error: aborting due to 21 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed
index b27281fa25c..6a9fe007d65 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.fixed
@@ -64,6 +64,34 @@ mod struct_mod {
     }
 }
 
+// issue 9942
+mod underscore_mod {
+    // allow use of `deref` so that `clippy --fix` includes `Deref`.
+    #![allow(noop_method_call)]
+
+    mod exports_underscore {
+        pub use std::ops::Deref as _;
+        pub fn dummy() {}
+    }
+
+    mod exports_underscore_ish {
+        pub use std::ops::Deref as _Deref;
+        pub fn dummy() {}
+    }
+
+    fn does_not_lint() {
+        use exports_underscore::*;
+        let _ = (&0).deref();
+        dummy();
+    }
+
+    fn does_lint() {
+        use exports_underscore_ish::{_Deref, dummy};
+        let _ = (&0).deref();
+        dummy();
+    }
+}
+
 fn main() {
     foo();
     multi_foo();
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr
index 709a665d65c..e39f240a4aa 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2018.stderr
@@ -38,55 +38,61 @@ LL | use wildcard_imports_helper::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:91:13
+  --> $DIR/wildcard_imports_2021.rs:89:13
+   |
+LL |         use exports_underscore_ish::*;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `exports_underscore_ish::{_Deref, dummy}`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports_2021.rs:119:13
    |
 LL |         use crate::fn_mod::*;
    |             ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:97:75
+  --> $DIR/wildcard_imports_2021.rs:125: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_2021.rs:98:13
+  --> $DIR/wildcard_imports_2021.rs:126:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:110:20
+  --> $DIR/wildcard_imports_2021.rs:138:20
    |
 LL |         use self::{inner::*, inner2::*};
    |                    ^^^^^^^^ help: try: `inner::inner_foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:110:30
+  --> $DIR/wildcard_imports_2021.rs:138:30
    |
 LL |         use self::{inner::*, inner2::*};
    |                              ^^^^^^^^^ help: try: `inner2::inner_bar`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:117:13
+  --> $DIR/wildcard_imports_2021.rs:145:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:146:9
+  --> $DIR/wildcard_imports_2021.rs:174:9
    |
 LL |     use crate::in_fn_test::*;
    |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:155:9
+  --> $DIR/wildcard_imports_2021.rs:183:9
    |
 LL |     use crate:: in_fn_test::  * ;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:156:9
+  --> $DIR/wildcard_imports_2021.rs:184:9
    |
 LL |       use crate:: fn_mod::
    |  _________^
@@ -94,40 +100,40 @@ LL | |         *;
    | |_________^ help: try: `crate:: fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:167:13
+  --> $DIR/wildcard_imports_2021.rs:195:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:202:17
+  --> $DIR/wildcard_imports_2021.rs:230:17
    |
 LL |             use super::*;
    |                 ^^^^^^^^ help: try: `super::insidefoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:210:13
+  --> $DIR/wildcard_imports_2021.rs:238:13
    |
 LL |         use crate::super_imports::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:219:17
+  --> $DIR/wildcard_imports_2021.rs:247:17
    |
 LL |             use super::super::*;
    |                 ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:228:13
+  --> $DIR/wildcard_imports_2021.rs:256:13
    |
 LL |         use super::super::super_imports::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:236:13
+  --> $DIR/wildcard_imports_2021.rs:264:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
 
-error: aborting due to 21 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed
index b27281fa25c..6a9fe007d65 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.fixed
@@ -64,6 +64,34 @@ mod struct_mod {
     }
 }
 
+// issue 9942
+mod underscore_mod {
+    // allow use of `deref` so that `clippy --fix` includes `Deref`.
+    #![allow(noop_method_call)]
+
+    mod exports_underscore {
+        pub use std::ops::Deref as _;
+        pub fn dummy() {}
+    }
+
+    mod exports_underscore_ish {
+        pub use std::ops::Deref as _Deref;
+        pub fn dummy() {}
+    }
+
+    fn does_not_lint() {
+        use exports_underscore::*;
+        let _ = (&0).deref();
+        dummy();
+    }
+
+    fn does_lint() {
+        use exports_underscore_ish::{_Deref, dummy};
+        let _ = (&0).deref();
+        dummy();
+    }
+}
+
 fn main() {
     foo();
     multi_foo();
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr
index 709a665d65c..e39f240a4aa 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.edition2021.stderr
@@ -38,55 +38,61 @@ LL | use wildcard_imports_helper::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:91:13
+  --> $DIR/wildcard_imports_2021.rs:89:13
+   |
+LL |         use exports_underscore_ish::*;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `exports_underscore_ish::{_Deref, dummy}`
+
+error: usage of wildcard import
+  --> $DIR/wildcard_imports_2021.rs:119:13
    |
 LL |         use crate::fn_mod::*;
    |             ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:97:75
+  --> $DIR/wildcard_imports_2021.rs:125: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_2021.rs:98:13
+  --> $DIR/wildcard_imports_2021.rs:126:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:110:20
+  --> $DIR/wildcard_imports_2021.rs:138:20
    |
 LL |         use self::{inner::*, inner2::*};
    |                    ^^^^^^^^ help: try: `inner::inner_foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:110:30
+  --> $DIR/wildcard_imports_2021.rs:138:30
    |
 LL |         use self::{inner::*, inner2::*};
    |                              ^^^^^^^^^ help: try: `inner2::inner_bar`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:117:13
+  --> $DIR/wildcard_imports_2021.rs:145:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:146:9
+  --> $DIR/wildcard_imports_2021.rs:174:9
    |
 LL |     use crate::in_fn_test::*;
    |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:155:9
+  --> $DIR/wildcard_imports_2021.rs:183:9
    |
 LL |     use crate:: in_fn_test::  * ;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:156:9
+  --> $DIR/wildcard_imports_2021.rs:184:9
    |
 LL |       use crate:: fn_mod::
    |  _________^
@@ -94,40 +100,40 @@ LL | |         *;
    | |_________^ help: try: `crate:: fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:167:13
+  --> $DIR/wildcard_imports_2021.rs:195:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:202:17
+  --> $DIR/wildcard_imports_2021.rs:230:17
    |
 LL |             use super::*;
    |                 ^^^^^^^^ help: try: `super::insidefoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:210:13
+  --> $DIR/wildcard_imports_2021.rs:238:13
    |
 LL |         use crate::super_imports::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:219:17
+  --> $DIR/wildcard_imports_2021.rs:247:17
    |
 LL |             use super::super::*;
    |                 ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:228:13
+  --> $DIR/wildcard_imports_2021.rs:256:13
    |
 LL |         use super::super::super_imports::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports_2021.rs:236:13
+  --> $DIR/wildcard_imports_2021.rs:264:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
 
-error: aborting due to 21 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/wildcard_imports_2021.rs b/src/tools/clippy/tests/ui/wildcard_imports_2021.rs
index 7dd2103eca7..18ebc0f5127 100644
--- a/src/tools/clippy/tests/ui/wildcard_imports_2021.rs
+++ b/src/tools/clippy/tests/ui/wildcard_imports_2021.rs
@@ -64,6 +64,34 @@ mod struct_mod {
     }
 }
 
+// issue 9942
+mod underscore_mod {
+    // allow use of `deref` so that `clippy --fix` includes `Deref`.
+    #![allow(noop_method_call)]
+
+    mod exports_underscore {
+        pub use std::ops::Deref as _;
+        pub fn dummy() {}
+    }
+
+    mod exports_underscore_ish {
+        pub use std::ops::Deref as _Deref;
+        pub fn dummy() {}
+    }
+
+    fn does_not_lint() {
+        use exports_underscore::*;
+        let _ = (&0).deref();
+        dummy();
+    }
+
+    fn does_lint() {
+        use exports_underscore_ish::*;
+        let _ = (&0).deref();
+        dummy();
+    }
+}
+
 fn main() {
     foo();
     multi_foo();
diff --git a/src/tools/clippy/tests/ui/write_literal.fixed b/src/tools/clippy/tests/ui/write_literal.fixed
index ee577574d28..3d216b76cbf 100644
--- a/src/tools/clippy/tests/ui/write_literal.fixed
+++ b/src/tools/clippy/tests/ui/write_literal.fixed
@@ -43,16 +43,22 @@ fn main() {
     // throw a warning
     writeln!(v, "hello world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
     writeln!(v, "world hello");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
 
     // named args shouldn't change anything either
     writeln!(v, "hello world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
     writeln!(v, "world hello");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
+
+    // #10128
+    writeln!(v, "hello {0} world", 2);
+    //~^ ERROR: literal with an empty format string
+    writeln!(v, "world {0} hello", 2);
+    //~^ ERROR: literal with an empty format string
+    writeln!(v, "hello {0} {1}, {bar}", 2, 3, bar = 4);
+    //~^ ERROR: literal with an empty format string
+    writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4);
+    //~^ ERROR: literal with an empty format string
 }
diff --git a/src/tools/clippy/tests/ui/write_literal.rs b/src/tools/clippy/tests/ui/write_literal.rs
index 588e8fd413a..79d6daa2e3b 100644
--- a/src/tools/clippy/tests/ui/write_literal.rs
+++ b/src/tools/clippy/tests/ui/write_literal.rs
@@ -43,16 +43,22 @@ fn main() {
     // throw a warning
     writeln!(v, "{0} {1}", "hello", "world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
     writeln!(v, "{1} {0}", "hello", "world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
 
     // named args shouldn't change anything either
     writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
     writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
+
+    // #10128
+    writeln!(v, "{0} {1} {2}", "hello", 2, "world");
+    //~^ ERROR: literal with an empty format string
+    writeln!(v, "{2} {1} {0}", "hello", 2, "world");
+    //~^ ERROR: literal with an empty format string
+    writeln!(v, "{0} {1} {2}, {bar}", "hello", 2, 3, bar = 4);
+    //~^ ERROR: literal with an empty format string
+    writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4);
+    //~^ ERROR: literal with an empty format string
 }
diff --git a/src/tools/clippy/tests/ui/write_literal.stderr b/src/tools/clippy/tests/ui/write_literal.stderr
index 372a54cf769..ee0d536e954 100644
--- a/src/tools/clippy/tests/ui/write_literal.stderr
+++ b/src/tools/clippy/tests/ui/write_literal.stderr
@@ -52,96 +52,96 @@ error: literal with an empty format string
   --> $DIR/write_literal.rs:44:28
    |
 LL |     writeln!(v, "{0} {1}", "hello", "world");
-   |                            ^^^^^^^
+   |                            ^^^^^^^^^^^^^^^^
    |
 help: try
    |
 LL -     writeln!(v, "{0} {1}", "hello", "world");
-LL +     writeln!(v, "hello {1}", "world");
+LL +     writeln!(v, "hello world");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal.rs:44:37
+  --> $DIR/write_literal.rs:46:28
    |
-LL |     writeln!(v, "{0} {1}", "hello", "world");
-   |                                     ^^^^^^^
+LL |     writeln!(v, "{1} {0}", "hello", "world");
+   |                            ^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     writeln!(v, "{0} {1}", "hello", "world");
-LL +     writeln!(v, "{0} world", "hello");
+LL -     writeln!(v, "{1} {0}", "hello", "world");
+LL +     writeln!(v, "world hello");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal.rs:47:37
+  --> $DIR/write_literal.rs:50:38
    |
-LL |     writeln!(v, "{1} {0}", "hello", "world");
-   |                                     ^^^^^^^
+LL |     writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     writeln!(v, "{1} {0}", "hello", "world");
-LL +     writeln!(v, "world {0}", "hello");
+LL -     writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
+LL +     writeln!(v, "hello world");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal.rs:47:28
+  --> $DIR/write_literal.rs:52:38
    |
-LL |     writeln!(v, "{1} {0}", "hello", "world");
-   |                            ^^^^^^^
+LL |     writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     writeln!(v, "{1} {0}", "hello", "world");
-LL +     writeln!(v, "{1} hello", "world");
+LL -     writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
+LL +     writeln!(v, "world hello");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal.rs:52:38
+  --> $DIR/write_literal.rs:56:32
    |
-LL |     writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
-   |                                      ^^^^^^^
+LL |     writeln!(v, "{0} {1} {2}", "hello", 2, "world");
+   |                                ^^^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
-LL +     writeln!(v, "hello {bar}", bar = "world");
+LL -     writeln!(v, "{0} {1} {2}", "hello", 2, "world");
+LL +     writeln!(v, "hello {0} world", 2);
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal.rs:52:53
+  --> $DIR/write_literal.rs:58:32
    |
-LL |     writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
-   |                                                     ^^^^^^^
+LL |     writeln!(v, "{2} {1} {0}", "hello", 2, "world");
+   |                                ^^^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     writeln!(v, "{foo} {bar}", foo = "hello", bar = "world");
-LL +     writeln!(v, "{foo} world", foo = "hello");
+LL -     writeln!(v, "{2} {1} {0}", "hello", 2, "world");
+LL +     writeln!(v, "world {0} hello", 2);
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal.rs:55:53
+  --> $DIR/write_literal.rs:60:39
    |
-LL |     writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
-   |                                                     ^^^^^^^
+LL |     writeln!(v, "{0} {1} {2}, {bar}", "hello", 2, 3, bar = 4);
+   |                                       ^^^^^^^
    |
 help: try
    |
-LL -     writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
-LL +     writeln!(v, "world {foo}", foo = "hello");
+LL -     writeln!(v, "{0} {1} {2}, {bar}", "hello", 2, 3, bar = 4);
+LL +     writeln!(v, "hello {0} {1}, {bar}", 2, 3, bar = 4);
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal.rs:55:38
+  --> $DIR/write_literal.rs:62:41
    |
-LL |     writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
-   |                                      ^^^^^^^
+LL |     writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4);
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^
    |
 help: try
    |
-LL -     writeln!(v, "{bar} {foo}", foo = "hello", bar = "world");
-LL +     writeln!(v, "{bar} hello", bar = "world");
+LL -     writeln!(v, "{0} {1} {2}, {3} {4}", "hello", 2, 3, "world", 4);
+LL +     writeln!(v, "hello {0} {1}, world {2}", 2, 3, 4);
    |
 
 error: aborting due to 12 previous errors
diff --git a/src/tools/clippy/tests/ui/write_literal_2.rs b/src/tools/clippy/tests/ui/write_literal_2.rs
index aa0c13c1340..b2ed552d46b 100644
--- a/src/tools/clippy/tests/ui/write_literal_2.rs
+++ b/src/tools/clippy/tests/ui/write_literal_2.rs
@@ -1,6 +1,6 @@
 //@no-rustfix: overlapping suggestions
 #![allow(unused_must_use)]
-#![warn(clippy::needless_raw_strings, clippy::write_literal)]
+#![warn(clippy::write_literal)]
 
 use std::io::Write;
 
@@ -11,9 +11,7 @@ fn main() {
     //~^ ERROR: literal with an empty format string
     //~| NOTE: `-D clippy::write-literal` implied by `-D warnings`
     writeln!(v, r"{}", r"{hello}");
-    //~^ ERROR: unnecessary raw string literal
-    //~| NOTE: `-D clippy::needless-raw-strings` implied by `-D warnings`
-    //~| ERROR: literal with an empty format string
+    //~^ ERROR: literal with an empty format string
     writeln!(v, "{}", '\'');
     //~^ ERROR: literal with an empty format string
     writeln!(v, "{}", '"');
@@ -26,17 +24,14 @@ fn main() {
         v,
         "some {}",
         "hello \
-        //~^ ERROR: literal with an empty format string
-        world!"
+        world!",
+        //~^^ ERROR: literal with an empty format string
     );
     writeln!(
         v,
         "some {}\
         {} \\ {}",
-        "1",
-        "2",
-        "3",
-        //~^ ERROR: literal with an empty format string
+        "1", "2", "3",
     );
     writeln!(v, "{}", "\\");
     //~^ ERROR: literal with an empty format string
@@ -51,7 +46,6 @@ fn main() {
     // hard mode
     writeln!(v, r#"{}{}"#, '#', '"');
     //~^ ERROR: literal with an empty format string
-    //~| ERROR: literal with an empty format string
     // should not lint
     writeln!(v, r"{}", "\r");
 }
diff --git a/src/tools/clippy/tests/ui/write_literal_2.stderr b/src/tools/clippy/tests/ui/write_literal_2.stderr
index 6d382a267ad..81ef49de082 100644
--- a/src/tools/clippy/tests/ui/write_literal_2.stderr
+++ b/src/tools/clippy/tests/ui/write_literal_2.stderr
@@ -1,14 +1,3 @@
-error: unnecessary raw string literal
-  --> $DIR/write_literal_2.rs:13:24
-   |
-LL |     writeln!(v, r"{}", r"{hello}");
-   |                        -^^^^^^^^^
-   |                        |
-   |                        help: use a string literal instead: `"{hello}"`
-   |
-   = note: `-D clippy::needless-raw-strings` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::needless_raw_strings)]`
-
 error: literal with an empty format string
   --> $DIR/write_literal_2.rs:10:23
    |
@@ -36,7 +25,7 @@ LL +     writeln!(v, r"{{hello}}");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:17:23
+  --> $DIR/write_literal_2.rs:15:23
    |
 LL |     writeln!(v, "{}", '\'');
    |                       ^^^^
@@ -48,7 +37,7 @@ LL +     writeln!(v, "'");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:19:23
+  --> $DIR/write_literal_2.rs:17:23
    |
 LL |     writeln!(v, "{}", '"');
    |                       ^^^
@@ -60,13 +49,13 @@ LL +     writeln!(v, "\"");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:21:24
+  --> $DIR/write_literal_2.rs:19:24
    |
 LL |     writeln!(v, r"{}", '"');
    |                        ^^^
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:23:24
+  --> $DIR/write_literal_2.rs:21:24
    |
 LL |     writeln!(v, r"{}", '\'');
    |                        ^^^^
@@ -78,59 +67,32 @@ LL +     writeln!(v, r"'");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:28:9
+  --> $DIR/write_literal_2.rs:26:9
    |
 LL | /         "hello \
-LL | |
-LL | |         world!"
+LL | |         world!",
    | |_______________^
    |
 help: try
    |
 LL ~         "some hello \
-LL +
-LL ~         world!"
+LL ~         world!",
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:36:9
+  --> $DIR/write_literal_2.rs:34:9
    |
-LL |         "1",
-   |         ^^^
+LL |         "1", "2", "3",
+   |         ^^^^^^^^^^^^^
    |
 help: try
    |
 LL ~         "some 1\
-LL ~         {} \\ {}",
+LL ~         2 \\ 3",
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:37:9
-   |
-LL |         "2",
-   |         ^^^
-   |
-help: try
-   |
-LL ~         2 \\ {}",
-LL ~         "1",
-   |
-
-error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:38:9
-   |
-LL |         "3",
-   |         ^^^
-   |
-help: try
-   |
-LL ~         {} \\ 3",
-LL |         "1",
-LL ~         "2",
-   |
-
-error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:41:23
+  --> $DIR/write_literal_2.rs:36:23
    |
 LL |     writeln!(v, "{}", "\\");
    |                       ^^^^
@@ -142,7 +104,7 @@ LL +     writeln!(v, "\\");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:43:24
+  --> $DIR/write_literal_2.rs:38:24
    |
 LL |     writeln!(v, r"{}", "\\");
    |                        ^^^^
@@ -154,7 +116,7 @@ LL +     writeln!(v, r"\");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:45:26
+  --> $DIR/write_literal_2.rs:40:26
    |
 LL |     writeln!(v, r#"{}"#, "\\");
    |                          ^^^^
@@ -166,7 +128,7 @@ LL +     writeln!(v, r#"\"#);
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:47:23
+  --> $DIR/write_literal_2.rs:42:23
    |
 LL |     writeln!(v, "{}", r"\");
    |                       ^^^^
@@ -178,7 +140,7 @@ LL +     writeln!(v, "\\");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:49:23
+  --> $DIR/write_literal_2.rs:44:23
    |
 LL |     writeln!(v, "{}", "\r");
    |                       ^^^^
@@ -190,16 +152,10 @@ LL +     writeln!(v, "\r");
    |
 
 error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:52:28
-   |
-LL |     writeln!(v, r#"{}{}"#, '#', '"');
-   |                            ^^^
-
-error: literal with an empty format string
-  --> $DIR/write_literal_2.rs:52:33
+  --> $DIR/write_literal_2.rs:47:28
    |
 LL |     writeln!(v, r#"{}{}"#, '#', '"');
-   |                                 ^^^
+   |                            ^^^^^^^^
 
-error: aborting due to 18 previous errors
+error: aborting due to 14 previous errors