about summary refs log tree commit diff
path: root/src/tools/clippy/tests
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-08-25 11:56:57 +0000
committerbors <bors@rust-lang.org>2024-08-25 11:56:57 +0000
commit89103466d77a3ae068bab0fd17c53bf7104f627b (patch)
tree82f46eebebb464aea694cece282bca82aa0cdb51 /src/tools/clippy/tests
parent717aec0f8eebdc5eb51756e5129dde15e8b25710 (diff)
parent6c3f43d5cc292a396a5dbb8400c07452e0fd026f (diff)
Auto merge of #129531 - Jarcho:clippyup, r=Manishearth
Clippy subtree update

r? `@Manishearth`
Diffstat (limited to 'src/tools/clippy/tests')
-rw-r--r--src/tools/clippy/tests/compile-test.rs385
-rw-r--r--src/tools/clippy/tests/config-metadata.rs78
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr45
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr14
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr80
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr71
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr98
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs178
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr14
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs16
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml3
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml0
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs15
-rw-r--r--src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr16
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.fixed20
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.rs20
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr2
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr26
-rw-r--r--src/tools/clippy/tests/ui/collapsible_match.stderr2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3717.fixed11
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3717.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-3717.stderr2
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs17
-rw-r--r--src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr10
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed13
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs13
-rw-r--r--src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr18
-rw-r--r--src/tools/clippy/tests/ui/double_must_use.rs8
-rw-r--r--src/tools/clippy/tests/ui/double_must_use.stderr16
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.fixed12
-rw-r--r--src/tools/clippy/tests/ui/explicit_iter_loop.rs12
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed21
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs21
-rw-r--r--src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr4
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs2
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr4
-rw-r--r--src/tools/clippy/tests/ui/string_slice.rs5
-rw-r--r--src/tools/clippy/tests/ui/string_slice.stderr14
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed9
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs8
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr20
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs53
-rw-r--r--src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr22
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr566
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr35
49 files changed, 1504 insertions, 511 deletions
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 64253514fbe..9754254cdd0 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -1,25 +1,31 @@
-// We need this feature as it changes `dylib` linking behavior and allows us to link to
-// `rustc_driver`.
-#![feature(rustc_private)]
+#![feature(rustc_private, let_chains)]
 #![warn(rust_2018_idioms, unused_lifetimes)]
 #![allow(unused_extern_crates)]
 
+use cargo_metadata::diagnostic::{Applicability, Diagnostic};
+use cargo_metadata::Message;
+use clippy_config::ClippyConfiguration;
+use clippy_lints::declared_lints::LINTS;
+use clippy_lints::deprecated_lints::{DEPRECATED, DEPRECATED_VERSION, RENAMED};
+use clippy_lints::LintInfo;
+use serde::{Deserialize, Serialize};
+use test_utils::IS_RUSTC_TEST_SUITE;
 use ui_test::custom_flags::rustfix::RustfixMode;
+use ui_test::custom_flags::Flag;
 use ui_test::spanned::Spanned;
+use ui_test::test_result::TestRun;
 use ui_test::{status_emitter, Args, CommandBuilder, Config, Match, OutputConflictHandling};
 
-use std::collections::BTreeMap;
+use std::collections::{BTreeMap, HashMap};
 use std::env::{self, set_var, var_os};
 use std::ffi::{OsStr, OsString};
-use std::fs;
+use std::fmt::Write;
 use std::path::{Path, PathBuf};
-use std::sync::LazyLock;
-use test_utils::IS_RUSTC_TEST_SUITE;
+use std::sync::mpsc::{channel, Sender};
+use std::{fs, iter, thread};
 
 // Test dependencies may need an `extern crate` here to ensure that they show up
 // in the depinfo file (otherwise cargo thinks they are unused)
-extern crate clippy_lints;
-extern crate clippy_utils;
 extern crate futures;
 extern crate if_chain;
 extern crate itertools;
@@ -55,7 +61,7 @@ static TEST_DEPENDENCIES: &[&str] = &[
 /// dependencies must be added to Cargo.toml at the project root. Test
 /// dependencies that are not *directly* used by this test module require an
 /// `extern crate` declaration.
-static EXTERN_FLAGS: LazyLock<Vec<String>> = LazyLock::new(|| {
+fn extern_flags() -> Vec<String> {
     let current_exe_depinfo = {
         let mut path = env::current_exe().unwrap();
         path.set_extension("d");
@@ -103,70 +109,93 @@ static EXTERN_FLAGS: LazyLock<Vec<String>> = LazyLock::new(|| {
         .into_iter()
         .map(|(name, path)| format!("--extern={name}={path}"))
         .collect()
-});
+}
 
 // whether to run internal tests or not
 const RUN_INTERNAL_TESTS: bool = cfg!(feature = "internal");
 
-fn base_config(test_dir: &str) -> (Config, Args) {
-    let mut args = Args::test().unwrap();
-    args.bless |= var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
-
-    let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into()));
-    let mut config = Config {
-        output_conflict_handling: OutputConflictHandling::Error,
-        filter_files: env::var("TESTNAME")
-            .map(|filters| filters.split(',').map(str::to_string).collect())
-            .unwrap_or_default(),
-        target: None,
-        bless_command: Some("cargo uibless".into()),
-        out_dir: target_dir.join("ui_test"),
-        ..Config::rustc(Path::new("tests").join(test_dir))
-    };
-    config.comment_defaults.base().exit_status = None.into();
-    config.comment_defaults.base().require_annotations = None.into();
-    config
-        .comment_defaults
-        .base()
-        .set_custom("rustfix", RustfixMode::Everything);
-    config.comment_defaults.base().diagnostic_code_prefix = Some(Spanned::dummy("clippy::".into())).into();
-    config.with_args(&args);
-    let current_exe_path = env::current_exe().unwrap();
-    let deps_path = current_exe_path.parent().unwrap();
-    let profile_path = deps_path.parent().unwrap();
-
-    config.program.args.extend(
-        [
-            "--emit=metadata",
-            "-Aunused",
-            "-Ainternal_features",
-            "-Zui-testing",
-            "-Zdeduplicate-diagnostics=no",
-            "-Dwarnings",
-            &format!("-Ldependency={}", deps_path.display()),
-        ]
-        .map(OsString::from),
-    );
-
-    config.program.args.extend(EXTERN_FLAGS.iter().map(OsString::from));
-    // Prevent rustc from creating `rustc-ice-*` files the console output is enough.
-    config.program.envs.push(("RUSTC_ICE".into(), Some("0".into())));
+struct TestContext {
+    args: Args,
+    extern_flags: Vec<String>,
+    diagnostic_collector: Option<DiagnosticCollector>,
+    collector_thread: Option<thread::JoinHandle<()>>,
+}
 
-    if let Some(host_libs) = option_env!("HOST_LIBS") {
-        let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display());
-        config.program.args.push(dep.into());
+impl TestContext {
+    fn new() -> Self {
+        let mut args = Args::test().unwrap();
+        args.bless |= var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
+        let (diagnostic_collector, collector_thread) = var_os("COLLECT_METADATA")
+            .is_some()
+            .then(DiagnosticCollector::spawn)
+            .unzip();
+        Self {
+            args,
+            extern_flags: extern_flags(),
+            diagnostic_collector,
+            collector_thread,
+        }
     }
 
-    config.program.program = profile_path.join(if cfg!(windows) {
-        "clippy-driver.exe"
-    } else {
-        "clippy-driver"
-    });
-    (config, args)
+    fn base_config(&self, test_dir: &str) -> Config {
+        let target_dir = PathBuf::from(var_os("CARGO_TARGET_DIR").unwrap_or_else(|| "target".into()));
+        let mut config = Config {
+            output_conflict_handling: OutputConflictHandling::Error,
+            filter_files: env::var("TESTNAME")
+                .map(|filters| filters.split(',').map(str::to_string).collect())
+                .unwrap_or_default(),
+            target: None,
+            bless_command: Some("cargo uibless".into()),
+            out_dir: target_dir.join("ui_test"),
+            ..Config::rustc(Path::new("tests").join(test_dir))
+        };
+        let defaults = config.comment_defaults.base();
+        defaults.exit_status = None.into();
+        defaults.require_annotations = None.into();
+        defaults.diagnostic_code_prefix = Some(Spanned::dummy("clippy::".into())).into();
+        defaults.set_custom("rustfix", RustfixMode::Everything);
+        if let Some(collector) = self.diagnostic_collector.clone() {
+            defaults.set_custom("diagnostic-collector", collector);
+        }
+        config.with_args(&self.args);
+        let current_exe_path = env::current_exe().unwrap();
+        let deps_path = current_exe_path.parent().unwrap();
+        let profile_path = deps_path.parent().unwrap();
+
+        config.program.args.extend(
+            [
+                "--emit=metadata",
+                "-Aunused",
+                "-Ainternal_features",
+                "-Zui-testing",
+                "-Zdeduplicate-diagnostics=no",
+                "-Dwarnings",
+                &format!("-Ldependency={}", deps_path.display()),
+            ]
+            .map(OsString::from),
+        );
+
+        config.program.args.extend(self.extern_flags.iter().map(OsString::from));
+        // Prevent rustc from creating `rustc-ice-*` files the console output is enough.
+        config.program.envs.push(("RUSTC_ICE".into(), Some("0".into())));
+
+        if let Some(host_libs) = option_env!("HOST_LIBS") {
+            let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display());
+            config.program.args.push(dep.into());
+        }
+
+        config.program.program = profile_path.join(if cfg!(windows) {
+            "clippy-driver.exe"
+        } else {
+            "clippy-driver"
+        });
+
+        config
+    }
 }
 
-fn run_ui() {
-    let (mut config, args) = base_config("ui");
+fn run_ui(cx: &TestContext) {
+    let mut config = cx.base_config("ui");
     config
         .program
         .envs
@@ -176,30 +205,29 @@ fn run_ui() {
         vec![config],
         ui_test::default_file_filter,
         ui_test::default_per_file_config,
-        status_emitter::Text::from(args.format),
+        status_emitter::Text::from(cx.args.format),
     )
     .unwrap();
 }
 
-fn run_internal_tests() {
-    // only run internal tests with the internal-tests feature
+fn run_internal_tests(cx: &TestContext) {
     if !RUN_INTERNAL_TESTS {
         return;
     }
-    let (mut config, args) = base_config("ui-internal");
+    let mut config = cx.base_config("ui-internal");
     config.bless_command = Some("cargo uitest --features internal -- -- --bless".into());
 
     ui_test::run_tests_generic(
         vec![config],
         ui_test::default_file_filter,
         ui_test::default_per_file_config,
-        status_emitter::Text::from(args.format),
+        status_emitter::Text::from(cx.args.format),
     )
     .unwrap();
 }
 
-fn run_ui_toml() {
-    let (mut config, args) = base_config("ui-toml");
+fn run_ui_toml(cx: &TestContext) {
+    let mut config = cx.base_config("ui-toml");
 
     config
         .comment_defaults
@@ -217,19 +245,19 @@ fn run_ui_toml() {
                 .envs
                 .push(("CLIPPY_CONF_DIR".into(), Some(path.parent().unwrap().into())));
         },
-        status_emitter::Text::from(args.format),
+        status_emitter::Text::from(cx.args.format),
     )
     .unwrap();
 }
 
 // Allow `Default::default` as `OptWithSpan` is not nameable
 #[allow(clippy::default_trait_access)]
-fn run_ui_cargo() {
+fn run_ui_cargo(cx: &TestContext) {
     if IS_RUSTC_TEST_SUITE {
         return;
     }
 
-    let (mut config, args) = base_config("ui-cargo");
+    let mut config = cx.base_config("ui-cargo");
     config.program.input_file_flag = CommandBuilder::cargo().input_file_flag;
     config.program.out_dir_flag = CommandBuilder::cargo().out_dir_flag;
     config.program.args = vec!["clippy".into(), "--color".into(), "never".into(), "--quiet".into()];
@@ -264,23 +292,25 @@ fn run_ui_cargo() {
                 .then(|| ui_test::default_any_file_filter(path, config) && !ignored_32bit(path))
         },
         |_config, _file_contents| {},
-        status_emitter::Text::from(args.format),
+        status_emitter::Text::from(cx.args.format),
     )
     .unwrap();
 }
 
 fn main() {
     set_var("CLIPPY_DISABLE_DOCS_LINKS", "true");
+
+    let cx = TestContext::new();
+
     // The SPEEDTEST_* env variables can be used to check Clippy's performance on your PR. It runs the
     // affected test 1000 times and gets the average.
     if let Ok(speedtest) = std::env::var("SPEEDTEST") {
         println!("----------- STARTING SPEEDTEST -----------");
         let f = match speedtest.as_str() {
-            "ui" => run_ui as fn(),
-            "cargo" => run_ui_cargo as fn(),
-            "toml" => run_ui_toml as fn(),
-            "internal" => run_internal_tests as fn(),
-            "ui-cargo-toml-metadata" => ui_cargo_toml_metadata as fn(),
+            "ui" => run_ui,
+            "cargo" => run_ui_cargo,
+            "toml" => run_ui_toml,
+            "internal" => run_internal_tests,
 
             _ => panic!("unknown speedtest: {speedtest} || accepted speedtests are: [ui, cargo, toml, internal]"),
         };
@@ -297,7 +327,7 @@ fn main() {
         let mut sum = 0;
         for _ in 0..iterations {
             let start = std::time::Instant::now();
-            f();
+            f(&cx);
             sum += start.elapsed().as_millis();
         }
         println!(
@@ -306,11 +336,17 @@ fn main() {
             sum / u128::from(iterations)
         );
     } else {
-        run_ui();
-        run_ui_toml();
-        run_ui_cargo();
-        run_internal_tests();
+        run_ui(&cx);
+        run_ui_toml(&cx);
+        run_ui_cargo(&cx);
+        run_internal_tests(&cx);
+        drop(cx.diagnostic_collector);
+
         ui_cargo_toml_metadata();
+
+        if let Some(thread) = cx.collector_thread {
+            thread.join().unwrap();
+        }
     }
 }
 
@@ -349,3 +385,180 @@ fn ui_cargo_toml_metadata() {
         );
     }
 }
+
+#[derive(Deserialize)]
+#[serde(untagged)]
+enum DiagnosticOrMessage {
+    Diagnostic(Diagnostic),
+    Message(Message),
+}
+
+/// Collects applicabilities from the diagnostics produced for each UI test, producing the
+/// `util/gh-pages/lints.json` file used by <https://rust-lang.github.io/rust-clippy/>
+#[derive(Debug, Clone)]
+struct DiagnosticCollector {
+    sender: Sender<Vec<u8>>,
+}
+
+impl DiagnosticCollector {
+    #[allow(clippy::assertions_on_constants)]
+    fn spawn() -> (Self, thread::JoinHandle<()>) {
+        assert!(!IS_RUSTC_TEST_SUITE && !RUN_INTERNAL_TESTS);
+
+        let (sender, receiver) = channel::<Vec<u8>>();
+
+        let handle = thread::spawn(|| {
+            let mut applicabilities = HashMap::new();
+
+            for stderr in receiver {
+                for line in stderr.split(|&byte| byte == b'\n') {
+                    let diag = match serde_json::from_slice(line) {
+                        Ok(DiagnosticOrMessage::Diagnostic(diag)) => diag,
+                        Ok(DiagnosticOrMessage::Message(Message::CompilerMessage(message))) => message.message,
+                        _ => continue,
+                    };
+
+                    if let Some(lint) = diag.code.as_ref().and_then(|code| code.code.strip_prefix("clippy::")) {
+                        let applicability = applicabilities
+                            .entry(lint.to_string())
+                            .or_insert(Applicability::Unspecified);
+                        let diag_applicability = diag
+                            .children
+                            .iter()
+                            .flat_map(|child| &child.spans)
+                            .filter_map(|span| span.suggestion_applicability.clone())
+                            .max_by_key(applicability_ord);
+                        if let Some(diag_applicability) = diag_applicability
+                            && applicability_ord(&diag_applicability) > applicability_ord(applicability)
+                        {
+                            *applicability = diag_applicability;
+                        }
+                    }
+                }
+            }
+
+            let configs = clippy_config::get_configuration_metadata();
+            let mut metadata: Vec<LintMetadata> = LINTS
+                .iter()
+                .map(|lint| LintMetadata::new(lint, &applicabilities, &configs))
+                .chain(
+                    iter::zip(DEPRECATED, DEPRECATED_VERSION)
+                        .map(|((lint, reason), version)| LintMetadata::new_deprecated(lint, reason, version)),
+                )
+                .collect();
+            metadata.sort_unstable_by(|a, b| a.id.cmp(&b.id));
+
+            let json = serde_json::to_string_pretty(&metadata).unwrap();
+            fs::write("util/gh-pages/lints.json", json).unwrap();
+        });
+
+        (Self { sender }, handle)
+    }
+}
+
+fn applicability_ord(applicability: &Applicability) -> u8 {
+    match applicability {
+        Applicability::MachineApplicable => 4,
+        Applicability::HasPlaceholders => 3,
+        Applicability::MaybeIncorrect => 2,
+        Applicability::Unspecified => 1,
+        _ => unimplemented!(),
+    }
+}
+
+impl Flag for DiagnosticCollector {
+    fn post_test_action(
+        &self,
+        _config: &ui_test::per_test_config::TestConfig<'_>,
+        _cmd: &mut std::process::Command,
+        output: &std::process::Output,
+        _build_manager: &ui_test::build_manager::BuildManager<'_>,
+    ) -> Result<Vec<TestRun>, ui_test::Errored> {
+        if !output.stderr.is_empty() {
+            self.sender.send(output.stderr.clone()).unwrap();
+        }
+        Ok(Vec::new())
+    }
+
+    fn clone_inner(&self) -> Box<dyn Flag> {
+        Box::new(self.clone())
+    }
+
+    fn must_be_unique(&self) -> bool {
+        true
+    }
+}
+
+#[derive(Debug, Serialize)]
+struct LintMetadata {
+    id: String,
+    id_location: Option<&'static str>,
+    group: &'static str,
+    level: &'static str,
+    docs: String,
+    version: &'static str,
+    applicability: Applicability,
+}
+
+impl LintMetadata {
+    fn new(lint: &LintInfo, applicabilities: &HashMap<String, Applicability>, configs: &[ClippyConfiguration]) -> Self {
+        let name = lint.name_lower();
+        let applicability = applicabilities
+            .get(&name)
+            .cloned()
+            .unwrap_or(Applicability::Unspecified);
+        let past_names = RENAMED
+            .iter()
+            .filter(|(_, new_name)| new_name.strip_prefix("clippy::") == Some(&name))
+            .map(|(old_name, _)| old_name.strip_prefix("clippy::").unwrap())
+            .collect::<Vec<_>>();
+        let mut docs = lint.explanation.to_string();
+        if !past_names.is_empty() {
+            docs.push_str("\n### Past names\n\n");
+            for past_name in past_names {
+                writeln!(&mut docs, " * {past_name}").unwrap();
+            }
+        }
+        let configs: Vec<_> = configs
+            .iter()
+            .filter(|conf| conf.lints.contains(&name.as_str()))
+            .collect();
+        if !configs.is_empty() {
+            docs.push_str("\n### Configuration\n\n");
+            for config in configs {
+                writeln!(&mut docs, "{config}").unwrap();
+            }
+        }
+        Self {
+            id: name,
+            id_location: Some(lint.location),
+            group: lint.category_str(),
+            level: lint.lint.default_level.as_str(),
+            docs,
+            version: lint.version.unwrap(),
+            applicability,
+        }
+    }
+
+    fn new_deprecated(name: &str, reason: &str, version: &'static str) -> Self {
+        // The reason starts with a lowercase letter and ends without a period.
+        // This needs to be fixed for the website.
+        let mut reason = reason.to_owned();
+        if let Some(reason) = reason.get_mut(0..1) {
+            reason.make_ascii_uppercase();
+        }
+        Self {
+            id: name.strip_prefix("clippy::").unwrap().into(),
+            id_location: None,
+            group: "deprecated",
+            level: "none",
+            version,
+            docs: format!(
+                "### What it does\n\n\
+                Nothing. This lint has been deprecated\n\n\
+                ### Deprecation reason\n\n{reason}.\n",
+            ),
+            applicability: Applicability::Unspecified,
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/config-metadata.rs b/src/tools/clippy/tests/config-metadata.rs
new file mode 100644
index 00000000000..3e3711873ba
--- /dev/null
+++ b/src/tools/clippy/tests/config-metadata.rs
@@ -0,0 +1,78 @@
+#![feature(rustc_private)]
+
+use clippy_config::{get_configuration_metadata, ClippyConfiguration};
+use itertools::Itertools;
+use regex::Regex;
+use std::borrow::Cow;
+use std::{env, fs};
+
+fn metadata() -> impl Iterator<Item = ClippyConfiguration> {
+    get_configuration_metadata()
+        .into_iter()
+        .filter(|config| config.deprecation_reason.is_none())
+        .filter(|config| !config.lints.is_empty())
+}
+
+#[test]
+fn book() {
+    let path = "book/src/lint_configuration.md";
+    let current = fs::read_to_string(path).unwrap();
+
+    let configs = metadata().map(|conf| conf.to_markdown_paragraph()).join("\n");
+    let expected = format!(
+        r#"<!--
+This file is generated by `cargo bless --test config-metadata`.
+Please use that command to update the file and do not edit it by hand.
+-->
+
+# Lint Configuration Options
+
+The following list shows each configuration option, along with a description, its default value, an example
+and lints affected.
+
+---
+
+{}
+"#,
+        configs.trim(),
+    );
+
+    if current != expected {
+        if env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0") {
+            fs::write(path, expected).unwrap();
+        } else {
+            panic!("`{path}` is out of date, run `cargo bless --test config-metadata` to update it");
+        }
+    }
+}
+
+#[test]
+fn changelog() {
+    let path = "CHANGELOG.md";
+    let current = fs::read_to_string(path).unwrap();
+
+    let configs = metadata().map(|conf| conf.to_markdown_link()).join("\n");
+
+    let re = Regex::new(
+        "(?s)\
+        (<!-- begin autogenerated links to configuration documentation -->)\
+        .*\
+        (<!-- end autogenerated links to configuration documentation -->)\
+        ",
+    )
+    .unwrap();
+    let expected = re.replace(&current, format!("$1\n{configs}\n$2"));
+
+    assert!(
+        matches!(expected, Cow::Owned(_)),
+        "failed to find configuration section in `{path}`"
+    );
+
+    if current != expected {
+        if env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0") {
+            fs::write(path, expected.as_bytes()).unwrap();
+        } else {
+            panic!("`{path}` is out of date, run `cargo bless --test config-metadata` to update it");
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr
index 1cc1034cd89..d24b0cd6162 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_crates.stderr
@@ -1,29 +1,44 @@
 error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:5
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13
    |
-LL |     std::f32::MAX;
-   |     ^^^^^^^^^^^^^
+LL |     let _ = std::path::is_separator(' ');
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: `-D clippy::absolute-paths` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]`
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13
+   |
+LL |     let _ = ::std::path::MAIN_SEPARATOR;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13
+   |
+LL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:41:5
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31
    |
-LL |     core::f32::MAX;
-   |     ^^^^^^^^^^^^^^
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |                               ^^^^^^^^^^^^^^^
 
 error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:42:5
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13
    |
-LL |     ::core::f32::MAX;
-   |     ^^^^^^^^^^^^^^^^
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |             ^^^^^^^^^^^^^^^
 
 error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:58:5
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13
    |
-LL |     ::std::f32::MAX;
-   |     ^^^^^^^^^^^^^^^
+LL |     let _ = std::option::Option::None::<i32>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr
new file mode 100644
index 00000000000..0cc6566af3a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.allow_long.stderr
@@ -0,0 +1,14 @@
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13
+   |
+LL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr
new file mode 100644
index 00000000000..53aa9030e0d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.default.stderr
@@ -0,0 +1,80 @@
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13
+   |
+LL |     let _ = std::path::is_separator(' ');
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13
+   |
+LL |     let _ = ::std::path::MAIN_SEPARATOR;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13
+   |
+LL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31
+   |
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |                               ^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13
+   |
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |             ^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13
+   |
+LL |     let _ = ::core::clone::Clone::clone(&0i32);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13
+   |
+LL |     let _ = <i32 as core::clone::Clone>::clone(&0i32);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13
+   |
+LL |     let _ = std::option::Option::None::<i32>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17
+   |
+LL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+   |                 ^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18
+   |
+LL |         where T: core::clone::Clone
+   |                  ^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32
+   |
+LL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+   |                                ^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5
+   |
+LL |     crate::m1::S
+   |     ^^^^^^^^^^^^
+
+error: aborting due to 12 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr
deleted file mode 100644
index f342ebf6632..00000000000
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.disallow_crates.stderr
+++ /dev/null
@@ -1,71 +0,0 @@
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:5
-   |
-LL |     std::f32::MAX;
-   |     ^^^^^^^^^^^^^
-   |
-   = note: `-D clippy::absolute-paths` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::absolute_paths)]`
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:41:5
-   |
-LL |     core::f32::MAX;
-   |     ^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:42:5
-   |
-LL |     ::core::f32::MAX;
-   |     ^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:5
-   |
-LL |     crate::a::b::c::C;
-   |     ^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:44:5
-   |
-LL |     crate::a::b::c::d::e::f::F;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:45:5
-   |
-LL |     crate::a::A;
-   |     ^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:46:5
-   |
-LL |     crate::a::b::B;
-   |     ^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:47:5
-   |
-LL |     crate::a::b::c::C::ZERO;
-   |     ^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:48:5
-   |
-LL |     helper::b::c::d::e::f();
-   |     ^^^^^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:49:5
-   |
-LL |     ::helper::b::c::d::e::f();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-
-error: consider bringing this path into scope with the `use` keyword
-  --> tests/ui-toml/absolute_paths/absolute_paths.rs:58:5
-   |
-LL |     ::std::f32::MAX;
-   |     ^^^^^^^^^^^^^^^
-
-error: aborting due to 11 previous errors
-
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr
new file mode 100644
index 00000000000..70d71f6c4ea
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.no_short.stderr
@@ -0,0 +1,98 @@
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:14:13
+   |
+LL |     let _ = std::path::is_separator(' ');
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:7:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:20:13
+   |
+LL |     let _ = ::std::path::MAIN_SEPARATOR;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:25:13
+   |
+LL |     let _ = std::collections::hash_map::HashMap::<i32, i32>::new();
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:31
+   |
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |                               ^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:28:13
+   |
+LL |     let _: &std::path::Path = std::path::Path::new("");
+   |             ^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:37:13
+   |
+LL |     let _ = ::core::clone::Clone::clone(&0i32);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:40:13
+   |
+LL |     let _ = <i32 as core::clone::Clone>::clone(&0i32);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:43:13
+   |
+LL |     let _ = std::option::Option::None::<i32>;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:17
+   |
+LL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+   |                 ^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:70:18
+   |
+LL |         where T: core::clone::Clone
+   |                  ^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:65:32
+   |
+LL |         impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+   |                                ^^^^^^^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:113:14
+   |
+LL | pub const _: crate::S = {
+   |              ^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:114:9
+   |
+LL |     let crate::S = m1::S;
+   |         ^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:116:5
+   |
+LL |     crate::m1::S
+   |     ^^^^^^^^^^^^
+
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths.rs:122:14
+   |
+LL |     let _ = <crate::S as Clone>::clone(&m1::S);
+   |              ^^^^^^^^
+
+error: aborting due to 15 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
index a828701bcee..c024f2f513c 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
@@ -1,97 +1,123 @@
 //@aux-build:../../ui/auxiliary/proc_macros.rs
-//@aux-build:helper.rs
-//@revisions: allow_crates disallow_crates
+//@revisions: default allow_crates allow_long no_short
+//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default
 //@[allow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates
-//@[disallow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/disallow_crates
-#![allow(clippy::no_effect, clippy::legacy_numeric_constants, unused)]
-#![warn(clippy::absolute_paths)]
-#![feature(decl_macro)]
+//@[allow_long] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_long
+//@[no_short] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/no_short
+#![deny(clippy::absolute_paths)]
 
-extern crate helper;
-#[macro_use]
 extern crate proc_macros;
+use proc_macros::{external, inline_macros, with_span};
 
-pub mod a {
-    pub mod b {
-        pub mod c {
-            pub struct C;
+#[inline_macros]
+fn main() {
+    let _ = std::path::is_separator(' ');
+    //~[default]^ absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[no_short]| absolute_paths
 
-            impl C {
-                pub const ZERO: u32 = 0;
-            }
+    // Make sure this is treated as having three path segments, not four.
+    let _ = ::std::path::MAIN_SEPARATOR;
+    //~[default]^ absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[no_short]| absolute_paths
 
-            pub mod d {
-                pub mod e {
-                    pub mod f {
-                        pub struct F;
-                    }
-                }
-            }
-        }
+    let _ = std::collections::hash_map::HashMap::<i32, i32>::new(); //~ absolute_paths
 
-        pub struct B;
-    }
+    // Note `std::path::Path::new` is treated as having three parts
+    let _: &std::path::Path = std::path::Path::new("");
+    //~[default]^ absolute_paths
+    //~[default]| absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[no_short]| absolute_paths
+    //~[no_short]| absolute_paths
 
-    pub struct A;
-}
+    // Treated as having three parts.
+    let _ = ::core::clone::Clone::clone(&0i32);
+    //~[default]^ absolute_paths
+    //~[no_short]| absolute_paths
+    let _ = <i32 as core::clone::Clone>::clone(&0i32);
+    //~[default]^ absolute_paths
+    //~[no_short]| absolute_paths
+    let _ = std::option::Option::None::<i32>;
+    //~[default]^ absolute_paths
+    //~[allow_crates]| absolute_paths
+    //~[no_short]| absolute_paths
 
-fn main() {
-    f32::max(1.0, 2.0);
-    std::f32::MAX;
-    core::f32::MAX;
-    ::core::f32::MAX;
-    crate::a::b::c::C;
-    crate::a::b::c::d::e::f::F;
-    crate::a::A;
-    crate::a::b::B;
-    crate::a::b::c::C::ZERO;
-    helper::b::c::d::e::f();
-    ::helper::b::c::d::e::f();
-    fn b() -> a::b::B {
-        todo!()
+    {
+        // FIXME: macro calls should be checked.
+        let x = 1i32;
+        let _ = core::ptr::addr_of!(x);
     }
-    std::println!("a");
-    let x = 1;
-    std::ptr::addr_of!(x);
-    // Test we handle max segments with `PathRoot` properly; this has 4 segments but we should say it
-    // has 3
-    ::std::f32::MAX;
-    // Do not lint due to the above
-    ::helper::a();
-    // Do not lint
-    helper::a();
-    use crate::a::b::c::C;
-    use a::b;
-    use std::f32::MAX;
-    a::b::c::d::e::f::F;
-    b::c::C;
-    fn a() -> a::A {
-        todo!()
-    }
-    use a::b::c;
 
-    fn c() -> c::C {
-        todo!()
+    {
+        // FIXME: derive macro paths should be checked.
+        #[derive(core::clone::Clone)]
+        struct S;
     }
-    fn d() -> Result<(), ()> {
-        todo!()
+
+    {
+        use core::fmt;
+        use core::marker::PhantomData;
+
+        struct X<T>(PhantomData<T>);
+        impl<T: core::cmp::Eq> core::fmt::Display for X<T>
+        //~[default]^ absolute_paths
+        //~[default]| absolute_paths
+        //~[no_short]| absolute_paths
+        //~[no_short]| absolute_paths
+        where T: core::clone::Clone
+        //~[no_short]^ absolute_paths
+        //~[default]| absolute_paths
+        {
+            fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+                Ok(())
+            }
+        }
     }
-    external! {
-        crate::a::b::c::C::ZERO;
+
+    {
+        mod m1 {
+            pub(crate) mod m2 {
+                pub(crate) const FOO: i32 = 0;
+            }
+        }
+        let _ = m1::m2::FOO;
     }
-    // For some reason, `path.span.from_expansion()` takes care of this for us
+
     with_span! {
         span
-        crate::a::b::c::C::ZERO;
+        let _ = std::path::is_separator(' ');
     }
-    macro_rules! local_crate {
-        () => {
-            crate::a::b::c::C::ZERO;
-        };
+
+    external! {
+        let _ = std::path::is_separator(' ');
     }
-    macro local_crate_2_0() {
-        crate::a::b::c::C::ZERO;
+
+    inline! {
+        let _ = std::path::is_separator(' ');
     }
-    local_crate!();
-    local_crate_2_0!();
+}
+
+pub use core::cmp::Ordering;
+pub use std::fs::File;
+
+#[derive(Clone)]
+pub struct S;
+mod m1 {
+    pub use crate::S;
+}
+
+//~[no_short]v absolute_paths
+pub const _: crate::S = {
+    let crate::S = m1::S; //~[no_short] absolute_paths
+
+    crate::m1::S
+    //~[default]^ absolute_paths
+    //~[no_short]| absolute_paths
+};
+
+pub fn f() {
+    let _ = <crate::S as Clone>::clone(&m1::S); //~[no_short] absolute_paths
 }
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr
new file mode 100644
index 00000000000..6fc495f0180
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.default.stderr
@@ -0,0 +1,14 @@
+error: consider bringing this path into scope with the `use` keyword
+  --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:15:13
+   |
+LL |     let _ = ::m1::m2::X;
+   |             ^^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui-toml/absolute_paths/absolute_paths_2015.rs:6:9
+   |
+LL | #![deny(clippy::absolute_paths)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs
new file mode 100644
index 00000000000..033c4780919
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths_2015.rs
@@ -0,0 +1,16 @@
+//@revisions: default allow_crates
+//@[default]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/default
+//@[allow_crates]rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates
+//@edition:2015
+
+#![deny(clippy::absolute_paths)]
+
+mod m1 {
+    pub mod m2 {
+        pub struct X;
+    }
+}
+
+fn main() {
+    let _ = ::m1::m2::X; //~[default] absolute_paths
+}
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml
index 59a621e9d1d..9da49abcd31 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_crates/clippy.toml
@@ -1,2 +1 @@
-absolute-paths-max-segments = 2
-absolute-paths-allowed-crates = ["crate", "helper"]
+absolute-paths-allowed-crates = ["core", "crate"]
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml
new file mode 100644
index 00000000000..5992fd1ed82
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/allow_long/clippy.toml
@@ -0,0 +1 @@
+absolute-paths-max-segments = 3
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs
deleted file mode 100644
index 8e2678f5fe6..00000000000
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/auxiliary/helper.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-pub fn a() {}
-
-pub mod b {
-    pub mod c {
-        pub mod d {
-            pub mod e {
-                pub fn f() {}
-            }
-        }
-    }
-}
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/default/clippy.toml
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml
deleted file mode 100644
index d44d648c641..00000000000
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/disallow_crates/clippy.toml
+++ /dev/null
@@ -1 +0,0 @@
-absolute-paths-max-segments = 2
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml b/src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml
new file mode 100644
index 00000000000..357524420c5
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/no_short/clippy.toml
@@ -0,0 +1 @@
+absolute-paths-max-segments = 0
diff --git a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs
index a312df5a43a..3dafea56514 100644
--- a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs
+++ b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.rs
@@ -1,7 +1,7 @@
 //! Tests macro_metavars_in_unsafe with default configuration
 #![feature(decl_macro)]
 #![warn(clippy::macro_metavars_in_unsafe)]
-#![allow(clippy::no_effect)]
+#![allow(clippy::no_effect, clippy::not_unsafe_ptr_arg_deref)]
 
 #[macro_export]
 macro_rules! allow_works {
@@ -237,6 +237,19 @@ macro_rules! nested_macros {
     }};
 }
 
+pub mod issue13219 {
+    #[macro_export]
+    macro_rules! m {
+        ($e:expr) => {
+            // Metavariable in a block tail expression
+            unsafe { $e }
+        };
+    }
+    pub fn f(p: *const i32) -> i32 {
+        m!(*p)
+    }
+}
+
 fn main() {
     allow_works!(1);
     simple!(1);
diff --git a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr
index d6b97f6fde1..6f0ebcbba02 100644
--- a/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr
+++ b/src/tools/clippy/tests/ui-toml/macro_metavars_in_unsafe/default/test.stderr
@@ -1,4 +1,16 @@
 error: this macro expands metavariables in an unsafe block
+  --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:245:13
+   |
+LL |             unsafe { $e }
+   |             ^^^^^^^^^^^^^
+   |
+   = note: this allows the user of the macro to write unsafe code outside of an unsafe block
+   = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable
+   = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite
+   = note: `-D clippy::macro-metavars-in-unsafe` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::macro_metavars_in_unsafe)]`
+
+error: this macro expands metavariables in an unsafe block
   --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:19:9
    |
 LL | /         unsafe {
@@ -10,8 +22,6 @@ LL | |         }
    = note: this allows the user of the macro to write unsafe code outside of an unsafe block
    = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable
    = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite
-   = note: `-D clippy::macro-metavars-in-unsafe` implied by `-D warnings`
-   = help: to override `-D warnings` add `#[allow(clippy::macro_metavars_in_unsafe)]`
 
 error: this macro expands metavariables in an unsafe block
   --> tests/ui-toml/macro_metavars_in_unsafe/default/test.rs:30:9
@@ -183,5 +193,5 @@ LL | |         }
    = help: consider expanding any metavariables outside of this block, e.g. by storing them in a variable
    = help: ... or also expand referenced metavariables in a safe context to require an unsafe block at callsite
 
-error: aborting due to 14 previous errors
+error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/assigning_clones.fixed b/src/tools/clippy/tests/ui/assigning_clones.fixed
index b376d55a402..09732d1a50c 100644
--- a/src/tools/clippy/tests/ui/assigning_clones.fixed
+++ b/src/tools/clippy/tests/ui/assigning_clones.fixed
@@ -396,3 +396,23 @@ impl<T: Clone> Clone for DerefWrapperWithClone<T> {
         *self = Self(source.0.clone());
     }
 }
+
+#[cfg(test)]
+mod test {
+    #[derive(Default)]
+    struct Data {
+        field: String,
+    }
+
+    fn test_data() -> Data {
+        Data {
+            field: "default_value".to_string(),
+        }
+    }
+
+    #[test]
+    fn test() {
+        let mut data = test_data();
+        data.field = "override_value".to_owned();
+    }
+}
diff --git a/src/tools/clippy/tests/ui/assigning_clones.rs b/src/tools/clippy/tests/ui/assigning_clones.rs
index 11a5d4459c3..6be25ae17a5 100644
--- a/src/tools/clippy/tests/ui/assigning_clones.rs
+++ b/src/tools/clippy/tests/ui/assigning_clones.rs
@@ -396,3 +396,23 @@ impl<T: Clone> Clone for DerefWrapperWithClone<T> {
         *self = Self(source.0.clone());
     }
 }
+
+#[cfg(test)]
+mod test {
+    #[derive(Default)]
+    struct Data {
+        field: String,
+    }
+
+    fn test_data() -> Data {
+        Data {
+            field: "default_value".to_string(),
+        }
+    }
+
+    #[test]
+    fn test() {
+        let mut data = test_data();
+        data.field = "override_value".to_owned();
+    }
+}
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr
index f7e659b10de..329be4d3662 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/complex_conditionals_nested.stderr
@@ -2,7 +2,7 @@ error: called `unwrap` on `x` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/complex_conditionals_nested.rs:13:13
    |
 LL |         if x.is_some() {
-   |         -------------- help: try: `if let Some(..) = x`
+   |         -------------- help: try: `if let Some(<item>) = x`
 LL |             // unnecessary
 LL |             x.unwrap();
    |             ^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
index ddd600418af..f7e338935a7 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
@@ -2,7 +2,7 @@ error: called `unwrap` on `x` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:46:9
    |
 LL |     if x.is_some() {
-   |     -------------- help: try: `if let Some(..) = x`
+   |     -------------- help: try: `if let Some(<item>) = x`
 LL |         // unnecessary
 LL |         x.unwrap();
    |         ^^^^^^^^^^
@@ -17,7 +17,7 @@ error: called `expect` on `x` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:49:9
    |
 LL |     if x.is_some() {
-   |     -------------- help: try: `if let Some(..) = x`
+   |     -------------- help: try: `if let Some(<item>) = x`
 ...
 LL |         x.expect("an error message");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -59,7 +59,7 @@ error: called `unwrap` on `x` after checking its variant with `is_none`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:65:9
    |
 LL |     if x.is_none() {
-   |     -------------- help: try: `if let Some(..) = x`
+   |     -------------- help: try: `if let Some(<item>) = x`
 ...
 LL |         x.unwrap();
    |         ^^^^^^^^^^
@@ -68,7 +68,7 @@ error: called `unwrap` on `x` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:13:13
    |
 LL |         if $a.is_some() {
-   |         --------------- help: try: `if let Some(..) = x`
+   |         --------------- help: try: `if let Some(<item>) = x`
 LL |             // unnecessary
 LL |             $a.unwrap();
    |             ^^^^^^^^^^^
@@ -82,7 +82,7 @@ error: called `unwrap` on `x` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:78:9
    |
 LL |     if x.is_ok() {
-   |     ------------ help: try: `if let Ok(..) = x`
+   |     ------------ help: try: `if let Ok(<item>) = x`
 LL |         // unnecessary
 LL |         x.unwrap();
    |         ^^^^^^^^^^
@@ -91,7 +91,7 @@ error: called `expect` on `x` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:81:9
    |
 LL |     if x.is_ok() {
-   |     ------------ help: try: `if let Ok(..) = x`
+   |     ------------ help: try: `if let Ok(<item>) = x`
 ...
 LL |         x.expect("an error message");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -127,7 +127,7 @@ error: called `unwrap_err` on `x` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:94:9
    |
 LL |     if x.is_ok() {
-   |     ------------ help: try: `if let Err(..) = x`
+   |     ------------ help: try: `if let Err(<item>) = x`
 ...
 LL |         x.unwrap_err();
    |         ^^^^^^^^^^^^^^
@@ -145,7 +145,7 @@ error: called `unwrap_err` on `x` after checking its variant with `is_err`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:102:9
    |
 LL |     if x.is_err() {
-   |     ------------- help: try: `if let Err(..) = x`
+   |     ------------- help: try: `if let Err(<item>) = x`
 ...
 LL |         x.unwrap_err();
    |         ^^^^^^^^^^^^^^
@@ -154,7 +154,7 @@ error: called `unwrap` on `x` after checking its variant with `is_err`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:106:9
    |
 LL |     if x.is_err() {
-   |     ------------- help: try: `if let Ok(..) = x`
+   |     ------------- help: try: `if let Ok(<item>) = x`
 ...
 LL |         x.unwrap();
    |         ^^^^^^^^^^
@@ -172,7 +172,7 @@ error: called `unwrap` on `option` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:134:9
    |
 LL |     if option.is_some() {
-   |     ------------------- help: try: `if let Some(..) = &option`
+   |     ------------------- help: try: `if let Some(<item>) = &option`
 LL |         option.as_ref().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -189,7 +189,7 @@ error: called `unwrap` on `result` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:144:9
    |
 LL |     if result.is_ok() {
-   |     ----------------- help: try: `if let Ok(..) = &result`
+   |     ----------------- help: try: `if let Ok(<item>) = &result`
 LL |         result.as_ref().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -206,7 +206,7 @@ error: called `unwrap` on `option` after checking its variant with `is_some`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:153:9
    |
 LL |     if option.is_some() {
-   |     ------------------- help: try: `if let Some(..) = &mut option`
+   |     ------------------- help: try: `if let Some(<item>) = &mut option`
 LL |         option.as_mut().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -223,7 +223,7 @@ error: called `unwrap` on `result` after checking its variant with `is_ok`
   --> tests/ui/checked_unwrap/simple_conditionals.rs:162:9
    |
 LL |     if result.is_ok() {
-   |     ----------------- help: try: `if let Ok(..) = &mut result`
+   |     ----------------- help: try: `if let Ok(<item>) = &mut result`
 LL |         result.as_mut().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/src/tools/clippy/tests/ui/collapsible_match.stderr b/src/tools/clippy/tests/ui/collapsible_match.stderr
index 01944baee79..1da78b56239 100644
--- a/src/tools/clippy/tests/ui/collapsible_match.stderr
+++ b/src/tools/clippy/tests/ui/collapsible_match.stderr
@@ -223,7 +223,7 @@ help: the outer pattern can be modified to include the inner pattern
 LL |     if let Issue9647::A { a, .. } = x {
    |                           ^ replace this binding
 LL |         if let Some(u) = a {
-   |                ^^^^^^^ with this pattern, prefixed by a:
+   |                ^^^^^^^ with this pattern, prefixed by `a`:
 
 error: this `if let` can be collapsed into the outer `if let`
   --> tests/ui/collapsible_match.rs:292:9
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.fixed b/src/tools/clippy/tests/ui/crashes/ice-3717.fixed
new file mode 100644
index 00000000000..3f54b326979
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-3717.fixed
@@ -0,0 +1,11 @@
+#![deny(clippy::implicit_hasher)]
+
+use std::collections::HashSet;
+
+fn main() {}
+
+pub fn ice_3717<S: ::std::hash::BuildHasher + Default>(_: &HashSet<usize, S>) {
+    //~^ ERROR: parameter of type `HashSet` should be generalized over different hashers
+    let _ = [0u8; 0];
+    let _: HashSet<usize> = HashSet::default();
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.rs b/src/tools/clippy/tests/ui/crashes/ice-3717.rs
index 770f6cf448a..2890a9277c7 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3717.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-3717.rs
@@ -1,7 +1,5 @@
 #![deny(clippy::implicit_hasher)]
 
-//@no-rustfix: need to change the suggestion to a multipart suggestion
-
 use std::collections::HashSet;
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-3717.stderr b/src/tools/clippy/tests/ui/crashes/ice-3717.stderr
index 4b4618ee1bb..aac72c66965 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-3717.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-3717.stderr
@@ -1,5 +1,5 @@
 error: parameter of type `HashSet` should be generalized over different hashers
-  --> tests/ui/crashes/ice-3717.rs:9:21
+  --> tests/ui/crashes/ice-3717.rs:7:21
    |
 LL | pub fn ice_3717(_: &HashSet<usize>) {
    |                     ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
index 56a8d22cb1c..9dafad8b784 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.rs
@@ -3,6 +3,7 @@
 use std::borrow::Cow;
 use std::cell::Cell;
 use std::fmt::Display;
+use std::ptr;
 use std::sync::atomic::AtomicUsize;
 use std::sync::Once;
 
@@ -53,4 +54,20 @@ mod issue_8493 {
     issue_8493!();
 }
 
+#[repr(C, align(8))]
+struct NoAtomic(usize);
+#[repr(C, align(8))]
+struct WithAtomic(AtomicUsize);
+
+const fn with_non_null() -> *const WithAtomic {
+    const NO_ATOMIC: NoAtomic = NoAtomic(0);
+    (&NO_ATOMIC as *const NoAtomic).cast()
+}
+const WITH_ATOMIC: *const WithAtomic = with_non_null();
+
+struct Generic<T>(T);
+impl<T> Generic<T> {
+    const RAW_POINTER: *const Cell<T> = ptr::null();
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
index 1f2b9561ce5..4a725147142 100644
--- a/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
+++ b/src/tools/clippy/tests/ui/declare_interior_mutable_const/others.stderr
@@ -1,5 +1,5 @@
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:9:1
+  --> tests/ui/declare_interior_mutable_const/others.rs:10:1
    |
 LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | const ATOMIC: AtomicUsize = AtomicUsize::new(5);
    = help: to override `-D warnings` add `#[allow(clippy::declare_interior_mutable_const)]`
 
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:10:1
+  --> tests/ui/declare_interior_mutable_const/others.rs:11:1
    |
 LL | const CELL: Cell<usize> = Cell::new(6);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,7 +17,7 @@ LL | const CELL: Cell<usize> = Cell::new(6);
    = help: consider making this `Sync` so that it can go in a static item or using a `thread_local`
 
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:11:1
+  --> tests/ui/declare_interior_mutable_const/others.rs:12:1
    |
 LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], Vec::new(), 7);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL | const ATOMIC_TUPLE: ([AtomicUsize; 1], Vec<AtomicUsize>, u8) = ([ATOMIC], V
    = help: consider making this a static item
 
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:16:9
+  --> tests/ui/declare_interior_mutable_const/others.rs:17:9
    |
 LL |         const $name: $ty = $e;
    |         ^^^^^^^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL | declare_const!(_ONCE: Once = Once::new());
    = note: this error originates in the macro `declare_const` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: a `const` item should not be interior mutable
-  --> tests/ui/declare_interior_mutable_const/others.rs:44:13
+  --> tests/ui/declare_interior_mutable_const/others.rs:45:13
    |
 LL |             const _BAZ: Cell<usize> = Cell::new(0);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed
new file mode 100644
index 00000000000..fb0f40b34a4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.fixed
@@ -0,0 +1,13 @@
+// This test checks that words starting with capital letters and ending with "ified" don't
+// trigger the lint.
+
+#![deny(clippy::doc_markdown)]
+
+pub enum OutputFormat {
+    /// `HumaNified`
+    //~^ ERROR: item in documentation is missing backticks
+    Plain,
+    // Should not warn!
+    /// JSONified console output
+    Json,
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs
new file mode 100644
index 00000000000..8c1e1a3cd6c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.rs
@@ -0,0 +1,13 @@
+// This test checks that words starting with capital letters and ending with "ified" don't
+// trigger the lint.
+
+#![deny(clippy::doc_markdown)]
+
+pub enum OutputFormat {
+    /// HumaNified
+    //~^ ERROR: item in documentation is missing backticks
+    Plain,
+    // Should not warn!
+    /// JSONified console output
+    Json,
+}
diff --git a/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr
new file mode 100644
index 00000000000..ae68a767ec9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/doc/doc_markdown-issue_13097.stderr
@@ -0,0 +1,18 @@
+error: item in documentation is missing backticks
+  --> tests/ui/doc/doc_markdown-issue_13097.rs:7:9
+   |
+LL |     /// HumaNified
+   |         ^^^^^^^^^^
+   |
+note: the lint level is defined here
+  --> tests/ui/doc/doc_markdown-issue_13097.rs:4:9
+   |
+LL | #![deny(clippy::doc_markdown)]
+   |         ^^^^^^^^^^^^^^^^^^^^
+help: try
+   |
+LL |     /// `HumaNified`
+   |         ~~~~~~~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/double_must_use.rs b/src/tools/clippy/tests/ui/double_must_use.rs
index 615de3e2474..4460aeb075b 100644
--- a/src/tools/clippy/tests/ui/double_must_use.rs
+++ b/src/tools/clippy/tests/ui/double_must_use.rs
@@ -3,19 +3,19 @@
 
 #[must_use]
 pub fn must_use_result() -> Result<(), ()> {
-    //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
+    //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already
     unimplemented!();
 }
 
 #[must_use]
 pub fn must_use_tuple() -> (Result<(), ()>, u8) {
-    //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
+    //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already
     unimplemented!();
 }
 
 #[must_use]
 pub fn must_use_array() -> [Result<(), ()>; 1] {
-    //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
+    //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already
     unimplemented!();
 }
 
@@ -32,7 +32,7 @@ async fn async_must_use() -> usize {
 
 #[must_use]
 async fn async_must_use_result() -> Result<(), ()> {
-    //~^ ERROR: this function has an empty `#[must_use]` attribute, but returns a type already
+    //~^ ERROR: this function has a `#[must_use]` attribute with no message, but returns a type already
     Ok(())
 }
 
diff --git a/src/tools/clippy/tests/ui/double_must_use.stderr b/src/tools/clippy/tests/ui/double_must_use.stderr
index 0f2154ecbcf..b26d1e48a8b 100644
--- a/src/tools/clippy/tests/ui/double_must_use.stderr
+++ b/src/tools/clippy/tests/ui/double_must_use.stderr
@@ -1,36 +1,36 @@
-error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
+error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
   --> tests/ui/double_must_use.rs:5:1
    |
 LL | pub fn must_use_result() -> Result<(), ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: either add some descriptive text or remove the attribute
+   = help: either add some descriptive message or remove the attribute
    = note: `-D clippy::double-must-use` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::double_must_use)]`
 
-error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
+error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
   --> tests/ui/double_must_use.rs:11:1
    |
 LL | pub fn must_use_tuple() -> (Result<(), ()>, u8) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: either add some descriptive text or remove the attribute
+   = help: either add some descriptive message or remove the attribute
 
-error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
+error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
   --> tests/ui/double_must_use.rs:17:1
    |
 LL | pub fn must_use_array() -> [Result<(), ()>; 1] {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: either add some descriptive text or remove the attribute
+   = help: either add some descriptive message or remove the attribute
 
-error: this function has an empty `#[must_use]` attribute, but returns a type already marked as `#[must_use]`
+error: this function has a `#[must_use]` attribute with no message, but returns a type already marked as `#[must_use]`
   --> tests/ui/double_must_use.rs:34:1
    |
 LL | async fn async_must_use_result() -> Result<(), ()> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: either add some descriptive text or remove the attribute
+   = help: either add some descriptive message or remove the attribute
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
index f38b34c5a7c..1148f0f6c6a 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.fixed
@@ -153,3 +153,15 @@ fn main() {
     let r = &x;
     for _ in r {}
 }
+
+#[clippy::msrv = "1.79"]
+pub fn issue_13184() {
+    // https://github.com/rust-lang/rust-clippy/issues/13184
+    // No need to fix, as IntoIterator for Box is valid starting from 1.80
+    let mut values: Box<[u32]> = Box::new([1, 2]);
+    for _ in values.iter() {}
+    for _ in values.iter_mut() {}
+
+    let rvalues = &values;
+    for _ in rvalues.iter() {}
+}
diff --git a/src/tools/clippy/tests/ui/explicit_iter_loop.rs b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
index 2e701ada5ac..4dda2f13e5b 100644
--- a/src/tools/clippy/tests/ui/explicit_iter_loop.rs
+++ b/src/tools/clippy/tests/ui/explicit_iter_loop.rs
@@ -153,3 +153,15 @@ fn main() {
     let r = &x;
     for _ in r.iter() {}
 }
+
+#[clippy::msrv = "1.79"]
+pub fn issue_13184() {
+    // https://github.com/rust-lang/rust-clippy/issues/13184
+    // No need to fix, as IntoIterator for Box is valid starting from 1.80
+    let mut values: Box<[u32]> = Box::new([1, 2]);
+    for _ in values.iter() {}
+    for _ in values.iter_mut() {}
+
+    let rvalues = &values;
+    for _ in rvalues.iter() {}
+}
diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
index 5778f8f526f..4c324587c96 100644
--- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
+++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.fixed
@@ -15,6 +15,14 @@ struct Foo {
     z: i32,
 }
 
+#[derive(Default)]
+#[allow(clippy::inconsistent_struct_constructor)]
+struct Bar {
+    x: i32,
+    y: i32,
+    z: i32,
+}
+
 mod without_base {
     use super::Foo;
 
@@ -70,4 +78,17 @@ mod with_base {
     }
 }
 
+mod with_allow_ty_def {
+    use super::Bar;
+
+    fn test() {
+        let x = 1;
+        let y = 1;
+        let z = 1;
+
+        // Should NOT lint because `Bar` is defined with `#[allow(clippy::inconsistent_struct_constructor)]`
+        Bar { y, x, z };
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
index 9efaf068934..d49f236b9b0 100644
--- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
+++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.rs
@@ -15,6 +15,14 @@ struct Foo {
     z: i32,
 }
 
+#[derive(Default)]
+#[allow(clippy::inconsistent_struct_constructor)]
+struct Bar {
+    x: i32,
+    y: i32,
+    z: i32,
+}
+
 mod without_base {
     use super::Foo;
 
@@ -74,4 +82,17 @@ mod with_base {
     }
 }
 
+mod with_allow_ty_def {
+    use super::Bar;
+
+    fn test() {
+        let x = 1;
+        let y = 1;
+        let z = 1;
+
+        // Should NOT lint because `Bar` is defined with `#[allow(clippy::inconsistent_struct_constructor)]`
+        Bar { y, x, z };
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
index 1192271f911..97bb7c789a7 100644
--- a/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
+++ b/src/tools/clippy/tests/ui/inconsistent_struct_constructor.stderr
@@ -1,5 +1,5 @@
 error: struct constructor field order is inconsistent with struct definition field order
-  --> tests/ui/inconsistent_struct_constructor.rs:28:9
+  --> tests/ui/inconsistent_struct_constructor.rs:36:9
    |
 LL |         Foo { y, x, z };
    |         ^^^^^^^^^^^^^^^ help: try: `Foo { x, y, z }`
@@ -8,7 +8,7 @@ LL |         Foo { y, x, z };
    = help: to override `-D warnings` add `#[allow(clippy::inconsistent_struct_constructor)]`
 
 error: struct constructor field order is inconsistent with struct definition field order
-  --> tests/ui/inconsistent_struct_constructor.rs:55:9
+  --> tests/ui/inconsistent_struct_constructor.rs:63:9
    |
 LL | /         Foo {
 LL | |             z,
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
index 2dccadd9fce..c8409d78ed7 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.rs
@@ -17,7 +17,7 @@ mod multiple {
     //~^ ERROR: `clippy::msrv` is defined multiple times
 
     mod foo {
-        #![clippy::msrv = "1"]
+        #![clippy::msrv = "1.0"]
         #![clippy::msrv = "1.0.0"]
         //~^ ERROR: `clippy::msrv` is defined multiple times
     }
diff --git a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
index b4cb1b5713f..dbc276ed89d 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_invalid_attr.stderr
@@ -31,8 +31,8 @@ LL |         #![clippy::msrv = "1.0.0"]
 note: first definition found here
   --> tests/ui/min_rust_version_invalid_attr.rs:20:9
    |
-LL |         #![clippy::msrv = "1"]
-   |         ^^^^^^^^^^^^^^^^^^^^^^
+LL |         #![clippy::msrv = "1.0"]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/string_slice.rs b/src/tools/clippy/tests/ui/string_slice.rs
index 440a86b104a..1d1911aaa1d 100644
--- a/src/tools/clippy/tests/ui/string_slice.rs
+++ b/src/tools/clippy/tests/ui/string_slice.rs
@@ -1,3 +1,5 @@
+use std::borrow::Cow;
+
 #[warn(clippy::string_slice)]
 #[allow(clippy::no_effect)]
 
@@ -11,4 +13,7 @@ fn main() {
     let s = String::from(m);
     &s[0..2];
     //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character
+    let a = Cow::Borrowed("foo");
+    &a[0..3];
+    //~^ ERROR: indexing into a string may panic if the index is within a UTF-8 character
 }
diff --git a/src/tools/clippy/tests/ui/string_slice.stderr b/src/tools/clippy/tests/ui/string_slice.stderr
index 7a4596b5f2d..bc0fcde34b8 100644
--- a/src/tools/clippy/tests/ui/string_slice.stderr
+++ b/src/tools/clippy/tests/ui/string_slice.stderr
@@ -1,5 +1,5 @@
 error: indexing into a string may panic if the index is within a UTF-8 character
-  --> tests/ui/string_slice.rs:5:6
+  --> tests/ui/string_slice.rs:7:6
    |
 LL |     &"Ölkanne"[1..];
    |      ^^^^^^^^^^^^^^
@@ -8,16 +8,22 @@ LL |     &"Ölkanne"[1..];
    = help: to override `-D warnings` add `#[allow(clippy::string_slice)]`
 
 error: indexing into a string may panic if the index is within a UTF-8 character
-  --> tests/ui/string_slice.rs:9:6
+  --> tests/ui/string_slice.rs:11:6
    |
 LL |     &m[2..5];
    |      ^^^^^^^
 
 error: indexing into a string may panic if the index is within a UTF-8 character
-  --> tests/ui/string_slice.rs:12:6
+  --> tests/ui/string_slice.rs:14:6
    |
 LL |     &s[0..2];
    |      ^^^^^^^
 
-error: aborting due to 3 previous errors
+error: indexing into a string may panic if the index is within a UTF-8 character
+  --> tests/ui/string_slice.rs:17:6
+   |
+LL |     &a[0..3];
+   |      ^^^^^^^
+
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed
new file mode 100644
index 00000000000..d4a0cdf3447
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.fixed
@@ -0,0 +1,9 @@
+#![warn(clippy::too_long_first_doc_paragraph)]
+
+/// A very short summary.
+///
+/// A much longer explanation that goes into a lot more detail about
+/// how the thing works, possibly with doclinks and so one,
+/// and probably spanning a many rows. Blablabla, it needs to be over
+/// 200 characters so I needed to write something longeeeeeeer.
+pub struct Foo;
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs
new file mode 100644
index 00000000000..5a3b6c42a32
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.rs
@@ -0,0 +1,8 @@
+#![warn(clippy::too_long_first_doc_paragraph)]
+
+/// A very short summary.
+/// A much longer explanation that goes into a lot more detail about
+/// how the thing works, possibly with doclinks and so one,
+/// and probably spanning a many rows. Blablabla, it needs to be over
+/// 200 characters so I needed to write something longeeeeeeer.
+pub struct Foo;
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr
new file mode 100644
index 00000000000..6403265a39c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr
@@ -0,0 +1,20 @@
+error: first doc comment paragraph is too long
+  --> tests/ui/too_long_first_doc_paragraph-fix.rs:3:1
+   |
+LL | / /// A very short summary.
+LL | | /// A much longer explanation that goes into a lot more detail about
+LL | | /// how the thing works, possibly with doclinks and so one,
+LL | | /// and probably spanning a many rows. Blablabla, it needs to be over
+LL | | /// 200 characters so I needed to write something longeeeeeeer.
+   | |_
+   |
+   = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`
+help: add an empty line
+   |
+LL ~ /// A very short summary.
+LL + ///
+   |
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs
new file mode 100644
index 00000000000..1042249c5b7
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.rs
@@ -0,0 +1,53 @@
+//@no-rustfix
+
+#![warn(clippy::too_long_first_doc_paragraph)]
+
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+pub struct Bar;
+
+// Should not warn! (not an item visible on mod page)
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+impl Bar {}
+
+// Should not warn! (less than 80 characters)
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+///
+/// Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+pub enum Enum {
+    A,
+}
+
+/// Lorem
+/// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+pub union Union {
+    a: u8,
+    b: u8,
+}
+
+// Should not warn! (title)
+/// # bla
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+pub union Union2 {
+    a: u8,
+    b: u8,
+}
+
+// Should not warn! (not public)
+/// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+/// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+/// gravida non lacinia at, rhoncus eu lacus.
+fn f() {}
+
+fn main() {
+    // test code goes here
+}
diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
new file mode 100644
index 00000000000..7f48e5cf884
--- /dev/null
+++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr
@@ -0,0 +1,22 @@
+error: first doc comment paragraph is too long
+  --> tests/ui/too_long_first_doc_paragraph.rs:5:1
+   |
+LL | / /// Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+LL | | /// gravida non lacinia at, rhoncus eu lacus.
+   | |_
+   |
+   = note: `-D clippy::too-long-first-doc-paragraph` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::too_long_first_doc_paragraph)]`
+
+error: first doc comment paragraph is too long
+  --> tests/ui/too_long_first_doc_paragraph.rs:26:1
+   |
+LL | / /// Lorem
+LL | | /// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia
+LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero,
+LL | | /// gravida non lacinia at, rhoncus eu lacus.
+   | |_
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
index fcd60f48bcc..bcdf65b217e 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval.stderr
@@ -2,316 +2,432 @@ error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:83:13
    |
 LL |     let _ = opt.unwrap_or_else(|| 2);
-   |             ^^^^--------------------
-   |                 |
-   |                 help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`
+help: use `unwrap_or` instead
+   |
+LL |     let _ = opt.unwrap_or(2);
+   |                 ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:84:13
    |
 LL |     let _ = opt.unwrap_or_else(|| astronomers_pi);
-   |             ^^^^---------------------------------
-   |                 |
-   |                 help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = opt.unwrap_or(astronomers_pi);
+   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:85:13
    |
 LL |     let _ = opt.unwrap_or_else(|| ext_str.some_field);
-   |             ^^^^-------------------------------------
-   |                 |
-   |                 help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = opt.unwrap_or(ext_str.some_field);
+   |                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:87:13
    |
 LL |     let _ = opt.and_then(|_| ext_opt);
-   |             ^^^^---------------------
-   |                 |
-   |                 help: use `and(..)` instead: `and(ext_opt)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _ = opt.and(ext_opt);
+   |                 ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:88:13
    |
 LL |     let _ = opt.or_else(|| ext_opt);
-   |             ^^^^-------------------
-   |                 |
-   |                 help: use `or(..)` instead: `or(ext_opt)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = opt.or(ext_opt);
+   |                 ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:89:13
    |
 LL |     let _ = opt.or_else(|| None);
-   |             ^^^^----------------
-   |                 |
-   |                 help: use `or(..)` instead: `or(None)`
+   |             ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = opt.or(None);
+   |                 ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:90:13
    |
 LL |     let _ = opt.get_or_insert_with(|| 2);
-   |             ^^^^------------------------
-   |                 |
-   |                 help: use `get_or_insert(..)` instead: `get_or_insert(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `get_or_insert` instead
+   |
+LL |     let _ = opt.get_or_insert(2);
+   |                 ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:91:13
    |
 LL |     let _ = opt.ok_or_else(|| 2);
-   |             ^^^^----------------
-   |                 |
-   |                 help: use `ok_or(..)` instead: `ok_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `ok_or` instead
+   |
+LL |     let _ = opt.ok_or(2);
+   |                 ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:92:13
    |
 LL |     let _ = nested_tuple_opt.unwrap_or_else(|| Some((1, 2)));
-   |             ^^^^^^^^^^^^^^^^^-------------------------------
-   |                              |
-   |                              help: use `unwrap_or(..)` instead: `unwrap_or(Some((1, 2)))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = nested_tuple_opt.unwrap_or(Some((1, 2)));
+   |                              ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:93:13
    |
 LL |     let _ = cond.then(|| astronomers_pi);
-   |             ^^^^^-----------------------
-   |                  |
-   |                  help: use `then_some(..)` instead: `then_some(astronomers_pi)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _ = cond.then_some(astronomers_pi);
+   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:94:13
    |
 LL |     let _ = true.then(|| -> _ {});
-   |             ^^^^^----------------
-   |                  |
-   |                  help: use `then_some(..)` instead: `then_some({})`
+   |             ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _ = true.then_some({});
+   |                  ~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:95:13
    |
 LL |     let _ = true.then(|| {});
-   |             ^^^^^-----------
-   |                  |
-   |                  help: use `then_some(..)` instead: `then_some({})`
+   |             ^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _ = true.then_some({});
+   |                  ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:99:13
    |
 LL |     let _ = Some(1).unwrap_or_else(|| *r);
-   |             ^^^^^^^^---------------------
-   |                     |
-   |                     help: use `unwrap_or(..)` instead: `unwrap_or(*r)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(1).unwrap_or(*r);
+   |                     ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:101:13
    |
 LL |     let _ = Some(1).unwrap_or_else(|| *b);
-   |             ^^^^^^^^---------------------
-   |                     |
-   |                     help: use `unwrap_or(..)` instead: `unwrap_or(*b)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(1).unwrap_or(*b);
+   |                     ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:103:13
    |
 LL |     let _ = Some(1).as_ref().unwrap_or_else(|| &r);
-   |             ^^^^^^^^^^^^^^^^^---------------------
-   |                              |
-   |                              help: use `unwrap_or(..)` instead: `unwrap_or(&r)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(1).as_ref().unwrap_or(&r);
+   |                              ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:104:13
    |
 LL |     let _ = Some(1).as_ref().unwrap_or_else(|| &b);
-   |             ^^^^^^^^^^^^^^^^^---------------------
-   |                              |
-   |                              help: use `unwrap_or(..)` instead: `unwrap_or(&b)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(1).as_ref().unwrap_or(&b);
+   |                              ~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:107:13
    |
 LL |     let _ = Some(10).unwrap_or_else(|| 2);
-   |             ^^^^^^^^^--------------------
-   |                      |
-   |                      help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Some(10).unwrap_or(2);
+   |                      ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:108:13
    |
 LL |     let _ = Some(10).and_then(|_| ext_opt);
-   |             ^^^^^^^^^---------------------
-   |                      |
-   |                      help: use `and(..)` instead: `and(ext_opt)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _ = Some(10).and(ext_opt);
+   |                      ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:109:28
    |
 LL |     let _: Option<usize> = None.or_else(|| ext_opt);
-   |                            ^^^^^-------------------
-   |                                 |
-   |                                 help: use `or(..)` instead: `or(ext_opt)`
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Option<usize> = None.or(ext_opt);
+   |                                 ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:110:13
    |
 LL |     let _ = None.get_or_insert_with(|| 2);
-   |             ^^^^^------------------------
-   |                  |
-   |                  help: use `get_or_insert(..)` instead: `get_or_insert(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `get_or_insert` instead
+   |
+LL |     let _ = None.get_or_insert(2);
+   |                  ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:111:35
    |
 LL |     let _: Result<usize, usize> = None.ok_or_else(|| 2);
-   |                                   ^^^^^----------------
-   |                                        |
-   |                                        help: use `ok_or(..)` instead: `ok_or(2)`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `ok_or` instead
+   |
+LL |     let _: Result<usize, usize> = None.ok_or(2);
+   |                                        ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:112:28
    |
 LL |     let _: Option<usize> = None.or_else(|| None);
-   |                            ^^^^^----------------
-   |                                 |
-   |                                 help: use `or(..)` instead: `or(None)`
+   |                            ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Option<usize> = None.or(None);
+   |                                 ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:115:13
    |
 LL |     let _ = deep.0.unwrap_or_else(|| 2);
-   |             ^^^^^^^--------------------
-   |                    |
-   |                    help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = deep.0.unwrap_or(2);
+   |                    ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:116:13
    |
 LL |     let _ = deep.0.and_then(|_| ext_opt);
-   |             ^^^^^^^---------------------
-   |                    |
-   |                    help: use `and(..)` instead: `and(ext_opt)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _ = deep.0.and(ext_opt);
+   |                    ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:117:13
    |
 LL |     let _ = deep.0.or_else(|| None);
-   |             ^^^^^^^----------------
-   |                    |
-   |                    help: use `or(..)` instead: `or(None)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = deep.0.or(None);
+   |                    ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:118:13
    |
 LL |     let _ = deep.0.get_or_insert_with(|| 2);
-   |             ^^^^^^^------------------------
-   |                    |
-   |                    help: use `get_or_insert(..)` instead: `get_or_insert(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `get_or_insert` instead
+   |
+LL |     let _ = deep.0.get_or_insert(2);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:119:13
    |
 LL |     let _ = deep.0.ok_or_else(|| 2);
-   |             ^^^^^^^----------------
-   |                    |
-   |                    help: use `ok_or(..)` instead: `ok_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `ok_or` instead
+   |
+LL |     let _ = deep.0.ok_or(2);
+   |                    ~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:150:28
    |
 LL |     let _: Option<usize> = None.or_else(|| Some(3));
-   |                            ^^^^^-------------------
-   |                                 |
-   |                                 help: use `or(..)` instead: `or(Some(3))`
+   |                            ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Option<usize> = None.or(Some(3));
+   |                                 ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:151:13
    |
 LL |     let _ = deep.0.or_else(|| Some(3));
-   |             ^^^^^^^-------------------
-   |                    |
-   |                    help: use `or(..)` instead: `or(Some(3))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = deep.0.or(Some(3));
+   |                    ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Option::None`
   --> tests/ui/unnecessary_lazy_eval.rs:152:13
    |
 LL |     let _ = opt.or_else(|| Some(3));
-   |             ^^^^-------------------
-   |                 |
-   |                 help: use `or(..)` instead: `or(Some(3))`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _ = opt.or(Some(3));
+   |                 ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:158:13
    |
 LL |     let _ = res2.unwrap_or_else(|_| 2);
-   |             ^^^^^---------------------
-   |                  |
-   |                  help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = res2.unwrap_or(2);
+   |                  ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:159:13
    |
 LL |     let _ = res2.unwrap_or_else(|_| astronomers_pi);
-   |             ^^^^^----------------------------------
-   |                  |
-   |                  help: use `unwrap_or(..)` instead: `unwrap_or(astronomers_pi)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = res2.unwrap_or(astronomers_pi);
+   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:160:13
    |
 LL |     let _ = res2.unwrap_or_else(|_| ext_str.some_field);
-   |             ^^^^^--------------------------------------
-   |                  |
-   |                  help: use `unwrap_or(..)` instead: `unwrap_or(ext_str.some_field)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = res2.unwrap_or(ext_str.some_field);
+   |                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:182:35
    |
 LL |     let _: Result<usize, usize> = res.and_then(|_| Err(2));
-   |                                   ^^^^--------------------
-   |                                       |
-   |                                       help: use `and(..)` instead: `and(Err(2))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _: Result<usize, usize> = res.and(Err(2));
+   |                                       ~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:183:35
    |
 LL |     let _: Result<usize, usize> = res.and_then(|_| Err(astronomers_pi));
-   |                                   ^^^^---------------------------------
-   |                                       |
-   |                                       help: use `and(..)` instead: `and(Err(astronomers_pi))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _: Result<usize, usize> = res.and(Err(astronomers_pi));
+   |                                       ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:184:35
    |
 LL |     let _: Result<usize, usize> = res.and_then(|_| Err(ext_str.some_field));
-   |                                   ^^^^-------------------------------------
-   |                                       |
-   |                                       help: use `and(..)` instead: `and(Err(ext_str.some_field))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `and` instead
+   |
+LL |     let _: Result<usize, usize> = res.and(Err(ext_str.some_field));
+   |                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:186:35
    |
 LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(2));
-   |                                   ^^^^------------------
-   |                                       |
-   |                                       help: use `or(..)` instead: `or(Ok(2))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Result<usize, usize> = res.or(Ok(2));
+   |                                       ~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:187:35
    |
 LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
-   |                                   ^^^^-------------------------------
-   |                                       |
-   |                                       help: use `or(..)` instead: `or(Ok(astronomers_pi))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Result<usize, usize> = res.or(Ok(astronomers_pi));
+   |                                       ~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:188:35
    |
 LL |     let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
-   |                                   ^^^^-----------------------------------
-   |                                       |
-   |                                       help: use `or(..)` instead: `or(Ok(ext_str.some_field))`
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `or` instead
+   |
+LL |     let _: Result<usize, usize> = res.or(Ok(ext_str.some_field));
+   |                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval.rs:189:35
@@ -324,193 +440,265 @@ LL | |     // some lines
 ...  |
 LL | |     // some lines
 LL | |     or_else(|_| Ok(ext_str.some_field));
-   | |_____----------------------------------^
-   |       |
-   |       help: use `or(..)` instead: `or(Ok(ext_str.some_field))`
+   | |_______________________________________^
+   |
+help: use `or` instead
+   |
+LL |     or(Ok(ext_str.some_field));
+   |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:219:14
    |
 LL |     let _x = false.then(|| i32::MAX + 1);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MAX + 1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MAX + 1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:221:14
    |
 LL |     let _x = false.then(|| i32::MAX * 2);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MAX * 2)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MAX * 2);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:223:14
    |
 LL |     let _x = false.then(|| i32::MAX - 1);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MAX - 1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MAX - 1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:225:14
    |
 LL |     let _x = false.then(|| i32::MIN - 1);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MIN - 1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MIN - 1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:227:14
    |
 LL |     let _x = false.then(|| (1 + 2 * 3 - 2 / 3 + 9) << 2);
-   |              ^^^^^^-------------------------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some((1 + 2 * 3 - 2 / 3 + 9) << 2)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some((1 + 2 * 3 - 2 / 3 + 9) << 2);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:229:14
    |
 LL |     let _x = false.then(|| 255u8 << 7);
-   |              ^^^^^^-------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255u8 << 7)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255u8 << 7);
+   |                    ~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:231:14
    |
 LL |     let _x = false.then(|| 255u8 << 8);
-   |              ^^^^^^-------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255u8 << 8)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255u8 << 8);
+   |                    ~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:233:14
    |
 LL |     let _x = false.then(|| 255u8 >> 8);
-   |              ^^^^^^-------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255u8 >> 8)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255u8 >> 8);
+   |                    ~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:236:14
    |
 LL |     let _x = false.then(|| i32::MAX + -1);
-   |              ^^^^^^----------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MAX + -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MAX + -1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:238:14
    |
 LL |     let _x = false.then(|| -i32::MAX);
-   |              ^^^^^^------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(-i32::MAX)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(-i32::MAX);
+   |                    ~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:240:14
    |
 LL |     let _x = false.then(|| -i32::MIN);
-   |              ^^^^^^------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(-i32::MIN)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(-i32::MIN);
+   |                    ~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:243:14
    |
 LL |     let _x = false.then(|| 255 >> -7);
-   |              ^^^^^^------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255 >> -7)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255 >> -7);
+   |                    ~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:245:14
    |
 LL |     let _x = false.then(|| 255 << -1);
-   |              ^^^^^^------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(255 << -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(255 << -1);
+   |                    ~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:247:14
    |
 LL |     let _x = false.then(|| 1 / 0);
-   |              ^^^^^^--------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(1 / 0)`
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(1 / 0);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:249:14
    |
 LL |     let _x = false.then(|| x << -1);
-   |              ^^^^^^----------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(x << -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(x << -1);
+   |                    ~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:251:14
    |
 LL |     let _x = false.then(|| x << 2);
-   |              ^^^^^^---------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(x << 2)`
+   |              ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(x << 2);
+   |                    ~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:261:14
    |
 LL |     let _x = false.then(|| x / 0);
-   |              ^^^^^^--------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(x / 0)`
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(x / 0);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:263:14
    |
 LL |     let _x = false.then(|| x % 0);
-   |              ^^^^^^--------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(x % 0)`
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(x % 0);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:266:14
    |
 LL |     let _x = false.then(|| 1 / -1);
-   |              ^^^^^^---------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(1 / -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(1 / -1);
+   |                    ~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:268:14
    |
 LL |     let _x = false.then(|| i32::MIN / -1);
-   |              ^^^^^^----------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MIN / -1)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MIN / -1);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:271:14
    |
 LL |     let _x = false.then(|| i32::MIN / 0);
-   |              ^^^^^^---------------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(i32::MIN / 0)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(i32::MIN / 0);
+   |                    ~~~~~~~~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:273:14
    |
 LL |     let _x = false.then(|| 4 / 2);
-   |              ^^^^^^--------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(4 / 2)`
+   |              ^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(4 / 2);
+   |                    ~~~~~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval.rs:281:14
    |
 LL |     let _x = false.then(|| f1 + f2);
-   |              ^^^^^^----------------
-   |                    |
-   |                    help: use `then_some(..)` instead: `then_some(f1 + f2)`
+   |              ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _x = false.then_some(f1 + f2);
+   |                    ~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 63 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
index b566b119571..390235b2124 100644
--- a/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
+++ b/src/tools/clippy/tests/ui/unnecessary_lazy_eval_unfixable.stderr
@@ -2,36 +2,47 @@ error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:13:13
    |
 LL |     let _ = Ok(1).unwrap_or_else(|()| 2);
-   |             ^^^^^^----------------------
-   |                   |
-   |                   help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::unnecessary-lazy-evaluations` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_lazy_evaluations)]`
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Ok(1).unwrap_or(2);
+   |                   ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:19:13
    |
 LL |     let _ = Ok(1).unwrap_or_else(|e::E| 2);
-   |             ^^^^^^------------------------
-   |                   |
-   |                   help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Ok(1).unwrap_or(2);
+   |                   ~~~~~~~~~~~~
 
 error: unnecessary closure used to substitute value for `Result::Err`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:21:13
    |
 LL |     let _ = Ok(1).unwrap_or_else(|SomeStruct { .. }| 2);
-   |             ^^^^^^-------------------------------------
-   |                   |
-   |                   help: use `unwrap_or(..)` instead: `unwrap_or(2)`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `unwrap_or` instead
+   |
+LL |     let _ = Ok(1).unwrap_or(2);
+   |                   ~~~~~~~~~~~~
 
 error: unnecessary closure used with `bool::then`
   --> tests/ui/unnecessary_lazy_eval_unfixable.rs:31:13
    |
 LL |     let _ = true.then(|| -> &[u8] { &[] });
-   |             ^^^^^-------------------------
-   |                  |
-   |                  help: use `then_some(..)` instead: `then_some({ &[] })`
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `then_some` instead
+   |
+LL |     let _ = true.then_some({ &[] });
+   |                  ~~~~~~~~~~~~~~~~~~
 
 error: aborting due to 4 previous errors