diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58ea0f9ab9d..7fdb300c977 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2695,6 +2695,7 @@ Released 2018-09-13
 [`enum_glob_use`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_glob_use
 [`enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names
 [`eq_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#eq_op
+[`equatable_if_let`]: https://rust-lang.github.io/rust-clippy/master/index.html#equatable_if_let
 [`erasing_op`]: https://rust-lang.github.io/rust-clippy/master/index.html#erasing_op
 [`eval_order_dependence`]: https://rust-lang.github.io/rust-clippy/master/index.html#eval_order_dependence
 [`excessive_precision`]: https://rust-lang.github.io/rust-clippy/master/index.html#excessive_precision
@@ -2898,6 +2899,7 @@ Released 2018-09-13
 [`no_effect`]: https://rust-lang.github.io/rust-clippy/master/index.html#no_effect
 [`non_ascii_literal`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_ascii_literal
 [`non_octal_unix_permissions`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_octal_unix_permissions
+[`non_send_fields_in_send_ty`]: https://rust-lang.github.io/rust-clippy/master/index.html#non_send_fields_in_send_ty
 [`nonminimal_bool`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonminimal_bool
 [`nonsensical_open_options`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonsensical_open_options
 [`nonstandard_macro_braces`]: https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
index e05db7af586..5538f62c8e7 100644
--- a/clippy_dev/src/lib.rs
+++ b/clippy_dev/src/lib.rs
@@ -3,14 +3,7 @@
 // warn on lints, that are included in `rust-lang/rust`s bootstrap
 #![warn(rust_2018_idioms, unused_lifetimes)]
 
-use itertools::Itertools;
-use regex::Regex;
-use std::collections::HashMap;
-use std::ffi::OsStr;
-use std::fs;
-use std::lazy::SyncLazy;
-use std::path::{Path, PathBuf};
-use walkdir::WalkDir;
+use std::path::PathBuf;
 
 pub mod bless;
 pub mod fmt;
@@ -19,323 +12,6 @@ pub mod serve;
 pub mod setup;
 pub mod update_lints;
 
-static DEC_CLIPPY_LINT_RE: SyncLazy<Regex> = SyncLazy::new(|| {
-    Regex::new(
-        r#"(?x)
-    declare_clippy_lint!\s*[\{(]
-    (?:\s+///.*)*
-    \s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
-    (?P<cat>[a-z_]+)\s*,\s*
-    "(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
-"#,
-    )
-    .unwrap()
-});
-
-static DEC_DEPRECATED_LINT_RE: SyncLazy<Regex> = SyncLazy::new(|| {
-    Regex::new(
-        r#"(?x)
-    declare_deprecated_lint!\s*[{(]\s*
-    (?:\s+///.*)*
-    \s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
-    "(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
-"#,
-    )
-    .unwrap()
-});
-static NL_ESCAPE_RE: SyncLazy<Regex> = SyncLazy::new(|| Regex::new(r#"\\\n\s*"#).unwrap());
-
-pub static DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.html";
-
-/// Lint data parsed from the Clippy source code.
-#[derive(Clone, PartialEq, Debug)]
-pub struct Lint {
-    pub name: String,
-    pub group: String,
-    pub desc: String,
-    pub deprecation: Option<String>,
-    pub module: String,
-}
-
-impl Lint {
-    #[must_use]
-    pub fn new(name: &str, group: &str, desc: &str, deprecation: Option<&str>, module: &str) -> Self {
-        Self {
-            name: name.to_lowercase(),
-            group: group.to_string(),
-            desc: NL_ESCAPE_RE.replace(&desc.replace("\\\"", "\""), "").to_string(),
-            deprecation: deprecation.map(ToString::to_string),
-            module: module.to_string(),
-        }
-    }
-
-    /// Returns all non-deprecated lints and non-internal lints
-    #[must_use]
-    pub fn usable_lints(lints: &[Self]) -> Vec<Self> {
-        lints
-            .iter()
-            .filter(|l| l.deprecation.is_none() && !l.group.starts_with("internal"))
-            .cloned()
-            .collect()
-    }
-
-    /// Returns all internal lints (not `internal_warn` lints)
-    #[must_use]
-    pub fn internal_lints(lints: &[Self]) -> Vec<Self> {
-        lints.iter().filter(|l| l.group == "internal").cloned().collect()
-    }
-
-    /// Returns all deprecated lints
-    #[must_use]
-    pub fn deprecated_lints(lints: &[Self]) -> Vec<Self> {
-        lints.iter().filter(|l| l.deprecation.is_some()).cloned().collect()
-    }
-
-    /// Returns the lints in a `HashMap`, grouped by the different lint groups
-    #[must_use]
-    pub fn by_lint_group(lints: impl Iterator<Item = Self>) -> HashMap<String, Vec<Self>> {
-        lints.map(|lint| (lint.group.to_string(), lint)).into_group_map()
-    }
-}
-
-/// Generates the Vec items for `register_lint_group` calls in `clippy_lints/src/lib.rs`.
-#[must_use]
-pub fn gen_lint_group_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
-    lints
-        .map(|l| format!("        LintId::of({}::{}),", l.module, l.name.to_uppercase()))
-        .sorted()
-        .collect::<Vec<String>>()
-}
-
-/// Generates the `pub mod module_name` list in `clippy_lints/src/lib.rs`.
-#[must_use]
-pub fn gen_modules_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
-    lints
-        .map(|l| &l.module)
-        .unique()
-        .map(|module| format!("mod {};", module))
-        .sorted()
-        .collect::<Vec<String>>()
-}
-
-/// Generates the list of lint links at the bottom of the README
-#[must_use]
-pub fn gen_changelog_lint_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
-    lints
-        .sorted_by_key(|l| &l.name)
-        .map(|l| format!("[`{}`]: {}#{}", l.name, DOCS_LINK, l.name))
-        .collect()
-}
-
-/// Generates the `register_removed` code in `./clippy_lints/src/lib.rs`.
-#[must_use]
-pub fn gen_deprecated<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
-    lints
-        .flat_map(|l| {
-            l.deprecation
-                .clone()
-                .map(|depr_text| {
-                    vec![
-                        "    store.register_removed(".to_string(),
-                        format!("        \"clippy::{}\",", l.name),
-                        format!("        \"{}\",", depr_text),
-                        "    );".to_string(),
-                    ]
-                })
-                .expect("only deprecated lints should be passed")
-        })
-        .collect::<Vec<String>>()
-}
-
-#[must_use]
-pub fn gen_register_lint_list<'a>(
-    internal_lints: impl Iterator<Item = &'a Lint>,
-    usable_lints: impl Iterator<Item = &'a Lint>,
-) -> Vec<String> {
-    let header = "    store.register_lints(&[".to_string();
-    let footer = "    ]);".to_string();
-    let internal_lints = internal_lints
-        .sorted_by_key(|l| format!("        {}::{},", l.module, l.name.to_uppercase()))
-        .map(|l| {
-            format!(
-                "        #[cfg(feature = \"internal-lints\")]\n        {}::{},",
-                l.module,
-                l.name.to_uppercase()
-            )
-        });
-    let other_lints = usable_lints
-        .sorted_by_key(|l| format!("        {}::{},", l.module, l.name.to_uppercase()))
-        .map(|l| format!("        {}::{},", l.module, l.name.to_uppercase()))
-        .sorted();
-    let mut lint_list = vec![header];
-    lint_list.extend(internal_lints);
-    lint_list.extend(other_lints);
-    lint_list.push(footer);
-    lint_list
-}
-
-/// Gathers all files in `src/clippy_lints` and gathers all lints inside
-pub fn gather_all() -> impl Iterator<Item = Lint> {
-    lint_files().flat_map(|f| gather_from_file(&f))
-}
-
-fn gather_from_file(dir_entry: &walkdir::DirEntry) -> impl Iterator<Item = Lint> {
-    let content = fs::read_to_string(dir_entry.path()).unwrap();
-    let path = dir_entry.path();
-    let filename = path.file_stem().unwrap();
-    let path_buf = path.with_file_name(filename);
-    let mut rel_path = path_buf
-        .strip_prefix(clippy_project_root().join("clippy_lints/src"))
-        .expect("only files in `clippy_lints/src` should be looked at");
-    // If the lints are stored in mod.rs, we get the module name from
-    // the containing directory:
-    if filename == "mod" {
-        rel_path = rel_path.parent().unwrap();
-    }
-
-    let module = rel_path
-        .components()
-        .map(|c| c.as_os_str().to_str().unwrap())
-        .collect::<Vec<_>>()
-        .join("::");
-
-    parse_contents(&content, &module)
-}
-
-fn parse_contents(content: &str, module: &str) -> impl Iterator<Item = Lint> {
-    let lints = DEC_CLIPPY_LINT_RE
-        .captures_iter(content)
-        .map(|m| Lint::new(&m["name"], &m["cat"], &m["desc"], None, module));
-    let deprecated = DEC_DEPRECATED_LINT_RE
-        .captures_iter(content)
-        .map(|m| Lint::new(&m["name"], "Deprecated", &m["desc"], Some(&m["desc"]), module));
-    // Removing the `.collect::<Vec<Lint>>().into_iter()` causes some lifetime issues due to the map
-    lints.chain(deprecated).collect::<Vec<Lint>>().into_iter()
-}
-
-/// Collects all .rs files in the `clippy_lints/src` directory
-fn lint_files() -> impl Iterator<Item = walkdir::DirEntry> {
-    // We use `WalkDir` instead of `fs::read_dir` here in order to recurse into subdirectories.
-    // Otherwise we would not collect all the lints, for example in `clippy_lints/src/methods/`.
-    let path = clippy_project_root().join("clippy_lints/src");
-    WalkDir::new(path)
-        .into_iter()
-        .filter_map(Result::ok)
-        .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
-}
-
-/// Whether a file has had its text changed or not
-#[derive(PartialEq, Debug)]
-pub struct FileChange {
-    pub changed: bool,
-    pub new_lines: String,
-}
-
-/// Replaces a region in a file delimited by two lines matching regexes.
-///
-/// `path` is the relative path to the file on which you want to perform the replacement.
-///
-/// See `replace_region_in_text` for documentation of the other options.
-///
-/// # Panics
-///
-/// Panics if the path could not read or then written
-pub fn replace_region_in_file<F>(
-    path: &Path,
-    start: &str,
-    end: &str,
-    replace_start: bool,
-    write_back: bool,
-    replacements: F,
-) -> FileChange
-where
-    F: FnOnce() -> Vec<String>,
-{
-    let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from {}: {}", path.display(), e));
-    let file_change = replace_region_in_text(&contents, start, end, replace_start, replacements);
-
-    if write_back {
-        if let Err(e) = fs::write(path, file_change.new_lines.as_bytes()) {
-            panic!("Cannot write to {}: {}", path.display(), e);
-        }
-    }
-    file_change
-}
-
-/// Replaces a region in a text delimited by two lines matching regexes.
-///
-/// * `text` is the input text on which you want to perform the replacement
-/// * `start` is a `&str` that describes the delimiter line before the region you want to replace.
-///   As the `&str` will be converted to a `Regex`, this can contain regex syntax, too.
-/// * `end` is a `&str` that describes the delimiter line until where the replacement should happen.
-///   As the `&str` will be converted to a `Regex`, this can contain regex syntax, too.
-/// * If `replace_start` is true, the `start` delimiter line is replaced as well. The `end`
-///   delimiter line is never replaced.
-/// * `replacements` is a closure that has to return a `Vec<String>` which contains the new text.
-///
-/// If you want to perform the replacement on files instead of already parsed text,
-/// use `replace_region_in_file`.
-///
-/// # Example
-///
-/// ```
-/// let the_text = "replace_start\nsome text\nthat will be replaced\nreplace_end";
-/// let result =
-///     clippy_dev::replace_region_in_text(the_text, "replace_start", "replace_end", false, || {
-///         vec!["a different".to_string(), "text".to_string()]
-///     })
-///     .new_lines;
-/// assert_eq!("replace_start\na different\ntext\nreplace_end", result);
-/// ```
-///
-/// # Panics
-///
-/// Panics if start or end is not valid regex
-pub fn replace_region_in_text<F>(text: &str, start: &str, end: &str, replace_start: bool, replacements: F) -> FileChange
-where
-    F: FnOnce() -> Vec<String>,
-{
-    let replace_it = replacements();
-    let mut in_old_region = false;
-    let mut found = false;
-    let mut new_lines = vec![];
-    let start = Regex::new(start).unwrap();
-    let end = Regex::new(end).unwrap();
-
-    for line in text.lines() {
-        if in_old_region {
-            if end.is_match(line) {
-                in_old_region = false;
-                new_lines.extend(replace_it.clone());
-                new_lines.push(line.to_string());
-            }
-        } else if start.is_match(line) {
-            if !replace_start {
-                new_lines.push(line.to_string());
-            }
-            in_old_region = true;
-            found = true;
-        } else {
-            new_lines.push(line.to_string());
-        }
-    }
-
-    if !found {
-        // This happens if the provided regex in `clippy_dev/src/main.rs` does not match in the
-        // given text or file. Most likely this is an error on the programmer's side and the Regex
-        // is incorrect.
-        eprintln!("error: regex \n{:?}\ndoesn't match. You may have to update it.", start);
-        std::process::exit(1);
-    }
-
-    let mut new_lines = new_lines.join("\n");
-    if text.ends_with('\n') {
-        new_lines.push('\n');
-    }
-    let changed = new_lines != text;
-    FileChange { changed, new_lines }
-}
-
 /// Returns the path to the Clippy project directory
 ///
 /// # Panics
@@ -360,200 +36,3 @@ pub fn clippy_project_root() -> PathBuf {
     }
     panic!("error: Can't determine root of project. Please run inside a Clippy working dir.");
 }
-
-#[test]
-fn test_parse_contents() {
-    let result: Vec<Lint> = parse_contents(
-        r#"
-declare_clippy_lint! {
-    pub PTR_ARG,
-    style,
-    "really long \
-     text"
-}
-
-declare_clippy_lint!{
-    pub DOC_MARKDOWN,
-    pedantic,
-    "single line"
-}
-
-/// some doc comment
-declare_deprecated_lint! {
-    pub SHOULD_ASSERT_EQ,
-    "`assert!()` will be more flexible with RFC 2011"
-}
-    "#,
-        "module_name",
-    )
-    .collect();
-
-    let expected = vec![
-        Lint::new("ptr_arg", "style", "really long text", None, "module_name"),
-        Lint::new("doc_markdown", "pedantic", "single line", None, "module_name"),
-        Lint::new(
-            "should_assert_eq",
-            "Deprecated",
-            "`assert!()` will be more flexible with RFC 2011",
-            Some("`assert!()` will be more flexible with RFC 2011"),
-            "module_name",
-        ),
-    ];
-    assert_eq!(expected, result);
-}
-
-#[test]
-fn test_replace_region() {
-    let text = "\nabc\n123\n789\ndef\nghi";
-    let expected = FileChange {
-        changed: true,
-        new_lines: "\nabc\nhello world\ndef\nghi".to_string(),
-    };
-    let result = replace_region_in_text(text, r#"^\s*abc$"#, r#"^\s*def"#, false, || {
-        vec!["hello world".to_string()]
-    });
-    assert_eq!(expected, result);
-}
-
-#[test]
-fn test_replace_region_with_start() {
-    let text = "\nabc\n123\n789\ndef\nghi";
-    let expected = FileChange {
-        changed: true,
-        new_lines: "\nhello world\ndef\nghi".to_string(),
-    };
-    let result = replace_region_in_text(text, r#"^\s*abc$"#, r#"^\s*def"#, true, || {
-        vec!["hello world".to_string()]
-    });
-    assert_eq!(expected, result);
-}
-
-#[test]
-fn test_replace_region_no_changes() {
-    let text = "123\n456\n789";
-    let expected = FileChange {
-        changed: false,
-        new_lines: "123\n456\n789".to_string(),
-    };
-    let result = replace_region_in_text(text, r#"^\s*123$"#, r#"^\s*456"#, false, Vec::new);
-    assert_eq!(expected, result);
-}
-
-#[test]
-fn test_usable_lints() {
-    let lints = vec![
-        Lint::new("should_assert_eq", "Deprecated", "abc", Some("Reason"), "module_name"),
-        Lint::new("should_assert_eq2", "Not Deprecated", "abc", None, "module_name"),
-        Lint::new("should_assert_eq2", "internal", "abc", None, "module_name"),
-        Lint::new("should_assert_eq2", "internal_style", "abc", None, "module_name"),
-    ];
-    let expected = vec![Lint::new(
-        "should_assert_eq2",
-        "Not Deprecated",
-        "abc",
-        None,
-        "module_name",
-    )];
-    assert_eq!(expected, Lint::usable_lints(&lints));
-}
-
-#[test]
-fn test_by_lint_group() {
-    let lints = vec![
-        Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-        Lint::new("should_assert_eq2", "group2", "abc", None, "module_name"),
-        Lint::new("incorrect_match", "group1", "abc", None, "module_name"),
-    ];
-    let mut expected: HashMap<String, Vec<Lint>> = HashMap::new();
-    expected.insert(
-        "group1".to_string(),
-        vec![
-            Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-            Lint::new("incorrect_match", "group1", "abc", None, "module_name"),
-        ],
-    );
-    expected.insert(
-        "group2".to_string(),
-        vec![Lint::new("should_assert_eq2", "group2", "abc", None, "module_name")],
-    );
-    assert_eq!(expected, Lint::by_lint_group(lints.into_iter()));
-}
-
-#[test]
-fn test_gen_changelog_lint_list() {
-    let lints = vec![
-        Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-        Lint::new("should_assert_eq2", "group2", "abc", None, "module_name"),
-    ];
-    let expected = vec![
-        format!("[`should_assert_eq`]: {}#should_assert_eq", DOCS_LINK.to_string()),
-        format!("[`should_assert_eq2`]: {}#should_assert_eq2", DOCS_LINK.to_string()),
-    ];
-    assert_eq!(expected, gen_changelog_lint_list(lints.iter()));
-}
-
-#[test]
-fn test_gen_deprecated() {
-    let lints = vec![
-        Lint::new(
-            "should_assert_eq",
-            "group1",
-            "abc",
-            Some("has been superseded by should_assert_eq2"),
-            "module_name",
-        ),
-        Lint::new(
-            "another_deprecated",
-            "group2",
-            "abc",
-            Some("will be removed"),
-            "module_name",
-        ),
-    ];
-    let expected: Vec<String> = vec![
-        "    store.register_removed(",
-        "        \"clippy::should_assert_eq\",",
-        "        \"has been superseded by should_assert_eq2\",",
-        "    );",
-        "    store.register_removed(",
-        "        \"clippy::another_deprecated\",",
-        "        \"will be removed\",",
-        "    );",
-    ]
-    .into_iter()
-    .map(String::from)
-    .collect();
-    assert_eq!(expected, gen_deprecated(lints.iter()));
-}
-
-#[test]
-#[should_panic]
-fn test_gen_deprecated_fail() {
-    let lints = vec![Lint::new("should_assert_eq2", "group2", "abc", None, "module_name")];
-    let _deprecated_lints = gen_deprecated(lints.iter());
-}
-
-#[test]
-fn test_gen_modules_list() {
-    let lints = vec![
-        Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-        Lint::new("incorrect_stuff", "group3", "abc", None, "another_module"),
-    ];
-    let expected = vec!["mod another_module;".to_string(), "mod module_name;".to_string()];
-    assert_eq!(expected, gen_modules_list(lints.iter()));
-}
-
-#[test]
-fn test_gen_lint_group_list() {
-    let lints = vec![
-        Lint::new("abc", "group1", "abc", None, "module_name"),
-        Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
-        Lint::new("internal", "internal_style", "abc", None, "module_name"),
-    ];
-    let expected = vec![
-        "        LintId::of(module_name::ABC),".to_string(),
-        "        LintId::of(module_name::INTERNAL),".to_string(),
-        "        LintId::of(module_name::SHOULD_ASSERT_EQ),".to_string(),
-    ];
-    assert_eq!(expected, gen_lint_group_list(lints.iter()));
-}
diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs
index db467c26f15..10d859988f6 100644
--- a/clippy_dev/src/update_lints.rs
+++ b/clippy_dev/src/update_lints.rs
@@ -1,8 +1,45 @@
-use crate::{
-    gather_all, gen_changelog_lint_list, gen_deprecated, gen_lint_group_list, gen_modules_list, gen_register_lint_list,
-    replace_region_in_file, Lint, DOCS_LINK,
-};
+use itertools::Itertools;
+use regex::Regex;
+use std::collections::HashMap;
+use std::ffi::OsStr;
+use std::fs;
+use std::lazy::SyncLazy;
 use std::path::Path;
+use walkdir::WalkDir;
+
+use crate::clippy_project_root;
+
+const GENERATED_FILE_COMMENT: &str = "// This file was generated by `cargo dev update_lints`.\n\
+     // Use that command to update this file and do not edit by hand.\n\
+     // Manual edits will be overwritten.\n\n";
+
+static DEC_CLIPPY_LINT_RE: SyncLazy<Regex> = SyncLazy::new(|| {
+    Regex::new(
+        r#"(?x)
+    declare_clippy_lint!\s*[\{(]
+    (?:\s+///.*)*
+    \s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
+    (?P<cat>[a-z_]+)\s*,\s*
+    "(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
+"#,
+    )
+    .unwrap()
+});
+
+static DEC_DEPRECATED_LINT_RE: SyncLazy<Regex> = SyncLazy::new(|| {
+    Regex::new(
+        r#"(?x)
+    declare_deprecated_lint!\s*[{(]\s*
+    (?:\s+///.*)*
+    \s+pub\s+(?P<name>[A-Z_][A-Z_0-9]*)\s*,\s*
+    "(?P<desc>(?:[^"\\]+|\\(?s).(?-s))*)"\s*[})]
+"#,
+    )
+    .unwrap()
+});
+static NL_ESCAPE_RE: SyncLazy<Regex> = SyncLazy::new(|| Regex::new(r#"\\\n\s*"#).unwrap());
+
+static DOCS_LINK: &str = "https://rust-lang.github.io/rust-clippy/master/index.html";
 
 #[derive(Clone, Copy, PartialEq)]
 pub enum UpdateMode {
@@ -10,6 +47,15 @@ pub enum UpdateMode {
     Change,
 }
 
+/// Runs the `update_lints` command.
+///
+/// This updates various generated values from the lint source code.
+///
+/// `update_mode` indicates if the files should be updated or if updates should be checked for.
+///
+/// # Panics
+///
+/// Panics if a file path could not read from or then written to
 #[allow(clippy::too_many_lines)]
 pub fn run(update_mode: UpdateMode) {
     let lint_list: Vec<Lint> = gather_all().collect();
@@ -52,26 +98,7 @@ pub fn run(update_mode: UpdateMode) {
     )
     .changed;
 
-    file_change |= replace_region_in_file(
-        Path::new("clippy_lints/src/lib.rs"),
-        "begin deprecated lints",
-        "end deprecated lints",
-        false,
-        update_mode == UpdateMode::Change,
-        || gen_deprecated(deprecated_lints.iter()),
-    )
-    .changed;
-
-    file_change |= replace_region_in_file(
-        Path::new("clippy_lints/src/lib.rs"),
-        "begin register lints",
-        "end register lints",
-        false,
-        update_mode == UpdateMode::Change,
-        || gen_register_lint_list(internal_lints.iter(), usable_lints.iter()),
-    )
-    .changed;
-
+    // This has to be in lib.rs, otherwise rustfmt doesn't work
     file_change |= replace_region_in_file(
         Path::new("clippy_lints/src/lib.rs"),
         "begin lints modules",
@@ -82,46 +109,37 @@ pub fn run(update_mode: UpdateMode) {
     )
     .changed;
 
-    // Generate lists of lints in the clippy::all lint group
-    file_change |= replace_region_in_file(
-        Path::new("clippy_lints/src/lib.rs"),
-        r#"store.register_group\(true, "clippy::all""#,
-        r#"\]\);"#,
-        false,
-        update_mode == UpdateMode::Change,
-        || {
-            // clippy::all should only include the following lint groups:
-            let all_group_lints = usable_lints.iter().filter(|l| {
-                matches!(
-                    &*l.group,
-                    "correctness" | "suspicious" | "style" | "complexity" | "perf"
-                )
-            });
-
-            gen_lint_group_list(all_group_lints)
-        },
-    )
-    .changed;
-
-    // Generate the list of lints for all other lint groups
-    for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
-        file_change |= replace_region_in_file(
-            Path::new("clippy_lints/src/lib.rs"),
-            &format!("store.register_group\\(true, \"clippy::{}\"", lint_group),
-            r#"\]\);"#,
-            false,
-            update_mode == UpdateMode::Change,
-            || gen_lint_group_list(lints.iter()),
-        )
-        .changed;
+    if file_change && update_mode == UpdateMode::Check {
+        exit_with_failure();
     }
 
-    if update_mode == UpdateMode::Check && file_change {
-        println!(
-            "Not all lints defined properly. \
-             Please run `cargo dev update_lints` to make sure all lints are defined properly."
+    process_file(
+        "clippy_lints/src/lib.register_lints.rs",
+        update_mode,
+        &gen_register_lint_list(internal_lints.iter(), usable_lints.iter()),
+    );
+    process_file(
+        "clippy_lints/src/lib.deprecated.rs",
+        update_mode,
+        &gen_deprecated(deprecated_lints.iter()),
+    );
+
+    let all_group_lints = usable_lints.iter().filter(|l| {
+        matches!(
+            &*l.group,
+            "correctness" | "suspicious" | "style" | "complexity" | "perf"
+        )
+    });
+    let content = gen_lint_group_list("all", all_group_lints);
+    process_file("clippy_lints/src/lib.register_all.rs", update_mode, &content);
+
+    for (lint_group, lints) in Lint::by_lint_group(usable_lints.into_iter().chain(internal_lints)) {
+        let content = gen_lint_group_list(&lint_group, lints.iter());
+        process_file(
+            &format!("clippy_lints/src/lib.register_{}.rs", lint_group),
+            update_mode,
+            &content,
         );
-        std::process::exit(1);
     }
 }
 
@@ -150,3 +168,538 @@ pub fn print_lints() {
 fn round_to_fifty(count: usize) -> usize {
     count / 50 * 50
 }
+
+fn process_file(path: impl AsRef<Path>, update_mode: UpdateMode, content: &str) {
+    if update_mode == UpdateMode::Check {
+        let old_content =
+            fs::read_to_string(&path).unwrap_or_else(|e| panic!("Cannot read from {}: {}", path.as_ref().display(), e));
+        if content != old_content {
+            exit_with_failure();
+        }
+    } else {
+        fs::write(&path, content.as_bytes())
+            .unwrap_or_else(|e| panic!("Cannot write to {}: {}", path.as_ref().display(), e));
+    }
+}
+
+fn exit_with_failure() {
+    println!(
+        "Not all lints defined properly. \
+                 Please run `cargo dev update_lints` to make sure all lints are defined properly."
+    );
+    std::process::exit(1);
+}
+
+/// Lint data parsed from the Clippy source code.
+#[derive(Clone, PartialEq, Debug)]
+struct Lint {
+    name: String,
+    group: String,
+    desc: String,
+    deprecation: Option<String>,
+    module: String,
+}
+
+impl Lint {
+    #[must_use]
+    fn new(name: &str, group: &str, desc: &str, deprecation: Option<&str>, module: &str) -> Self {
+        Self {
+            name: name.to_lowercase(),
+            group: group.to_string(),
+            desc: NL_ESCAPE_RE.replace(&desc.replace("\\\"", "\""), "").to_string(),
+            deprecation: deprecation.map(ToString::to_string),
+            module: module.to_string(),
+        }
+    }
+
+    /// Returns all non-deprecated lints and non-internal lints
+    #[must_use]
+    fn usable_lints(lints: &[Self]) -> Vec<Self> {
+        lints
+            .iter()
+            .filter(|l| l.deprecation.is_none() && !l.group.starts_with("internal"))
+            .cloned()
+            .collect()
+    }
+
+    /// Returns all internal lints (not `internal_warn` lints)
+    #[must_use]
+    fn internal_lints(lints: &[Self]) -> Vec<Self> {
+        lints.iter().filter(|l| l.group == "internal").cloned().collect()
+    }
+
+    /// Returns all deprecated lints
+    #[must_use]
+    fn deprecated_lints(lints: &[Self]) -> Vec<Self> {
+        lints.iter().filter(|l| l.deprecation.is_some()).cloned().collect()
+    }
+
+    /// Returns the lints in a `HashMap`, grouped by the different lint groups
+    #[must_use]
+    fn by_lint_group(lints: impl Iterator<Item = Self>) -> HashMap<String, Vec<Self>> {
+        lints.map(|lint| (lint.group.to_string(), lint)).into_group_map()
+    }
+}
+
+/// Generates the code for registering a group
+fn gen_lint_group_list<'a>(group_name: &str, lints: impl Iterator<Item = &'a Lint>) -> String {
+    let mut details: Vec<_> = lints.map(|l| (&l.module, l.name.to_uppercase())).collect();
+    details.sort_unstable();
+
+    let mut output = GENERATED_FILE_COMMENT.to_string();
+
+    output.push_str(&format!(
+        "store.register_group(true, \"clippy::{0}\", Some(\"clippy_{0}\"), vec![\n",
+        group_name
+    ));
+    for (module, name) in details {
+        output.push_str(&format!("    LintId::of({}::{}),\n", module, name));
+    }
+    output.push_str("])\n");
+
+    output
+}
+
+/// Generates the module declarations for `lints`
+#[must_use]
+fn gen_modules_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
+    lints
+        .map(|l| &l.module)
+        .unique()
+        .map(|module| format!("mod {};", module))
+        .sorted()
+        .collect::<Vec<String>>()
+}
+
+/// Generates the list of lint links at the bottom of the CHANGELOG
+#[must_use]
+fn gen_changelog_lint_list<'a>(lints: impl Iterator<Item = &'a Lint>) -> Vec<String> {
+    lints
+        .sorted_by_key(|l| &l.name)
+        .map(|l| format!("[`{}`]: {}#{}", l.name, DOCS_LINK, l.name))
+        .collect()
+}
+
+/// Generates the `register_removed` code
+#[must_use]
+fn gen_deprecated<'a>(lints: impl Iterator<Item = &'a Lint>) -> String {
+    let mut output = GENERATED_FILE_COMMENT.to_string();
+    output.push_str("{\n");
+    for Lint { name, deprecation, .. } in lints {
+        output.push_str(&format!(
+            concat!(
+                "    store.register_removed(\n",
+                "        \"clippy::{}\",\n",
+                "        \"{}\",\n",
+                "    );\n"
+            ),
+            name,
+            deprecation.as_ref().expect("`lints` are deprecated")
+        ));
+    }
+    output.push_str("}\n");
+
+    output
+}
+
+/// Generates the code for registering lints
+#[must_use]
+fn gen_register_lint_list<'a>(
+    internal_lints: impl Iterator<Item = &'a Lint>,
+    usable_lints: impl Iterator<Item = &'a Lint>,
+) -> String {
+    let mut details: Vec<_> = internal_lints
+        .map(|l| (false, &l.module, l.name.to_uppercase()))
+        .chain(usable_lints.map(|l| (true, &l.module, l.name.to_uppercase())))
+        .collect();
+    details.sort_unstable();
+
+    let mut output = GENERATED_FILE_COMMENT.to_string();
+    output.push_str("store.register_lints(&[\n");
+
+    for (is_public, module_name, lint_name) in details {
+        if !is_public {
+            output.push_str("    #[cfg(feature = \"internal-lints\")]\n");
+        }
+        output.push_str(&format!("    {}::{},\n", module_name, lint_name));
+    }
+    output.push_str("])\n");
+
+    output
+}
+
+/// Gathers all files in `src/clippy_lints` and gathers all lints inside
+fn gather_all() -> impl Iterator<Item = Lint> {
+    lint_files().flat_map(|f| gather_from_file(&f))
+}
+
+fn gather_from_file(dir_entry: &walkdir::DirEntry) -> impl Iterator<Item = Lint> {
+    let content = fs::read_to_string(dir_entry.path()).unwrap();
+    let path = dir_entry.path();
+    let filename = path.file_stem().unwrap();
+    let path_buf = path.with_file_name(filename);
+    let mut rel_path = path_buf
+        .strip_prefix(clippy_project_root().join("clippy_lints/src"))
+        .expect("only files in `clippy_lints/src` should be looked at");
+    // If the lints are stored in mod.rs, we get the module name from
+    // the containing directory:
+    if filename == "mod" {
+        rel_path = rel_path.parent().unwrap();
+    }
+
+    let module = rel_path
+        .components()
+        .map(|c| c.as_os_str().to_str().unwrap())
+        .collect::<Vec<_>>()
+        .join("::");
+
+    parse_contents(&content, &module)
+}
+
+fn parse_contents(content: &str, module: &str) -> impl Iterator<Item = Lint> {
+    let lints = DEC_CLIPPY_LINT_RE
+        .captures_iter(content)
+        .map(|m| Lint::new(&m["name"], &m["cat"], &m["desc"], None, module));
+    let deprecated = DEC_DEPRECATED_LINT_RE
+        .captures_iter(content)
+        .map(|m| Lint::new(&m["name"], "Deprecated", &m["desc"], Some(&m["desc"]), module));
+    // Removing the `.collect::<Vec<Lint>>().into_iter()` causes some lifetime issues due to the map
+    lints.chain(deprecated).collect::<Vec<Lint>>().into_iter()
+}
+
+/// Collects all .rs files in the `clippy_lints/src` directory
+fn lint_files() -> impl Iterator<Item = walkdir::DirEntry> {
+    // We use `WalkDir` instead of `fs::read_dir` here in order to recurse into subdirectories.
+    // Otherwise we would not collect all the lints, for example in `clippy_lints/src/methods/`.
+    let path = clippy_project_root().join("clippy_lints/src");
+    WalkDir::new(path)
+        .into_iter()
+        .filter_map(Result::ok)
+        .filter(|f| f.path().extension() == Some(OsStr::new("rs")))
+}
+
+/// Whether a file has had its text changed or not
+#[derive(PartialEq, Debug)]
+struct FileChange {
+    changed: bool,
+    new_lines: String,
+}
+
+/// Replaces a region in a file delimited by two lines matching regexes.
+///
+/// `path` is the relative path to the file on which you want to perform the replacement.
+///
+/// See `replace_region_in_text` for documentation of the other options.
+///
+/// # Panics
+///
+/// Panics if the path could not read or then written
+fn replace_region_in_file<F>(
+    path: &Path,
+    start: &str,
+    end: &str,
+    replace_start: bool,
+    write_back: bool,
+    replacements: F,
+) -> FileChange
+where
+    F: FnOnce() -> Vec<String>,
+{
+    let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("Cannot read from {}: {}", path.display(), e));
+    let file_change = replace_region_in_text(&contents, start, end, replace_start, replacements);
+
+    if write_back {
+        if let Err(e) = fs::write(path, file_change.new_lines.as_bytes()) {
+            panic!("Cannot write to {}: {}", path.display(), e);
+        }
+    }
+    file_change
+}
+
+/// Replaces a region in a text delimited by two lines matching regexes.
+///
+/// * `text` is the input text on which you want to perform the replacement
+/// * `start` is a `&str` that describes the delimiter line before the region you want to replace.
+///   As the `&str` will be converted to a `Regex`, this can contain regex syntax, too.
+/// * `end` is a `&str` that describes the delimiter line until where the replacement should happen.
+///   As the `&str` will be converted to a `Regex`, this can contain regex syntax, too.
+/// * If `replace_start` is true, the `start` delimiter line is replaced as well. The `end`
+///   delimiter line is never replaced.
+/// * `replacements` is a closure that has to return a `Vec<String>` which contains the new text.
+///
+/// If you want to perform the replacement on files instead of already parsed text,
+/// use `replace_region_in_file`.
+///
+/// # Example
+///
+/// ```ignore
+/// let the_text = "replace_start\nsome text\nthat will be replaced\nreplace_end";
+/// let result =
+///     replace_region_in_text(the_text, "replace_start", "replace_end", false, || {
+///         vec!["a different".to_string(), "text".to_string()]
+///     })
+///     .new_lines;
+/// assert_eq!("replace_start\na different\ntext\nreplace_end", result);
+/// ```
+///
+/// # Panics
+///
+/// Panics if start or end is not valid regex
+fn replace_region_in_text<F>(text: &str, start: &str, end: &str, replace_start: bool, replacements: F) -> FileChange
+where
+    F: FnOnce() -> Vec<String>,
+{
+    let replace_it = replacements();
+    let mut in_old_region = false;
+    let mut found = false;
+    let mut new_lines = vec![];
+    let start = Regex::new(start).unwrap();
+    let end = Regex::new(end).unwrap();
+
+    for line in text.lines() {
+        if in_old_region {
+            if end.is_match(line) {
+                in_old_region = false;
+                new_lines.extend(replace_it.clone());
+                new_lines.push(line.to_string());
+            }
+        } else if start.is_match(line) {
+            if !replace_start {
+                new_lines.push(line.to_string());
+            }
+            in_old_region = true;
+            found = true;
+        } else {
+            new_lines.push(line.to_string());
+        }
+    }
+
+    if !found {
+        // This happens if the provided regex in `clippy_dev/src/main.rs` does not match in the
+        // given text or file. Most likely this is an error on the programmer's side and the Regex
+        // is incorrect.
+        eprintln!("error: regex \n{:?}\ndoesn't match. You may have to update it.", start);
+        std::process::exit(1);
+    }
+
+    let mut new_lines = new_lines.join("\n");
+    if text.ends_with('\n') {
+        new_lines.push('\n');
+    }
+    let changed = new_lines != text;
+    FileChange { changed, new_lines }
+}
+
+#[test]
+fn test_parse_contents() {
+    let result: Vec<Lint> = parse_contents(
+        r#"
+declare_clippy_lint! {
+    pub PTR_ARG,
+    style,
+    "really long \
+     text"
+}
+
+declare_clippy_lint!{
+    pub DOC_MARKDOWN,
+    pedantic,
+    "single line"
+}
+
+/// some doc comment
+declare_deprecated_lint! {
+    pub SHOULD_ASSERT_EQ,
+    "`assert!()` will be more flexible with RFC 2011"
+}
+    "#,
+        "module_name",
+    )
+    .collect();
+
+    let expected = vec![
+        Lint::new("ptr_arg", "style", "really long text", None, "module_name"),
+        Lint::new("doc_markdown", "pedantic", "single line", None, "module_name"),
+        Lint::new(
+            "should_assert_eq",
+            "Deprecated",
+            "`assert!()` will be more flexible with RFC 2011",
+            Some("`assert!()` will be more flexible with RFC 2011"),
+            "module_name",
+        ),
+    ];
+    assert_eq!(expected, result);
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn test_replace_region() {
+        let text = "\nabc\n123\n789\ndef\nghi";
+        let expected = FileChange {
+            changed: true,
+            new_lines: "\nabc\nhello world\ndef\nghi".to_string(),
+        };
+        let result = replace_region_in_text(text, r#"^\s*abc$"#, r#"^\s*def"#, false, || {
+            vec!["hello world".to_string()]
+        });
+        assert_eq!(expected, result);
+    }
+
+    #[test]
+    fn test_replace_region_with_start() {
+        let text = "\nabc\n123\n789\ndef\nghi";
+        let expected = FileChange {
+            changed: true,
+            new_lines: "\nhello world\ndef\nghi".to_string(),
+        };
+        let result = replace_region_in_text(text, r#"^\s*abc$"#, r#"^\s*def"#, true, || {
+            vec!["hello world".to_string()]
+        });
+        assert_eq!(expected, result);
+    }
+
+    #[test]
+    fn test_replace_region_no_changes() {
+        let text = "123\n456\n789";
+        let expected = FileChange {
+            changed: false,
+            new_lines: "123\n456\n789".to_string(),
+        };
+        let result = replace_region_in_text(text, r#"^\s*123$"#, r#"^\s*456"#, false, Vec::new);
+        assert_eq!(expected, result);
+    }
+
+    #[test]
+    fn test_usable_lints() {
+        let lints = vec![
+            Lint::new("should_assert_eq", "Deprecated", "abc", Some("Reason"), "module_name"),
+            Lint::new("should_assert_eq2", "Not Deprecated", "abc", None, "module_name"),
+            Lint::new("should_assert_eq2", "internal", "abc", None, "module_name"),
+            Lint::new("should_assert_eq2", "internal_style", "abc", None, "module_name"),
+        ];
+        let expected = vec![Lint::new(
+            "should_assert_eq2",
+            "Not Deprecated",
+            "abc",
+            None,
+            "module_name",
+        )];
+        assert_eq!(expected, Lint::usable_lints(&lints));
+    }
+
+    #[test]
+    fn test_by_lint_group() {
+        let lints = vec![
+            Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
+            Lint::new("should_assert_eq2", "group2", "abc", None, "module_name"),
+            Lint::new("incorrect_match", "group1", "abc", None, "module_name"),
+        ];
+        let mut expected: HashMap<String, Vec<Lint>> = HashMap::new();
+        expected.insert(
+            "group1".to_string(),
+            vec![
+                Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
+                Lint::new("incorrect_match", "group1", "abc", None, "module_name"),
+            ],
+        );
+        expected.insert(
+            "group2".to_string(),
+            vec![Lint::new("should_assert_eq2", "group2", "abc", None, "module_name")],
+        );
+        assert_eq!(expected, Lint::by_lint_group(lints.into_iter()));
+    }
+
+    #[test]
+    fn test_gen_changelog_lint_list() {
+        let lints = vec![
+            Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
+            Lint::new("should_assert_eq2", "group2", "abc", None, "module_name"),
+        ];
+        let expected = vec![
+            format!("[`should_assert_eq`]: {}#should_assert_eq", DOCS_LINK.to_string()),
+            format!("[`should_assert_eq2`]: {}#should_assert_eq2", DOCS_LINK.to_string()),
+        ];
+        assert_eq!(expected, gen_changelog_lint_list(lints.iter()));
+    }
+
+    #[test]
+    fn test_gen_deprecated() {
+        let lints = vec![
+            Lint::new(
+                "should_assert_eq",
+                "group1",
+                "abc",
+                Some("has been superseded by should_assert_eq2"),
+                "module_name",
+            ),
+            Lint::new(
+                "another_deprecated",
+                "group2",
+                "abc",
+                Some("will be removed"),
+                "module_name",
+            ),
+        ];
+
+        let expected = GENERATED_FILE_COMMENT.to_string()
+            + &[
+                "{",
+                "    store.register_removed(",
+                "        \"clippy::should_assert_eq\",",
+                "        \"has been superseded by should_assert_eq2\",",
+                "    );",
+                "    store.register_removed(",
+                "        \"clippy::another_deprecated\",",
+                "        \"will be removed\",",
+                "    );",
+                "}",
+            ]
+            .join("\n")
+            + "\n";
+
+        assert_eq!(expected, gen_deprecated(lints.iter()));
+    }
+
+    #[test]
+    #[should_panic]
+    fn test_gen_deprecated_fail() {
+        let lints = vec![Lint::new("should_assert_eq2", "group2", "abc", None, "module_name")];
+        let _deprecated_lints = gen_deprecated(lints.iter());
+    }
+
+    #[test]
+    fn test_gen_modules_list() {
+        let lints = vec![
+            Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
+            Lint::new("incorrect_stuff", "group3", "abc", None, "another_module"),
+        ];
+        let expected = vec!["mod another_module;".to_string(), "mod module_name;".to_string()];
+        assert_eq!(expected, gen_modules_list(lints.iter()));
+    }
+
+    #[test]
+    fn test_gen_lint_group_list() {
+        let lints = vec![
+            Lint::new("abc", "group1", "abc", None, "module_name"),
+            Lint::new("should_assert_eq", "group1", "abc", None, "module_name"),
+            Lint::new("internal", "internal_style", "abc", None, "module_name"),
+        ];
+        let expected = GENERATED_FILE_COMMENT.to_string()
+            + &[
+                "store.register_group(true, \"clippy::group1\", Some(\"clippy_group1\"), vec![",
+                "    LintId::of(module_name::ABC),",
+                "    LintId::of(module_name::INTERNAL),",
+                "    LintId::of(module_name::SHOULD_ASSERT_EQ),",
+                "])",
+            ]
+            .join("\n")
+            + "\n";
+
+        let result = gen_lint_group_list("group1", lints.iter());
+
+        assert_eq!(expected, result);
+    }
+}
diff --git a/clippy_lints/src/attrs.rs b/clippy_lints/src/attrs.rs
index 2ef7dcc1775..6f8b645dd70 100644
--- a/clippy_lints/src/attrs.rs
+++ b/clippy_lints/src/attrs.rs
@@ -563,7 +563,7 @@ fn check_deprecated_cfg_attr(cx: &EarlyContext<'_>, attr: &Attribute) {
             skip_item.path.segments.last().expect("empty path in attribute").ident.name == sym::skip;
         // Only lint outer attributes, because custom inner attributes are unstable
         // Tracking issue: https://github.com/rust-lang/rust/issues/54726
-        if let AttrStyle::Outer = attr.style;
+        if attr.style == AttrStyle::Outer;
         then {
             span_lint_and_sugg(
                 cx,
diff --git a/clippy_lints/src/await_holding_invalid.rs b/clippy_lints/src/await_holding_invalid.rs
index 0cc79c8b6e8..28615b9217c 100644
--- a/clippy_lints/src/await_holding_invalid.rs
+++ b/clippy_lints/src/await_holding_invalid.rs
@@ -16,7 +16,7 @@ declare_clippy_lint! {
     /// The Mutex types found in std::sync and parking_lot
     /// are not designed to operate in an async context across await points.
     ///
-    /// There are two potential solutions. One is to use an asynx-aware Mutex
+    /// There are two potential solutions. One is to use an async-aware Mutex
     /// type. Many asynchronous foundation crates provide such a Mutex type. The
     /// other solution is to ensure the mutex is unlocked before calling await,
     /// either by introducing a scope or an explicit call to Drop::drop.
diff --git a/clippy_lints/src/casts/cast_precision_loss.rs b/clippy_lints/src/casts/cast_precision_loss.rs
index 63ac8fd2dd2..334e1646cd4 100644
--- a/clippy_lints/src/casts/cast_precision_loss.rs
+++ b/clippy_lints/src/casts/cast_precision_loss.rs
@@ -12,7 +12,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, ca
     }
 
     let from_nbits = utils::int_ty_to_nbits(cast_from, cx.tcx);
-    let to_nbits = if let ty::Float(FloatTy::F32) = cast_to.kind() {
+    let to_nbits = if cast_to.kind() == &ty::Float(FloatTy::F32) {
         32
     } else {
         64
diff --git a/clippy_lints/src/derivable_impls.rs b/clippy_lints/src/derivable_impls.rs
index 15252ef96cd..fdef0abe970 100644
--- a/clippy_lints/src/derivable_impls.rs
+++ b/clippy_lints/src/derivable_impls.rs
@@ -83,6 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls {
             if !attrs.iter().any(|attr| attr.doc_str().is_some());
             if let child_attrs = cx.tcx.hir().attrs(impl_item_hir);
             if !child_attrs.iter().any(|attr| attr.doc_str().is_some());
+            if adt_def.is_struct();
             then {
                 if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind {
                     if let Some(PathSegment { args: Some(a), .. }) = p.segments.last() {
diff --git a/clippy_lints/src/derive.rs b/clippy_lints/src/derive.rs
index 8416b8440df..24ac5917dcb 100644
--- a/clippy_lints/src/derive.rs
+++ b/clippy_lints/src/derive.rs
@@ -393,7 +393,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
 
         if_chain! {
             if let Some(header) = kind.header();
-            if let Unsafety::Unsafe = header.unsafety;
+            if header.unsafety == Unsafety::Unsafe;
             then {
                 self.has_unsafe = true;
             }
@@ -408,7 +408,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> {
         }
 
         if let ExprKind::Block(block, _) = expr.kind {
-            if let BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) = block.rules {
+            if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) {
                 self.has_unsafe = true;
             }
         }
diff --git a/clippy_lints/src/doc.rs b/clippy_lints/src/doc.rs
index 33ed6273ad2..9840affbf6f 100644
--- a/clippy_lints/src/doc.rs
+++ b/clippy_lints/src/doc.rs
@@ -236,7 +236,17 @@ impl<'tcx> LateLintPass<'tcx> for DocMarkdown {
             hir::ItemKind::Impl(ref impl_) => {
                 self.in_trait_impl = impl_.of_trait.is_some();
             },
-            _ => {},
+            hir::ItemKind::Trait(_, unsafety, ..) => {
+                if !headers.safety && unsafety == hir::Unsafety::Unsafe {
+                    span_lint(
+                        cx,
+                        MISSING_SAFETY_DOC,
+                        item.span,
+                        "docs for unsafe trait missing `# Safety` section",
+                    );
+                }
+            },
+            _ => (),
         }
     }
 
@@ -396,6 +406,15 @@ struct DocHeaders {
 }
 
 fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &'a [Attribute]) -> DocHeaders {
+    use pulldown_cmark::{BrokenLink, CowStr, Options};
+    /// We don't want the parser to choke on intra doc links. Since we don't
+    /// actually care about rendering them, just pretend that all broken links are
+    /// point to a fake address.
+    #[allow(clippy::unnecessary_wraps)] // we're following a type signature
+    fn fake_broken_link_callback<'a>(_: BrokenLink<'_>) -> Option<(CowStr<'a>, CowStr<'a>)> {
+        Some(("fake".into(), "fake".into()))
+    }
+
     let mut doc = String::new();
     let mut spans = vec![];
 
@@ -430,7 +449,10 @@ fn check_attrs<'a>(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs
         };
     }
 
-    let parser = pulldown_cmark::Parser::new(&doc).into_offset_iter();
+    let mut cb = fake_broken_link_callback;
+
+    let parser =
+        pulldown_cmark::Parser::new_with_broken_link_callback(&doc, Options::empty(), Some(&mut cb)).into_offset_iter();
     // Iterate over all `Events` and combine consecutive events into one
     let events = parser.coalesce(|previous, current| {
         use pulldown_cmark::Event::Text;
diff --git a/clippy_lints/src/equatable_if_let.rs b/clippy_lints/src/equatable_if_let.rs
new file mode 100644
index 00000000000..0c6ba91c943
--- /dev/null
+++ b/clippy_lints/src/equatable_if_let.rs
@@ -0,0 +1,100 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::implements_trait;
+use if_chain::if_chain;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind, Pat, PatKind};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::Ty;
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for pattern matchings that can be expressed using equality.
+    ///
+    /// ### Why is this bad?
+    ///
+    /// * It reads better and has less cognitive load because equality won't cause binding.
+    /// * It is a [Yoda condition](https://en.wikipedia.org/wiki/Yoda_conditions). Yoda conditions are widely
+    /// criticized for increasing the cognitive load of reading the code.
+    /// * Equality is a simple bool expression and can be merged with `&&` and `||` and
+    /// reuse if blocks
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// if let Some(2) = x {
+    ///     do_thing();
+    /// }
+    /// ```
+    /// Should be written
+    /// ```rust,ignore
+    /// if x == Some(2) {
+    ///     do_thing();
+    /// }
+    /// ```
+    pub EQUATABLE_IF_LET,
+    nursery,
+    "using pattern matching instead of equality"
+}
+
+declare_lint_pass!(PatternEquality => [EQUATABLE_IF_LET]);
+
+/// detects if pattern matches just one thing
+fn unary_pattern(pat: &Pat<'_>) -> bool {
+    fn array_rec(pats: &[Pat<'_>]) -> bool {
+        pats.iter().all(unary_pattern)
+    }
+    match &pat.kind {
+        PatKind::Slice(_, _, _) | PatKind::Range(_, _, _) | PatKind::Binding(..) | PatKind::Wild | PatKind::Or(_) => {
+            false
+        },
+        PatKind::Struct(_, a, etc) => !etc && a.iter().all(|x| unary_pattern(x.pat)),
+        PatKind::Tuple(a, etc) | PatKind::TupleStruct(_, a, etc) => !etc.is_some() && array_rec(a),
+        PatKind::Ref(x, _) | PatKind::Box(x) => unary_pattern(x),
+        PatKind::Path(_) | PatKind::Lit(_) => true,
+    }
+}
+
+fn is_structural_partial_eq(cx: &LateContext<'tcx>, ty: Ty<'tcx>, other: Ty<'tcx>) -> bool {
+    if let Some(def_id) = cx.tcx.lang_items().eq_trait() {
+        implements_trait(cx, ty, def_id, &[other.into()])
+    } else {
+        false
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for PatternEquality {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
+        if_chain! {
+            if let ExprKind::Let(pat, exp, _) = expr.kind;
+            if unary_pattern(pat);
+            let exp_ty = cx.typeck_results().expr_ty(exp);
+            let pat_ty = cx.typeck_results().pat_ty(pat);
+            if is_structural_partial_eq(cx, exp_ty, pat_ty);
+            then {
+
+                let mut applicability = Applicability::MachineApplicable;
+                let pat_str = match pat.kind {
+                    PatKind::Struct(..) => format!(
+                        "({})",
+                        snippet_with_applicability(cx, pat.span, "..", &mut applicability),
+                    ),
+                    _ => snippet_with_applicability(cx, pat.span, "..", &mut applicability).to_string(),
+                };
+                span_lint_and_sugg(
+                    cx,
+                    EQUATABLE_IF_LET,
+                    expr.span,
+                    "this pattern matching can be expressed using equality",
+                    "try",
+                    format!(
+                        "{} == {}",
+                        snippet_with_applicability(cx, exp.span, "..", &mut applicability),
+                        pat_str,
+                    ),
+                    applicability,
+                );
+            }
+        }
+    }
+}
diff --git a/clippy_lints/src/erasing_op.rs b/clippy_lints/src/erasing_op.rs
index 026d14d0ea2..d0944c37cf5 100644
--- a/clippy_lints/src/erasing_op.rs
+++ b/clippy_lints/src/erasing_op.rs
@@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for ErasingOp {
 }
 
 fn check(cx: &LateContext<'_>, e: &Expr<'_>, span: Span) {
-    if let Some(Constant::Int(0)) = constant_simple(cx, cx.typeck_results(), e) {
+    if constant_simple(cx, cx.typeck_results(), e) == Some(Constant::Int(0)) {
         span_lint(
             cx,
             ERASING_OP,
diff --git a/clippy_lints/src/escape.rs b/clippy_lints/src/escape.rs
index 090be73af3b..75b1c882c23 100644
--- a/clippy_lints/src/escape.rs
+++ b/clippy_lints/src/escape.rs
@@ -90,7 +90,7 @@ impl<'tcx> LateLintPass<'tcx> for BoxedLocal {
                 for trait_item in items {
                     if trait_item.id.hir_id() == hir_id {
                         // be sure we have `self` parameter in this function
-                        if let AssocItemKind::Fn { has_self: true } = trait_item.kind {
+                        if trait_item.kind == (AssocItemKind::Fn { has_self: true }) {
                             trait_self_ty = Some(
                                 TraitRef::identity(cx.tcx, trait_item.id.def_id.to_def_id())
                                     .self_ty()
diff --git a/clippy_lints/src/eta_reduction.rs b/clippy_lints/src/eta_reduction.rs
index 9df92cc5b64..765a6c7585a 100644
--- a/clippy_lints/src/eta_reduction.rs
+++ b/clippy_lints/src/eta_reduction.rs
@@ -116,7 +116,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
                     if let Some(mut snippet) = snippet_opt(cx, callee.span) {
                         if_chain! {
                             if let ty::Closure(_, substs) = callee_ty.peel_refs().kind();
-                            if let ClosureKind::FnMut = substs.as_closure().kind();
+                            if substs.as_closure().kind() == ClosureKind::FnMut;
                             if get_enclosing_loop_or_closure(cx.tcx, expr).is_some()
                                 || UsedAfterExprVisitor::is_found(cx, callee);
 
diff --git a/clippy_lints/src/eval_order_dependence.rs b/clippy_lints/src/eval_order_dependence.rs
index 8714ce90164..1b56dd4b081 100644
--- a/clippy_lints/src/eval_order_dependence.rs
+++ b/clippy_lints/src/eval_order_dependence.rs
@@ -141,7 +141,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DivergenceVisitor<'a, 'tcx> {
                 match typ.kind() {
                     ty::FnDef(..) | ty::FnPtr(_) => {
                         let sig = typ.fn_sig(self.cx.tcx);
-                        if let ty::Never = self.cx.tcx.erase_late_bound_regions(sig).output().kind() {
+                        if self.cx.tcx.erase_late_bound_regions(sig).output().kind() == &ty::Never {
                             self.report_diverging_sub_expr(e);
                         }
                     },
diff --git a/clippy_lints/src/format.rs b/clippy_lints/src/format.rs
index 129a8475e1c..8df7f91ce59 100644
--- a/clippy_lints/src/format.rs
+++ b/clippy_lints/src/format.rs
@@ -112,7 +112,7 @@ fn is_display_arg(expr: &Expr<'_>) -> bool {
         if let ExprKind::Call(_, [_, fmt]) = expr.kind;
         if let ExprKind::Path(QPath::Resolved(_, path)) = fmt.kind;
         if let [.., t, _] = path.segments;
-        if t.ident.name.as_str() == "Display";
+        if t.ident.name == sym::Display;
         then { true } else { false }
     }
 }
diff --git a/clippy_lints/src/identity_op.rs b/clippy_lints/src/identity_op.rs
index 5feb0ce8dec..73bdd67ff5d 100644
--- a/clippy_lints/src/identity_op.rs
+++ b/clippy_lints/src/identity_op.rs
@@ -1,5 +1,4 @@
 use clippy_utils::source::snippet;
-use if_chain::if_chain;
 use rustc_hir::{BinOp, BinOpKind, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
@@ -62,16 +61,9 @@ impl<'tcx> LateLintPass<'tcx> for IdentityOp {
 
 fn is_allowed(cx: &LateContext<'_>, cmp: BinOp, left: &Expr<'_>, right: &Expr<'_>) -> bool {
     // `1 << 0` is a common pattern in bit manipulation code
-    if_chain! {
-        if let BinOpKind::Shl = cmp.node;
-        if let Some(Constant::Int(0)) = constant_simple(cx, cx.typeck_results(), right);
-        if let Some(Constant::Int(1)) = constant_simple(cx, cx.typeck_results(), left);
-        then {
-            return true;
-        }
-    }
-
-    false
+    cmp.node == BinOpKind::Shl
+        && constant_simple(cx, cx.typeck_results(), right) == Some(Constant::Int(0))
+        && constant_simple(cx, cx.typeck_results(), left) == Some(Constant::Int(1))
 }
 
 #[allow(clippy::cast_possible_wrap)]
diff --git a/clippy_lints/src/if_then_panic.rs b/clippy_lints/src/if_then_panic.rs
index ee575c81a8b..10bca59e6d0 100644
--- a/clippy_lints/src/if_then_panic.rs
+++ b/clippy_lints/src/if_then_panic.rs
@@ -1,7 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::higher::PanicExpn;
-use clippy_utils::is_expn_of;
 use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::{is_expn_of, sugg};
 use rustc_errors::Applicability;
 use rustc_hir::{Block, Expr, ExprKind, StmtKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
@@ -74,12 +74,14 @@ impl LateLintPass<'_> for IfThenPanic {
                 };
                 let mut applicability = Applicability::MachineApplicable;
                 let sugg = snippet_with_applicability(cx, span, "..", &mut applicability);
-
-                let cond_sugg =
-                if let ExprKind::DropTemps(Expr{kind: ExprKind::Unary(UnOp::Not, not_expr), ..}) = cond.kind {
-                    snippet_with_applicability(cx, not_expr.span, "..", &mut applicability).to_string()
+                let cond_sugg = if let ExprKind::DropTemps(e, ..) = cond.kind {
+                    if let Expr{kind: ExprKind::Unary(UnOp::Not, not_expr), ..} = e {
+                         sugg::Sugg::hir_with_applicability(cx, not_expr, "..", &mut applicability).maybe_par().to_string()
+                    } else {
+                       format!("!{}", sugg::Sugg::hir_with_applicability(cx, e, "..", &mut applicability).maybe_par().to_string())
+                    }
                 } else {
-                    format!("!{}", snippet_with_applicability(cx, cond.span, "..", &mut applicability))
+                   format!("!{}", sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par().to_string())
                 };
 
                 span_lint_and_sugg(
diff --git a/clippy_lints/src/implicit_hasher.rs b/clippy_lints/src/implicit_hasher.rs
index 9da06d1418e..81eb51e6f7c 100644
--- a/clippy_lints/src/implicit_hasher.rs
+++ b/clippy_lints/src/implicit_hasher.rs
@@ -167,12 +167,20 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
                             continue;
                         }
                         let generics_suggestion_span = generics.span.substitute_dummy({
-                            let pos = snippet_opt(cx, item.span.until(body.params[0].pat.span))
-                                .and_then(|snip| {
-                                    let i = snip.find("fn")?;
-                                    Some(item.span.lo() + BytePos((i + (&snip[i..]).find('(')?) as u32))
-                                })
-                                .expect("failed to create span for type parameters");
+                            let pos = snippet_opt(
+                                cx,
+                                Span::new(
+                                    item.span.lo(),
+                                    body.params[0].pat.span.lo(),
+                                    item.span.ctxt(),
+                                    item.span.parent(),
+                                ),
+                            )
+                            .and_then(|snip| {
+                                let i = snip.find("fn")?;
+                                Some(item.span.lo() + BytePos((i + (&snip[i..]).find('(')?) as u32))
+                            })
+                            .expect("failed to create span for type parameters");
                             Span::new(pos, pos, item.span.ctxt(), item.span.parent())
                         });
 
diff --git a/clippy_lints/src/integer_division.rs b/clippy_lints/src/integer_division.rs
index a0e6f12b812..c962e814fa5 100644
--- a/clippy_lints/src/integer_division.rs
+++ b/clippy_lints/src/integer_division.rs
@@ -48,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for IntegerDivision {
 fn is_integer_division<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) -> bool {
     if_chain! {
         if let hir::ExprKind::Binary(binop, left, right) = &expr.kind;
-        if let hir::BinOpKind::Div = &binop.node;
+        if binop.node == hir::BinOpKind::Div;
         then {
             let (left_ty, right_ty) = (cx.typeck_results().expr_ty(left), cx.typeck_results().expr_ty(right));
             return left_ty.is_integral() && right_ty.is_integral();
diff --git a/clippy_lints/src/large_enum_variant.rs b/clippy_lints/src/large_enum_variant.rs
index e4b8e754628..392166237be 100644
--- a/clippy_lints/src/large_enum_variant.rs
+++ b/clippy_lints/src/large_enum_variant.rs
@@ -1,13 +1,14 @@
 //! lint when there is a large size difference between variants on an enum
 
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::source::snippet_opt;
+use clippy_utils::source::snippet_with_applicability;
 use rustc_errors::Applicability;
-use rustc_hir::{Item, ItemKind, VariantData};
+use rustc_hir::{Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::source_map::Span;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -58,6 +59,17 @@ impl LargeEnumVariant {
     }
 }
 
+struct FieldInfo {
+    ind: usize,
+    size: u64,
+}
+
+struct VariantInfo {
+    ind: usize,
+    size: u64,
+    fields_size: Vec<FieldInfo>,
+}
+
 impl_lint_pass!(LargeEnumVariant => [LARGE_ENUM_VARIANT]);
 
 impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
@@ -68,72 +80,95 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant {
         if let ItemKind::Enum(ref def, _) = item.kind {
             let ty = cx.tcx.type_of(item.def_id);
             let adt = ty.ty_adt_def().expect("already checked whether this is an enum");
-
-            let mut largest_variant: Option<(_, _)> = None;
-            let mut second_variant: Option<(_, _)> = None;
-
-            for (i, variant) in adt.variants.iter().enumerate() {
-                let size: u64 = variant
-                    .fields
-                    .iter()
-                    .filter_map(|f| {
-                        let ty = cx.tcx.type_of(f.did);
-                        // don't count generics by filtering out everything
-                        // that does not have a layout
-                        cx.layout_of(ty).ok().map(|l| l.size.bytes())
-                    })
-                    .sum();
-
-                let grouped = (size, (i, variant));
-
-                if grouped.0 >= largest_variant.map_or(0, |x| x.0) {
-                    second_variant = largest_variant;
-                    largest_variant = Some(grouped);
-                }
+            if adt.variants.len() <= 1 {
+                return;
             }
+            let mut variants_size: Vec<VariantInfo> = adt
+                .variants
+                .iter()
+                .enumerate()
+                .map(|(i, variant)| {
+                    let mut fields_size = Vec::new();
+                    let size: u64 = variant
+                        .fields
+                        .iter()
+                        .enumerate()
+                        .filter_map(|(i, f)| {
+                            let ty = cx.tcx.type_of(f.did);
+                            // don't count generics by filtering out everything
+                            // that does not have a layout
+                            cx.layout_of(ty).ok().map(|l| {
+                                let size = l.size.bytes();
+                                fields_size.push(FieldInfo { ind: i, size });
+                                size
+                            })
+                        })
+                        .sum();
+                    VariantInfo {
+                        ind: i,
+                        size,
+                        fields_size,
+                    }
+                })
+                .collect();
 
-            if let (Some(largest), Some(second)) = (largest_variant, second_variant) {
-                let difference = largest.0 - second.0;
+            variants_size.sort_by(|a, b| (b.size.cmp(&a.size)));
 
-                if difference > self.maximum_size_difference_allowed {
-                    let (i, variant) = largest.1;
+            let mut difference = variants_size[0].size - variants_size[1].size;
+            if difference > self.maximum_size_difference_allowed {
+                let help_text = "consider boxing the large fields to reduce the total size of the enum";
+                span_lint_and_then(
+                    cx,
+                    LARGE_ENUM_VARIANT,
+                    def.variants[variants_size[0].ind].span,
+                    "large size difference between variants",
+                    |diag| {
+                        diag.span_label(
+                            def.variants[variants_size[0].ind].span,
+                            &format!("this variant is {} bytes", variants_size[0].size),
+                        );
+                        diag.span_note(
+                            def.variants[variants_size[1].ind].span,
+                            &format!("and the second-largest variant is {} bytes:", variants_size[1].size),
+                        );
 
-                    let help_text = "consider boxing the large fields to reduce the total size of the enum";
-                    span_lint_and_then(
-                        cx,
-                        LARGE_ENUM_VARIANT,
-                        def.variants[i].span,
-                        "large size difference between variants",
-                        |diag| {
-                            diag.span_label(
-                                def.variants[(largest.1).0].span,
-                                &format!("this variant is {} bytes", largest.0),
-                            );
-                            diag.span_note(
-                                def.variants[(second.1).0].span,
-                                &format!("and the second-largest variant is {} bytes:", second.0),
-                            );
-                            if variant.fields.len() == 1 {
-                                let span = match def.variants[i].data {
-                                    VariantData::Struct(fields, ..) | VariantData::Tuple(fields, ..) => {
-                                        fields[0].ty.span
-                                    },
-                                    VariantData::Unit(..) => unreachable!(),
-                                };
-                                if let Some(snip) = snippet_opt(cx, span) {
-                                    diag.span_suggestion(
-                                        span,
-                                        help_text,
-                                        format!("Box<{}>", snip),
-                                        Applicability::MaybeIncorrect,
-                                    );
-                                    return;
+                        let fields = def.variants[variants_size[0].ind].data.fields();
+                        variants_size[0].fields_size.sort_by(|a, b| (a.size.cmp(&b.size)));
+                        let mut applicability = Applicability::MaybeIncorrect;
+                        let sugg: Vec<(Span, String)> = variants_size[0]
+                            .fields_size
+                            .iter()
+                            .rev()
+                            .map_while(|val| {
+                                if difference > self.maximum_size_difference_allowed {
+                                    difference = difference.saturating_sub(val.size);
+                                    Some((
+                                        fields[val.ind].ty.span,
+                                        format!(
+                                            "Box<{}>",
+                                            snippet_with_applicability(
+                                                cx,
+                                                fields[val.ind].ty.span,
+                                                "..",
+                                                &mut applicability
+                                            )
+                                            .into_owned()
+                                        ),
+                                    ))
+                                } else {
+                                    None
                                 }
-                            }
-                            diag.span_help(def.variants[i].span, help_text);
-                        },
-                    );
-                }
+                            })
+                            .collect();
+
+                        if !sugg.is_empty() {
+                            diag.multipart_suggestion(help_text, sugg, Applicability::MaybeIncorrect);
+                            return;
+                        }
+
+                        diag.span_help(def.variants[variants_size[0].ind].span, help_text);
+                    },
+                );
             }
         }
     }
diff --git a/clippy_lints/src/len_zero.rs b/clippy_lints/src/len_zero.rs
index de46e50a68a..f336fb9d42f 100644
--- a/clippy_lints/src/len_zero.rs
+++ b/clippy_lints/src/len_zero.rs
@@ -455,14 +455,10 @@ fn is_empty_array(expr: &Expr<'_>) -> bool {
 fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     /// Gets an `AssocItem` and return true if it matches `is_empty(self)`.
     fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool {
-        if let ty::AssocKind::Fn = item.kind {
-            if item.ident.name.as_str() == "is_empty" {
-                let sig = cx.tcx.fn_sig(item.def_id);
-                let ty = sig.skip_binder();
-                ty.inputs().len() == 1
-            } else {
-                false
-            }
+        if item.kind == ty::AssocKind::Fn && item.ident.name.as_str() == "is_empty" {
+            let sig = cx.tcx.fn_sig(item.def_id);
+            let ty = sig.skip_binder();
+            ty.inputs().len() == 1
         } else {
             false
         }
diff --git a/clippy_lints/src/lib.deprecated.rs b/clippy_lints/src/lib.deprecated.rs
new file mode 100644
index 00000000000..80bde1b1138
--- /dev/null
+++ b/clippy_lints/src/lib.deprecated.rs
@@ -0,0 +1,70 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+{
+    store.register_removed(
+        "clippy::should_assert_eq",
+        "`assert!()` will be more flexible with RFC 2011",
+    );
+    store.register_removed(
+        "clippy::extend_from_slice",
+        "`.extend_from_slice(_)` is a faster way to extend a Vec by a slice",
+    );
+    store.register_removed(
+        "clippy::range_step_by_zero",
+        "`iterator.step_by(0)` panics nowadays",
+    );
+    store.register_removed(
+        "clippy::unstable_as_slice",
+        "`Vec::as_slice` has been stabilized in 1.7",
+    );
+    store.register_removed(
+        "clippy::unstable_as_mut_slice",
+        "`Vec::as_mut_slice` has been stabilized in 1.7",
+    );
+    store.register_removed(
+        "clippy::misaligned_transmute",
+        "this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr",
+    );
+    store.register_removed(
+        "clippy::assign_ops",
+        "using compound assignment operators (e.g., `+=`) is harmless",
+    );
+    store.register_removed(
+        "clippy::if_let_redundant_pattern_matching",
+        "this lint has been changed to redundant_pattern_matching",
+    );
+    store.register_removed(
+        "clippy::unsafe_vector_initialization",
+        "the replacement suggested by this lint had substantially different behavior",
+    );
+    store.register_removed(
+        "clippy::unused_collect",
+        "`collect` has been marked as #[must_use] in rustc and that covers all cases of this lint",
+    );
+    store.register_removed(
+        "clippy::replace_consts",
+        "associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants",
+    );
+    store.register_removed(
+        "clippy::regex_macro",
+        "the regex! macro has been removed from the regex crate in 2018",
+    );
+    store.register_removed(
+        "clippy::find_map",
+        "this lint has been replaced by `manual_find_map`, a more specific lint",
+    );
+    store.register_removed(
+        "clippy::filter_map",
+        "this lint has been replaced by `manual_filter_map`, a more specific lint",
+    );
+    store.register_removed(
+        "clippy::pub_enum_variant_names",
+        "set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items",
+    );
+    store.register_removed(
+        "clippy::wrong_pub_self_convention",
+        "set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items",
+    );
+}
diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs
new file mode 100644
index 00000000000..3e6e0244754
--- /dev/null
+++ b/clippy_lints/src/lib.register_all.rs
@@ -0,0 +1,304 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::all", Some("clippy_all"), vec![
+    LintId::of(absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS),
+    LintId::of(approx_const::APPROX_CONSTANT),
+    LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
+    LintId::of(assign_ops::ASSIGN_OP_PATTERN),
+    LintId::of(assign_ops::MISREFACTORED_ASSIGN_OP),
+    LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
+    LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
+    LintId::of(attrs::DEPRECATED_CFG_ATTR),
+    LintId::of(attrs::DEPRECATED_SEMVER),
+    LintId::of(attrs::MISMATCHED_TARGET_OS),
+    LintId::of(attrs::USELESS_ATTRIBUTE),
+    LintId::of(bit_mask::BAD_BIT_MASK),
+    LintId::of(bit_mask::INEFFECTIVE_BIT_MASK),
+    LintId::of(blacklisted_name::BLACKLISTED_NAME),
+    LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
+    LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
+    LintId::of(booleans::LOGIC_BUG),
+    LintId::of(booleans::NONMINIMAL_BOOL),
+    LintId::of(casts::CAST_REF_TO_MUT),
+    LintId::of(casts::CHAR_LIT_AS_U8),
+    LintId::of(casts::FN_TO_NUMERIC_CAST),
+    LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
+    LintId::of(casts::UNNECESSARY_CAST),
+    LintId::of(collapsible_if::COLLAPSIBLE_ELSE_IF),
+    LintId::of(collapsible_if::COLLAPSIBLE_IF),
+    LintId::of(collapsible_match::COLLAPSIBLE_MATCH),
+    LintId::of(comparison_chain::COMPARISON_CHAIN),
+    LintId::of(copies::IFS_SAME_COND),
+    LintId::of(copies::IF_SAME_THEN_ELSE),
+    LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
+    LintId::of(derivable_impls::DERIVABLE_IMPLS),
+    LintId::of(derive::DERIVE_HASH_XOR_EQ),
+    LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
+    LintId::of(doc::MISSING_SAFETY_DOC),
+    LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
+    LintId::of(double_comparison::DOUBLE_COMPARISONS),
+    LintId::of(double_parens::DOUBLE_PARENS),
+    LintId::of(drop_forget_ref::DROP_COPY),
+    LintId::of(drop_forget_ref::DROP_REF),
+    LintId::of(drop_forget_ref::FORGET_COPY),
+    LintId::of(drop_forget_ref::FORGET_REF),
+    LintId::of(duration_subsec::DURATION_SUBSEC),
+    LintId::of(entry::MAP_ENTRY),
+    LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
+    LintId::of(enum_variants::ENUM_VARIANT_NAMES),
+    LintId::of(enum_variants::MODULE_INCEPTION),
+    LintId::of(eq_op::EQ_OP),
+    LintId::of(eq_op::OP_REF),
+    LintId::of(erasing_op::ERASING_OP),
+    LintId::of(escape::BOXED_LOCAL),
+    LintId::of(eta_reduction::REDUNDANT_CLOSURE),
+    LintId::of(eval_order_dependence::DIVERGING_SUB_EXPRESSION),
+    LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
+    LintId::of(explicit_write::EXPLICIT_WRITE),
+    LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
+    LintId::of(float_literal::EXCESSIVE_PRECISION),
+    LintId::of(format::USELESS_FORMAT),
+    LintId::of(formatting::POSSIBLE_MISSING_COMMA),
+    LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
+    LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
+    LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
+    LintId::of(from_over_into::FROM_OVER_INTO),
+    LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
+    LintId::of(functions::DOUBLE_MUST_USE),
+    LintId::of(functions::MUST_USE_UNIT),
+    LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
+    LintId::of(functions::RESULT_UNIT_ERR),
+    LintId::of(functions::TOO_MANY_ARGUMENTS),
+    LintId::of(get_last_with_len::GET_LAST_WITH_LEN),
+    LintId::of(identity_op::IDENTITY_OP),
+    LintId::of(if_let_mutex::IF_LET_MUTEX),
+    LintId::of(if_then_panic::IF_THEN_PANIC),
+    LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
+    LintId::of(infinite_iter::INFINITE_ITER),
+    LintId::of(inherent_to_string::INHERENT_TO_STRING),
+    LintId::of(inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
+    LintId::of(inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
+    LintId::of(int_plus_one::INT_PLUS_ONE),
+    LintId::of(large_const_arrays::LARGE_CONST_ARRAYS),
+    LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
+    LintId::of(len_zero::COMPARISON_TO_EMPTY),
+    LintId::of(len_zero::LEN_WITHOUT_IS_EMPTY),
+    LintId::of(len_zero::LEN_ZERO),
+    LintId::of(let_underscore::LET_UNDERSCORE_LOCK),
+    LintId::of(lifetimes::EXTRA_UNUSED_LIFETIMES),
+    LintId::of(lifetimes::NEEDLESS_LIFETIMES),
+    LintId::of(literal_representation::INCONSISTENT_DIGIT_GROUPING),
+    LintId::of(literal_representation::MISTYPED_LITERAL_SUFFIXES),
+    LintId::of(literal_representation::UNUSUAL_BYTE_GROUPINGS),
+    LintId::of(loops::EMPTY_LOOP),
+    LintId::of(loops::EXPLICIT_COUNTER_LOOP),
+    LintId::of(loops::FOR_KV_MAP),
+    LintId::of(loops::FOR_LOOPS_OVER_FALLIBLES),
+    LintId::of(loops::ITER_NEXT_LOOP),
+    LintId::of(loops::MANUAL_FLATTEN),
+    LintId::of(loops::MANUAL_MEMCPY),
+    LintId::of(loops::MUT_RANGE_BOUND),
+    LintId::of(loops::NEEDLESS_COLLECT),
+    LintId::of(loops::NEEDLESS_RANGE_LOOP),
+    LintId::of(loops::NEVER_LOOP),
+    LintId::of(loops::SAME_ITEM_PUSH),
+    LintId::of(loops::SINGLE_ELEMENT_LOOP),
+    LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
+    LintId::of(loops::WHILE_LET_LOOP),
+    LintId::of(loops::WHILE_LET_ON_ITERATOR),
+    LintId::of(main_recursion::MAIN_RECURSION),
+    LintId::of(manual_async_fn::MANUAL_ASYNC_FN),
+    LintId::of(manual_map::MANUAL_MAP),
+    LintId::of(manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
+    LintId::of(manual_strip::MANUAL_STRIP),
+    LintId::of(manual_unwrap_or::MANUAL_UNWRAP_OR),
+    LintId::of(map_clone::MAP_CLONE),
+    LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
+    LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
+    LintId::of(match_result_ok::MATCH_RESULT_OK),
+    LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
+    LintId::of(matches::MATCH_AS_REF),
+    LintId::of(matches::MATCH_LIKE_MATCHES_MACRO),
+    LintId::of(matches::MATCH_OVERLAPPING_ARM),
+    LintId::of(matches::MATCH_REF_PATS),
+    LintId::of(matches::MATCH_SINGLE_BINDING),
+    LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
+    LintId::of(matches::SINGLE_MATCH),
+    LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
+    LintId::of(mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
+    LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
+    LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
+    LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
+    LintId::of(methods::BIND_INSTEAD_OF_MAP),
+    LintId::of(methods::BYTES_NTH),
+    LintId::of(methods::CHARS_LAST_CMP),
+    LintId::of(methods::CHARS_NEXT_CMP),
+    LintId::of(methods::CLONE_DOUBLE_REF),
+    LintId::of(methods::CLONE_ON_COPY),
+    LintId::of(methods::EXPECT_FUN_CALL),
+    LintId::of(methods::EXTEND_WITH_DRAIN),
+    LintId::of(methods::FILTER_MAP_IDENTITY),
+    LintId::of(methods::FILTER_NEXT),
+    LintId::of(methods::FLAT_MAP_IDENTITY),
+    LintId::of(methods::INSPECT_FOR_EACH),
+    LintId::of(methods::INTO_ITER_ON_REF),
+    LintId::of(methods::ITERATOR_STEP_BY_ZERO),
+    LintId::of(methods::ITER_CLONED_COLLECT),
+    LintId::of(methods::ITER_COUNT),
+    LintId::of(methods::ITER_NEXT_SLICE),
+    LintId::of(methods::ITER_NTH),
+    LintId::of(methods::ITER_NTH_ZERO),
+    LintId::of(methods::ITER_SKIP_NEXT),
+    LintId::of(methods::MANUAL_FILTER_MAP),
+    LintId::of(methods::MANUAL_FIND_MAP),
+    LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
+    LintId::of(methods::MANUAL_SPLIT_ONCE),
+    LintId::of(methods::MANUAL_STR_REPEAT),
+    LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
+    LintId::of(methods::MAP_IDENTITY),
+    LintId::of(methods::NEW_RET_NO_SELF),
+    LintId::of(methods::OK_EXPECT),
+    LintId::of(methods::OPTION_AS_REF_DEREF),
+    LintId::of(methods::OPTION_FILTER_MAP),
+    LintId::of(methods::OPTION_MAP_OR_NONE),
+    LintId::of(methods::OR_FUN_CALL),
+    LintId::of(methods::RESULT_MAP_OR_INTO_OPTION),
+    LintId::of(methods::SEARCH_IS_SOME),
+    LintId::of(methods::SHOULD_IMPLEMENT_TRAIT),
+    LintId::of(methods::SINGLE_CHAR_ADD_STR),
+    LintId::of(methods::SINGLE_CHAR_PATTERN),
+    LintId::of(methods::SKIP_WHILE_NEXT),
+    LintId::of(methods::STRING_EXTEND_CHARS),
+    LintId::of(methods::SUSPICIOUS_MAP),
+    LintId::of(methods::SUSPICIOUS_SPLITN),
+    LintId::of(methods::UNINIT_ASSUMED_INIT),
+    LintId::of(methods::UNNECESSARY_FILTER_MAP),
+    LintId::of(methods::UNNECESSARY_FOLD),
+    LintId::of(methods::UNNECESSARY_LAZY_EVALUATIONS),
+    LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
+    LintId::of(methods::USELESS_ASREF),
+    LintId::of(methods::WRONG_SELF_CONVENTION),
+    LintId::of(methods::ZST_OFFSET),
+    LintId::of(minmax::MIN_MAX),
+    LintId::of(misc::CMP_NAN),
+    LintId::of(misc::CMP_OWNED),
+    LintId::of(misc::MODULO_ONE),
+    LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
+    LintId::of(misc::TOPLEVEL_REF_ARG),
+    LintId::of(misc::ZERO_PTR),
+    LintId::of(misc_early::BUILTIN_TYPE_SHADOW),
+    LintId::of(misc_early::DOUBLE_NEG),
+    LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
+    LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
+    LintId::of(misc_early::REDUNDANT_PATTERN),
+    LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
+    LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
+    LintId::of(mut_key::MUTABLE_KEY_TYPE),
+    LintId::of(mut_mutex_lock::MUT_MUTEX_LOCK),
+    LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
+    LintId::of(mutex_atomic::MUTEX_ATOMIC),
+    LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
+    LintId::of(needless_bool::BOOL_COMPARISON),
+    LintId::of(needless_bool::NEEDLESS_BOOL),
+    LintId::of(needless_borrow::NEEDLESS_BORROW),
+    LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
+    LintId::of(needless_option_as_deref::NEEDLESS_OPTION_AS_DEREF),
+    LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
+    LintId::of(needless_update::NEEDLESS_UPDATE),
+    LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
+    LintId::of(neg_multiply::NEG_MULTIPLY),
+    LintId::of(new_without_default::NEW_WITHOUT_DEFAULT),
+    LintId::of(no_effect::NO_EFFECT),
+    LintId::of(no_effect::UNNECESSARY_OPERATION),
+    LintId::of(non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
+    LintId::of(non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
+    LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
+    LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
+    LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
+    LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
+    LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
+    LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
+    LintId::of(precedence::PRECEDENCE),
+    LintId::of(ptr::CMP_NULL),
+    LintId::of(ptr::INVALID_NULL_PTR_USAGE),
+    LintId::of(ptr::MUT_FROM_REF),
+    LintId::of(ptr::PTR_ARG),
+    LintId::of(ptr_eq::PTR_EQ),
+    LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
+    LintId::of(question_mark::QUESTION_MARK),
+    LintId::of(ranges::MANUAL_RANGE_CONTAINS),
+    LintId::of(ranges::RANGE_ZIP_WITH_LEN),
+    LintId::of(ranges::REVERSED_EMPTY_RANGES),
+    LintId::of(redundant_clone::REDUNDANT_CLONE),
+    LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
+    LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
+    LintId::of(redundant_slicing::REDUNDANT_SLICING),
+    LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
+    LintId::of(reference::DEREF_ADDROF),
+    LintId::of(reference::REF_IN_DEREF),
+    LintId::of(regex::INVALID_REGEX),
+    LintId::of(repeat_once::REPEAT_ONCE),
+    LintId::of(returns::LET_AND_RETURN),
+    LintId::of(returns::NEEDLESS_RETURN),
+    LintId::of(self_assignment::SELF_ASSIGNMENT),
+    LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
+    LintId::of(serde_api::SERDE_API_MISUSE),
+    LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
+    LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
+    LintId::of(slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
+    LintId::of(stable_sort_primitive::STABLE_SORT_PRIMITIVE),
+    LintId::of(strings::STRING_FROM_UTF8_AS_BYTES),
+    LintId::of(strlen_on_c_strings::STRLEN_ON_C_STRINGS),
+    LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
+    LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
+    LintId::of(swap::ALMOST_SWAPPED),
+    LintId::of(swap::MANUAL_SWAP),
+    LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
+    LintId::of(temporary_assignment::TEMPORARY_ASSIGNMENT),
+    LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
+    LintId::of(to_string_in_display::TO_STRING_IN_DISPLAY),
+    LintId::of(transmute::CROSSPOINTER_TRANSMUTE),
+    LintId::of(transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
+    LintId::of(transmute::TRANSMUTE_BYTES_TO_STR),
+    LintId::of(transmute::TRANSMUTE_FLOAT_TO_INT),
+    LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
+    LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
+    LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
+    LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
+    LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
+    LintId::of(transmute::WRONG_TRANSMUTE),
+    LintId::of(transmuting_null::TRANSMUTING_NULL),
+    LintId::of(try_err::TRY_ERR),
+    LintId::of(types::BORROWED_BOX),
+    LintId::of(types::BOX_COLLECTION),
+    LintId::of(types::REDUNDANT_ALLOCATION),
+    LintId::of(types::TYPE_COMPLEXITY),
+    LintId::of(types::VEC_BOX),
+    LintId::of(undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
+    LintId::of(unicode::INVISIBLE_CHARACTERS),
+    LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
+    LintId::of(unit_types::UNIT_ARG),
+    LintId::of(unit_types::UNIT_CMP),
+    LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
+    LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
+    LintId::of(unnecessary_sort_by::UNNECESSARY_SORT_BY),
+    LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
+    LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
+    LintId::of(unused_unit::UNUSED_UNIT),
+    LintId::of(unwrap::PANICKING_UNWRAP),
+    LintId::of(unwrap::UNNECESSARY_UNWRAP),
+    LintId::of(upper_case_acronyms::UPPER_CASE_ACRONYMS),
+    LintId::of(useless_conversion::USELESS_CONVERSION),
+    LintId::of(vec::USELESS_VEC),
+    LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
+    LintId::of(vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
+    LintId::of(write::PRINTLN_EMPTY_STRING),
+    LintId::of(write::PRINT_LITERAL),
+    LintId::of(write::PRINT_WITH_NEWLINE),
+    LintId::of(write::WRITELN_EMPTY_STRING),
+    LintId::of(write::WRITE_LITERAL),
+    LintId::of(write::WRITE_WITH_NEWLINE),
+    LintId::of(zero_div_zero::ZERO_DIVIDED_BY_ZERO),
+])
diff --git a/clippy_lints/src/lib.register_cargo.rs b/clippy_lints/src/lib.register_cargo.rs
new file mode 100644
index 00000000000..1809f2cc7d4
--- /dev/null
+++ b/clippy_lints/src/lib.register_cargo.rs
@@ -0,0 +1,11 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::cargo", Some("clippy_cargo"), vec![
+    LintId::of(cargo_common_metadata::CARGO_COMMON_METADATA),
+    LintId::of(feature_name::NEGATIVE_FEATURE_NAMES),
+    LintId::of(feature_name::REDUNDANT_FEATURE_NAMES),
+    LintId::of(multiple_crate_versions::MULTIPLE_CRATE_VERSIONS),
+    LintId::of(wildcard_dependencies::WILDCARD_DEPENDENCIES),
+])
diff --git a/clippy_lints/src/lib.register_complexity.rs b/clippy_lints/src/lib.register_complexity.rs
new file mode 100644
index 00000000000..64b82fc0faa
--- /dev/null
+++ b/clippy_lints/src/lib.register_complexity.rs
@@ -0,0 +1,94 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec![
+    LintId::of(attrs::DEPRECATED_CFG_ATTR),
+    LintId::of(booleans::NONMINIMAL_BOOL),
+    LintId::of(casts::CHAR_LIT_AS_U8),
+    LintId::of(casts::UNNECESSARY_CAST),
+    LintId::of(derivable_impls::DERIVABLE_IMPLS),
+    LintId::of(double_comparison::DOUBLE_COMPARISONS),
+    LintId::of(double_parens::DOUBLE_PARENS),
+    LintId::of(duration_subsec::DURATION_SUBSEC),
+    LintId::of(eval_order_dependence::DIVERGING_SUB_EXPRESSION),
+    LintId::of(explicit_write::EXPLICIT_WRITE),
+    LintId::of(format::USELESS_FORMAT),
+    LintId::of(functions::TOO_MANY_ARGUMENTS),
+    LintId::of(get_last_with_len::GET_LAST_WITH_LEN),
+    LintId::of(identity_op::IDENTITY_OP),
+    LintId::of(int_plus_one::INT_PLUS_ONE),
+    LintId::of(lifetimes::EXTRA_UNUSED_LIFETIMES),
+    LintId::of(lifetimes::NEEDLESS_LIFETIMES),
+    LintId::of(loops::EXPLICIT_COUNTER_LOOP),
+    LintId::of(loops::MANUAL_FLATTEN),
+    LintId::of(loops::SINGLE_ELEMENT_LOOP),
+    LintId::of(loops::WHILE_LET_LOOP),
+    LintId::of(manual_strip::MANUAL_STRIP),
+    LintId::of(manual_unwrap_or::MANUAL_UNWRAP_OR),
+    LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
+    LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
+    LintId::of(matches::MATCH_AS_REF),
+    LintId::of(matches::MATCH_SINGLE_BINDING),
+    LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
+    LintId::of(methods::BIND_INSTEAD_OF_MAP),
+    LintId::of(methods::CLONE_ON_COPY),
+    LintId::of(methods::FILTER_MAP_IDENTITY),
+    LintId::of(methods::FILTER_NEXT),
+    LintId::of(methods::FLAT_MAP_IDENTITY),
+    LintId::of(methods::INSPECT_FOR_EACH),
+    LintId::of(methods::ITER_COUNT),
+    LintId::of(methods::MANUAL_FILTER_MAP),
+    LintId::of(methods::MANUAL_FIND_MAP),
+    LintId::of(methods::MANUAL_SPLIT_ONCE),
+    LintId::of(methods::MAP_IDENTITY),
+    LintId::of(methods::OPTION_AS_REF_DEREF),
+    LintId::of(methods::OPTION_FILTER_MAP),
+    LintId::of(methods::SEARCH_IS_SOME),
+    LintId::of(methods::SKIP_WHILE_NEXT),
+    LintId::of(methods::UNNECESSARY_FILTER_MAP),
+    LintId::of(methods::USELESS_ASREF),
+    LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
+    LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
+    LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
+    LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
+    LintId::of(needless_bool::BOOL_COMPARISON),
+    LintId::of(needless_bool::NEEDLESS_BOOL),
+    LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
+    LintId::of(needless_option_as_deref::NEEDLESS_OPTION_AS_DEREF),
+    LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
+    LintId::of(needless_update::NEEDLESS_UPDATE),
+    LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
+    LintId::of(no_effect::NO_EFFECT),
+    LintId::of(no_effect::UNNECESSARY_OPERATION),
+    LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
+    LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
+    LintId::of(precedence::PRECEDENCE),
+    LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
+    LintId::of(ranges::RANGE_ZIP_WITH_LEN),
+    LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
+    LintId::of(redundant_slicing::REDUNDANT_SLICING),
+    LintId::of(reference::DEREF_ADDROF),
+    LintId::of(reference::REF_IN_DEREF),
+    LintId::of(repeat_once::REPEAT_ONCE),
+    LintId::of(strings::STRING_FROM_UTF8_AS_BYTES),
+    LintId::of(strlen_on_c_strings::STRLEN_ON_C_STRINGS),
+    LintId::of(swap::MANUAL_SWAP),
+    LintId::of(temporary_assignment::TEMPORARY_ASSIGNMENT),
+    LintId::of(transmute::CROSSPOINTER_TRANSMUTE),
+    LintId::of(transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
+    LintId::of(transmute::TRANSMUTE_BYTES_TO_STR),
+    LintId::of(transmute::TRANSMUTE_FLOAT_TO_INT),
+    LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
+    LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
+    LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
+    LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
+    LintId::of(types::BORROWED_BOX),
+    LintId::of(types::TYPE_COMPLEXITY),
+    LintId::of(types::VEC_BOX),
+    LintId::of(unit_types::UNIT_ARG),
+    LintId::of(unnecessary_sort_by::UNNECESSARY_SORT_BY),
+    LintId::of(unwrap::UNNECESSARY_UNWRAP),
+    LintId::of(useless_conversion::USELESS_CONVERSION),
+    LintId::of(zero_div_zero::ZERO_DIVIDED_BY_ZERO),
+])
diff --git a/clippy_lints/src/lib.register_correctness.rs b/clippy_lints/src/lib.register_correctness.rs
new file mode 100644
index 00000000000..e0ef7b3b8af
--- /dev/null
+++ b/clippy_lints/src/lib.register_correctness.rs
@@ -0,0 +1,73 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![
+    LintId::of(absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS),
+    LintId::of(approx_const::APPROX_CONSTANT),
+    LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
+    LintId::of(attrs::DEPRECATED_SEMVER),
+    LintId::of(attrs::MISMATCHED_TARGET_OS),
+    LintId::of(attrs::USELESS_ATTRIBUTE),
+    LintId::of(bit_mask::BAD_BIT_MASK),
+    LintId::of(bit_mask::INEFFECTIVE_BIT_MASK),
+    LintId::of(booleans::LOGIC_BUG),
+    LintId::of(casts::CAST_REF_TO_MUT),
+    LintId::of(copies::IFS_SAME_COND),
+    LintId::of(copies::IF_SAME_THEN_ELSE),
+    LintId::of(derive::DERIVE_HASH_XOR_EQ),
+    LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
+    LintId::of(drop_forget_ref::DROP_COPY),
+    LintId::of(drop_forget_ref::DROP_REF),
+    LintId::of(drop_forget_ref::FORGET_COPY),
+    LintId::of(drop_forget_ref::FORGET_REF),
+    LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
+    LintId::of(eq_op::EQ_OP),
+    LintId::of(erasing_op::ERASING_OP),
+    LintId::of(formatting::POSSIBLE_MISSING_COMMA),
+    LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
+    LintId::of(if_let_mutex::IF_LET_MUTEX),
+    LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
+    LintId::of(infinite_iter::INFINITE_ITER),
+    LintId::of(inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
+    LintId::of(inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
+    LintId::of(let_underscore::LET_UNDERSCORE_LOCK),
+    LintId::of(literal_representation::MISTYPED_LITERAL_SUFFIXES),
+    LintId::of(loops::ITER_NEXT_LOOP),
+    LintId::of(loops::NEVER_LOOP),
+    LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
+    LintId::of(mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
+    LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
+    LintId::of(methods::CLONE_DOUBLE_REF),
+    LintId::of(methods::ITERATOR_STEP_BY_ZERO),
+    LintId::of(methods::SUSPICIOUS_SPLITN),
+    LintId::of(methods::UNINIT_ASSUMED_INIT),
+    LintId::of(methods::ZST_OFFSET),
+    LintId::of(minmax::MIN_MAX),
+    LintId::of(misc::CMP_NAN),
+    LintId::of(misc::MODULO_ONE),
+    LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
+    LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
+    LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
+    LintId::of(ptr::INVALID_NULL_PTR_USAGE),
+    LintId::of(ptr::MUT_FROM_REF),
+    LintId::of(ranges::REVERSED_EMPTY_RANGES),
+    LintId::of(regex::INVALID_REGEX),
+    LintId::of(self_assignment::SELF_ASSIGNMENT),
+    LintId::of(serde_api::SERDE_API_MISUSE),
+    LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
+    LintId::of(swap::ALMOST_SWAPPED),
+    LintId::of(to_string_in_display::TO_STRING_IN_DISPLAY),
+    LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
+    LintId::of(transmute::WRONG_TRANSMUTE),
+    LintId::of(transmuting_null::TRANSMUTING_NULL),
+    LintId::of(undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
+    LintId::of(unicode::INVISIBLE_CHARACTERS),
+    LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
+    LintId::of(unit_types::UNIT_CMP),
+    LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
+    LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
+    LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
+    LintId::of(unwrap::PANICKING_UNWRAP),
+    LintId::of(vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
+])
diff --git a/clippy_lints/src/lib.register_internal.rs b/clippy_lints/src/lib.register_internal.rs
new file mode 100644
index 00000000000..c8c1e0262ab
--- /dev/null
+++ b/clippy_lints/src/lib.register_internal.rs
@@ -0,0 +1,18 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::internal", Some("clippy_internal"), vec![
+    LintId::of(utils::internal_lints::CLIPPY_LINTS_INTERNAL),
+    LintId::of(utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS),
+    LintId::of(utils::internal_lints::COMPILER_LINT_FUNCTIONS),
+    LintId::of(utils::internal_lints::DEFAULT_LINT),
+    LintId::of(utils::internal_lints::IF_CHAIN_STYLE),
+    LintId::of(utils::internal_lints::INTERNING_DEFINED_SYMBOL),
+    LintId::of(utils::internal_lints::INVALID_PATHS),
+    LintId::of(utils::internal_lints::LINT_WITHOUT_LINT_PASS),
+    LintId::of(utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM),
+    LintId::of(utils::internal_lints::OUTER_EXPN_EXPN_DATA),
+    LintId::of(utils::internal_lints::PRODUCE_ICE),
+    LintId::of(utils::internal_lints::UNNECESSARY_SYMBOL_STR),
+])
diff --git a/clippy_lints/src/lib.register_lints.rs b/clippy_lints/src/lib.register_lints.rs
new file mode 100644
index 00000000000..2ba2b3da55c
--- /dev/null
+++ b/clippy_lints/src/lib.register_lints.rs
@@ -0,0 +1,510 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_lints(&[
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::CLIPPY_LINTS_INTERNAL,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::COMPILER_LINT_FUNCTIONS,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::DEFAULT_LINT,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::IF_CHAIN_STYLE,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::INTERNING_DEFINED_SYMBOL,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::INVALID_PATHS,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::LINT_WITHOUT_LINT_PASS,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::OUTER_EXPN_EXPN_DATA,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::PRODUCE_ICE,
+    #[cfg(feature = "internal-lints")]
+    utils::internal_lints::UNNECESSARY_SYMBOL_STR,
+    absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS,
+    approx_const::APPROX_CONSTANT,
+    arithmetic::FLOAT_ARITHMETIC,
+    arithmetic::INTEGER_ARITHMETIC,
+    as_conversions::AS_CONVERSIONS,
+    asm_syntax::INLINE_ASM_X86_ATT_SYNTAX,
+    asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX,
+    assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
+    assign_ops::ASSIGN_OP_PATTERN,
+    assign_ops::MISREFACTORED_ASSIGN_OP,
+    async_yields_async::ASYNC_YIELDS_ASYNC,
+    attrs::BLANKET_CLIPPY_RESTRICTION_LINTS,
+    attrs::DEPRECATED_CFG_ATTR,
+    attrs::DEPRECATED_SEMVER,
+    attrs::EMPTY_LINE_AFTER_OUTER_ATTR,
+    attrs::INLINE_ALWAYS,
+    attrs::MISMATCHED_TARGET_OS,
+    attrs::USELESS_ATTRIBUTE,
+    await_holding_invalid::AWAIT_HOLDING_LOCK,
+    await_holding_invalid::AWAIT_HOLDING_REFCELL_REF,
+    bit_mask::BAD_BIT_MASK,
+    bit_mask::INEFFECTIVE_BIT_MASK,
+    bit_mask::VERBOSE_BIT_MASK,
+    blacklisted_name::BLACKLISTED_NAME,
+    blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS,
+    bool_assert_comparison::BOOL_ASSERT_COMPARISON,
+    booleans::LOGIC_BUG,
+    booleans::NONMINIMAL_BOOL,
+    bytecount::NAIVE_BYTECOUNT,
+    cargo_common_metadata::CARGO_COMMON_METADATA,
+    case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
+    casts::CAST_LOSSLESS,
+    casts::CAST_POSSIBLE_TRUNCATION,
+    casts::CAST_POSSIBLE_WRAP,
+    casts::CAST_PRECISION_LOSS,
+    casts::CAST_PTR_ALIGNMENT,
+    casts::CAST_REF_TO_MUT,
+    casts::CAST_SIGN_LOSS,
+    casts::CHAR_LIT_AS_U8,
+    casts::FN_TO_NUMERIC_CAST,
+    casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
+    casts::PTR_AS_PTR,
+    casts::UNNECESSARY_CAST,
+    checked_conversions::CHECKED_CONVERSIONS,
+    cognitive_complexity::COGNITIVE_COMPLEXITY,
+    collapsible_if::COLLAPSIBLE_ELSE_IF,
+    collapsible_if::COLLAPSIBLE_IF,
+    collapsible_match::COLLAPSIBLE_MATCH,
+    comparison_chain::COMPARISON_CHAIN,
+    copies::BRANCHES_SHARING_CODE,
+    copies::IFS_SAME_COND,
+    copies::IF_SAME_THEN_ELSE,
+    copies::SAME_FUNCTIONS_IN_IF_CONDITION,
+    copy_iterator::COPY_ITERATOR,
+    create_dir::CREATE_DIR,
+    dbg_macro::DBG_MACRO,
+    default::DEFAULT_TRAIT_ACCESS,
+    default::FIELD_REASSIGN_WITH_DEFAULT,
+    default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK,
+    dereference::EXPLICIT_DEREF_METHODS,
+    derivable_impls::DERIVABLE_IMPLS,
+    derive::DERIVE_HASH_XOR_EQ,
+    derive::DERIVE_ORD_XOR_PARTIAL_ORD,
+    derive::EXPL_IMPL_CLONE_ON_COPY,
+    derive::UNSAFE_DERIVE_DESERIALIZE,
+    disallowed_method::DISALLOWED_METHOD,
+    disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS,
+    disallowed_type::DISALLOWED_TYPE,
+    doc::DOC_MARKDOWN,
+    doc::MISSING_ERRORS_DOC,
+    doc::MISSING_PANICS_DOC,
+    doc::MISSING_SAFETY_DOC,
+    doc::NEEDLESS_DOCTEST_MAIN,
+    double_comparison::DOUBLE_COMPARISONS,
+    double_parens::DOUBLE_PARENS,
+    drop_forget_ref::DROP_COPY,
+    drop_forget_ref::DROP_REF,
+    drop_forget_ref::FORGET_COPY,
+    drop_forget_ref::FORGET_REF,
+    duration_subsec::DURATION_SUBSEC,
+    else_if_without_else::ELSE_IF_WITHOUT_ELSE,
+    empty_enum::EMPTY_ENUM,
+    entry::MAP_ENTRY,
+    enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT,
+    enum_variants::ENUM_VARIANT_NAMES,
+    enum_variants::MODULE_INCEPTION,
+    enum_variants::MODULE_NAME_REPETITIONS,
+    eq_op::EQ_OP,
+    eq_op::OP_REF,
+    equatable_if_let::EQUATABLE_IF_LET,
+    erasing_op::ERASING_OP,
+    escape::BOXED_LOCAL,
+    eta_reduction::REDUNDANT_CLOSURE,
+    eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
+    eval_order_dependence::DIVERGING_SUB_EXPRESSION,
+    eval_order_dependence::EVAL_ORDER_DEPENDENCE,
+    excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS,
+    excessive_bools::STRUCT_EXCESSIVE_BOOLS,
+    exhaustive_items::EXHAUSTIVE_ENUMS,
+    exhaustive_items::EXHAUSTIVE_STRUCTS,
+    exit::EXIT,
+    explicit_write::EXPLICIT_WRITE,
+    fallible_impl_from::FALLIBLE_IMPL_FROM,
+    feature_name::NEGATIVE_FEATURE_NAMES,
+    feature_name::REDUNDANT_FEATURE_NAMES,
+    float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS,
+    float_literal::EXCESSIVE_PRECISION,
+    float_literal::LOSSY_FLOAT_LITERAL,
+    floating_point_arithmetic::IMPRECISE_FLOPS,
+    floating_point_arithmetic::SUBOPTIMAL_FLOPS,
+    format::USELESS_FORMAT,
+    formatting::POSSIBLE_MISSING_COMMA,
+    formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING,
+    formatting::SUSPICIOUS_ELSE_FORMATTING,
+    formatting::SUSPICIOUS_UNARY_OP_FORMATTING,
+    from_over_into::FROM_OVER_INTO,
+    from_str_radix_10::FROM_STR_RADIX_10,
+    functions::DOUBLE_MUST_USE,
+    functions::MUST_USE_CANDIDATE,
+    functions::MUST_USE_UNIT,
+    functions::NOT_UNSAFE_PTR_ARG_DEREF,
+    functions::RESULT_UNIT_ERR,
+    functions::TOO_MANY_ARGUMENTS,
+    functions::TOO_MANY_LINES,
+    future_not_send::FUTURE_NOT_SEND,
+    get_last_with_len::GET_LAST_WITH_LEN,
+    identity_op::IDENTITY_OP,
+    if_let_mutex::IF_LET_MUTEX,
+    if_not_else::IF_NOT_ELSE,
+    if_then_panic::IF_THEN_PANIC,
+    if_then_some_else_none::IF_THEN_SOME_ELSE_NONE,
+    implicit_hasher::IMPLICIT_HASHER,
+    implicit_return::IMPLICIT_RETURN,
+    implicit_saturating_sub::IMPLICIT_SATURATING_SUB,
+    inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR,
+    indexing_slicing::INDEXING_SLICING,
+    indexing_slicing::OUT_OF_BOUNDS_INDEXING,
+    infinite_iter::INFINITE_ITER,
+    infinite_iter::MAYBE_INFINITE_ITER,
+    inherent_impl::MULTIPLE_INHERENT_IMPL,
+    inherent_to_string::INHERENT_TO_STRING,
+    inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY,
+    inline_fn_without_body::INLINE_FN_WITHOUT_BODY,
+    int_plus_one::INT_PLUS_ONE,
+    integer_division::INTEGER_DIVISION,
+    invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS,
+    items_after_statements::ITEMS_AFTER_STATEMENTS,
+    iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR,
+    large_const_arrays::LARGE_CONST_ARRAYS,
+    large_enum_variant::LARGE_ENUM_VARIANT,
+    large_stack_arrays::LARGE_STACK_ARRAYS,
+    len_zero::COMPARISON_TO_EMPTY,
+    len_zero::LEN_WITHOUT_IS_EMPTY,
+    len_zero::LEN_ZERO,
+    let_if_seq::USELESS_LET_IF_SEQ,
+    let_underscore::LET_UNDERSCORE_DROP,
+    let_underscore::LET_UNDERSCORE_LOCK,
+    let_underscore::LET_UNDERSCORE_MUST_USE,
+    lifetimes::EXTRA_UNUSED_LIFETIMES,
+    lifetimes::NEEDLESS_LIFETIMES,
+    literal_representation::DECIMAL_LITERAL_REPRESENTATION,
+    literal_representation::INCONSISTENT_DIGIT_GROUPING,
+    literal_representation::LARGE_DIGIT_GROUPS,
+    literal_representation::MISTYPED_LITERAL_SUFFIXES,
+    literal_representation::UNREADABLE_LITERAL,
+    literal_representation::UNUSUAL_BYTE_GROUPINGS,
+    loops::EMPTY_LOOP,
+    loops::EXPLICIT_COUNTER_LOOP,
+    loops::EXPLICIT_INTO_ITER_LOOP,
+    loops::EXPLICIT_ITER_LOOP,
+    loops::FOR_KV_MAP,
+    loops::FOR_LOOPS_OVER_FALLIBLES,
+    loops::ITER_NEXT_LOOP,
+    loops::MANUAL_FLATTEN,
+    loops::MANUAL_MEMCPY,
+    loops::MUT_RANGE_BOUND,
+    loops::NEEDLESS_COLLECT,
+    loops::NEEDLESS_RANGE_LOOP,
+    loops::NEVER_LOOP,
+    loops::SAME_ITEM_PUSH,
+    loops::SINGLE_ELEMENT_LOOP,
+    loops::WHILE_IMMUTABLE_CONDITION,
+    loops::WHILE_LET_LOOP,
+    loops::WHILE_LET_ON_ITERATOR,
+    macro_use::MACRO_USE_IMPORTS,
+    main_recursion::MAIN_RECURSION,
+    manual_async_fn::MANUAL_ASYNC_FN,
+    manual_map::MANUAL_MAP,
+    manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE,
+    manual_ok_or::MANUAL_OK_OR,
+    manual_strip::MANUAL_STRIP,
+    manual_unwrap_or::MANUAL_UNWRAP_OR,
+    map_clone::MAP_CLONE,
+    map_err_ignore::MAP_ERR_IGNORE,
+    map_unit_fn::OPTION_MAP_UNIT_FN,
+    map_unit_fn::RESULT_MAP_UNIT_FN,
+    match_on_vec_items::MATCH_ON_VEC_ITEMS,
+    match_result_ok::MATCH_RESULT_OK,
+    matches::INFALLIBLE_DESTRUCTURING_MATCH,
+    matches::MATCH_AS_REF,
+    matches::MATCH_BOOL,
+    matches::MATCH_LIKE_MATCHES_MACRO,
+    matches::MATCH_OVERLAPPING_ARM,
+    matches::MATCH_REF_PATS,
+    matches::MATCH_SAME_ARMS,
+    matches::MATCH_SINGLE_BINDING,
+    matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
+    matches::MATCH_WILD_ERR_ARM,
+    matches::REDUNDANT_PATTERN_MATCHING,
+    matches::REST_PAT_IN_FULLY_BOUND_STRUCTS,
+    matches::SINGLE_MATCH,
+    matches::SINGLE_MATCH_ELSE,
+    matches::WILDCARD_ENUM_MATCH_ARM,
+    matches::WILDCARD_IN_OR_PATTERNS,
+    mem_discriminant::MEM_DISCRIMINANT_NON_ENUM,
+    mem_forget::MEM_FORGET,
+    mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
+    mem_replace::MEM_REPLACE_WITH_DEFAULT,
+    mem_replace::MEM_REPLACE_WITH_UNINIT,
+    methods::BIND_INSTEAD_OF_MAP,
+    methods::BYTES_NTH,
+    methods::CHARS_LAST_CMP,
+    methods::CHARS_NEXT_CMP,
+    methods::CLONED_INSTEAD_OF_COPIED,
+    methods::CLONE_DOUBLE_REF,
+    methods::CLONE_ON_COPY,
+    methods::CLONE_ON_REF_PTR,
+    methods::EXPECT_FUN_CALL,
+    methods::EXPECT_USED,
+    methods::EXTEND_WITH_DRAIN,
+    methods::FILETYPE_IS_FILE,
+    methods::FILTER_MAP_IDENTITY,
+    methods::FILTER_MAP_NEXT,
+    methods::FILTER_NEXT,
+    methods::FLAT_MAP_IDENTITY,
+    methods::FLAT_MAP_OPTION,
+    methods::FROM_ITER_INSTEAD_OF_COLLECT,
+    methods::GET_UNWRAP,
+    methods::IMPLICIT_CLONE,
+    methods::INEFFICIENT_TO_STRING,
+    methods::INSPECT_FOR_EACH,
+    methods::INTO_ITER_ON_REF,
+    methods::ITERATOR_STEP_BY_ZERO,
+    methods::ITER_CLONED_COLLECT,
+    methods::ITER_COUNT,
+    methods::ITER_NEXT_SLICE,
+    methods::ITER_NTH,
+    methods::ITER_NTH_ZERO,
+    methods::ITER_SKIP_NEXT,
+    methods::MANUAL_FILTER_MAP,
+    methods::MANUAL_FIND_MAP,
+    methods::MANUAL_SATURATING_ARITHMETIC,
+    methods::MANUAL_SPLIT_ONCE,
+    methods::MANUAL_STR_REPEAT,
+    methods::MAP_COLLECT_RESULT_UNIT,
+    methods::MAP_FLATTEN,
+    methods::MAP_IDENTITY,
+    methods::MAP_UNWRAP_OR,
+    methods::NEW_RET_NO_SELF,
+    methods::OK_EXPECT,
+    methods::OPTION_AS_REF_DEREF,
+    methods::OPTION_FILTER_MAP,
+    methods::OPTION_MAP_OR_NONE,
+    methods::OR_FUN_CALL,
+    methods::RESULT_MAP_OR_INTO_OPTION,
+    methods::SEARCH_IS_SOME,
+    methods::SHOULD_IMPLEMENT_TRAIT,
+    methods::SINGLE_CHAR_ADD_STR,
+    methods::SINGLE_CHAR_PATTERN,
+    methods::SKIP_WHILE_NEXT,
+    methods::STRING_EXTEND_CHARS,
+    methods::SUSPICIOUS_MAP,
+    methods::SUSPICIOUS_SPLITN,
+    methods::UNINIT_ASSUMED_INIT,
+    methods::UNNECESSARY_FILTER_MAP,
+    methods::UNNECESSARY_FOLD,
+    methods::UNNECESSARY_LAZY_EVALUATIONS,
+    methods::UNWRAP_OR_ELSE_DEFAULT,
+    methods::UNWRAP_USED,
+    methods::USELESS_ASREF,
+    methods::WRONG_SELF_CONVENTION,
+    methods::ZST_OFFSET,
+    minmax::MIN_MAX,
+    misc::CMP_NAN,
+    misc::CMP_OWNED,
+    misc::FLOAT_CMP,
+    misc::FLOAT_CMP_CONST,
+    misc::MODULO_ONE,
+    misc::SHORT_CIRCUIT_STATEMENT,
+    misc::TOPLEVEL_REF_ARG,
+    misc::USED_UNDERSCORE_BINDING,
+    misc::ZERO_PTR,
+    misc_early::BUILTIN_TYPE_SHADOW,
+    misc_early::DOUBLE_NEG,
+    misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
+    misc_early::MIXED_CASE_HEX_LITERALS,
+    misc_early::REDUNDANT_PATTERN,
+    misc_early::UNNEEDED_FIELD_PATTERN,
+    misc_early::UNNEEDED_WILDCARD_PATTERN,
+    misc_early::UNSEPARATED_LITERAL_SUFFIX,
+    misc_early::ZERO_PREFIXED_LITERAL,
+    missing_const_for_fn::MISSING_CONST_FOR_FN,
+    missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS,
+    missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES,
+    missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS,
+    module_style::MOD_MODULE_FILES,
+    module_style::SELF_NAMED_MODULE_FILES,
+    modulo_arithmetic::MODULO_ARITHMETIC,
+    multiple_crate_versions::MULTIPLE_CRATE_VERSIONS,
+    mut_key::MUTABLE_KEY_TYPE,
+    mut_mut::MUT_MUT,
+    mut_mutex_lock::MUT_MUTEX_LOCK,
+    mut_reference::UNNECESSARY_MUT_PASSED,
+    mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL,
+    mutex_atomic::MUTEX_ATOMIC,
+    mutex_atomic::MUTEX_INTEGER,
+    needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE,
+    needless_bitwise_bool::NEEDLESS_BITWISE_BOOL,
+    needless_bool::BOOL_COMPARISON,
+    needless_bool::NEEDLESS_BOOL,
+    needless_borrow::NEEDLESS_BORROW,
+    needless_borrow::REF_BINDING_TO_REFERENCE,
+    needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
+    needless_continue::NEEDLESS_CONTINUE,
+    needless_for_each::NEEDLESS_FOR_EACH,
+    needless_option_as_deref::NEEDLESS_OPTION_AS_DEREF,
+    needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
+    needless_question_mark::NEEDLESS_QUESTION_MARK,
+    needless_update::NEEDLESS_UPDATE,
+    neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD,
+    neg_multiply::NEG_MULTIPLY,
+    new_without_default::NEW_WITHOUT_DEFAULT,
+    no_effect::NO_EFFECT,
+    no_effect::UNNECESSARY_OPERATION,
+    non_copy_const::BORROW_INTERIOR_MUTABLE_CONST,
+    non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST,
+    non_expressive_names::JUST_UNDERSCORES_AND_DIGITS,
+    non_expressive_names::MANY_SINGLE_CHAR_NAMES,
+    non_expressive_names::SIMILAR_NAMES,
+    non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS,
+    non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY,
+    nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES,
+    open_options::NONSENSICAL_OPEN_OPTIONS,
+    option_env_unwrap::OPTION_ENV_UNWRAP,
+    option_if_let_else::OPTION_IF_LET_ELSE,
+    overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
+    panic_in_result_fn::PANIC_IN_RESULT_FN,
+    panic_unimplemented::PANIC,
+    panic_unimplemented::TODO,
+    panic_unimplemented::UNIMPLEMENTED,
+    panic_unimplemented::UNREACHABLE,
+    partialeq_ne_impl::PARTIALEQ_NE_IMPL,
+    pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE,
+    pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF,
+    path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE,
+    pattern_type_mismatch::PATTERN_TYPE_MISMATCH,
+    precedence::PRECEDENCE,
+    ptr::CMP_NULL,
+    ptr::INVALID_NULL_PTR_USAGE,
+    ptr::MUT_FROM_REF,
+    ptr::PTR_ARG,
+    ptr_eq::PTR_EQ,
+    ptr_offset_with_cast::PTR_OFFSET_WITH_CAST,
+    question_mark::QUESTION_MARK,
+    ranges::MANUAL_RANGE_CONTAINS,
+    ranges::RANGE_MINUS_ONE,
+    ranges::RANGE_PLUS_ONE,
+    ranges::RANGE_ZIP_WITH_LEN,
+    ranges::REVERSED_EMPTY_RANGES,
+    redundant_clone::REDUNDANT_CLONE,
+    redundant_closure_call::REDUNDANT_CLOSURE_CALL,
+    redundant_else::REDUNDANT_ELSE,
+    redundant_field_names::REDUNDANT_FIELD_NAMES,
+    redundant_pub_crate::REDUNDANT_PUB_CRATE,
+    redundant_slicing::REDUNDANT_SLICING,
+    redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
+    ref_option_ref::REF_OPTION_REF,
+    reference::DEREF_ADDROF,
+    reference::REF_IN_DEREF,
+    regex::INVALID_REGEX,
+    regex::TRIVIAL_REGEX,
+    repeat_once::REPEAT_ONCE,
+    returns::LET_AND_RETURN,
+    returns::NEEDLESS_RETURN,
+    same_name_method::SAME_NAME_METHOD,
+    self_assignment::SELF_ASSIGNMENT,
+    self_named_constructors::SELF_NAMED_CONSTRUCTORS,
+    semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED,
+    serde_api::SERDE_API_MISUSE,
+    shadow::SHADOW_REUSE,
+    shadow::SHADOW_SAME,
+    shadow::SHADOW_UNRELATED,
+    single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
+    size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT,
+    slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
+    stable_sort_primitive::STABLE_SORT_PRIMITIVE,
+    strings::STRING_ADD,
+    strings::STRING_ADD_ASSIGN,
+    strings::STRING_FROM_UTF8_AS_BYTES,
+    strings::STRING_LIT_AS_BYTES,
+    strings::STRING_TO_STRING,
+    strings::STR_TO_STRING,
+    strlen_on_c_strings::STRLEN_ON_C_STRINGS,
+    suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS,
+    suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL,
+    suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
+    swap::ALMOST_SWAPPED,
+    swap::MANUAL_SWAP,
+    tabs_in_doc_comments::TABS_IN_DOC_COMMENTS,
+    temporary_assignment::TEMPORARY_ASSIGNMENT,
+    to_digit_is_some::TO_DIGIT_IS_SOME,
+    to_string_in_display::TO_STRING_IN_DISPLAY,
+    trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS,
+    trait_bounds::TYPE_REPETITION_IN_BOUNDS,
+    transmute::CROSSPOINTER_TRANSMUTE,
+    transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
+    transmute::TRANSMUTE_BYTES_TO_STR,
+    transmute::TRANSMUTE_FLOAT_TO_INT,
+    transmute::TRANSMUTE_INT_TO_BOOL,
+    transmute::TRANSMUTE_INT_TO_CHAR,
+    transmute::TRANSMUTE_INT_TO_FLOAT,
+    transmute::TRANSMUTE_PTR_TO_PTR,
+    transmute::TRANSMUTE_PTR_TO_REF,
+    transmute::UNSOUND_COLLECTION_TRANSMUTE,
+    transmute::USELESS_TRANSMUTE,
+    transmute::WRONG_TRANSMUTE,
+    transmuting_null::TRANSMUTING_NULL,
+    try_err::TRY_ERR,
+    types::BORROWED_BOX,
+    types::BOX_COLLECTION,
+    types::LINKEDLIST,
+    types::OPTION_OPTION,
+    types::RC_BUFFER,
+    types::RC_MUTEX,
+    types::REDUNDANT_ALLOCATION,
+    types::TYPE_COMPLEXITY,
+    types::VEC_BOX,
+    undropped_manually_drops::UNDROPPED_MANUALLY_DROPS,
+    unicode::INVISIBLE_CHARACTERS,
+    unicode::NON_ASCII_LITERAL,
+    unicode::UNICODE_NOT_NFC,
+    unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
+    unit_types::LET_UNIT_VALUE,
+    unit_types::UNIT_ARG,
+    unit_types::UNIT_CMP,
+    unnamed_address::FN_ADDRESS_COMPARISONS,
+    unnamed_address::VTABLE_ADDRESS_COMPARISONS,
+    unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS,
+    unnecessary_sort_by::UNNECESSARY_SORT_BY,
+    unnecessary_wraps::UNNECESSARY_WRAPS,
+    unnested_or_patterns::UNNESTED_OR_PATTERNS,
+    unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
+    unused_async::UNUSED_ASYNC,
+    unused_io_amount::UNUSED_IO_AMOUNT,
+    unused_self::UNUSED_SELF,
+    unused_unit::UNUSED_UNIT,
+    unwrap::PANICKING_UNWRAP,
+    unwrap::UNNECESSARY_UNWRAP,
+    unwrap_in_result::UNWRAP_IN_RESULT,
+    upper_case_acronyms::UPPER_CASE_ACRONYMS,
+    use_self::USE_SELF,
+    useless_conversion::USELESS_CONVERSION,
+    vec::USELESS_VEC,
+    vec_init_then_push::VEC_INIT_THEN_PUSH,
+    vec_resize_to_zero::VEC_RESIZE_TO_ZERO,
+    verbose_file_reads::VERBOSE_FILE_READS,
+    wildcard_dependencies::WILDCARD_DEPENDENCIES,
+    wildcard_imports::ENUM_GLOB_USE,
+    wildcard_imports::WILDCARD_IMPORTS,
+    write::PRINTLN_EMPTY_STRING,
+    write::PRINT_LITERAL,
+    write::PRINT_STDERR,
+    write::PRINT_STDOUT,
+    write::PRINT_WITH_NEWLINE,
+    write::USE_DEBUG,
+    write::WRITELN_EMPTY_STRING,
+    write::WRITE_LITERAL,
+    write::WRITE_WITH_NEWLINE,
+    zero_div_zero::ZERO_DIVIDED_BY_ZERO,
+    zero_sized_map_values::ZERO_SIZED_MAP_VALUES,
+])
diff --git a/clippy_lints/src/lib.register_nursery.rs b/clippy_lints/src/lib.register_nursery.rs
new file mode 100644
index 00000000000..96e0b421094
--- /dev/null
+++ b/clippy_lints/src/lib.register_nursery.rs
@@ -0,0 +1,30 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
+    LintId::of(attrs::EMPTY_LINE_AFTER_OUTER_ATTR),
+    LintId::of(cognitive_complexity::COGNITIVE_COMPLEXITY),
+    LintId::of(copies::BRANCHES_SHARING_CODE),
+    LintId::of(disallowed_method::DISALLOWED_METHOD),
+    LintId::of(disallowed_type::DISALLOWED_TYPE),
+    LintId::of(equatable_if_let::EQUATABLE_IF_LET),
+    LintId::of(fallible_impl_from::FALLIBLE_IMPL_FROM),
+    LintId::of(floating_point_arithmetic::IMPRECISE_FLOPS),
+    LintId::of(floating_point_arithmetic::SUBOPTIMAL_FLOPS),
+    LintId::of(future_not_send::FUTURE_NOT_SEND),
+    LintId::of(let_if_seq::USELESS_LET_IF_SEQ),
+    LintId::of(missing_const_for_fn::MISSING_CONST_FOR_FN),
+    LintId::of(mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL),
+    LintId::of(mutex_atomic::MUTEX_INTEGER),
+    LintId::of(non_send_fields_in_send_ty::NON_SEND_FIELDS_IN_SEND_TY),
+    LintId::of(nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES),
+    LintId::of(option_if_let_else::OPTION_IF_LET_ELSE),
+    LintId::of(path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE),
+    LintId::of(redundant_pub_crate::REDUNDANT_PUB_CRATE),
+    LintId::of(regex::TRIVIAL_REGEX),
+    LintId::of(strings::STRING_LIT_AS_BYTES),
+    LintId::of(suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
+    LintId::of(transmute::USELESS_TRANSMUTE),
+    LintId::of(use_self::USE_SELF),
+])
diff --git a/clippy_lints/src/lib.register_pedantic.rs b/clippy_lints/src/lib.register_pedantic.rs
new file mode 100644
index 00000000000..6533b94e82b
--- /dev/null
+++ b/clippy_lints/src/lib.register_pedantic.rs
@@ -0,0 +1,100 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
+    LintId::of(attrs::INLINE_ALWAYS),
+    LintId::of(await_holding_invalid::AWAIT_HOLDING_LOCK),
+    LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
+    LintId::of(bit_mask::VERBOSE_BIT_MASK),
+    LintId::of(bytecount::NAIVE_BYTECOUNT),
+    LintId::of(case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS),
+    LintId::of(casts::CAST_LOSSLESS),
+    LintId::of(casts::CAST_POSSIBLE_TRUNCATION),
+    LintId::of(casts::CAST_POSSIBLE_WRAP),
+    LintId::of(casts::CAST_PRECISION_LOSS),
+    LintId::of(casts::CAST_PTR_ALIGNMENT),
+    LintId::of(casts::CAST_SIGN_LOSS),
+    LintId::of(casts::PTR_AS_PTR),
+    LintId::of(checked_conversions::CHECKED_CONVERSIONS),
+    LintId::of(copies::SAME_FUNCTIONS_IN_IF_CONDITION),
+    LintId::of(copy_iterator::COPY_ITERATOR),
+    LintId::of(default::DEFAULT_TRAIT_ACCESS),
+    LintId::of(dereference::EXPLICIT_DEREF_METHODS),
+    LintId::of(derive::EXPL_IMPL_CLONE_ON_COPY),
+    LintId::of(derive::UNSAFE_DERIVE_DESERIALIZE),
+    LintId::of(doc::DOC_MARKDOWN),
+    LintId::of(doc::MISSING_ERRORS_DOC),
+    LintId::of(doc::MISSING_PANICS_DOC),
+    LintId::of(empty_enum::EMPTY_ENUM),
+    LintId::of(enum_variants::MODULE_NAME_REPETITIONS),
+    LintId::of(eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS),
+    LintId::of(excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS),
+    LintId::of(excessive_bools::STRUCT_EXCESSIVE_BOOLS),
+    LintId::of(functions::MUST_USE_CANDIDATE),
+    LintId::of(functions::TOO_MANY_LINES),
+    LintId::of(if_not_else::IF_NOT_ELSE),
+    LintId::of(implicit_hasher::IMPLICIT_HASHER),
+    LintId::of(implicit_saturating_sub::IMPLICIT_SATURATING_SUB),
+    LintId::of(inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR),
+    LintId::of(infinite_iter::MAYBE_INFINITE_ITER),
+    LintId::of(invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS),
+    LintId::of(items_after_statements::ITEMS_AFTER_STATEMENTS),
+    LintId::of(iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR),
+    LintId::of(large_stack_arrays::LARGE_STACK_ARRAYS),
+    LintId::of(let_underscore::LET_UNDERSCORE_DROP),
+    LintId::of(literal_representation::LARGE_DIGIT_GROUPS),
+    LintId::of(literal_representation::UNREADABLE_LITERAL),
+    LintId::of(loops::EXPLICIT_INTO_ITER_LOOP),
+    LintId::of(loops::EXPLICIT_ITER_LOOP),
+    LintId::of(macro_use::MACRO_USE_IMPORTS),
+    LintId::of(manual_ok_or::MANUAL_OK_OR),
+    LintId::of(match_on_vec_items::MATCH_ON_VEC_ITEMS),
+    LintId::of(matches::MATCH_BOOL),
+    LintId::of(matches::MATCH_SAME_ARMS),
+    LintId::of(matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS),
+    LintId::of(matches::MATCH_WILD_ERR_ARM),
+    LintId::of(matches::SINGLE_MATCH_ELSE),
+    LintId::of(methods::CLONED_INSTEAD_OF_COPIED),
+    LintId::of(methods::FILTER_MAP_NEXT),
+    LintId::of(methods::FLAT_MAP_OPTION),
+    LintId::of(methods::FROM_ITER_INSTEAD_OF_COLLECT),
+    LintId::of(methods::IMPLICIT_CLONE),
+    LintId::of(methods::INEFFICIENT_TO_STRING),
+    LintId::of(methods::MAP_FLATTEN),
+    LintId::of(methods::MAP_UNWRAP_OR),
+    LintId::of(misc::FLOAT_CMP),
+    LintId::of(misc::USED_UNDERSCORE_BINDING),
+    LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
+    LintId::of(mut_mut::MUT_MUT),
+    LintId::of(needless_bitwise_bool::NEEDLESS_BITWISE_BOOL),
+    LintId::of(needless_borrow::REF_BINDING_TO_REFERENCE),
+    LintId::of(needless_continue::NEEDLESS_CONTINUE),
+    LintId::of(needless_for_each::NEEDLESS_FOR_EACH),
+    LintId::of(needless_pass_by_value::NEEDLESS_PASS_BY_VALUE),
+    LintId::of(non_expressive_names::MANY_SINGLE_CHAR_NAMES),
+    LintId::of(non_expressive_names::SIMILAR_NAMES),
+    LintId::of(pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE),
+    LintId::of(pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF),
+    LintId::of(ranges::RANGE_MINUS_ONE),
+    LintId::of(ranges::RANGE_PLUS_ONE),
+    LintId::of(redundant_else::REDUNDANT_ELSE),
+    LintId::of(ref_option_ref::REF_OPTION_REF),
+    LintId::of(semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED),
+    LintId::of(strings::STRING_ADD_ASSIGN),
+    LintId::of(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
+    LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
+    LintId::of(transmute::TRANSMUTE_PTR_TO_PTR),
+    LintId::of(types::LINKEDLIST),
+    LintId::of(types::OPTION_OPTION),
+    LintId::of(unicode::NON_ASCII_LITERAL),
+    LintId::of(unicode::UNICODE_NOT_NFC),
+    LintId::of(unit_types::LET_UNIT_VALUE),
+    LintId::of(unnecessary_wraps::UNNECESSARY_WRAPS),
+    LintId::of(unnested_or_patterns::UNNESTED_OR_PATTERNS),
+    LintId::of(unused_async::UNUSED_ASYNC),
+    LintId::of(unused_self::UNUSED_SELF),
+    LintId::of(wildcard_imports::ENUM_GLOB_USE),
+    LintId::of(wildcard_imports::WILDCARD_IMPORTS),
+    LintId::of(zero_sized_map_values::ZERO_SIZED_MAP_VALUES),
+])
diff --git a/clippy_lints/src/lib.register_perf.rs b/clippy_lints/src/lib.register_perf.rs
new file mode 100644
index 00000000000..5432345760b
--- /dev/null
+++ b/clippy_lints/src/lib.register_perf.rs
@@ -0,0 +1,27 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::perf", Some("clippy_perf"), vec![
+    LintId::of(entry::MAP_ENTRY),
+    LintId::of(escape::BOXED_LOCAL),
+    LintId::of(large_const_arrays::LARGE_CONST_ARRAYS),
+    LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
+    LintId::of(loops::MANUAL_MEMCPY),
+    LintId::of(loops::NEEDLESS_COLLECT),
+    LintId::of(methods::EXPECT_FUN_CALL),
+    LintId::of(methods::EXTEND_WITH_DRAIN),
+    LintId::of(methods::ITER_NTH),
+    LintId::of(methods::MANUAL_STR_REPEAT),
+    LintId::of(methods::OR_FUN_CALL),
+    LintId::of(methods::SINGLE_CHAR_PATTERN),
+    LintId::of(misc::CMP_OWNED),
+    LintId::of(mutex_atomic::MUTEX_ATOMIC),
+    LintId::of(redundant_clone::REDUNDANT_CLONE),
+    LintId::of(slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
+    LintId::of(stable_sort_primitive::STABLE_SORT_PRIMITIVE),
+    LintId::of(types::BOX_COLLECTION),
+    LintId::of(types::REDUNDANT_ALLOCATION),
+    LintId::of(vec::USELESS_VEC),
+    LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
+])
diff --git a/clippy_lints/src/lib.register_restriction.rs b/clippy_lints/src/lib.register_restriction.rs
new file mode 100644
index 00000000000..4463dea5fcb
--- /dev/null
+++ b/clippy_lints/src/lib.register_restriction.rs
@@ -0,0 +1,65 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
+    LintId::of(arithmetic::FLOAT_ARITHMETIC),
+    LintId::of(arithmetic::INTEGER_ARITHMETIC),
+    LintId::of(as_conversions::AS_CONVERSIONS),
+    LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
+    LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
+    LintId::of(create_dir::CREATE_DIR),
+    LintId::of(dbg_macro::DBG_MACRO),
+    LintId::of(default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK),
+    LintId::of(disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS),
+    LintId::of(else_if_without_else::ELSE_IF_WITHOUT_ELSE),
+    LintId::of(exhaustive_items::EXHAUSTIVE_ENUMS),
+    LintId::of(exhaustive_items::EXHAUSTIVE_STRUCTS),
+    LintId::of(exit::EXIT),
+    LintId::of(float_literal::LOSSY_FLOAT_LITERAL),
+    LintId::of(if_then_some_else_none::IF_THEN_SOME_ELSE_NONE),
+    LintId::of(implicit_return::IMPLICIT_RETURN),
+    LintId::of(indexing_slicing::INDEXING_SLICING),
+    LintId::of(inherent_impl::MULTIPLE_INHERENT_IMPL),
+    LintId::of(integer_division::INTEGER_DIVISION),
+    LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
+    LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
+    LintId::of(map_err_ignore::MAP_ERR_IGNORE),
+    LintId::of(matches::REST_PAT_IN_FULLY_BOUND_STRUCTS),
+    LintId::of(matches::WILDCARD_ENUM_MATCH_ARM),
+    LintId::of(mem_forget::MEM_FORGET),
+    LintId::of(methods::CLONE_ON_REF_PTR),
+    LintId::of(methods::EXPECT_USED),
+    LintId::of(methods::FILETYPE_IS_FILE),
+    LintId::of(methods::GET_UNWRAP),
+    LintId::of(methods::UNWRAP_USED),
+    LintId::of(misc::FLOAT_CMP_CONST),
+    LintId::of(misc_early::UNNEEDED_FIELD_PATTERN),
+    LintId::of(missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS),
+    LintId::of(missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES),
+    LintId::of(missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS),
+    LintId::of(module_style::MOD_MODULE_FILES),
+    LintId::of(module_style::SELF_NAMED_MODULE_FILES),
+    LintId::of(modulo_arithmetic::MODULO_ARITHMETIC),
+    LintId::of(panic_in_result_fn::PANIC_IN_RESULT_FN),
+    LintId::of(panic_unimplemented::PANIC),
+    LintId::of(panic_unimplemented::TODO),
+    LintId::of(panic_unimplemented::UNIMPLEMENTED),
+    LintId::of(panic_unimplemented::UNREACHABLE),
+    LintId::of(pattern_type_mismatch::PATTERN_TYPE_MISMATCH),
+    LintId::of(same_name_method::SAME_NAME_METHOD),
+    LintId::of(shadow::SHADOW_REUSE),
+    LintId::of(shadow::SHADOW_SAME),
+    LintId::of(shadow::SHADOW_UNRELATED),
+    LintId::of(strings::STRING_ADD),
+    LintId::of(strings::STRING_TO_STRING),
+    LintId::of(strings::STR_TO_STRING),
+    LintId::of(types::RC_BUFFER),
+    LintId::of(types::RC_MUTEX),
+    LintId::of(unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS),
+    LintId::of(unwrap_in_result::UNWRAP_IN_RESULT),
+    LintId::of(verbose_file_reads::VERBOSE_FILE_READS),
+    LintId::of(write::PRINT_STDERR),
+    LintId::of(write::PRINT_STDOUT),
+    LintId::of(write::USE_DEBUG),
+])
diff --git a/clippy_lints/src/lib.register_style.rs b/clippy_lints/src/lib.register_style.rs
new file mode 100644
index 00000000000..a39c111c574
--- /dev/null
+++ b/clippy_lints/src/lib.register_style.rs
@@ -0,0 +1,114 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::style", Some("clippy_style"), vec![
+    LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
+    LintId::of(assign_ops::ASSIGN_OP_PATTERN),
+    LintId::of(blacklisted_name::BLACKLISTED_NAME),
+    LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
+    LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
+    LintId::of(casts::FN_TO_NUMERIC_CAST),
+    LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
+    LintId::of(collapsible_if::COLLAPSIBLE_ELSE_IF),
+    LintId::of(collapsible_if::COLLAPSIBLE_IF),
+    LintId::of(collapsible_match::COLLAPSIBLE_MATCH),
+    LintId::of(comparison_chain::COMPARISON_CHAIN),
+    LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
+    LintId::of(doc::MISSING_SAFETY_DOC),
+    LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
+    LintId::of(enum_variants::ENUM_VARIANT_NAMES),
+    LintId::of(enum_variants::MODULE_INCEPTION),
+    LintId::of(eq_op::OP_REF),
+    LintId::of(eta_reduction::REDUNDANT_CLOSURE),
+    LintId::of(float_literal::EXCESSIVE_PRECISION),
+    LintId::of(from_over_into::FROM_OVER_INTO),
+    LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
+    LintId::of(functions::DOUBLE_MUST_USE),
+    LintId::of(functions::MUST_USE_UNIT),
+    LintId::of(functions::RESULT_UNIT_ERR),
+    LintId::of(if_then_panic::IF_THEN_PANIC),
+    LintId::of(inherent_to_string::INHERENT_TO_STRING),
+    LintId::of(len_zero::COMPARISON_TO_EMPTY),
+    LintId::of(len_zero::LEN_WITHOUT_IS_EMPTY),
+    LintId::of(len_zero::LEN_ZERO),
+    LintId::of(literal_representation::INCONSISTENT_DIGIT_GROUPING),
+    LintId::of(literal_representation::UNUSUAL_BYTE_GROUPINGS),
+    LintId::of(loops::FOR_KV_MAP),
+    LintId::of(loops::NEEDLESS_RANGE_LOOP),
+    LintId::of(loops::SAME_ITEM_PUSH),
+    LintId::of(loops::WHILE_LET_ON_ITERATOR),
+    LintId::of(main_recursion::MAIN_RECURSION),
+    LintId::of(manual_async_fn::MANUAL_ASYNC_FN),
+    LintId::of(manual_map::MANUAL_MAP),
+    LintId::of(manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
+    LintId::of(map_clone::MAP_CLONE),
+    LintId::of(match_result_ok::MATCH_RESULT_OK),
+    LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
+    LintId::of(matches::MATCH_LIKE_MATCHES_MACRO),
+    LintId::of(matches::MATCH_OVERLAPPING_ARM),
+    LintId::of(matches::MATCH_REF_PATS),
+    LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
+    LintId::of(matches::SINGLE_MATCH),
+    LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
+    LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
+    LintId::of(methods::BYTES_NTH),
+    LintId::of(methods::CHARS_LAST_CMP),
+    LintId::of(methods::CHARS_NEXT_CMP),
+    LintId::of(methods::INTO_ITER_ON_REF),
+    LintId::of(methods::ITER_CLONED_COLLECT),
+    LintId::of(methods::ITER_NEXT_SLICE),
+    LintId::of(methods::ITER_NTH_ZERO),
+    LintId::of(methods::ITER_SKIP_NEXT),
+    LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
+    LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
+    LintId::of(methods::NEW_RET_NO_SELF),
+    LintId::of(methods::OK_EXPECT),
+    LintId::of(methods::OPTION_MAP_OR_NONE),
+    LintId::of(methods::RESULT_MAP_OR_INTO_OPTION),
+    LintId::of(methods::SHOULD_IMPLEMENT_TRAIT),
+    LintId::of(methods::SINGLE_CHAR_ADD_STR),
+    LintId::of(methods::STRING_EXTEND_CHARS),
+    LintId::of(methods::UNNECESSARY_FOLD),
+    LintId::of(methods::UNNECESSARY_LAZY_EVALUATIONS),
+    LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
+    LintId::of(methods::WRONG_SELF_CONVENTION),
+    LintId::of(misc::TOPLEVEL_REF_ARG),
+    LintId::of(misc::ZERO_PTR),
+    LintId::of(misc_early::BUILTIN_TYPE_SHADOW),
+    LintId::of(misc_early::DOUBLE_NEG),
+    LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
+    LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
+    LintId::of(misc_early::REDUNDANT_PATTERN),
+    LintId::of(mut_mutex_lock::MUT_MUTEX_LOCK),
+    LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
+    LintId::of(needless_borrow::NEEDLESS_BORROW),
+    LintId::of(neg_multiply::NEG_MULTIPLY),
+    LintId::of(new_without_default::NEW_WITHOUT_DEFAULT),
+    LintId::of(non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
+    LintId::of(non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
+    LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
+    LintId::of(ptr::CMP_NULL),
+    LintId::of(ptr::PTR_ARG),
+    LintId::of(ptr_eq::PTR_EQ),
+    LintId::of(question_mark::QUESTION_MARK),
+    LintId::of(ranges::MANUAL_RANGE_CONTAINS),
+    LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
+    LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
+    LintId::of(returns::LET_AND_RETURN),
+    LintId::of(returns::NEEDLESS_RETURN),
+    LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
+    LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
+    LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
+    LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
+    LintId::of(try_err::TRY_ERR),
+    LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
+    LintId::of(unused_unit::UNUSED_UNIT),
+    LintId::of(upper_case_acronyms::UPPER_CASE_ACRONYMS),
+    LintId::of(write::PRINTLN_EMPTY_STRING),
+    LintId::of(write::PRINT_LITERAL),
+    LintId::of(write::PRINT_WITH_NEWLINE),
+    LintId::of(write::WRITELN_EMPTY_STRING),
+    LintId::of(write::WRITE_LITERAL),
+    LintId::of(write::WRITE_WITH_NEWLINE),
+])
diff --git a/clippy_lints/src/lib.register_suspicious.rs b/clippy_lints/src/lib.register_suspicious.rs
new file mode 100644
index 00000000000..8859787fbc8
--- /dev/null
+++ b/clippy_lints/src/lib.register_suspicious.rs
@@ -0,0 +1,20 @@
+// This file was generated by `cargo dev update_lints`.
+// Use that command to update this file and do not edit by hand.
+// Manual edits will be overwritten.
+
+store.register_group(true, "clippy::suspicious", Some("clippy_suspicious"), vec![
+    LintId::of(assign_ops::MISREFACTORED_ASSIGN_OP),
+    LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
+    LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
+    LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
+    LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
+    LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
+    LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
+    LintId::of(loops::EMPTY_LOOP),
+    LintId::of(loops::FOR_LOOPS_OVER_FALLIBLES),
+    LintId::of(loops::MUT_RANGE_BOUND),
+    LintId::of(methods::SUSPICIOUS_MAP),
+    LintId::of(mut_key::MUTABLE_KEY_TYPE),
+    LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
+    LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
+])
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index 89724917482..9fc6a9e0ccc 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -203,6 +203,7 @@ mod entry;
 mod enum_clike;
 mod enum_variants;
 mod eq_op;
+mod equatable_if_let;
 mod erasing_op;
 mod escape;
 mod eta_reduction;
@@ -303,6 +304,7 @@ mod no_effect;
 mod non_copy_const;
 mod non_expressive_names;
 mod non_octal_unix_permissions;
+mod non_send_fields_in_send_ty;
 mod nonstandard_macro_braces;
 mod open_options;
 mod option_env_unwrap;
@@ -438,1401 +440,23 @@ pub fn read_conf(sess: &Session) -> Conf {
 pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
     register_removed_non_tool_lints(store);
 
-    // begin deprecated lints, do not remove this comment, it’s used in `update_lints`
-    store.register_removed(
-        "clippy::should_assert_eq",
-        "`assert!()` will be more flexible with RFC 2011",
-    );
-    store.register_removed(
-        "clippy::extend_from_slice",
-        "`.extend_from_slice(_)` is a faster way to extend a Vec by a slice",
-    );
-    store.register_removed(
-        "clippy::range_step_by_zero",
-        "`iterator.step_by(0)` panics nowadays",
-    );
-    store.register_removed(
-        "clippy::unstable_as_slice",
-        "`Vec::as_slice` has been stabilized in 1.7",
-    );
-    store.register_removed(
-        "clippy::unstable_as_mut_slice",
-        "`Vec::as_mut_slice` has been stabilized in 1.7",
-    );
-    store.register_removed(
-        "clippy::misaligned_transmute",
-        "this lint has been split into cast_ptr_alignment and transmute_ptr_to_ptr",
-    );
-    store.register_removed(
-        "clippy::assign_ops",
-        "using compound assignment operators (e.g., `+=`) is harmless",
-    );
-    store.register_removed(
-        "clippy::if_let_redundant_pattern_matching",
-        "this lint has been changed to redundant_pattern_matching",
-    );
-    store.register_removed(
-        "clippy::unsafe_vector_initialization",
-        "the replacement suggested by this lint had substantially different behavior",
-    );
-    store.register_removed(
-        "clippy::unused_collect",
-        "`collect` has been marked as #[must_use] in rustc and that covers all cases of this lint",
-    );
-    store.register_removed(
-        "clippy::replace_consts",
-        "associated-constants `MIN`/`MAX` of integers are preferred to `{min,max}_value()` and module constants",
-    );
-    store.register_removed(
-        "clippy::regex_macro",
-        "the regex! macro has been removed from the regex crate in 2018",
-    );
-    store.register_removed(
-        "clippy::find_map",
-        "this lint has been replaced by `manual_find_map`, a more specific lint",
-    );
-    store.register_removed(
-        "clippy::filter_map",
-        "this lint has been replaced by `manual_filter_map`, a more specific lint",
-    );
-    store.register_removed(
-        "clippy::pub_enum_variant_names",
-        "set the `avoid-breaking-exported-api` config option to `false` to enable the `enum_variant_names` lint for public items",
-    );
-    store.register_removed(
-        "clippy::wrong_pub_self_convention",
-        "set the `avoid-breaking-exported-api` config option to `false` to enable the `wrong_self_convention` lint for public items",
-    );
-    // end deprecated lints, do not remove this comment, it’s used in `update_lints`
+    include!("lib.deprecated.rs");
 
-    // begin register lints, do not remove this comment, it’s used in `update_lints`
-    store.register_lints(&[
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::CLIPPY_LINTS_INTERNAL,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::COMPILER_LINT_FUNCTIONS,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::DEFAULT_LINT,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::IF_CHAIN_STYLE,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::INTERNING_DEFINED_SYMBOL,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::INVALID_PATHS,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::LINT_WITHOUT_LINT_PASS,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::OUTER_EXPN_EXPN_DATA,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::PRODUCE_ICE,
-        #[cfg(feature = "internal-lints")]
-        utils::internal_lints::UNNECESSARY_SYMBOL_STR,
-        absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS,
-        approx_const::APPROX_CONSTANT,
-        arithmetic::FLOAT_ARITHMETIC,
-        arithmetic::INTEGER_ARITHMETIC,
-        as_conversions::AS_CONVERSIONS,
-        asm_syntax::INLINE_ASM_X86_ATT_SYNTAX,
-        asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX,
-        assertions_on_constants::ASSERTIONS_ON_CONSTANTS,
-        assign_ops::ASSIGN_OP_PATTERN,
-        assign_ops::MISREFACTORED_ASSIGN_OP,
-        async_yields_async::ASYNC_YIELDS_ASYNC,
-        attrs::BLANKET_CLIPPY_RESTRICTION_LINTS,
-        attrs::DEPRECATED_CFG_ATTR,
-        attrs::DEPRECATED_SEMVER,
-        attrs::EMPTY_LINE_AFTER_OUTER_ATTR,
-        attrs::INLINE_ALWAYS,
-        attrs::MISMATCHED_TARGET_OS,
-        attrs::USELESS_ATTRIBUTE,
-        await_holding_invalid::AWAIT_HOLDING_LOCK,
-        await_holding_invalid::AWAIT_HOLDING_REFCELL_REF,
-        bit_mask::BAD_BIT_MASK,
-        bit_mask::INEFFECTIVE_BIT_MASK,
-        bit_mask::VERBOSE_BIT_MASK,
-        blacklisted_name::BLACKLISTED_NAME,
-        blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS,
-        bool_assert_comparison::BOOL_ASSERT_COMPARISON,
-        booleans::LOGIC_BUG,
-        booleans::NONMINIMAL_BOOL,
-        bytecount::NAIVE_BYTECOUNT,
-        cargo_common_metadata::CARGO_COMMON_METADATA,
-        case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS,
-        casts::CAST_LOSSLESS,
-        casts::CAST_POSSIBLE_TRUNCATION,
-        casts::CAST_POSSIBLE_WRAP,
-        casts::CAST_PRECISION_LOSS,
-        casts::CAST_PTR_ALIGNMENT,
-        casts::CAST_REF_TO_MUT,
-        casts::CAST_SIGN_LOSS,
-        casts::CHAR_LIT_AS_U8,
-        casts::FN_TO_NUMERIC_CAST,
-        casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
-        casts::PTR_AS_PTR,
-        casts::UNNECESSARY_CAST,
-        checked_conversions::CHECKED_CONVERSIONS,
-        cognitive_complexity::COGNITIVE_COMPLEXITY,
-        collapsible_if::COLLAPSIBLE_ELSE_IF,
-        collapsible_if::COLLAPSIBLE_IF,
-        collapsible_match::COLLAPSIBLE_MATCH,
-        comparison_chain::COMPARISON_CHAIN,
-        copies::BRANCHES_SHARING_CODE,
-        copies::IFS_SAME_COND,
-        copies::IF_SAME_THEN_ELSE,
-        copies::SAME_FUNCTIONS_IN_IF_CONDITION,
-        copy_iterator::COPY_ITERATOR,
-        create_dir::CREATE_DIR,
-        dbg_macro::DBG_MACRO,
-        default::DEFAULT_TRAIT_ACCESS,
-        default::FIELD_REASSIGN_WITH_DEFAULT,
-        default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK,
-        dereference::EXPLICIT_DEREF_METHODS,
-        derivable_impls::DERIVABLE_IMPLS,
-        derive::DERIVE_HASH_XOR_EQ,
-        derive::DERIVE_ORD_XOR_PARTIAL_ORD,
-        derive::EXPL_IMPL_CLONE_ON_COPY,
-        derive::UNSAFE_DERIVE_DESERIALIZE,
-        disallowed_method::DISALLOWED_METHOD,
-        disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS,
-        disallowed_type::DISALLOWED_TYPE,
-        doc::DOC_MARKDOWN,
-        doc::MISSING_ERRORS_DOC,
-        doc::MISSING_PANICS_DOC,
-        doc::MISSING_SAFETY_DOC,
-        doc::NEEDLESS_DOCTEST_MAIN,
-        double_comparison::DOUBLE_COMPARISONS,
-        double_parens::DOUBLE_PARENS,
-        drop_forget_ref::DROP_COPY,
-        drop_forget_ref::DROP_REF,
-        drop_forget_ref::FORGET_COPY,
-        drop_forget_ref::FORGET_REF,
-        duration_subsec::DURATION_SUBSEC,
-        else_if_without_else::ELSE_IF_WITHOUT_ELSE,
-        empty_enum::EMPTY_ENUM,
-        entry::MAP_ENTRY,
-        enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT,
-        enum_variants::ENUM_VARIANT_NAMES,
-        enum_variants::MODULE_INCEPTION,
-        enum_variants::MODULE_NAME_REPETITIONS,
-        eq_op::EQ_OP,
-        eq_op::OP_REF,
-        erasing_op::ERASING_OP,
-        escape::BOXED_LOCAL,
-        eta_reduction::REDUNDANT_CLOSURE,
-        eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS,
-        eval_order_dependence::DIVERGING_SUB_EXPRESSION,
-        eval_order_dependence::EVAL_ORDER_DEPENDENCE,
-        excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS,
-        excessive_bools::STRUCT_EXCESSIVE_BOOLS,
-        exhaustive_items::EXHAUSTIVE_ENUMS,
-        exhaustive_items::EXHAUSTIVE_STRUCTS,
-        exit::EXIT,
-        explicit_write::EXPLICIT_WRITE,
-        fallible_impl_from::FALLIBLE_IMPL_FROM,
-        feature_name::NEGATIVE_FEATURE_NAMES,
-        feature_name::REDUNDANT_FEATURE_NAMES,
-        float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS,
-        float_literal::EXCESSIVE_PRECISION,
-        float_literal::LOSSY_FLOAT_LITERAL,
-        floating_point_arithmetic::IMPRECISE_FLOPS,
-        floating_point_arithmetic::SUBOPTIMAL_FLOPS,
-        format::USELESS_FORMAT,
-        formatting::POSSIBLE_MISSING_COMMA,
-        formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING,
-        formatting::SUSPICIOUS_ELSE_FORMATTING,
-        formatting::SUSPICIOUS_UNARY_OP_FORMATTING,
-        from_over_into::FROM_OVER_INTO,
-        from_str_radix_10::FROM_STR_RADIX_10,
-        functions::DOUBLE_MUST_USE,
-        functions::MUST_USE_CANDIDATE,
-        functions::MUST_USE_UNIT,
-        functions::NOT_UNSAFE_PTR_ARG_DEREF,
-        functions::RESULT_UNIT_ERR,
-        functions::TOO_MANY_ARGUMENTS,
-        functions::TOO_MANY_LINES,
-        future_not_send::FUTURE_NOT_SEND,
-        get_last_with_len::GET_LAST_WITH_LEN,
-        identity_op::IDENTITY_OP,
-        if_let_mutex::IF_LET_MUTEX,
-        if_not_else::IF_NOT_ELSE,
-        if_then_panic::IF_THEN_PANIC,
-        if_then_some_else_none::IF_THEN_SOME_ELSE_NONE,
-        implicit_hasher::IMPLICIT_HASHER,
-        implicit_return::IMPLICIT_RETURN,
-        implicit_saturating_sub::IMPLICIT_SATURATING_SUB,
-        inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR,
-        indexing_slicing::INDEXING_SLICING,
-        indexing_slicing::OUT_OF_BOUNDS_INDEXING,
-        infinite_iter::INFINITE_ITER,
-        infinite_iter::MAYBE_INFINITE_ITER,
-        inherent_impl::MULTIPLE_INHERENT_IMPL,
-        inherent_to_string::INHERENT_TO_STRING,
-        inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY,
-        inline_fn_without_body::INLINE_FN_WITHOUT_BODY,
-        int_plus_one::INT_PLUS_ONE,
-        integer_division::INTEGER_DIVISION,
-        invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS,
-        items_after_statements::ITEMS_AFTER_STATEMENTS,
-        iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR,
-        large_const_arrays::LARGE_CONST_ARRAYS,
-        large_enum_variant::LARGE_ENUM_VARIANT,
-        large_stack_arrays::LARGE_STACK_ARRAYS,
-        len_zero::COMPARISON_TO_EMPTY,
-        len_zero::LEN_WITHOUT_IS_EMPTY,
-        len_zero::LEN_ZERO,
-        let_if_seq::USELESS_LET_IF_SEQ,
-        let_underscore::LET_UNDERSCORE_DROP,
-        let_underscore::LET_UNDERSCORE_LOCK,
-        let_underscore::LET_UNDERSCORE_MUST_USE,
-        lifetimes::EXTRA_UNUSED_LIFETIMES,
-        lifetimes::NEEDLESS_LIFETIMES,
-        literal_representation::DECIMAL_LITERAL_REPRESENTATION,
-        literal_representation::INCONSISTENT_DIGIT_GROUPING,
-        literal_representation::LARGE_DIGIT_GROUPS,
-        literal_representation::MISTYPED_LITERAL_SUFFIXES,
-        literal_representation::UNREADABLE_LITERAL,
-        literal_representation::UNUSUAL_BYTE_GROUPINGS,
-        loops::EMPTY_LOOP,
-        loops::EXPLICIT_COUNTER_LOOP,
-        loops::EXPLICIT_INTO_ITER_LOOP,
-        loops::EXPLICIT_ITER_LOOP,
-        loops::FOR_KV_MAP,
-        loops::FOR_LOOPS_OVER_FALLIBLES,
-        loops::ITER_NEXT_LOOP,
-        loops::MANUAL_FLATTEN,
-        loops::MANUAL_MEMCPY,
-        loops::MUT_RANGE_BOUND,
-        loops::NEEDLESS_COLLECT,
-        loops::NEEDLESS_RANGE_LOOP,
-        loops::NEVER_LOOP,
-        loops::SAME_ITEM_PUSH,
-        loops::SINGLE_ELEMENT_LOOP,
-        loops::WHILE_IMMUTABLE_CONDITION,
-        loops::WHILE_LET_LOOP,
-        loops::WHILE_LET_ON_ITERATOR,
-        macro_use::MACRO_USE_IMPORTS,
-        main_recursion::MAIN_RECURSION,
-        manual_async_fn::MANUAL_ASYNC_FN,
-        manual_map::MANUAL_MAP,
-        manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE,
-        manual_ok_or::MANUAL_OK_OR,
-        manual_strip::MANUAL_STRIP,
-        manual_unwrap_or::MANUAL_UNWRAP_OR,
-        map_clone::MAP_CLONE,
-        map_err_ignore::MAP_ERR_IGNORE,
-        map_unit_fn::OPTION_MAP_UNIT_FN,
-        map_unit_fn::RESULT_MAP_UNIT_FN,
-        match_on_vec_items::MATCH_ON_VEC_ITEMS,
-        match_result_ok::MATCH_RESULT_OK,
-        matches::INFALLIBLE_DESTRUCTURING_MATCH,
-        matches::MATCH_AS_REF,
-        matches::MATCH_BOOL,
-        matches::MATCH_LIKE_MATCHES_MACRO,
-        matches::MATCH_OVERLAPPING_ARM,
-        matches::MATCH_REF_PATS,
-        matches::MATCH_SAME_ARMS,
-        matches::MATCH_SINGLE_BINDING,
-        matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS,
-        matches::MATCH_WILD_ERR_ARM,
-        matches::REDUNDANT_PATTERN_MATCHING,
-        matches::REST_PAT_IN_FULLY_BOUND_STRUCTS,
-        matches::SINGLE_MATCH,
-        matches::SINGLE_MATCH_ELSE,
-        matches::WILDCARD_ENUM_MATCH_ARM,
-        matches::WILDCARD_IN_OR_PATTERNS,
-        mem_discriminant::MEM_DISCRIMINANT_NON_ENUM,
-        mem_forget::MEM_FORGET,
-        mem_replace::MEM_REPLACE_OPTION_WITH_NONE,
-        mem_replace::MEM_REPLACE_WITH_DEFAULT,
-        mem_replace::MEM_REPLACE_WITH_UNINIT,
-        methods::BIND_INSTEAD_OF_MAP,
-        methods::BYTES_NTH,
-        methods::CHARS_LAST_CMP,
-        methods::CHARS_NEXT_CMP,
-        methods::CLONED_INSTEAD_OF_COPIED,
-        methods::CLONE_DOUBLE_REF,
-        methods::CLONE_ON_COPY,
-        methods::CLONE_ON_REF_PTR,
-        methods::EXPECT_FUN_CALL,
-        methods::EXPECT_USED,
-        methods::EXTEND_WITH_DRAIN,
-        methods::FILETYPE_IS_FILE,
-        methods::FILTER_MAP_IDENTITY,
-        methods::FILTER_MAP_NEXT,
-        methods::FILTER_NEXT,
-        methods::FLAT_MAP_IDENTITY,
-        methods::FLAT_MAP_OPTION,
-        methods::FROM_ITER_INSTEAD_OF_COLLECT,
-        methods::GET_UNWRAP,
-        methods::IMPLICIT_CLONE,
-        methods::INEFFICIENT_TO_STRING,
-        methods::INSPECT_FOR_EACH,
-        methods::INTO_ITER_ON_REF,
-        methods::ITERATOR_STEP_BY_ZERO,
-        methods::ITER_CLONED_COLLECT,
-        methods::ITER_COUNT,
-        methods::ITER_NEXT_SLICE,
-        methods::ITER_NTH,
-        methods::ITER_NTH_ZERO,
-        methods::ITER_SKIP_NEXT,
-        methods::MANUAL_FILTER_MAP,
-        methods::MANUAL_FIND_MAP,
-        methods::MANUAL_SATURATING_ARITHMETIC,
-        methods::MANUAL_SPLIT_ONCE,
-        methods::MANUAL_STR_REPEAT,
-        methods::MAP_COLLECT_RESULT_UNIT,
-        methods::MAP_FLATTEN,
-        methods::MAP_IDENTITY,
-        methods::MAP_UNWRAP_OR,
-        methods::NEW_RET_NO_SELF,
-        methods::OK_EXPECT,
-        methods::OPTION_AS_REF_DEREF,
-        methods::OPTION_FILTER_MAP,
-        methods::OPTION_MAP_OR_NONE,
-        methods::OR_FUN_CALL,
-        methods::RESULT_MAP_OR_INTO_OPTION,
-        methods::SEARCH_IS_SOME,
-        methods::SHOULD_IMPLEMENT_TRAIT,
-        methods::SINGLE_CHAR_ADD_STR,
-        methods::SINGLE_CHAR_PATTERN,
-        methods::SKIP_WHILE_NEXT,
-        methods::STRING_EXTEND_CHARS,
-        methods::SUSPICIOUS_MAP,
-        methods::SUSPICIOUS_SPLITN,
-        methods::UNINIT_ASSUMED_INIT,
-        methods::UNNECESSARY_FILTER_MAP,
-        methods::UNNECESSARY_FOLD,
-        methods::UNNECESSARY_LAZY_EVALUATIONS,
-        methods::UNWRAP_OR_ELSE_DEFAULT,
-        methods::UNWRAP_USED,
-        methods::USELESS_ASREF,
-        methods::WRONG_SELF_CONVENTION,
-        methods::ZST_OFFSET,
-        minmax::MIN_MAX,
-        misc::CMP_NAN,
-        misc::CMP_OWNED,
-        misc::FLOAT_CMP,
-        misc::FLOAT_CMP_CONST,
-        misc::MODULO_ONE,
-        misc::SHORT_CIRCUIT_STATEMENT,
-        misc::TOPLEVEL_REF_ARG,
-        misc::USED_UNDERSCORE_BINDING,
-        misc::ZERO_PTR,
-        misc_early::BUILTIN_TYPE_SHADOW,
-        misc_early::DOUBLE_NEG,
-        misc_early::DUPLICATE_UNDERSCORE_ARGUMENT,
-        misc_early::MIXED_CASE_HEX_LITERALS,
-        misc_early::REDUNDANT_PATTERN,
-        misc_early::UNNEEDED_FIELD_PATTERN,
-        misc_early::UNNEEDED_WILDCARD_PATTERN,
-        misc_early::UNSEPARATED_LITERAL_SUFFIX,
-        misc_early::ZERO_PREFIXED_LITERAL,
-        missing_const_for_fn::MISSING_CONST_FOR_FN,
-        missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS,
-        missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES,
-        missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS,
-        module_style::MOD_MODULE_FILES,
-        module_style::SELF_NAMED_MODULE_FILES,
-        modulo_arithmetic::MODULO_ARITHMETIC,
-        multiple_crate_versions::MULTIPLE_CRATE_VERSIONS,
-        mut_key::MUTABLE_KEY_TYPE,
-        mut_mut::MUT_MUT,
-        mut_mutex_lock::MUT_MUTEX_LOCK,
-        mut_reference::UNNECESSARY_MUT_PASSED,
-        mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL,
-        mutex_atomic::MUTEX_ATOMIC,
-        mutex_atomic::MUTEX_INTEGER,
-        needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE,
-        needless_bitwise_bool::NEEDLESS_BITWISE_BOOL,
-        needless_bool::BOOL_COMPARISON,
-        needless_bool::NEEDLESS_BOOL,
-        needless_borrow::NEEDLESS_BORROW,
-        needless_borrow::REF_BINDING_TO_REFERENCE,
-        needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE,
-        needless_continue::NEEDLESS_CONTINUE,
-        needless_for_each::NEEDLESS_FOR_EACH,
-        needless_option_as_deref::NEEDLESS_OPTION_AS_DEREF,
-        needless_pass_by_value::NEEDLESS_PASS_BY_VALUE,
-        needless_question_mark::NEEDLESS_QUESTION_MARK,
-        needless_update::NEEDLESS_UPDATE,
-        neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD,
-        neg_multiply::NEG_MULTIPLY,
-        new_without_default::NEW_WITHOUT_DEFAULT,
-        no_effect::NO_EFFECT,
-        no_effect::UNNECESSARY_OPERATION,
-        non_copy_const::BORROW_INTERIOR_MUTABLE_CONST,
-        non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST,
-        non_expressive_names::JUST_UNDERSCORES_AND_DIGITS,
-        non_expressive_names::MANY_SINGLE_CHAR_NAMES,
-        non_expressive_names::SIMILAR_NAMES,
-        non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS,
-        nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES,
-        open_options::NONSENSICAL_OPEN_OPTIONS,
-        option_env_unwrap::OPTION_ENV_UNWRAP,
-        option_if_let_else::OPTION_IF_LET_ELSE,
-        overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL,
-        panic_in_result_fn::PANIC_IN_RESULT_FN,
-        panic_unimplemented::PANIC,
-        panic_unimplemented::TODO,
-        panic_unimplemented::UNIMPLEMENTED,
-        panic_unimplemented::UNREACHABLE,
-        partialeq_ne_impl::PARTIALEQ_NE_IMPL,
-        pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE,
-        pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF,
-        path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE,
-        pattern_type_mismatch::PATTERN_TYPE_MISMATCH,
-        precedence::PRECEDENCE,
-        ptr::CMP_NULL,
-        ptr::INVALID_NULL_PTR_USAGE,
-        ptr::MUT_FROM_REF,
-        ptr::PTR_ARG,
-        ptr_eq::PTR_EQ,
-        ptr_offset_with_cast::PTR_OFFSET_WITH_CAST,
-        question_mark::QUESTION_MARK,
-        ranges::MANUAL_RANGE_CONTAINS,
-        ranges::RANGE_MINUS_ONE,
-        ranges::RANGE_PLUS_ONE,
-        ranges::RANGE_ZIP_WITH_LEN,
-        ranges::REVERSED_EMPTY_RANGES,
-        redundant_clone::REDUNDANT_CLONE,
-        redundant_closure_call::REDUNDANT_CLOSURE_CALL,
-        redundant_else::REDUNDANT_ELSE,
-        redundant_field_names::REDUNDANT_FIELD_NAMES,
-        redundant_pub_crate::REDUNDANT_PUB_CRATE,
-        redundant_slicing::REDUNDANT_SLICING,
-        redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES,
-        ref_option_ref::REF_OPTION_REF,
-        reference::DEREF_ADDROF,
-        reference::REF_IN_DEREF,
-        regex::INVALID_REGEX,
-        regex::TRIVIAL_REGEX,
-        repeat_once::REPEAT_ONCE,
-        returns::LET_AND_RETURN,
-        returns::NEEDLESS_RETURN,
-        same_name_method::SAME_NAME_METHOD,
-        self_assignment::SELF_ASSIGNMENT,
-        self_named_constructors::SELF_NAMED_CONSTRUCTORS,
-        semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED,
-        serde_api::SERDE_API_MISUSE,
-        shadow::SHADOW_REUSE,
-        shadow::SHADOW_SAME,
-        shadow::SHADOW_UNRELATED,
-        single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS,
-        size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT,
-        slow_vector_initialization::SLOW_VECTOR_INITIALIZATION,
-        stable_sort_primitive::STABLE_SORT_PRIMITIVE,
-        strings::STRING_ADD,
-        strings::STRING_ADD_ASSIGN,
-        strings::STRING_FROM_UTF8_AS_BYTES,
-        strings::STRING_LIT_AS_BYTES,
-        strings::STRING_TO_STRING,
-        strings::STR_TO_STRING,
-        strlen_on_c_strings::STRLEN_ON_C_STRINGS,
-        suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS,
-        suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL,
-        suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL,
-        swap::ALMOST_SWAPPED,
-        swap::MANUAL_SWAP,
-        tabs_in_doc_comments::TABS_IN_DOC_COMMENTS,
-        temporary_assignment::TEMPORARY_ASSIGNMENT,
-        to_digit_is_some::TO_DIGIT_IS_SOME,
-        to_string_in_display::TO_STRING_IN_DISPLAY,
-        trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS,
-        trait_bounds::TYPE_REPETITION_IN_BOUNDS,
-        transmute::CROSSPOINTER_TRANSMUTE,
-        transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
-        transmute::TRANSMUTE_BYTES_TO_STR,
-        transmute::TRANSMUTE_FLOAT_TO_INT,
-        transmute::TRANSMUTE_INT_TO_BOOL,
-        transmute::TRANSMUTE_INT_TO_CHAR,
-        transmute::TRANSMUTE_INT_TO_FLOAT,
-        transmute::TRANSMUTE_PTR_TO_PTR,
-        transmute::TRANSMUTE_PTR_TO_REF,
-        transmute::UNSOUND_COLLECTION_TRANSMUTE,
-        transmute::USELESS_TRANSMUTE,
-        transmute::WRONG_TRANSMUTE,
-        transmuting_null::TRANSMUTING_NULL,
-        try_err::TRY_ERR,
-        types::BORROWED_BOX,
-        types::BOX_COLLECTION,
-        types::LINKEDLIST,
-        types::OPTION_OPTION,
-        types::RC_BUFFER,
-        types::RC_MUTEX,
-        types::REDUNDANT_ALLOCATION,
-        types::TYPE_COMPLEXITY,
-        types::VEC_BOX,
-        undropped_manually_drops::UNDROPPED_MANUALLY_DROPS,
-        unicode::INVISIBLE_CHARACTERS,
-        unicode::NON_ASCII_LITERAL,
-        unicode::UNICODE_NOT_NFC,
-        unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD,
-        unit_types::LET_UNIT_VALUE,
-        unit_types::UNIT_ARG,
-        unit_types::UNIT_CMP,
-        unnamed_address::FN_ADDRESS_COMPARISONS,
-        unnamed_address::VTABLE_ADDRESS_COMPARISONS,
-        unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS,
-        unnecessary_sort_by::UNNECESSARY_SORT_BY,
-        unnecessary_wraps::UNNECESSARY_WRAPS,
-        unnested_or_patterns::UNNESTED_OR_PATTERNS,
-        unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME,
-        unused_async::UNUSED_ASYNC,
-        unused_io_amount::UNUSED_IO_AMOUNT,
-        unused_self::UNUSED_SELF,
-        unused_unit::UNUSED_UNIT,
-        unwrap::PANICKING_UNWRAP,
-        unwrap::UNNECESSARY_UNWRAP,
-        unwrap_in_result::UNWRAP_IN_RESULT,
-        upper_case_acronyms::UPPER_CASE_ACRONYMS,
-        use_self::USE_SELF,
-        useless_conversion::USELESS_CONVERSION,
-        vec::USELESS_VEC,
-        vec_init_then_push::VEC_INIT_THEN_PUSH,
-        vec_resize_to_zero::VEC_RESIZE_TO_ZERO,
-        verbose_file_reads::VERBOSE_FILE_READS,
-        wildcard_dependencies::WILDCARD_DEPENDENCIES,
-        wildcard_imports::ENUM_GLOB_USE,
-        wildcard_imports::WILDCARD_IMPORTS,
-        write::PRINTLN_EMPTY_STRING,
-        write::PRINT_LITERAL,
-        write::PRINT_STDERR,
-        write::PRINT_STDOUT,
-        write::PRINT_WITH_NEWLINE,
-        write::USE_DEBUG,
-        write::WRITELN_EMPTY_STRING,
-        write::WRITE_LITERAL,
-        write::WRITE_WITH_NEWLINE,
-        zero_div_zero::ZERO_DIVIDED_BY_ZERO,
-        zero_sized_map_values::ZERO_SIZED_MAP_VALUES,
-    ]);
-    // end register lints, do not remove this comment, it’s used in `update_lints`
-
-    store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
-        LintId::of(arithmetic::FLOAT_ARITHMETIC),
-        LintId::of(arithmetic::INTEGER_ARITHMETIC),
-        LintId::of(as_conversions::AS_CONVERSIONS),
-        LintId::of(asm_syntax::INLINE_ASM_X86_ATT_SYNTAX),
-        LintId::of(asm_syntax::INLINE_ASM_X86_INTEL_SYNTAX),
-        LintId::of(create_dir::CREATE_DIR),
-        LintId::of(dbg_macro::DBG_MACRO),
-        LintId::of(default_numeric_fallback::DEFAULT_NUMERIC_FALLBACK),
-        LintId::of(disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS),
-        LintId::of(else_if_without_else::ELSE_IF_WITHOUT_ELSE),
-        LintId::of(exhaustive_items::EXHAUSTIVE_ENUMS),
-        LintId::of(exhaustive_items::EXHAUSTIVE_STRUCTS),
-        LintId::of(exit::EXIT),
-        LintId::of(float_literal::LOSSY_FLOAT_LITERAL),
-        LintId::of(if_then_some_else_none::IF_THEN_SOME_ELSE_NONE),
-        LintId::of(implicit_return::IMPLICIT_RETURN),
-        LintId::of(indexing_slicing::INDEXING_SLICING),
-        LintId::of(inherent_impl::MULTIPLE_INHERENT_IMPL),
-        LintId::of(integer_division::INTEGER_DIVISION),
-        LintId::of(let_underscore::LET_UNDERSCORE_MUST_USE),
-        LintId::of(literal_representation::DECIMAL_LITERAL_REPRESENTATION),
-        LintId::of(map_err_ignore::MAP_ERR_IGNORE),
-        LintId::of(matches::REST_PAT_IN_FULLY_BOUND_STRUCTS),
-        LintId::of(matches::WILDCARD_ENUM_MATCH_ARM),
-        LintId::of(mem_forget::MEM_FORGET),
-        LintId::of(methods::CLONE_ON_REF_PTR),
-        LintId::of(methods::EXPECT_USED),
-        LintId::of(methods::FILETYPE_IS_FILE),
-        LintId::of(methods::GET_UNWRAP),
-        LintId::of(methods::UNWRAP_USED),
-        LintId::of(misc::FLOAT_CMP_CONST),
-        LintId::of(misc_early::UNNEEDED_FIELD_PATTERN),
-        LintId::of(missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS),
-        LintId::of(missing_enforced_import_rename::MISSING_ENFORCED_IMPORT_RENAMES),
-        LintId::of(missing_inline::MISSING_INLINE_IN_PUBLIC_ITEMS),
-        LintId::of(module_style::MOD_MODULE_FILES),
-        LintId::of(module_style::SELF_NAMED_MODULE_FILES),
-        LintId::of(modulo_arithmetic::MODULO_ARITHMETIC),
-        LintId::of(panic_in_result_fn::PANIC_IN_RESULT_FN),
-        LintId::of(panic_unimplemented::PANIC),
-        LintId::of(panic_unimplemented::TODO),
-        LintId::of(panic_unimplemented::UNIMPLEMENTED),
-        LintId::of(panic_unimplemented::UNREACHABLE),
-        LintId::of(pattern_type_mismatch::PATTERN_TYPE_MISMATCH),
-        LintId::of(same_name_method::SAME_NAME_METHOD),
-        LintId::of(shadow::SHADOW_REUSE),
-        LintId::of(shadow::SHADOW_SAME),
-        LintId::of(strings::STRING_ADD),
-        LintId::of(strings::STRING_TO_STRING),
-        LintId::of(strings::STR_TO_STRING),
-        LintId::of(types::RC_BUFFER),
-        LintId::of(types::RC_MUTEX),
-        LintId::of(unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS),
-        LintId::of(unwrap_in_result::UNWRAP_IN_RESULT),
-        LintId::of(verbose_file_reads::VERBOSE_FILE_READS),
-        LintId::of(write::PRINT_STDERR),
-        LintId::of(write::PRINT_STDOUT),
-        LintId::of(write::USE_DEBUG),
-    ]);
-
-    store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
-        LintId::of(attrs::INLINE_ALWAYS),
-        LintId::of(await_holding_invalid::AWAIT_HOLDING_LOCK),
-        LintId::of(await_holding_invalid::AWAIT_HOLDING_REFCELL_REF),
-        LintId::of(bit_mask::VERBOSE_BIT_MASK),
-        LintId::of(bytecount::NAIVE_BYTECOUNT),
-        LintId::of(case_sensitive_file_extension_comparisons::CASE_SENSITIVE_FILE_EXTENSION_COMPARISONS),
-        LintId::of(casts::CAST_LOSSLESS),
-        LintId::of(casts::CAST_POSSIBLE_TRUNCATION),
-        LintId::of(casts::CAST_POSSIBLE_WRAP),
-        LintId::of(casts::CAST_PRECISION_LOSS),
-        LintId::of(casts::CAST_PTR_ALIGNMENT),
-        LintId::of(casts::CAST_SIGN_LOSS),
-        LintId::of(casts::PTR_AS_PTR),
-        LintId::of(checked_conversions::CHECKED_CONVERSIONS),
-        LintId::of(copies::SAME_FUNCTIONS_IN_IF_CONDITION),
-        LintId::of(copy_iterator::COPY_ITERATOR),
-        LintId::of(default::DEFAULT_TRAIT_ACCESS),
-        LintId::of(dereference::EXPLICIT_DEREF_METHODS),
-        LintId::of(derive::EXPL_IMPL_CLONE_ON_COPY),
-        LintId::of(derive::UNSAFE_DERIVE_DESERIALIZE),
-        LintId::of(doc::DOC_MARKDOWN),
-        LintId::of(doc::MISSING_ERRORS_DOC),
-        LintId::of(doc::MISSING_PANICS_DOC),
-        LintId::of(empty_enum::EMPTY_ENUM),
-        LintId::of(enum_variants::MODULE_NAME_REPETITIONS),
-        LintId::of(eta_reduction::REDUNDANT_CLOSURE_FOR_METHOD_CALLS),
-        LintId::of(excessive_bools::FN_PARAMS_EXCESSIVE_BOOLS),
-        LintId::of(excessive_bools::STRUCT_EXCESSIVE_BOOLS),
-        LintId::of(functions::MUST_USE_CANDIDATE),
-        LintId::of(functions::TOO_MANY_LINES),
-        LintId::of(if_not_else::IF_NOT_ELSE),
-        LintId::of(implicit_hasher::IMPLICIT_HASHER),
-        LintId::of(implicit_saturating_sub::IMPLICIT_SATURATING_SUB),
-        LintId::of(inconsistent_struct_constructor::INCONSISTENT_STRUCT_CONSTRUCTOR),
-        LintId::of(infinite_iter::MAYBE_INFINITE_ITER),
-        LintId::of(invalid_upcast_comparisons::INVALID_UPCAST_COMPARISONS),
-        LintId::of(items_after_statements::ITEMS_AFTER_STATEMENTS),
-        LintId::of(iter_not_returning_iterator::ITER_NOT_RETURNING_ITERATOR),
-        LintId::of(large_stack_arrays::LARGE_STACK_ARRAYS),
-        LintId::of(let_underscore::LET_UNDERSCORE_DROP),
-        LintId::of(literal_representation::LARGE_DIGIT_GROUPS),
-        LintId::of(literal_representation::UNREADABLE_LITERAL),
-        LintId::of(loops::EXPLICIT_INTO_ITER_LOOP),
-        LintId::of(loops::EXPLICIT_ITER_LOOP),
-        LintId::of(macro_use::MACRO_USE_IMPORTS),
-        LintId::of(manual_ok_or::MANUAL_OK_OR),
-        LintId::of(match_on_vec_items::MATCH_ON_VEC_ITEMS),
-        LintId::of(matches::MATCH_BOOL),
-        LintId::of(matches::MATCH_SAME_ARMS),
-        LintId::of(matches::MATCH_WILDCARD_FOR_SINGLE_VARIANTS),
-        LintId::of(matches::MATCH_WILD_ERR_ARM),
-        LintId::of(matches::SINGLE_MATCH_ELSE),
-        LintId::of(methods::CLONED_INSTEAD_OF_COPIED),
-        LintId::of(methods::FILTER_MAP_NEXT),
-        LintId::of(methods::FLAT_MAP_OPTION),
-        LintId::of(methods::FROM_ITER_INSTEAD_OF_COLLECT),
-        LintId::of(methods::IMPLICIT_CLONE),
-        LintId::of(methods::INEFFICIENT_TO_STRING),
-        LintId::of(methods::MAP_FLATTEN),
-        LintId::of(methods::MAP_UNWRAP_OR),
-        LintId::of(misc::FLOAT_CMP),
-        LintId::of(misc::USED_UNDERSCORE_BINDING),
-        LintId::of(misc_early::UNSEPARATED_LITERAL_SUFFIX),
-        LintId::of(mut_mut::MUT_MUT),
-        LintId::of(needless_bitwise_bool::NEEDLESS_BITWISE_BOOL),
-        LintId::of(needless_borrow::REF_BINDING_TO_REFERENCE),
-        LintId::of(needless_continue::NEEDLESS_CONTINUE),
-        LintId::of(needless_for_each::NEEDLESS_FOR_EACH),
-        LintId::of(needless_pass_by_value::NEEDLESS_PASS_BY_VALUE),
-        LintId::of(non_expressive_names::MANY_SINGLE_CHAR_NAMES),
-        LintId::of(non_expressive_names::SIMILAR_NAMES),
-        LintId::of(pass_by_ref_or_value::LARGE_TYPES_PASSED_BY_VALUE),
-        LintId::of(pass_by_ref_or_value::TRIVIALLY_COPY_PASS_BY_REF),
-        LintId::of(ranges::RANGE_MINUS_ONE),
-        LintId::of(ranges::RANGE_PLUS_ONE),
-        LintId::of(redundant_else::REDUNDANT_ELSE),
-        LintId::of(ref_option_ref::REF_OPTION_REF),
-        LintId::of(semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED),
-        LintId::of(shadow::SHADOW_UNRELATED),
-        LintId::of(strings::STRING_ADD_ASSIGN),
-        LintId::of(trait_bounds::TRAIT_DUPLICATION_IN_BOUNDS),
-        LintId::of(trait_bounds::TYPE_REPETITION_IN_BOUNDS),
-        LintId::of(transmute::TRANSMUTE_PTR_TO_PTR),
-        LintId::of(types::LINKEDLIST),
-        LintId::of(types::OPTION_OPTION),
-        LintId::of(unicode::NON_ASCII_LITERAL),
-        LintId::of(unicode::UNICODE_NOT_NFC),
-        LintId::of(unit_types::LET_UNIT_VALUE),
-        LintId::of(unnecessary_wraps::UNNECESSARY_WRAPS),
-        LintId::of(unnested_or_patterns::UNNESTED_OR_PATTERNS),
-        LintId::of(unused_async::UNUSED_ASYNC),
-        LintId::of(unused_self::UNUSED_SELF),
-        LintId::of(wildcard_imports::ENUM_GLOB_USE),
-        LintId::of(wildcard_imports::WILDCARD_IMPORTS),
-        LintId::of(zero_sized_map_values::ZERO_SIZED_MAP_VALUES),
-    ]);
+    include!("lib.register_lints.rs");
+    include!("lib.register_restriction.rs");
+    include!("lib.register_pedantic.rs");
 
     #[cfg(feature = "internal-lints")]
-    store.register_group(true, "clippy::internal", Some("clippy_internal"), vec![
-        LintId::of(utils::internal_lints::CLIPPY_LINTS_INTERNAL),
-        LintId::of(utils::internal_lints::COLLAPSIBLE_SPAN_LINT_CALLS),
-        LintId::of(utils::internal_lints::COMPILER_LINT_FUNCTIONS),
-        LintId::of(utils::internal_lints::DEFAULT_LINT),
-        LintId::of(utils::internal_lints::IF_CHAIN_STYLE),
-        LintId::of(utils::internal_lints::INTERNING_DEFINED_SYMBOL),
-        LintId::of(utils::internal_lints::INVALID_PATHS),
-        LintId::of(utils::internal_lints::LINT_WITHOUT_LINT_PASS),
-        LintId::of(utils::internal_lints::MATCH_TYPE_ON_DIAGNOSTIC_ITEM),
-        LintId::of(utils::internal_lints::OUTER_EXPN_EXPN_DATA),
-        LintId::of(utils::internal_lints::PRODUCE_ICE),
-        LintId::of(utils::internal_lints::UNNECESSARY_SYMBOL_STR),
-    ]);
+    include!("lib.register_internal.rs");
 
-    store.register_group(true, "clippy::all", Some("clippy"), vec![
-        LintId::of(absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS),
-        LintId::of(approx_const::APPROX_CONSTANT),
-        LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
-        LintId::of(assign_ops::ASSIGN_OP_PATTERN),
-        LintId::of(assign_ops::MISREFACTORED_ASSIGN_OP),
-        LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
-        LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
-        LintId::of(attrs::DEPRECATED_CFG_ATTR),
-        LintId::of(attrs::DEPRECATED_SEMVER),
-        LintId::of(attrs::MISMATCHED_TARGET_OS),
-        LintId::of(attrs::USELESS_ATTRIBUTE),
-        LintId::of(bit_mask::BAD_BIT_MASK),
-        LintId::of(bit_mask::INEFFECTIVE_BIT_MASK),
-        LintId::of(blacklisted_name::BLACKLISTED_NAME),
-        LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
-        LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
-        LintId::of(booleans::LOGIC_BUG),
-        LintId::of(booleans::NONMINIMAL_BOOL),
-        LintId::of(casts::CAST_REF_TO_MUT),
-        LintId::of(casts::CHAR_LIT_AS_U8),
-        LintId::of(casts::FN_TO_NUMERIC_CAST),
-        LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
-        LintId::of(casts::UNNECESSARY_CAST),
-        LintId::of(collapsible_if::COLLAPSIBLE_ELSE_IF),
-        LintId::of(collapsible_if::COLLAPSIBLE_IF),
-        LintId::of(collapsible_match::COLLAPSIBLE_MATCH),
-        LintId::of(comparison_chain::COMPARISON_CHAIN),
-        LintId::of(copies::IFS_SAME_COND),
-        LintId::of(copies::IF_SAME_THEN_ELSE),
-        LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
-        LintId::of(derivable_impls::DERIVABLE_IMPLS),
-        LintId::of(derive::DERIVE_HASH_XOR_EQ),
-        LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
-        LintId::of(doc::MISSING_SAFETY_DOC),
-        LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
-        LintId::of(double_comparison::DOUBLE_COMPARISONS),
-        LintId::of(double_parens::DOUBLE_PARENS),
-        LintId::of(drop_forget_ref::DROP_COPY),
-        LintId::of(drop_forget_ref::DROP_REF),
-        LintId::of(drop_forget_ref::FORGET_COPY),
-        LintId::of(drop_forget_ref::FORGET_REF),
-        LintId::of(duration_subsec::DURATION_SUBSEC),
-        LintId::of(entry::MAP_ENTRY),
-        LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
-        LintId::of(enum_variants::ENUM_VARIANT_NAMES),
-        LintId::of(enum_variants::MODULE_INCEPTION),
-        LintId::of(eq_op::EQ_OP),
-        LintId::of(eq_op::OP_REF),
-        LintId::of(erasing_op::ERASING_OP),
-        LintId::of(escape::BOXED_LOCAL),
-        LintId::of(eta_reduction::REDUNDANT_CLOSURE),
-        LintId::of(eval_order_dependence::DIVERGING_SUB_EXPRESSION),
-        LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
-        LintId::of(explicit_write::EXPLICIT_WRITE),
-        LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
-        LintId::of(float_literal::EXCESSIVE_PRECISION),
-        LintId::of(format::USELESS_FORMAT),
-        LintId::of(formatting::POSSIBLE_MISSING_COMMA),
-        LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
-        LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
-        LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
-        LintId::of(from_over_into::FROM_OVER_INTO),
-        LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
-        LintId::of(functions::DOUBLE_MUST_USE),
-        LintId::of(functions::MUST_USE_UNIT),
-        LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
-        LintId::of(functions::RESULT_UNIT_ERR),
-        LintId::of(functions::TOO_MANY_ARGUMENTS),
-        LintId::of(get_last_with_len::GET_LAST_WITH_LEN),
-        LintId::of(identity_op::IDENTITY_OP),
-        LintId::of(if_let_mutex::IF_LET_MUTEX),
-        LintId::of(if_then_panic::IF_THEN_PANIC),
-        LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
-        LintId::of(infinite_iter::INFINITE_ITER),
-        LintId::of(inherent_to_string::INHERENT_TO_STRING),
-        LintId::of(inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
-        LintId::of(inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
-        LintId::of(int_plus_one::INT_PLUS_ONE),
-        LintId::of(large_const_arrays::LARGE_CONST_ARRAYS),
-        LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
-        LintId::of(len_zero::COMPARISON_TO_EMPTY),
-        LintId::of(len_zero::LEN_WITHOUT_IS_EMPTY),
-        LintId::of(len_zero::LEN_ZERO),
-        LintId::of(let_underscore::LET_UNDERSCORE_LOCK),
-        LintId::of(lifetimes::EXTRA_UNUSED_LIFETIMES),
-        LintId::of(lifetimes::NEEDLESS_LIFETIMES),
-        LintId::of(literal_representation::INCONSISTENT_DIGIT_GROUPING),
-        LintId::of(literal_representation::MISTYPED_LITERAL_SUFFIXES),
-        LintId::of(literal_representation::UNUSUAL_BYTE_GROUPINGS),
-        LintId::of(loops::EMPTY_LOOP),
-        LintId::of(loops::EXPLICIT_COUNTER_LOOP),
-        LintId::of(loops::FOR_KV_MAP),
-        LintId::of(loops::FOR_LOOPS_OVER_FALLIBLES),
-        LintId::of(loops::ITER_NEXT_LOOP),
-        LintId::of(loops::MANUAL_FLATTEN),
-        LintId::of(loops::MANUAL_MEMCPY),
-        LintId::of(loops::MUT_RANGE_BOUND),
-        LintId::of(loops::NEEDLESS_COLLECT),
-        LintId::of(loops::NEEDLESS_RANGE_LOOP),
-        LintId::of(loops::NEVER_LOOP),
-        LintId::of(loops::SAME_ITEM_PUSH),
-        LintId::of(loops::SINGLE_ELEMENT_LOOP),
-        LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
-        LintId::of(loops::WHILE_LET_LOOP),
-        LintId::of(loops::WHILE_LET_ON_ITERATOR),
-        LintId::of(main_recursion::MAIN_RECURSION),
-        LintId::of(manual_async_fn::MANUAL_ASYNC_FN),
-        LintId::of(manual_map::MANUAL_MAP),
-        LintId::of(manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
-        LintId::of(manual_strip::MANUAL_STRIP),
-        LintId::of(manual_unwrap_or::MANUAL_UNWRAP_OR),
-        LintId::of(map_clone::MAP_CLONE),
-        LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
-        LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
-        LintId::of(match_result_ok::MATCH_RESULT_OK),
-        LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
-        LintId::of(matches::MATCH_AS_REF),
-        LintId::of(matches::MATCH_LIKE_MATCHES_MACRO),
-        LintId::of(matches::MATCH_OVERLAPPING_ARM),
-        LintId::of(matches::MATCH_REF_PATS),
-        LintId::of(matches::MATCH_SINGLE_BINDING),
-        LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
-        LintId::of(matches::SINGLE_MATCH),
-        LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
-        LintId::of(mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
-        LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
-        LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
-        LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
-        LintId::of(methods::BIND_INSTEAD_OF_MAP),
-        LintId::of(methods::BYTES_NTH),
-        LintId::of(methods::CHARS_LAST_CMP),
-        LintId::of(methods::CHARS_NEXT_CMP),
-        LintId::of(methods::CLONE_DOUBLE_REF),
-        LintId::of(methods::CLONE_ON_COPY),
-        LintId::of(methods::EXPECT_FUN_CALL),
-        LintId::of(methods::EXTEND_WITH_DRAIN),
-        LintId::of(methods::FILTER_MAP_IDENTITY),
-        LintId::of(methods::FILTER_NEXT),
-        LintId::of(methods::FLAT_MAP_IDENTITY),
-        LintId::of(methods::INSPECT_FOR_EACH),
-        LintId::of(methods::INTO_ITER_ON_REF),
-        LintId::of(methods::ITERATOR_STEP_BY_ZERO),
-        LintId::of(methods::ITER_CLONED_COLLECT),
-        LintId::of(methods::ITER_COUNT),
-        LintId::of(methods::ITER_NEXT_SLICE),
-        LintId::of(methods::ITER_NTH),
-        LintId::of(methods::ITER_NTH_ZERO),
-        LintId::of(methods::ITER_SKIP_NEXT),
-        LintId::of(methods::MANUAL_FILTER_MAP),
-        LintId::of(methods::MANUAL_FIND_MAP),
-        LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
-        LintId::of(methods::MANUAL_SPLIT_ONCE),
-        LintId::of(methods::MANUAL_STR_REPEAT),
-        LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
-        LintId::of(methods::MAP_IDENTITY),
-        LintId::of(methods::NEW_RET_NO_SELF),
-        LintId::of(methods::OK_EXPECT),
-        LintId::of(methods::OPTION_AS_REF_DEREF),
-        LintId::of(methods::OPTION_FILTER_MAP),
-        LintId::of(methods::OPTION_MAP_OR_NONE),
-        LintId::of(methods::OR_FUN_CALL),
-        LintId::of(methods::RESULT_MAP_OR_INTO_OPTION),
-        LintId::of(methods::SEARCH_IS_SOME),
-        LintId::of(methods::SHOULD_IMPLEMENT_TRAIT),
-        LintId::of(methods::SINGLE_CHAR_ADD_STR),
-        LintId::of(methods::SINGLE_CHAR_PATTERN),
-        LintId::of(methods::SKIP_WHILE_NEXT),
-        LintId::of(methods::STRING_EXTEND_CHARS),
-        LintId::of(methods::SUSPICIOUS_MAP),
-        LintId::of(methods::SUSPICIOUS_SPLITN),
-        LintId::of(methods::UNINIT_ASSUMED_INIT),
-        LintId::of(methods::UNNECESSARY_FILTER_MAP),
-        LintId::of(methods::UNNECESSARY_FOLD),
-        LintId::of(methods::UNNECESSARY_LAZY_EVALUATIONS),
-        LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
-        LintId::of(methods::USELESS_ASREF),
-        LintId::of(methods::WRONG_SELF_CONVENTION),
-        LintId::of(methods::ZST_OFFSET),
-        LintId::of(minmax::MIN_MAX),
-        LintId::of(misc::CMP_NAN),
-        LintId::of(misc::CMP_OWNED),
-        LintId::of(misc::MODULO_ONE),
-        LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
-        LintId::of(misc::TOPLEVEL_REF_ARG),
-        LintId::of(misc::ZERO_PTR),
-        LintId::of(misc_early::BUILTIN_TYPE_SHADOW),
-        LintId::of(misc_early::DOUBLE_NEG),
-        LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
-        LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
-        LintId::of(misc_early::REDUNDANT_PATTERN),
-        LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
-        LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
-        LintId::of(mut_key::MUTABLE_KEY_TYPE),
-        LintId::of(mut_mutex_lock::MUT_MUTEX_LOCK),
-        LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
-        LintId::of(mutex_atomic::MUTEX_ATOMIC),
-        LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
-        LintId::of(needless_bool::BOOL_COMPARISON),
-        LintId::of(needless_bool::NEEDLESS_BOOL),
-        LintId::of(needless_borrow::NEEDLESS_BORROW),
-        LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
-        LintId::of(needless_option_as_deref::NEEDLESS_OPTION_AS_DEREF),
-        LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
-        LintId::of(needless_update::NEEDLESS_UPDATE),
-        LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
-        LintId::of(neg_multiply::NEG_MULTIPLY),
-        LintId::of(new_without_default::NEW_WITHOUT_DEFAULT),
-        LintId::of(no_effect::NO_EFFECT),
-        LintId::of(no_effect::UNNECESSARY_OPERATION),
-        LintId::of(non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
-        LintId::of(non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
-        LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
-        LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
-        LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
-        LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
-        LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
-        LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
-        LintId::of(precedence::PRECEDENCE),
-        LintId::of(ptr::CMP_NULL),
-        LintId::of(ptr::INVALID_NULL_PTR_USAGE),
-        LintId::of(ptr::MUT_FROM_REF),
-        LintId::of(ptr::PTR_ARG),
-        LintId::of(ptr_eq::PTR_EQ),
-        LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
-        LintId::of(question_mark::QUESTION_MARK),
-        LintId::of(ranges::MANUAL_RANGE_CONTAINS),
-        LintId::of(ranges::RANGE_ZIP_WITH_LEN),
-        LintId::of(ranges::REVERSED_EMPTY_RANGES),
-        LintId::of(redundant_clone::REDUNDANT_CLONE),
-        LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
-        LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
-        LintId::of(redundant_slicing::REDUNDANT_SLICING),
-        LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
-        LintId::of(reference::DEREF_ADDROF),
-        LintId::of(reference::REF_IN_DEREF),
-        LintId::of(regex::INVALID_REGEX),
-        LintId::of(repeat_once::REPEAT_ONCE),
-        LintId::of(returns::LET_AND_RETURN),
-        LintId::of(returns::NEEDLESS_RETURN),
-        LintId::of(self_assignment::SELF_ASSIGNMENT),
-        LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
-        LintId::of(serde_api::SERDE_API_MISUSE),
-        LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
-        LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
-        LintId::of(slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
-        LintId::of(stable_sort_primitive::STABLE_SORT_PRIMITIVE),
-        LintId::of(strings::STRING_FROM_UTF8_AS_BYTES),
-        LintId::of(strlen_on_c_strings::STRLEN_ON_C_STRINGS),
-        LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
-        LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
-        LintId::of(swap::ALMOST_SWAPPED),
-        LintId::of(swap::MANUAL_SWAP),
-        LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
-        LintId::of(temporary_assignment::TEMPORARY_ASSIGNMENT),
-        LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
-        LintId::of(to_string_in_display::TO_STRING_IN_DISPLAY),
-        LintId::of(transmute::CROSSPOINTER_TRANSMUTE),
-        LintId::of(transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
-        LintId::of(transmute::TRANSMUTE_BYTES_TO_STR),
-        LintId::of(transmute::TRANSMUTE_FLOAT_TO_INT),
-        LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
-        LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
-        LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
-        LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
-        LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
-        LintId::of(transmute::WRONG_TRANSMUTE),
-        LintId::of(transmuting_null::TRANSMUTING_NULL),
-        LintId::of(try_err::TRY_ERR),
-        LintId::of(types::BORROWED_BOX),
-        LintId::of(types::BOX_COLLECTION),
-        LintId::of(types::REDUNDANT_ALLOCATION),
-        LintId::of(types::TYPE_COMPLEXITY),
-        LintId::of(types::VEC_BOX),
-        LintId::of(undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
-        LintId::of(unicode::INVISIBLE_CHARACTERS),
-        LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
-        LintId::of(unit_types::UNIT_ARG),
-        LintId::of(unit_types::UNIT_CMP),
-        LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
-        LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
-        LintId::of(unnecessary_sort_by::UNNECESSARY_SORT_BY),
-        LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
-        LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
-        LintId::of(unused_unit::UNUSED_UNIT),
-        LintId::of(unwrap::PANICKING_UNWRAP),
-        LintId::of(unwrap::UNNECESSARY_UNWRAP),
-        LintId::of(upper_case_acronyms::UPPER_CASE_ACRONYMS),
-        LintId::of(useless_conversion::USELESS_CONVERSION),
-        LintId::of(vec::USELESS_VEC),
-        LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
-        LintId::of(vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
-        LintId::of(write::PRINTLN_EMPTY_STRING),
-        LintId::of(write::PRINT_LITERAL),
-        LintId::of(write::PRINT_WITH_NEWLINE),
-        LintId::of(write::WRITELN_EMPTY_STRING),
-        LintId::of(write::WRITE_LITERAL),
-        LintId::of(write::WRITE_WITH_NEWLINE),
-        LintId::of(zero_div_zero::ZERO_DIVIDED_BY_ZERO),
-    ]);
-
-    store.register_group(true, "clippy::style", Some("clippy_style"), vec![
-        LintId::of(assertions_on_constants::ASSERTIONS_ON_CONSTANTS),
-        LintId::of(assign_ops::ASSIGN_OP_PATTERN),
-        LintId::of(blacklisted_name::BLACKLISTED_NAME),
-        LintId::of(blocks_in_if_conditions::BLOCKS_IN_IF_CONDITIONS),
-        LintId::of(bool_assert_comparison::BOOL_ASSERT_COMPARISON),
-        LintId::of(casts::FN_TO_NUMERIC_CAST),
-        LintId::of(casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION),
-        LintId::of(collapsible_if::COLLAPSIBLE_ELSE_IF),
-        LintId::of(collapsible_if::COLLAPSIBLE_IF),
-        LintId::of(collapsible_match::COLLAPSIBLE_MATCH),
-        LintId::of(comparison_chain::COMPARISON_CHAIN),
-        LintId::of(default::FIELD_REASSIGN_WITH_DEFAULT),
-        LintId::of(doc::MISSING_SAFETY_DOC),
-        LintId::of(doc::NEEDLESS_DOCTEST_MAIN),
-        LintId::of(enum_variants::ENUM_VARIANT_NAMES),
-        LintId::of(enum_variants::MODULE_INCEPTION),
-        LintId::of(eq_op::OP_REF),
-        LintId::of(eta_reduction::REDUNDANT_CLOSURE),
-        LintId::of(float_literal::EXCESSIVE_PRECISION),
-        LintId::of(from_over_into::FROM_OVER_INTO),
-        LintId::of(from_str_radix_10::FROM_STR_RADIX_10),
-        LintId::of(functions::DOUBLE_MUST_USE),
-        LintId::of(functions::MUST_USE_UNIT),
-        LintId::of(functions::RESULT_UNIT_ERR),
-        LintId::of(if_then_panic::IF_THEN_PANIC),
-        LintId::of(inherent_to_string::INHERENT_TO_STRING),
-        LintId::of(len_zero::COMPARISON_TO_EMPTY),
-        LintId::of(len_zero::LEN_WITHOUT_IS_EMPTY),
-        LintId::of(len_zero::LEN_ZERO),
-        LintId::of(literal_representation::INCONSISTENT_DIGIT_GROUPING),
-        LintId::of(literal_representation::UNUSUAL_BYTE_GROUPINGS),
-        LintId::of(loops::FOR_KV_MAP),
-        LintId::of(loops::NEEDLESS_RANGE_LOOP),
-        LintId::of(loops::SAME_ITEM_PUSH),
-        LintId::of(loops::WHILE_LET_ON_ITERATOR),
-        LintId::of(main_recursion::MAIN_RECURSION),
-        LintId::of(manual_async_fn::MANUAL_ASYNC_FN),
-        LintId::of(manual_map::MANUAL_MAP),
-        LintId::of(manual_non_exhaustive::MANUAL_NON_EXHAUSTIVE),
-        LintId::of(map_clone::MAP_CLONE),
-        LintId::of(match_result_ok::MATCH_RESULT_OK),
-        LintId::of(matches::INFALLIBLE_DESTRUCTURING_MATCH),
-        LintId::of(matches::MATCH_LIKE_MATCHES_MACRO),
-        LintId::of(matches::MATCH_OVERLAPPING_ARM),
-        LintId::of(matches::MATCH_REF_PATS),
-        LintId::of(matches::REDUNDANT_PATTERN_MATCHING),
-        LintId::of(matches::SINGLE_MATCH),
-        LintId::of(mem_replace::MEM_REPLACE_OPTION_WITH_NONE),
-        LintId::of(mem_replace::MEM_REPLACE_WITH_DEFAULT),
-        LintId::of(methods::BYTES_NTH),
-        LintId::of(methods::CHARS_LAST_CMP),
-        LintId::of(methods::CHARS_NEXT_CMP),
-        LintId::of(methods::INTO_ITER_ON_REF),
-        LintId::of(methods::ITER_CLONED_COLLECT),
-        LintId::of(methods::ITER_NEXT_SLICE),
-        LintId::of(methods::ITER_NTH_ZERO),
-        LintId::of(methods::ITER_SKIP_NEXT),
-        LintId::of(methods::MANUAL_SATURATING_ARITHMETIC),
-        LintId::of(methods::MAP_COLLECT_RESULT_UNIT),
-        LintId::of(methods::NEW_RET_NO_SELF),
-        LintId::of(methods::OK_EXPECT),
-        LintId::of(methods::OPTION_MAP_OR_NONE),
-        LintId::of(methods::RESULT_MAP_OR_INTO_OPTION),
-        LintId::of(methods::SHOULD_IMPLEMENT_TRAIT),
-        LintId::of(methods::SINGLE_CHAR_ADD_STR),
-        LintId::of(methods::STRING_EXTEND_CHARS),
-        LintId::of(methods::UNNECESSARY_FOLD),
-        LintId::of(methods::UNNECESSARY_LAZY_EVALUATIONS),
-        LintId::of(methods::UNWRAP_OR_ELSE_DEFAULT),
-        LintId::of(methods::WRONG_SELF_CONVENTION),
-        LintId::of(misc::TOPLEVEL_REF_ARG),
-        LintId::of(misc::ZERO_PTR),
-        LintId::of(misc_early::BUILTIN_TYPE_SHADOW),
-        LintId::of(misc_early::DOUBLE_NEG),
-        LintId::of(misc_early::DUPLICATE_UNDERSCORE_ARGUMENT),
-        LintId::of(misc_early::MIXED_CASE_HEX_LITERALS),
-        LintId::of(misc_early::REDUNDANT_PATTERN),
-        LintId::of(mut_mutex_lock::MUT_MUTEX_LOCK),
-        LintId::of(mut_reference::UNNECESSARY_MUT_PASSED),
-        LintId::of(needless_borrow::NEEDLESS_BORROW),
-        LintId::of(neg_multiply::NEG_MULTIPLY),
-        LintId::of(new_without_default::NEW_WITHOUT_DEFAULT),
-        LintId::of(non_copy_const::BORROW_INTERIOR_MUTABLE_CONST),
-        LintId::of(non_copy_const::DECLARE_INTERIOR_MUTABLE_CONST),
-        LintId::of(non_expressive_names::JUST_UNDERSCORES_AND_DIGITS),
-        LintId::of(ptr::CMP_NULL),
-        LintId::of(ptr::PTR_ARG),
-        LintId::of(ptr_eq::PTR_EQ),
-        LintId::of(question_mark::QUESTION_MARK),
-        LintId::of(ranges::MANUAL_RANGE_CONTAINS),
-        LintId::of(redundant_field_names::REDUNDANT_FIELD_NAMES),
-        LintId::of(redundant_static_lifetimes::REDUNDANT_STATIC_LIFETIMES),
-        LintId::of(returns::LET_AND_RETURN),
-        LintId::of(returns::NEEDLESS_RETURN),
-        LintId::of(self_named_constructors::SELF_NAMED_CONSTRUCTORS),
-        LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
-        LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
-        LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
-        LintId::of(try_err::TRY_ERR),
-        LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
-        LintId::of(unused_unit::UNUSED_UNIT),
-        LintId::of(upper_case_acronyms::UPPER_CASE_ACRONYMS),
-        LintId::of(write::PRINTLN_EMPTY_STRING),
-        LintId::of(write::PRINT_LITERAL),
-        LintId::of(write::PRINT_WITH_NEWLINE),
-        LintId::of(write::WRITELN_EMPTY_STRING),
-        LintId::of(write::WRITE_LITERAL),
-        LintId::of(write::WRITE_WITH_NEWLINE),
-    ]);
-
-    store.register_group(true, "clippy::complexity", Some("clippy_complexity"), vec![
-        LintId::of(attrs::DEPRECATED_CFG_ATTR),
-        LintId::of(booleans::NONMINIMAL_BOOL),
-        LintId::of(casts::CHAR_LIT_AS_U8),
-        LintId::of(casts::UNNECESSARY_CAST),
-        LintId::of(derivable_impls::DERIVABLE_IMPLS),
-        LintId::of(double_comparison::DOUBLE_COMPARISONS),
-        LintId::of(double_parens::DOUBLE_PARENS),
-        LintId::of(duration_subsec::DURATION_SUBSEC),
-        LintId::of(eval_order_dependence::DIVERGING_SUB_EXPRESSION),
-        LintId::of(explicit_write::EXPLICIT_WRITE),
-        LintId::of(format::USELESS_FORMAT),
-        LintId::of(functions::TOO_MANY_ARGUMENTS),
-        LintId::of(get_last_with_len::GET_LAST_WITH_LEN),
-        LintId::of(identity_op::IDENTITY_OP),
-        LintId::of(int_plus_one::INT_PLUS_ONE),
-        LintId::of(lifetimes::EXTRA_UNUSED_LIFETIMES),
-        LintId::of(lifetimes::NEEDLESS_LIFETIMES),
-        LintId::of(loops::EXPLICIT_COUNTER_LOOP),
-        LintId::of(loops::MANUAL_FLATTEN),
-        LintId::of(loops::SINGLE_ELEMENT_LOOP),
-        LintId::of(loops::WHILE_LET_LOOP),
-        LintId::of(manual_strip::MANUAL_STRIP),
-        LintId::of(manual_unwrap_or::MANUAL_UNWRAP_OR),
-        LintId::of(map_unit_fn::OPTION_MAP_UNIT_FN),
-        LintId::of(map_unit_fn::RESULT_MAP_UNIT_FN),
-        LintId::of(matches::MATCH_AS_REF),
-        LintId::of(matches::MATCH_SINGLE_BINDING),
-        LintId::of(matches::WILDCARD_IN_OR_PATTERNS),
-        LintId::of(methods::BIND_INSTEAD_OF_MAP),
-        LintId::of(methods::CLONE_ON_COPY),
-        LintId::of(methods::FILTER_MAP_IDENTITY),
-        LintId::of(methods::FILTER_NEXT),
-        LintId::of(methods::FLAT_MAP_IDENTITY),
-        LintId::of(methods::INSPECT_FOR_EACH),
-        LintId::of(methods::ITER_COUNT),
-        LintId::of(methods::MANUAL_FILTER_MAP),
-        LintId::of(methods::MANUAL_FIND_MAP),
-        LintId::of(methods::MANUAL_SPLIT_ONCE),
-        LintId::of(methods::MAP_IDENTITY),
-        LintId::of(methods::OPTION_AS_REF_DEREF),
-        LintId::of(methods::OPTION_FILTER_MAP),
-        LintId::of(methods::SEARCH_IS_SOME),
-        LintId::of(methods::SKIP_WHILE_NEXT),
-        LintId::of(methods::UNNECESSARY_FILTER_MAP),
-        LintId::of(methods::USELESS_ASREF),
-        LintId::of(misc::SHORT_CIRCUIT_STATEMENT),
-        LintId::of(misc_early::UNNEEDED_WILDCARD_PATTERN),
-        LintId::of(misc_early::ZERO_PREFIXED_LITERAL),
-        LintId::of(needless_arbitrary_self_type::NEEDLESS_ARBITRARY_SELF_TYPE),
-        LintId::of(needless_bool::BOOL_COMPARISON),
-        LintId::of(needless_bool::NEEDLESS_BOOL),
-        LintId::of(needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE),
-        LintId::of(needless_option_as_deref::NEEDLESS_OPTION_AS_DEREF),
-        LintId::of(needless_question_mark::NEEDLESS_QUESTION_MARK),
-        LintId::of(needless_update::NEEDLESS_UPDATE),
-        LintId::of(neg_cmp_op_on_partial_ord::NEG_CMP_OP_ON_PARTIAL_ORD),
-        LintId::of(no_effect::NO_EFFECT),
-        LintId::of(no_effect::UNNECESSARY_OPERATION),
-        LintId::of(overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL),
-        LintId::of(partialeq_ne_impl::PARTIALEQ_NE_IMPL),
-        LintId::of(precedence::PRECEDENCE),
-        LintId::of(ptr_offset_with_cast::PTR_OFFSET_WITH_CAST),
-        LintId::of(ranges::RANGE_ZIP_WITH_LEN),
-        LintId::of(redundant_closure_call::REDUNDANT_CLOSURE_CALL),
-        LintId::of(redundant_slicing::REDUNDANT_SLICING),
-        LintId::of(reference::DEREF_ADDROF),
-        LintId::of(reference::REF_IN_DEREF),
-        LintId::of(repeat_once::REPEAT_ONCE),
-        LintId::of(strings::STRING_FROM_UTF8_AS_BYTES),
-        LintId::of(strlen_on_c_strings::STRLEN_ON_C_STRINGS),
-        LintId::of(swap::MANUAL_SWAP),
-        LintId::of(temporary_assignment::TEMPORARY_ASSIGNMENT),
-        LintId::of(transmute::CROSSPOINTER_TRANSMUTE),
-        LintId::of(transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS),
-        LintId::of(transmute::TRANSMUTE_BYTES_TO_STR),
-        LintId::of(transmute::TRANSMUTE_FLOAT_TO_INT),
-        LintId::of(transmute::TRANSMUTE_INT_TO_BOOL),
-        LintId::of(transmute::TRANSMUTE_INT_TO_CHAR),
-        LintId::of(transmute::TRANSMUTE_INT_TO_FLOAT),
-        LintId::of(transmute::TRANSMUTE_PTR_TO_REF),
-        LintId::of(types::BORROWED_BOX),
-        LintId::of(types::TYPE_COMPLEXITY),
-        LintId::of(types::VEC_BOX),
-        LintId::of(unit_types::UNIT_ARG),
-        LintId::of(unnecessary_sort_by::UNNECESSARY_SORT_BY),
-        LintId::of(unwrap::UNNECESSARY_UNWRAP),
-        LintId::of(useless_conversion::USELESS_CONVERSION),
-        LintId::of(zero_div_zero::ZERO_DIVIDED_BY_ZERO),
-    ]);
-
-    store.register_group(true, "clippy::correctness", Some("clippy_correctness"), vec![
-        LintId::of(absurd_extreme_comparisons::ABSURD_EXTREME_COMPARISONS),
-        LintId::of(approx_const::APPROX_CONSTANT),
-        LintId::of(async_yields_async::ASYNC_YIELDS_ASYNC),
-        LintId::of(attrs::DEPRECATED_SEMVER),
-        LintId::of(attrs::MISMATCHED_TARGET_OS),
-        LintId::of(attrs::USELESS_ATTRIBUTE),
-        LintId::of(bit_mask::BAD_BIT_MASK),
-        LintId::of(bit_mask::INEFFECTIVE_BIT_MASK),
-        LintId::of(booleans::LOGIC_BUG),
-        LintId::of(casts::CAST_REF_TO_MUT),
-        LintId::of(copies::IFS_SAME_COND),
-        LintId::of(copies::IF_SAME_THEN_ELSE),
-        LintId::of(derive::DERIVE_HASH_XOR_EQ),
-        LintId::of(derive::DERIVE_ORD_XOR_PARTIAL_ORD),
-        LintId::of(drop_forget_ref::DROP_COPY),
-        LintId::of(drop_forget_ref::DROP_REF),
-        LintId::of(drop_forget_ref::FORGET_COPY),
-        LintId::of(drop_forget_ref::FORGET_REF),
-        LintId::of(enum_clike::ENUM_CLIKE_UNPORTABLE_VARIANT),
-        LintId::of(eq_op::EQ_OP),
-        LintId::of(erasing_op::ERASING_OP),
-        LintId::of(formatting::POSSIBLE_MISSING_COMMA),
-        LintId::of(functions::NOT_UNSAFE_PTR_ARG_DEREF),
-        LintId::of(if_let_mutex::IF_LET_MUTEX),
-        LintId::of(indexing_slicing::OUT_OF_BOUNDS_INDEXING),
-        LintId::of(infinite_iter::INFINITE_ITER),
-        LintId::of(inherent_to_string::INHERENT_TO_STRING_SHADOW_DISPLAY),
-        LintId::of(inline_fn_without_body::INLINE_FN_WITHOUT_BODY),
-        LintId::of(let_underscore::LET_UNDERSCORE_LOCK),
-        LintId::of(literal_representation::MISTYPED_LITERAL_SUFFIXES),
-        LintId::of(loops::ITER_NEXT_LOOP),
-        LintId::of(loops::NEVER_LOOP),
-        LintId::of(loops::WHILE_IMMUTABLE_CONDITION),
-        LintId::of(mem_discriminant::MEM_DISCRIMINANT_NON_ENUM),
-        LintId::of(mem_replace::MEM_REPLACE_WITH_UNINIT),
-        LintId::of(methods::CLONE_DOUBLE_REF),
-        LintId::of(methods::ITERATOR_STEP_BY_ZERO),
-        LintId::of(methods::SUSPICIOUS_SPLITN),
-        LintId::of(methods::UNINIT_ASSUMED_INIT),
-        LintId::of(methods::ZST_OFFSET),
-        LintId::of(minmax::MIN_MAX),
-        LintId::of(misc::CMP_NAN),
-        LintId::of(misc::MODULO_ONE),
-        LintId::of(non_octal_unix_permissions::NON_OCTAL_UNIX_PERMISSIONS),
-        LintId::of(open_options::NONSENSICAL_OPEN_OPTIONS),
-        LintId::of(option_env_unwrap::OPTION_ENV_UNWRAP),
-        LintId::of(ptr::INVALID_NULL_PTR_USAGE),
-        LintId::of(ptr::MUT_FROM_REF),
-        LintId::of(ranges::REVERSED_EMPTY_RANGES),
-        LintId::of(regex::INVALID_REGEX),
-        LintId::of(self_assignment::SELF_ASSIGNMENT),
-        LintId::of(serde_api::SERDE_API_MISUSE),
-        LintId::of(size_of_in_element_count::SIZE_OF_IN_ELEMENT_COUNT),
-        LintId::of(swap::ALMOST_SWAPPED),
-        LintId::of(to_string_in_display::TO_STRING_IN_DISPLAY),
-        LintId::of(transmute::UNSOUND_COLLECTION_TRANSMUTE),
-        LintId::of(transmute::WRONG_TRANSMUTE),
-        LintId::of(transmuting_null::TRANSMUTING_NULL),
-        LintId::of(undropped_manually_drops::UNDROPPED_MANUALLY_DROPS),
-        LintId::of(unicode::INVISIBLE_CHARACTERS),
-        LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
-        LintId::of(unit_types::UNIT_CMP),
-        LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
-        LintId::of(unnamed_address::VTABLE_ADDRESS_COMPARISONS),
-        LintId::of(unused_io_amount::UNUSED_IO_AMOUNT),
-        LintId::of(unwrap::PANICKING_UNWRAP),
-        LintId::of(vec_resize_to_zero::VEC_RESIZE_TO_ZERO),
-    ]);
-
-    store.register_group(true, "clippy::suspicious", None, vec![
-        LintId::of(assign_ops::MISREFACTORED_ASSIGN_OP),
-        LintId::of(attrs::BLANKET_CLIPPY_RESTRICTION_LINTS),
-        LintId::of(eval_order_dependence::EVAL_ORDER_DEPENDENCE),
-        LintId::of(float_equality_without_abs::FLOAT_EQUALITY_WITHOUT_ABS),
-        LintId::of(formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING),
-        LintId::of(formatting::SUSPICIOUS_ELSE_FORMATTING),
-        LintId::of(formatting::SUSPICIOUS_UNARY_OP_FORMATTING),
-        LintId::of(loops::EMPTY_LOOP),
-        LintId::of(loops::FOR_LOOPS_OVER_FALLIBLES),
-        LintId::of(loops::MUT_RANGE_BOUND),
-        LintId::of(methods::SUSPICIOUS_MAP),
-        LintId::of(mut_key::MUTABLE_KEY_TYPE),
-        LintId::of(suspicious_trait_impl::SUSPICIOUS_ARITHMETIC_IMPL),
-        LintId::of(suspicious_trait_impl::SUSPICIOUS_OP_ASSIGN_IMPL),
-    ]);
-
-    store.register_group(true, "clippy::perf", Some("clippy_perf"), vec![
-        LintId::of(entry::MAP_ENTRY),
-        LintId::of(escape::BOXED_LOCAL),
-        LintId::of(large_const_arrays::LARGE_CONST_ARRAYS),
-        LintId::of(large_enum_variant::LARGE_ENUM_VARIANT),
-        LintId::of(loops::MANUAL_MEMCPY),
-        LintId::of(loops::NEEDLESS_COLLECT),
-        LintId::of(methods::EXPECT_FUN_CALL),
-        LintId::of(methods::EXTEND_WITH_DRAIN),
-        LintId::of(methods::ITER_NTH),
-        LintId::of(methods::MANUAL_STR_REPEAT),
-        LintId::of(methods::OR_FUN_CALL),
-        LintId::of(methods::SINGLE_CHAR_PATTERN),
-        LintId::of(misc::CMP_OWNED),
-        LintId::of(mutex_atomic::MUTEX_ATOMIC),
-        LintId::of(redundant_clone::REDUNDANT_CLONE),
-        LintId::of(slow_vector_initialization::SLOW_VECTOR_INITIALIZATION),
-        LintId::of(stable_sort_primitive::STABLE_SORT_PRIMITIVE),
-        LintId::of(types::BOX_COLLECTION),
-        LintId::of(types::REDUNDANT_ALLOCATION),
-        LintId::of(vec::USELESS_VEC),
-        LintId::of(vec_init_then_push::VEC_INIT_THEN_PUSH),
-    ]);
-
-    store.register_group(true, "clippy::cargo", Some("clippy_cargo"), vec![
-        LintId::of(cargo_common_metadata::CARGO_COMMON_METADATA),
-        LintId::of(feature_name::NEGATIVE_FEATURE_NAMES),
-        LintId::of(feature_name::REDUNDANT_FEATURE_NAMES),
-        LintId::of(multiple_crate_versions::MULTIPLE_CRATE_VERSIONS),
-        LintId::of(wildcard_dependencies::WILDCARD_DEPENDENCIES),
-    ]);
-
-    store.register_group(true, "clippy::nursery", Some("clippy_nursery"), vec![
-        LintId::of(attrs::EMPTY_LINE_AFTER_OUTER_ATTR),
-        LintId::of(cognitive_complexity::COGNITIVE_COMPLEXITY),
-        LintId::of(copies::BRANCHES_SHARING_CODE),
-        LintId::of(disallowed_method::DISALLOWED_METHOD),
-        LintId::of(disallowed_type::DISALLOWED_TYPE),
-        LintId::of(fallible_impl_from::FALLIBLE_IMPL_FROM),
-        LintId::of(floating_point_arithmetic::IMPRECISE_FLOPS),
-        LintId::of(floating_point_arithmetic::SUBOPTIMAL_FLOPS),
-        LintId::of(future_not_send::FUTURE_NOT_SEND),
-        LintId::of(let_if_seq::USELESS_LET_IF_SEQ),
-        LintId::of(missing_const_for_fn::MISSING_CONST_FOR_FN),
-        LintId::of(mutable_debug_assertion::DEBUG_ASSERT_WITH_MUT_CALL),
-        LintId::of(mutex_atomic::MUTEX_INTEGER),
-        LintId::of(nonstandard_macro_braces::NONSTANDARD_MACRO_BRACES),
-        LintId::of(option_if_let_else::OPTION_IF_LET_ELSE),
-        LintId::of(path_buf_push_overwrite::PATH_BUF_PUSH_OVERWRITE),
-        LintId::of(redundant_pub_crate::REDUNDANT_PUB_CRATE),
-        LintId::of(regex::TRIVIAL_REGEX),
-        LintId::of(strings::STRING_LIT_AS_BYTES),
-        LintId::of(suspicious_operation_groupings::SUSPICIOUS_OPERATION_GROUPINGS),
-        LintId::of(transmute::USELESS_TRANSMUTE),
-        LintId::of(use_self::USE_SELF),
-    ]);
+    include!("lib.register_all.rs");
+    include!("lib.register_style.rs");
+    include!("lib.register_complexity.rs");
+    include!("lib.register_correctness.rs");
+    include!("lib.register_suspicious.rs");
+    include!("lib.register_perf.rs");
+    include!("lib.register_cargo.rs");
+    include!("lib.register_nursery.rs");
 
     #[cfg(feature = "metadata-collector-lint")]
     {
@@ -1931,7 +555,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| Box::new(same_name_method::SameNameMethod));
     store.register_late_pass(|| Box::new(map_clone::MapClone));
     store.register_late_pass(|| Box::new(map_err_ignore::MapErrIgnore));
-    store.register_late_pass(|| Box::new(shadow::Shadow));
+    store.register_late_pass(|| Box::new(shadow::Shadow::default()));
     store.register_late_pass(|| Box::new(unit_types::UnitTypes));
     store.register_late_pass(|| Box::new(loops::Loops));
     store.register_late_pass(|| Box::new(main_recursion::MainRecursion::default()));
@@ -2092,6 +716,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|| Box::new(option_if_let_else::OptionIfLetElse));
     store.register_late_pass(|| Box::new(future_not_send::FutureNotSend));
     store.register_late_pass(|| Box::new(if_let_mutex::IfLetMutex));
+    store.register_late_pass(|| Box::new(equatable_if_let::PatternEquality));
     store.register_late_pass(|| Box::new(mut_mutex_lock::MutMutexLock));
     store.register_late_pass(|| Box::new(match_on_vec_items::MatchOnVecItems));
     store.register_late_pass(|| Box::new(manual_async_fn::ManualAsyncFn));
@@ -2142,6 +767,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move || Box::new(feature_name::FeatureName));
     store.register_late_pass(move || Box::new(iter_not_returning_iterator::IterNotReturningIterator));
     store.register_late_pass(move || Box::new(if_then_panic::IfThenPanic));
+    let enable_raw_pointer_heuristic_for_send = conf.enable_raw_pointer_heuristic_for_send;
+    store.register_late_pass(move || Box::new(non_send_fields_in_send_ty::NonSendFieldInSendTy::new(enable_raw_pointer_heuristic_for_send)));
 }
 
 #[rustfmt::skip]
diff --git a/clippy_lints/src/loops/mut_range_bound.rs b/clippy_lints/src/loops/mut_range_bound.rs
index 358d53e8859..aedf0844937 100644
--- a/clippy_lints/src/loops/mut_range_bound.rs
+++ b/clippy_lints/src/loops/mut_range_bound.rs
@@ -92,7 +92,7 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
     fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
 
     fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, diag_expr_id: HirId, bk: ty::BorrowKind) {
-        if let ty::BorrowKind::MutBorrow = bk {
+        if bk == ty::BorrowKind::MutBorrow {
             if let PlaceBase::Local(id) = cmt.place.base {
                 if Some(id) == self.hir_id_low && !BreakAfterExprVisitor::is_found(self.cx, diag_expr_id) {
                     self.span_low = Some(self.cx.tcx.hir().span(diag_expr_id));
diff --git a/clippy_lints/src/loops/needless_range_loop.rs b/clippy_lints/src/loops/needless_range_loop.rs
index 7157b801185..172d9fc39a2 100644
--- a/clippy_lints/src/loops/needless_range_loop.rs
+++ b/clippy_lints/src/loops/needless_range_loop.rs
@@ -95,7 +95,7 @@ pub(super) fn check<'tcx>(
                     let mut take_expr = end;
 
                     if let ExprKind::Binary(ref op, left, right) = end.kind {
-                        if let BinOpKind::Add = op.node {
+                        if op.node == BinOpKind::Add {
                             let start_equal_left = SpanlessEq::new(cx).eq_expr(start, left);
                             let start_equal_right = SpanlessEq::new(cx).eq_expr(start, right);
 
diff --git a/clippy_lints/src/loops/never_loop.rs b/clippy_lints/src/loops/never_loop.rs
index 41956650c9f..c0fde5e5166 100644
--- a/clippy_lints/src/loops/never_loop.rs
+++ b/clippy_lints/src/loops/never_loop.rs
@@ -14,7 +14,7 @@ pub(super) fn check(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
             NeverLoopResult::AlwaysBreak => {
                 span_lint_and_then(cx, NEVER_LOOP, expr.span, "this loop never actually loops", |diag| {
                     if_chain! {
-                        if let LoopSource::ForLoop = source;
+                        if source == LoopSource::ForLoop;
                         if let Some((_, Node::Expr(parent_match))) = cx.tcx.hir().parent_iter(expr.hir_id).nth(1);
                         if let Some(ForLoop { arg: iterator, pat, span: for_span, .. }) = ForLoop::hir(parent_match);
                         then {
diff --git a/clippy_lints/src/manual_async_fn.rs b/clippy_lints/src/manual_async_fn.rs
index 8e1385fb83a..b632af455f8 100644
--- a/clippy_lints/src/manual_async_fn.rs
+++ b/clippy_lints/src/manual_async_fn.rs
@@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualAsyncFn {
     ) {
         if_chain! {
             if let Some(header) = kind.header();
-            if let IsAsync::NotAsync = header.asyncness;
+            if header.asyncness == IsAsync::NotAsync;
             // Check that this function returns `impl Future`
             if let FnRetTy::Return(ret_ty) = decl.output;
             if let Some((trait_ref, output_lifetimes)) = future_trait_ref(cx, ret_ty);
@@ -178,7 +178,7 @@ fn desugared_async_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>)
         if args.len() == 1;
         if let Expr{kind: ExprKind::Closure(_, _, body_id, ..), ..} = args[0];
         let closure_body = cx.tcx.hir().body(body_id);
-        if let Some(GeneratorKind::Async(AsyncGeneratorKind::Block)) = closure_body.generator_kind;
+        if closure_body.generator_kind == Some(GeneratorKind::Async(AsyncGeneratorKind::Block));
         then {
             return Some(closure_body);
         }
diff --git a/clippy_lints/src/map_unit_fn.rs b/clippy_lints/src/map_unit_fn.rs
index 952e250bb9e..40de9ffcd4e 100644
--- a/clippy_lints/src/map_unit_fn.rs
+++ b/clippy_lints/src/map_unit_fn.rs
@@ -205,14 +205,13 @@ fn suggestion_msg(function_type: &str, map_type: &str) -> String {
 fn lint_map_unit_fn(cx: &LateContext<'_>, stmt: &hir::Stmt<'_>, expr: &hir::Expr<'_>, map_args: &[hir::Expr<'_>]) {
     let var_arg = &map_args[0];
 
-    let (map_type, variant, lint) =
-        if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(var_arg), sym::Option) {
-            ("Option", "Some", OPTION_MAP_UNIT_FN)
-        } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(var_arg), sym::Result) {
-            ("Result", "Ok", RESULT_MAP_UNIT_FN)
-        } else {
-            return;
-        };
+    let (map_type, variant, lint) = if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(var_arg), sym::Option) {
+        ("Option", "Some", OPTION_MAP_UNIT_FN)
+    } else if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(var_arg), sym::Result) {
+        ("Result", "Ok", RESULT_MAP_UNIT_FN)
+    } else {
+        return;
+    };
     let fn_arg = &map_args[1];
 
     if is_unit_function(cx, fn_arg) {
diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs
index a685c1eaa2c..56d4163a6b3 100644
--- a/clippy_lints/src/matches.rs
+++ b/clippy_lints/src/matches.rs
@@ -1025,8 +1025,7 @@ fn check_wild_enum_match(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>])
     let adt_def = match ty.kind() {
         ty::Adt(adt_def, _)
             if adt_def.is_enum()
-                && !(is_type_diagnostic_item(cx, ty, sym::Option)
-                    || is_type_diagnostic_item(cx, ty, sym::Result)) =>
+                && !(is_type_diagnostic_item(cx, ty, sym::Option) || is_type_diagnostic_item(cx, ty, sym::Result)) =>
         {
             adt_def
         },
diff --git a/clippy_lints/src/methods/mod.rs b/clippy_lints/src/methods/mod.rs
index 2025056ac94..b26d11c0d6b 100644
--- a/clippy_lints/src/methods/mod.rs
+++ b/clippy_lints/src/methods/mod.rs
@@ -1284,8 +1284,9 @@ declare_clippy_lint! {
     ///
     /// ### Why is this bad?
     /// It looks suspicious. Maybe `map` was confused with `filter`.
-    /// If the `map` call is intentional, this should be rewritten. Or, if you intend to
-    /// drive the iterator to completion, you can just use `for_each` instead.
+    /// If the `map` call is intentional, this should be rewritten
+    /// using `inspect`. Or, if you intend to drive the iterator to
+    /// completion, you can just use `for_each` instead.
     ///
     /// ### Example
     /// ```rust
diff --git a/clippy_lints/src/methods/or_fun_call.rs b/clippy_lints/src/methods/or_fun_call.rs
index cabbb840076..b5bbbb09092 100644
--- a/clippy_lints/src/methods/or_fun_call.rs
+++ b/clippy_lints/src/methods/or_fun_call.rs
@@ -178,15 +178,15 @@ pub(super) fn check<'tcx>(
             hir::ExprKind::Index(..) | hir::ExprKind::MethodCall(..) => {
                 check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None);
             },
-            hir::ExprKind::Block(block, _) => {
-                if let BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) = block.rules {
-                    if let Some(block_expr) = block.expr {
-                        if let hir::ExprKind::MethodCall(..) = block_expr.kind {
-                            check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None);
-                        }
+            hir::ExprKind::Block(block, _)
+                if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided) =>
+            {
+                if let Some(block_expr) = block.expr {
+                    if let hir::ExprKind::MethodCall(..) = block_expr.kind {
+                        check_general_case(cx, name, method_span, &args[0], &args[1], expr.span, None);
                     }
                 }
-            },
+            }
             _ => (),
         }
     }
diff --git a/clippy_lints/src/methods/suspicious_map.rs b/clippy_lints/src/methods/suspicious_map.rs
index 0fd0668c734..18ded291915 100644
--- a/clippy_lints/src/methods/suspicious_map.rs
+++ b/clippy_lints/src/methods/suspicious_map.rs
@@ -28,7 +28,7 @@ pub fn check<'tcx>(cx: &LateContext<'tcx>, expr: &hir::Expr<'_>, count_recv: &hi
                 expr.span,
                 "this call to `map()` won't have an effect on the call to `count()`",
                 None,
-                "make sure you did not confuse `map` with `filter` or `for_each`",
+                "make sure you did not confuse `map` with `filter`, `for_each` or `inspect`",
             );
         }
     }
diff --git a/clippy_lints/src/methods/unnecessary_filter_map.rs b/clippy_lints/src/methods/unnecessary_filter_map.rs
index a9d3764d92d..59bdfb923ed 100644
--- a/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -35,8 +35,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, arg: &hir::Expr<
             let in_ty = cx.typeck_results().node_type(body.params[0].hir_id);
             match cx.typeck_results().expr_ty(&body.value).kind() {
                 ty::Adt(adt, subst)
-                    if cx.tcx.is_diagnostic_item(sym::Option, adt.did)
-                        && TyS::same_type(in_ty, subst.type_at(0)) =>
+                    if cx.tcx.is_diagnostic_item(sym::Option, adt.did) && TyS::same_type(in_ty, subst.type_at(0)) =>
                 {
                     "filter"
                 },
diff --git a/clippy_lints/src/modulo_arithmetic.rs b/clippy_lints/src/modulo_arithmetic.rs
index 2d14943b56c..f45e68233a1 100644
--- a/clippy_lints/src/modulo_arithmetic.rs
+++ b/clippy_lints/src/modulo_arithmetic.rs
@@ -128,7 +128,7 @@ impl<'tcx> LateLintPass<'tcx> for ModuloArithmetic {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         match &expr.kind {
             ExprKind::Binary(op, lhs, rhs) | ExprKind::AssignOp(op, lhs, rhs) => {
-                if let BinOpKind::Rem = op.node {
+                if op.node == BinOpKind::Rem {
                     let lhs_operand = analyze_operand(lhs, cx, expr);
                     let rhs_operand = analyze_operand(rhs, cx, expr);
                     if_chain! {
diff --git a/clippy_lints/src/needless_bool.rs b/clippy_lints/src/needless_bool.rs
index c9dd94400ef..91944653500 100644
--- a/clippy_lints/src/needless_bool.rs
+++ b/clippy_lints/src/needless_bool.rs
@@ -248,7 +248,7 @@ fn check_comparison<'a, 'tcx>(
         if l_ty.is_bool() && r_ty.is_bool() {
             let mut applicability = Applicability::MachineApplicable;
 
-            if let BinOpKind::Eq = op.node {
+            if op.node == BinOpKind::Eq {
                 let expression_info = one_side_is_unary_not(left_side, right_side);
                 if expression_info.one_side_is_unary_not {
                     span_lint_and_sugg(
diff --git a/clippy_lints/src/neg_multiply.rs b/clippy_lints/src/neg_multiply.rs
index fa36d8fb1b3..1b15d29439f 100644
--- a/clippy_lints/src/neg_multiply.rs
+++ b/clippy_lints/src/neg_multiply.rs
@@ -46,7 +46,7 @@ impl<'tcx> LateLintPass<'tcx> for NegMultiply {
 fn check_mul(cx: &LateContext<'_>, span: Span, lit: &Expr<'_>, exp: &Expr<'_>) {
     if_chain! {
         if let ExprKind::Lit(ref l) = lit.kind;
-        if let Constant::Int(1) = consts::lit_to_constant(&l.node, cx.typeck_results().expr_ty_opt(lit));
+        if consts::lit_to_constant(&l.node, cx.typeck_results().expr_ty_opt(lit)) == Constant::Int(1);
         if cx.typeck_results().expr_ty(exp).is_integral();
         then {
             span_lint(cx, NEG_MULTIPLY, span, "negation by multiplying with `-1`");
diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs
index 0ad616a39d2..0ac27f1cba2 100644
--- a/clippy_lints/src/new_without_default.rs
+++ b/clippy_lints/src/new_without_default.rs
@@ -69,7 +69,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
         }) = item.kind
         {
             for assoc_item in items {
-                if let hir::AssocItemKind::Fn { has_self: false } = assoc_item.kind {
+                if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) {
                     let impl_item = cx.tcx.hir().impl_item(assoc_item.id);
                     if in_external_macro(cx.sess(), impl_item.span) {
                         return;
diff --git a/clippy_lints/src/non_send_fields_in_send_ty.rs b/clippy_lints/src/non_send_fields_in_send_ty.rs
new file mode 100644
index 00000000000..374b7bd5964
--- /dev/null
+++ b/clippy_lints/src/non_send_fields_in_send_ty.rs
@@ -0,0 +1,238 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::is_lint_allowed;
+use clippy_utils::source::snippet;
+use clippy_utils::ty::{implements_trait, is_copy};
+use rustc_ast::ImplPolarity;
+use rustc_hir::def_id::DefId;
+use rustc_hir::{FieldDef, Item, ItemKind, Node};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::ty::{self, subst::GenericArgKind, Ty};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Warns about fields in struct implementing `Send` that are neither `Send` nor `Copy`.
+    ///
+    /// ### Why is this bad?
+    /// Sending the struct to another thread will transfer the ownership to
+    /// the new thread by dropping in the current thread during the transfer.
+    /// This causes soundness issues for non-`Send` fields, as they are also
+    /// dropped and might not be set up to handle this.
+    ///
+    /// See:
+    /// * [*The Rustonomicon* about *Send and Sync*](https://doc.rust-lang.org/nomicon/send-and-sync.html)
+    /// * [The documentation of `Send`](https://doc.rust-lang.org/std/marker/trait.Send.html)
+    ///
+    /// ### Known Problems
+    /// Data structures that contain raw pointers may cause false positives.
+    /// They are sometimes safe to be sent across threads but do not implement
+    /// the `Send` trait. This lint has a heuristic to filter out basic cases
+    /// such as `Vec<*const T>`, but it's not perfect. Feel free to create an
+    /// issue if you have a suggestion on how this heuristic can be improved.
+    ///
+    /// ### Example
+    /// ```rust,ignore
+    /// struct ExampleStruct<T> {
+    ///     rc_is_not_send: Rc<String>,
+    ///     unbounded_generic_field: T,
+    /// }
+    ///
+    /// // This impl is unsound because it allows sending `!Send` types through `ExampleStruct`
+    /// unsafe impl<T> Send for ExampleStruct<T> {}
+    /// ```
+    /// Use thread-safe types like [`std::sync::Arc`](https://doc.rust-lang.org/std/sync/struct.Arc.html)
+    /// or specify correct bounds on generic type parameters (`T: Send`).
+    pub NON_SEND_FIELDS_IN_SEND_TY,
+    nursery,
+    "there is field that does not implement `Send` in a `Send` struct"
+}
+
+#[derive(Copy, Clone)]
+pub struct NonSendFieldInSendTy {
+    enable_raw_pointer_heuristic: bool,
+}
+
+impl NonSendFieldInSendTy {
+    pub fn new(enable_raw_pointer_heuristic: bool) -> Self {
+        Self {
+            enable_raw_pointer_heuristic,
+        }
+    }
+}
+
+impl_lint_pass!(NonSendFieldInSendTy => [NON_SEND_FIELDS_IN_SEND_TY]);
+
+impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
+        let ty_allowed_in_send = if self.enable_raw_pointer_heuristic {
+            ty_allowed_with_raw_pointer_heuristic
+        } else {
+            ty_allowed_without_raw_pointer_heuristic
+        };
+
+        // Checks if we are in `Send` impl item.
+        // We start from `Send` impl instead of `check_field_def()` because
+        // single `AdtDef` may have multiple `Send` impls due to generic
+        // parameters, and the lint is much easier to implement in this way.
+        if_chain! {
+            if let Some(send_trait) = cx.tcx.get_diagnostic_item(sym::Send);
+            if let ItemKind::Impl(hir_impl) = &item.kind;
+            if let Some(trait_ref) = &hir_impl.of_trait;
+            if let Some(trait_id) = trait_ref.trait_def_id();
+            if send_trait == trait_id;
+            if hir_impl.polarity == ImplPolarity::Positive;
+            if let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.def_id);
+            if let self_ty = ty_trait_ref.self_ty();
+            if let ty::Adt(adt_def, impl_trait_substs) = self_ty.kind();
+            then {
+                let mut non_send_fields = Vec::new();
+
+                let hir_map = cx.tcx.hir();
+                for variant in &adt_def.variants {
+                    for field in &variant.fields {
+                        if_chain! {
+                            if let Some(field_hir_id) = field
+                                .did
+                                .as_local()
+                                .map(|local_def_id| hir_map.local_def_id_to_hir_id(local_def_id));
+                            if !is_lint_allowed(cx, NON_SEND_FIELDS_IN_SEND_TY, field_hir_id);
+                            if let field_ty = field.ty(cx.tcx, impl_trait_substs);
+                            if !ty_allowed_in_send(cx, field_ty, send_trait);
+                            if let Node::Field(field_def) = hir_map.get(field_hir_id);
+                            then {
+                                non_send_fields.push(NonSendField {
+                                    def: field_def,
+                                    ty: field_ty,
+                                    generic_params: collect_generic_params(cx, field_ty),
+                                })
+                            }
+                        }
+                    }
+                }
+
+                if !non_send_fields.is_empty() {
+                    span_lint_and_then(
+                        cx,
+                        NON_SEND_FIELDS_IN_SEND_TY,
+                        item.span,
+                        &format!(
+                            "this implementation is unsound, as some fields in `{}` are `!Send`",
+                            snippet(cx, hir_impl.self_ty.span, "Unknown")
+                        ),
+                        |diag| {
+                            for field in non_send_fields {
+                                diag.span_note(
+                                    field.def.span,
+                                    &format!("the type of field `{}` is `!Send`", field.def.ident.name),
+                                );
+
+                                match field.generic_params.len() {
+                                    0 => diag.help("use a thread-safe type that implements `Send`"),
+                                    1 if is_ty_param(field.ty) => diag.help(&format!("add `{}: Send` bound in `Send` impl", field.ty)),
+                                    _ => diag.help(&format!(
+                                        "add bounds on type parameter{} `{}` that satisfy `{}: Send`",
+                                        if field.generic_params.len() > 1 { "s" } else { "" },
+                                        field.generic_params_string(),
+                                        snippet(cx, field.def.ty.span, "Unknown"),
+                                    )),
+                                };
+                            }
+                        },
+                    );
+                }
+            }
+        }
+    }
+}
+
+struct NonSendField<'tcx> {
+    def: &'tcx FieldDef<'tcx>,
+    ty: Ty<'tcx>,
+    generic_params: Vec<Ty<'tcx>>,
+}
+
+impl<'tcx> NonSendField<'tcx> {
+    fn generic_params_string(&self) -> String {
+        self.generic_params
+            .iter()
+            .map(ToString::to_string)
+            .collect::<Vec<_>>()
+            .join(", ")
+    }
+}
+
+/// Given a type, collect all of its generic parameters.
+/// Example: `MyStruct<P, Box<Q, R>>` => `vec![P, Q, R]`
+fn collect_generic_params<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Vec<Ty<'tcx>> {
+    ty.walk(cx.tcx)
+        .filter_map(|inner| match inner.unpack() {
+            GenericArgKind::Type(inner_ty) => Some(inner_ty),
+            _ => None,
+        })
+        .filter(|&inner_ty| is_ty_param(inner_ty))
+        .collect()
+}
+
+/// Be more strict when the heuristic is disabled
+fn ty_allowed_without_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, send_trait: DefId) -> bool {
+    if implements_trait(cx, ty, send_trait, &[]) {
+        return true;
+    }
+
+    if is_copy(cx, ty) && !contains_raw_pointer(cx, ty) {
+        return true;
+    }
+
+    false
+}
+
+/// Heuristic to allow cases like `Vec<*const u8>`
+fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, send_trait: DefId) -> bool {
+    if implements_trait(cx, ty, send_trait, &[]) || is_copy(cx, ty) {
+        return true;
+    }
+
+    // The type is known to be `!Send` and `!Copy`
+    match ty.kind() {
+        ty::Tuple(_) => ty
+            .tuple_fields()
+            .all(|ty| ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait)),
+        ty::Array(ty, _) | ty::Slice(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait),
+        ty::Adt(_, substs) => {
+            if contains_raw_pointer(cx, ty) {
+                // descends only if ADT contains any raw pointers
+                substs.iter().all(|generic_arg| match generic_arg.unpack() {
+                    GenericArgKind::Type(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait),
+                    // Lifetimes and const generics are not solid part of ADT and ignored
+                    GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => true,
+                })
+            } else {
+                false
+            }
+        },
+        // Raw pointers are `!Send` but allowed by the heuristic
+        ty::RawPtr(_) => true,
+        _ => false,
+    }
+}
+
+/// Checks if the type contains any raw pointers in substs (including nested ones).
+fn contains_raw_pointer<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> bool {
+    for ty_node in target_ty.walk(cx.tcx) {
+        if_chain! {
+            if let GenericArgKind::Type(inner_ty) = ty_node.unpack();
+            if let ty::RawPtr(_) = inner_ty.kind();
+            then {
+                return true;
+            }
+        }
+    }
+
+    false
+}
+
+/// Returns `true` if the type is a type parameter such as `T`.
+fn is_ty_param(target_ty: Ty<'_>) -> bool {
+    matches!(target_ty.kind(), ty::Param(_))
+}
diff --git a/clippy_lints/src/overflow_check_conditional.rs b/clippy_lints/src/overflow_check_conditional.rs
index 34755afdb72..0f9e5ada3a8 100644
--- a/clippy_lints/src/overflow_check_conditional.rs
+++ b/clippy_lints/src/overflow_check_conditional.rs
@@ -26,6 +26,9 @@ declare_clippy_lint! {
 
 declare_lint_pass!(OverflowCheckConditional => [OVERFLOW_CHECK_CONDITIONAL]);
 
+const OVERFLOW_MSG: &str = "you are trying to use classic C overflow conditions that will fail in Rust";
+const UNDERFLOW_MSG: &str = "you are trying to use classic C underflow conditions that will fail in Rust";
+
 impl<'tcx> LateLintPass<'tcx> for OverflowCheckConditional {
     // a + b < a, a > a + b, a < a - b, a - b > a
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
@@ -40,17 +43,11 @@ impl<'tcx> LateLintPass<'tcx> for OverflowCheckConditional {
             if cx.typeck_results().expr_ty(ident1).is_integral();
             if cx.typeck_results().expr_ty(ident2).is_integral();
             then {
-                if let BinOpKind::Lt = op.node {
-                    if let BinOpKind::Add = op2.node {
-                        span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
-                            "you are trying to use classic C overflow conditions that will fail in Rust");
-                    }
+                if op.node == BinOpKind::Lt && op2.node == BinOpKind::Add {
+                    span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span, OVERFLOW_MSG);
                 }
-                if let BinOpKind::Gt = op.node {
-                    if let BinOpKind::Sub = op2.node {
-                        span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
-                            "you are trying to use classic C underflow conditions that will fail in Rust");
-                    }
+                if op.node == BinOpKind::Gt && op2.node == BinOpKind::Sub {
+                    span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span, UNDERFLOW_MSG);
                 }
             }
         }
@@ -65,17 +62,11 @@ impl<'tcx> LateLintPass<'tcx> for OverflowCheckConditional {
             if cx.typeck_results().expr_ty(ident1).is_integral();
             if cx.typeck_results().expr_ty(ident2).is_integral();
             then {
-                if let BinOpKind::Gt = op.node {
-                    if let BinOpKind::Add = op2.node {
-                        span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
-                            "you are trying to use classic C overflow conditions that will fail in Rust");
-                    }
+                if op.node == BinOpKind::Gt && op2.node == BinOpKind::Add {
+                    span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span, OVERFLOW_MSG);
                 }
-                if let BinOpKind::Lt = op.node {
-                    if let BinOpKind::Sub = op2.node {
-                        span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span,
-                            "you are trying to use classic C underflow conditions that will fail in Rust");
-                    }
+                if op.node == BinOpKind::Lt && op2.node == BinOpKind::Sub {
+                    span_lint(cx, OVERFLOW_CHECK_CONDITIONAL, expr.span, UNDERFLOW_MSG);
                 }
             }
         }
diff --git a/clippy_lints/src/redundant_pub_crate.rs b/clippy_lints/src/redundant_pub_crate.rs
index ed2e1f90fa5..919d4e11e5a 100644
--- a/clippy_lints/src/redundant_pub_crate.rs
+++ b/clippy_lints/src/redundant_pub_crate.rs
@@ -41,25 +41,23 @@ impl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]);
 impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
         if let VisibilityKind::Crate { .. } = item.vis.node {
-            if !cx.access_levels.is_exported(item.def_id) {
-                if let Some(false) = self.is_exported.last() {
-                    let span = item.span.with_hi(item.ident.span.hi());
-                    let descr = cx.tcx.def_kind(item.def_id).descr(item.def_id.to_def_id());
-                    span_lint_and_then(
-                        cx,
-                        REDUNDANT_PUB_CRATE,
-                        span,
-                        &format!("pub(crate) {} inside private module", descr),
-                        |diag| {
-                            diag.span_suggestion(
-                                item.vis.span,
-                                "consider using",
-                                "pub".to_string(),
-                                Applicability::MachineApplicable,
-                            );
-                        },
-                    );
-                }
+            if !cx.access_levels.is_exported(item.def_id) && self.is_exported.last() == Some(&false) {
+                let span = item.span.with_hi(item.ident.span.hi());
+                let descr = cx.tcx.def_kind(item.def_id).descr(item.def_id.to_def_id());
+                span_lint_and_then(
+                    cx,
+                    REDUNDANT_PUB_CRATE,
+                    span,
+                    &format!("pub(crate) {} inside private module", descr),
+                    |diag| {
+                        diag.span_suggestion(
+                            item.vis.span,
+                            "consider using",
+                            "pub".to_string(),
+                            Applicability::MachineApplicable,
+                        );
+                    },
+                );
             }
         }
 
diff --git a/clippy_lints/src/repeat_once.rs b/clippy_lints/src/repeat_once.rs
index 5fd0d152763..cf94c0e97d9 100644
--- a/clippy_lints/src/repeat_once.rs
+++ b/clippy_lints/src/repeat_once.rs
@@ -48,7 +48,7 @@ impl<'tcx> LateLintPass<'tcx> for RepeatOnce {
         if_chain! {
             if let ExprKind::MethodCall(path, _, [receiver, count], _) = &expr.kind;
             if path.ident.name == sym!(repeat);
-            if let Some(Constant::Int(1)) = constant_context(cx, cx.typeck_results()).expr(count);
+            if constant_context(cx, cx.typeck_results()).expr(count) == Some(Constant::Int(1));
             if !in_macro(receiver.span);
             then {
                 let ty = cx.typeck_results().expr_ty(receiver).peel_refs();
diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs
index b9e317a3cfd..2ca7c18800e 100644
--- a/clippy_lints/src/shadow.rs
+++ b/clippy_lints/src/shadow.rs
@@ -1,17 +1,14 @@
-use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::diagnostics::span_lint_and_note;
 use clippy_utils::source::snippet;
-use clippy_utils::{contains_name, higher, iter_input_pats};
-use rustc_hir::intravisit::FnKind;
-use rustc_hir::{
-    Block, Body, Expr, ExprKind, FnDecl, Guard, HirId, Local, MutTy, Pat, PatKind, Path, QPath, StmtKind, Ty, TyKind,
-    UnOp,
-};
-use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty;
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::source_map::Span;
-use rustc_span::symbol::Symbol;
+use clippy_utils::visitors::is_local_used;
+use rustc_data_structures::fx::FxHashMap;
+use rustc_hir::def::Res;
+use rustc_hir::def_id::LocalDefId;
+use rustc_hir::hir_id::ItemLocalId;
+use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, Node, Pat, PatKind, QPath, UnOp};
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{Span, Symbol};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -23,10 +20,6 @@ declare_clippy_lint! {
     /// code. Still, some may opt to avoid it in their code base, they can set this
     /// lint to `Warn`.
     ///
-    /// ### Known problems
-    /// This lint, as the other shadowing related lints,
-    /// currently only catches very simple patterns.
-    ///
     /// ### Example
     /// ```rust
     /// # let x = 1;
@@ -52,10 +45,6 @@ declare_clippy_lint! {
     /// because a value may be bound to different things depending on position in
     /// the code.
     ///
-    /// ### Known problems
-    /// This lint, as the other shadowing related lints,
-    /// currently only catches very simple patterns.
-    ///
     /// ### Example
     /// ```rust
     /// let x = 2;
@@ -83,12 +72,6 @@ declare_clippy_lint! {
     /// any place in the code. This can be alleviated by either giving more specific
     /// names to bindings or introducing more scopes to contain the bindings.
     ///
-    /// ### Known problems
-    /// This lint, as the other shadowing related lints,
-    /// currently only catches very simple patterns. Note that
-    /// `allow`/`warn`/`deny`/`forbid` attributes only work on the function level
-    /// for this lint.
-    ///
     /// ### Example
     /// ```rust
     /// # let y = 1;
@@ -102,307 +85,151 @@ declare_clippy_lint! {
     /// let w = z; // use different variable name
     /// ```
     pub SHADOW_UNRELATED,
-    pedantic,
+    restriction,
     "rebinding a name without even using the original value"
 }
 
-declare_lint_pass!(Shadow => [SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED]);
+#[derive(Default)]
+pub(crate) struct Shadow {
+    bindings: Vec<FxHashMap<Symbol, Vec<ItemLocalId>>>,
+}
+
+impl_lint_pass!(Shadow => [SHADOW_SAME, SHADOW_REUSE, SHADOW_UNRELATED]);
 
 impl<'tcx> LateLintPass<'tcx> for Shadow {
-    fn check_fn(
-        &mut self,
-        cx: &LateContext<'tcx>,
-        _: FnKind<'tcx>,
-        decl: &'tcx FnDecl<'_>,
-        body: &'tcx Body<'_>,
-        _: Span,
-        _: HirId,
-    ) {
-        if in_external_macro(cx.sess(), body.value.span) {
+    fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
+        let (id, ident) = match pat.kind {
+            PatKind::Binding(_, hir_id, ident, _) => (hir_id, ident),
+            _ => return,
+        };
+        if ident.span.from_expansion() || ident.span.is_dummy() {
             return;
         }
-        check_fn(cx, decl, body);
-    }
-}
+        let HirId { owner, local_id } = id;
 
-fn check_fn<'tcx>(cx: &LateContext<'tcx>, decl: &'tcx FnDecl<'_>, body: &'tcx Body<'_>) {
-    let mut bindings = Vec::with_capacity(decl.inputs.len());
-    for arg in iter_input_pats(decl, body) {
-        if let PatKind::Binding(.., ident, _) = arg.pat.kind {
-            bindings.push((ident.name, ident.span));
+        // get (or insert) the list of items for this owner and symbol
+        let data = self.bindings.last_mut().unwrap();
+        let items_with_name = data.entry(ident.name).or_default();
+
+        // check other bindings with the same name, most recently seen first
+        for &prev in items_with_name.iter().rev() {
+            if prev == local_id {
+                // repeated binding in an `Or` pattern
+                return;
+            }
+
+            if is_shadow(cx, owner, prev, local_id) {
+                let prev_hir_id = HirId { owner, local_id: prev };
+                lint_shadow(cx, pat, prev_hir_id, ident.span);
+                // only lint against the "nearest" shadowed binding
+                break;
+            }
+        }
+        // store the binding
+        items_with_name.push(local_id);
+    }
+
+    fn check_body(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {
+        let hir = cx.tcx.hir();
+        if !matches!(hir.body_owner_kind(hir.body_owner(body.id())), BodyOwnerKind::Closure) {
+            self.bindings.push(FxHashMap::default());
         }
     }
-    check_expr(cx, &body.value, &mut bindings);
-}
 
-fn check_block<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'_>, bindings: &mut Vec<(Symbol, Span)>) {
-    let len = bindings.len();
-    for stmt in block.stmts {
-        match stmt.kind {
-            StmtKind::Local(local) => check_local(cx, local, bindings),
-            StmtKind::Expr(e) | StmtKind::Semi(e) => check_expr(cx, e, bindings),
-            StmtKind::Item(..) => {},
+    fn check_body_post(&mut self, cx: &LateContext<'_>, body: &Body<'_>) {
+        let hir = cx.tcx.hir();
+        if !matches!(hir.body_owner_kind(hir.body_owner(body.id())), BodyOwnerKind::Closure) {
+            self.bindings.pop();
         }
     }
-    if let Some(o) = block.expr {
-        check_expr(cx, o, bindings);
-    }
-    bindings.truncate(len);
 }
 
-fn check_local<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>, bindings: &mut Vec<(Symbol, Span)>) {
-    if in_external_macro(cx.sess(), local.span) {
-        return;
-    }
-    if higher::is_from_for_desugar(local) {
-        return;
-    }
-    let Local {
-        pat,
-        ref ty,
-        ref init,
+fn is_shadow(cx: &LateContext<'_>, owner: LocalDefId, first: ItemLocalId, second: ItemLocalId) -> bool {
+    let scope_tree = cx.tcx.region_scope_tree(owner.to_def_id());
+    let first_scope = scope_tree.var_scope(first);
+    let second_scope = scope_tree.var_scope(second);
+    scope_tree.is_subscope_of(second_scope, first_scope)
+}
+
+fn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span) {
+    let (lint, msg) = match find_init(cx, pat.hir_id) {
+        Some(expr) if is_self_shadow(cx, pat, expr, shadowed) => {
+            let msg = format!(
+                "`{}` is shadowed by itself in `{}`",
+                snippet(cx, pat.span, "_"),
+                snippet(cx, expr.span, "..")
+            );
+            (SHADOW_SAME, msg)
+        },
+        Some(expr) if is_local_used(cx, expr, shadowed) => {
+            let msg = format!(
+                "`{}` is shadowed by `{}` which reuses the original value",
+                snippet(cx, pat.span, "_"),
+                snippet(cx, expr.span, "..")
+            );
+            (SHADOW_REUSE, msg)
+        },
+        _ => {
+            let msg = format!("`{}` shadows a previous, unrelated binding", snippet(cx, pat.span, "_"));
+            (SHADOW_UNRELATED, msg)
+        },
+    };
+    span_lint_and_note(
+        cx,
+        lint,
         span,
-        ..
-    } = *local;
-    if let Some(t) = *ty {
-        check_ty(cx, t, bindings);
-    }
-    if let Some(o) = *init {
-        check_expr(cx, o, bindings);
-        check_pat(cx, pat, Some(o), span, bindings);
-    } else {
-        check_pat(cx, pat, None, span, bindings);
-    }
+        &msg,
+        Some(cx.tcx.hir().span(shadowed)),
+        "previous binding is here",
+    );
 }
 
-fn is_binding(cx: &LateContext<'_>, pat_id: HirId) -> bool {
-    let var_ty = cx.typeck_results().node_type_opt(pat_id);
-    var_ty.map_or(false, |var_ty| !matches!(var_ty.kind(), ty::Adt(..)))
-}
-
-fn check_pat<'tcx>(
-    cx: &LateContext<'tcx>,
-    pat: &'tcx Pat<'_>,
-    init: Option<&'tcx Expr<'_>>,
-    span: Span,
-    bindings: &mut Vec<(Symbol, Span)>,
-) {
-    // TODO: match more stuff / destructuring
-    match pat.kind {
-        PatKind::Binding(.., ident, ref inner) => {
-            let name = ident.name;
-            if is_binding(cx, pat.hir_id) {
-                let mut new_binding = true;
-                for tup in bindings.iter_mut() {
-                    if tup.0 == name {
-                        lint_shadow(cx, name, span, pat.span, init, tup.1);
-                        tup.1 = ident.span;
-                        new_binding = false;
-                        break;
-                    }
-                }
-                if new_binding {
-                    bindings.push((name, ident.span));
-                }
-            }
-            if let Some(p) = *inner {
-                check_pat(cx, p, init, span, bindings);
-            }
-        },
-        PatKind::Struct(_, pfields, _) => {
-            if let Some(init_struct) = init {
-                if let ExprKind::Struct(_, efields, _) = init_struct.kind {
-                    for field in pfields {
-                        let name = field.ident.name;
-                        let efield = efields
-                            .iter()
-                            .find_map(|f| if f.ident.name == name { Some(&*f.expr) } else { None });
-                        check_pat(cx, field.pat, efield, span, bindings);
-                    }
-                } else {
-                    for field in pfields {
-                        check_pat(cx, field.pat, init, span, bindings);
-                    }
-                }
-            } else {
-                for field in pfields {
-                    check_pat(cx, field.pat, None, span, bindings);
-                }
-            }
-        },
-        PatKind::Tuple(inner, _) => {
-            if let Some(init_tup) = init {
-                if let ExprKind::Tup(tup) = init_tup.kind {
-                    for (i, p) in inner.iter().enumerate() {
-                        check_pat(cx, p, Some(&tup[i]), p.span, bindings);
-                    }
-                } else {
-                    for p in inner {
-                        check_pat(cx, p, init, span, bindings);
-                    }
-                }
-            } else {
-                for p in inner {
-                    check_pat(cx, p, None, span, bindings);
-                }
-            }
-        },
-        PatKind::Box(inner) => {
-            if let Some(initp) = init {
-                if let ExprKind::Box(inner_init) = initp.kind {
-                    check_pat(cx, inner, Some(inner_init), span, bindings);
-                } else {
-                    check_pat(cx, inner, init, span, bindings);
-                }
-            } else {
-                check_pat(cx, inner, init, span, bindings);
-            }
-        },
-        PatKind::Ref(inner, _) => check_pat(cx, inner, init, span, bindings),
-        // PatVec(Vec<P<Pat>>, Option<P<Pat>>, Vec<P<Pat>>),
-        _ => (),
+/// Returns true if the expression is a simple transformation of a local binding such as `&x`
+fn is_self_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, mut expr: &Expr<'_>, hir_id: HirId) -> bool {
+    let hir = cx.tcx.hir();
+    let is_direct_binding = hir
+        .parent_iter(pat.hir_id)
+        .map_while(|(_id, node)| match node {
+            Node::Pat(pat) => Some(pat),
+            _ => None,
+        })
+        .all(|pat| matches!(pat.kind, PatKind::Ref(..) | PatKind::Or(_)));
+    if !is_direct_binding {
+        return false;
     }
-}
-
-fn lint_shadow<'tcx>(
-    cx: &LateContext<'tcx>,
-    name: Symbol,
-    span: Span,
-    pattern_span: Span,
-    init: Option<&'tcx Expr<'_>>,
-    prev_span: Span,
-) {
-    if let Some(expr) = init {
-        if is_self_shadow(name, expr) {
-            span_lint_and_then(
-                cx,
-                SHADOW_SAME,
-                span,
-                &format!(
-                    "`{}` is shadowed by itself in `{}`",
-                    snippet(cx, pattern_span, "_"),
-                    snippet(cx, expr.span, "..")
-                ),
-                |diag| {
-                    diag.span_note(prev_span, "previous binding is here");
+    loop {
+        expr = match expr.kind {
+            ExprKind::Box(e)
+            | ExprKind::AddrOf(_, _, e)
+            | ExprKind::Block(
+                &Block {
+                    stmts: [],
+                    expr: Some(e),
+                    ..
                 },
-            );
-        } else if contains_name(name, expr) {
-            span_lint_and_then(
-                cx,
-                SHADOW_REUSE,
-                pattern_span,
-                &format!(
-                    "`{}` is shadowed by `{}` which reuses the original value",
-                    snippet(cx, pattern_span, "_"),
-                    snippet(cx, expr.span, "..")
-                ),
-                |diag| {
-                    diag.span_note(expr.span, "initialization happens here");
-                    diag.span_note(prev_span, "previous binding is here");
-                },
-            );
-        } else {
-            span_lint_and_then(
-                cx,
-                SHADOW_UNRELATED,
-                pattern_span,
-                &format!("`{}` is being shadowed", snippet(cx, pattern_span, "_")),
-                |diag| {
-                    diag.span_note(expr.span, "initialization happens here");
-                    diag.span_note(prev_span, "previous binding is here");
-                },
-            );
+                _,
+            )
+            | ExprKind::Unary(UnOp::Deref, e) => e,
+            ExprKind::Path(QPath::Resolved(None, path)) => break path.res == Res::Local(hir_id),
+            _ => break false,
         }
-    } else {
-        span_lint_and_then(
-            cx,
-            SHADOW_UNRELATED,
-            span,
-            &format!("`{}` shadows a previous declaration", snippet(cx, pattern_span, "_")),
-            |diag| {
-                diag.span_note(prev_span, "previous binding is here");
+    }
+}
+
+/// Finds the "init" expression for a pattern: `let <pat> = <init>;` or
+/// `match <init> { .., <pat> => .., .. }`
+fn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
+    for (_, node) in cx.tcx.hir().parent_iter(hir_id) {
+        let init = match node {
+            Node::Arm(_) | Node::Pat(_) => continue,
+            Node::Expr(expr) => match expr.kind {
+                ExprKind::Match(e, _, _) => Some(e),
+                _ => None,
             },
-        );
+            Node::Local(local) => local.init,
+            _ => None,
+        };
+        return init;
     }
-}
-
-fn check_expr<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, bindings: &mut Vec<(Symbol, Span)>) {
-    if in_external_macro(cx.sess(), expr.span) {
-        return;
-    }
-    match expr.kind {
-        ExprKind::Unary(_, e) | ExprKind::Field(e, _) | ExprKind::AddrOf(_, _, e) | ExprKind::Box(e) => {
-            check_expr(cx, e, bindings);
-        },
-        ExprKind::Block(block, _) | ExprKind::Loop(block, ..) => check_block(cx, block, bindings),
-        // ExprKind::Call
-        // ExprKind::MethodCall
-        ExprKind::Array(v) | ExprKind::Tup(v) => {
-            for e in v {
-                check_expr(cx, e, bindings);
-            }
-        },
-        ExprKind::If(cond, then, ref otherwise) => {
-            check_expr(cx, cond, bindings);
-            check_expr(cx, then, bindings);
-            if let Some(o) = *otherwise {
-                check_expr(cx, o, bindings);
-            }
-        },
-        ExprKind::Match(init, arms, _) => {
-            check_expr(cx, init, bindings);
-            let len = bindings.len();
-            for arm in arms {
-                check_pat(cx, arm.pat, Some(init), arm.pat.span, bindings);
-                // This is ugly, but needed to get the right type
-                if let Some(ref guard) = arm.guard {
-                    match guard {
-                        Guard::If(if_expr) => check_expr(cx, if_expr, bindings),
-                        Guard::IfLet(guard_pat, guard_expr) => {
-                            check_pat(cx, guard_pat, Some(*guard_expr), guard_pat.span, bindings);
-                            check_expr(cx, guard_expr, bindings);
-                        },
-                    }
-                }
-                check_expr(cx, arm.body, bindings);
-                bindings.truncate(len);
-            }
-        },
-        _ => (),
-    }
-}
-
-fn check_ty<'tcx>(cx: &LateContext<'tcx>, ty: &'tcx Ty<'_>, bindings: &mut Vec<(Symbol, Span)>) {
-    match ty.kind {
-        TyKind::Slice(sty) => check_ty(cx, sty, bindings),
-        TyKind::Array(fty, ref anon_const) => {
-            check_ty(cx, fty, bindings);
-            check_expr(cx, &cx.tcx.hir().body(anon_const.body).value, bindings);
-        },
-        TyKind::Ptr(MutTy { ty: mty, .. }) | TyKind::Rptr(_, MutTy { ty: mty, .. }) => check_ty(cx, mty, bindings),
-        TyKind::Tup(tup) => {
-            for t in tup {
-                check_ty(cx, t, bindings);
-            }
-        },
-        TyKind::Typeof(ref anon_const) => check_expr(cx, &cx.tcx.hir().body(anon_const.body).value, bindings),
-        _ => (),
-    }
-}
-
-fn is_self_shadow(name: Symbol, expr: &Expr<'_>) -> bool {
-    match expr.kind {
-        ExprKind::Box(inner) | ExprKind::AddrOf(_, _, inner) => is_self_shadow(name, inner),
-        ExprKind::Block(block, _) => {
-            block.stmts.is_empty() && block.expr.as_ref().map_or(false, |e| is_self_shadow(name, e))
-        },
-        ExprKind::Unary(op, inner) => (UnOp::Deref == op) && is_self_shadow(name, inner),
-        ExprKind::Path(QPath::Resolved(_, path)) => path_eq_name(name, path),
-        _ => false,
-    }
-}
-
-fn path_eq_name(name: Symbol, path: &Path<'_>) -> bool {
-    !path.is_global() && path.segments.len() == 1 && path.segments[0].ident.name == name
+    None
 }
diff --git a/clippy_lints/src/transmuting_null.rs b/clippy_lints/src/transmuting_null.rs
index a67fa792205..ef80663d1da 100644
--- a/clippy_lints/src/transmuting_null.rs
+++ b/clippy_lints/src/transmuting_null.rs
@@ -49,8 +49,8 @@ impl<'tcx> LateLintPass<'tcx> for TransmutingNull {
                 let mut const_eval_context = constant_context(cx, cx.typeck_results());
                 if_chain! {
                     if let ExprKind::Path(ref _qpath) = arg.kind;
-                    let x = const_eval_context.expr(arg);
-                    if let Some(Constant::RawPtr(0)) = x;
+                    if let Some(Constant::RawPtr(x)) = const_eval_context.expr(arg);
+                    if x == 0;
                     then {
                         span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG)
                     }
diff --git a/clippy_lints/src/types/option_option.rs b/clippy_lints/src/types/option_option.rs
index 4f50284e941..903e62995c6 100644
--- a/clippy_lints/src/types/option_option.rs
+++ b/clippy_lints/src/types/option_option.rs
@@ -7,9 +7,7 @@ use rustc_span::symbol::sym;
 use super::OPTION_OPTION;
 
 pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_>, def_id: DefId) -> bool {
-    if cx.tcx.is_diagnostic_item(sym::Option, def_id)
-        && is_ty_param_diagnostic_item(cx, qpath, sym::Option).is_some()
-    {
+    if cx.tcx.is_diagnostic_item(sym::Option, def_id) && is_ty_param_diagnostic_item(cx, qpath, sym::Option).is_some() {
         span_lint(
             cx,
             OPTION_OPTION,
diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs
index 1e0447239be..6cbada4c150 100644
--- a/clippy_lints/src/utils/conf.rs
+++ b/clippy_lints/src/utils/conf.rs
@@ -284,6 +284,10 @@ define_Conf! {
     ///
     /// The list of unicode scripts allowed to be used in the scope.
     (allowed_scripts: Vec<String> = vec!["Latin".to_string()]),
+    /// Lint: NON_SEND_FIELDS_IN_SEND_TY.
+    ///
+    /// Whether to apply the raw pointer heuristic to determine if a type is `Send`.
+    (enable_raw_pointer_heuristic_for_send: bool = true),
 }
 
 /// Search for the configuration file.
diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs
index 59c40050522..9f9edbf258a 100644
--- a/clippy_lints/src/utils/internal_lints.rs
+++ b/clippy_lints/src/utils/internal_lints.rs
@@ -8,7 +8,7 @@ use clippy_utils::{
     paths, SpanlessEq,
 };
 use if_chain::if_chain;
-use rustc_ast::ast::{Crate as AstCrate, ItemKind, LitKind, ModKind, NodeId};
+use rustc_ast::ast::{Crate, ItemKind, LitKind, ModKind, NodeId};
 use rustc_ast::visit::FnKind;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_errors::Applicability;
@@ -18,8 +18,8 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::hir_id::CRATE_HIR_ID;
 use rustc_hir::intravisit::{NestedVisitorMap, Visitor};
 use rustc_hir::{
-    BinOpKind, Block, Crate, Expr, ExprKind, HirId, Item, Local, MutTy, Mutability, Node, Path, Stmt, StmtKind, Ty,
-    TyKind, UnOp,
+    BinOpKind, Block, Expr, ExprKind, HirId, Item, Local, MutTy, Mutability, Node, Path, Stmt, StmtKind, Ty, TyKind,
+    UnOp,
 };
 use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 use rustc_middle::hir::map::Map;
@@ -317,7 +317,7 @@ declare_clippy_lint! {
 declare_lint_pass!(ClippyLintsInternal => [CLIPPY_LINTS_INTERNAL]);
 
 impl EarlyLintPass for ClippyLintsInternal {
-    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &AstCrate) {
+    fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {
         if let Some(utils) = krate.items.iter().find(|item| item.ident.name.as_str() == "utils") {
             if let ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) = utils.kind {
                 if let Some(paths) = items.iter().find(|item| item.ident.name.as_str() == "paths") {
@@ -412,7 +412,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
         }
     }
 
-    fn check_crate_post(&mut self, cx: &LateContext<'tcx>, _: &'tcx Crate<'_>) {
+    fn check_crate_post(&mut self, cx: &LateContext<'tcx>) {
         if is_lint_allowed(cx, LINT_WITHOUT_LINT_PASS, CRATE_HIR_ID) {
             return;
         }
@@ -907,7 +907,7 @@ pub struct InterningDefinedSymbol {
 impl_lint_pass!(InterningDefinedSymbol => [INTERNING_DEFINED_SYMBOL, UNNECESSARY_SYMBOL_STR]);
 
 impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol {
-    fn check_crate(&mut self, cx: &LateContext<'_>, _: &Crate<'_>) {
+    fn check_crate(&mut self, cx: &LateContext<'_>) {
         if !self.symbol_map.is_empty() {
             return;
         }
diff --git a/clippy_lints/src/zero_div_zero.rs b/clippy_lints/src/zero_div_zero.rs
index b29ced28ac4..e0746ce4d81 100644
--- a/clippy_lints/src/zero_div_zero.rs
+++ b/clippy_lints/src/zero_div_zero.rs
@@ -32,7 +32,7 @@ impl<'tcx> LateLintPass<'tcx> for ZeroDiv {
         // check for instances of 0.0/0.0
         if_chain! {
             if let ExprKind::Binary(ref op, left, right) = expr.kind;
-            if let BinOpKind::Div = op.node;
+            if op.node == BinOpKind::Div;
             // TODO - constant_simple does not fold many operations involving floats.
             // That's probably fine for this lint - it's pretty unlikely that someone would
             // do something like 0.0/(2.0 - 2.0), but it would be nice to warn on that case too.
diff --git a/clippy_utils/src/lib.rs b/clippy_utils/src/lib.rs
index 00123fdba24..c47aa9170e5 100644
--- a/clippy_utils/src/lib.rs
+++ b/clippy_utils/src/lib.rs
@@ -509,7 +509,6 @@ pub fn path_to_local_id(expr: &Expr<'_>, id: HirId) -> bool {
 }
 
 /// Gets the definition associated to a path.
-#[allow(clippy::shadow_unrelated)] // false positive #6563
 pub fn path_to_res(cx: &LateContext<'_>, path: &[&str]) -> Res {
     macro_rules! try_res {
         ($e:expr) => {
@@ -683,7 +682,17 @@ pub fn is_default_equivalent(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
             _ => false,
         },
         ExprKind::Tup(items) | ExprKind::Array(items) => items.iter().all(|x| is_default_equivalent(cx, x)),
-        ExprKind::Repeat(x, _) => is_default_equivalent(cx, x),
+        ExprKind::Repeat(x, y) => if_chain! {
+            if let ExprKind::Lit(ref const_lit) = cx.tcx.hir().body(y.body).value.kind;
+            if let LitKind::Int(v, _) = const_lit.node;
+            if v <= 32 && is_default_equivalent(cx, x);
+            then {
+                true
+            }
+            else {
+                false
+            }
+        },
         ExprKind::Call(repl_func, _) => if_chain! {
             if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind;
             if let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id();
@@ -1498,7 +1507,7 @@ pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tc
 
     if let ExprKind::Match(_, arms, ref source) = expr.kind {
         // desugared from a `?` operator
-        if let MatchSource::TryDesugar = *source {
+        if *source == MatchSource::TryDesugar {
             return Some(expr);
         }
 
diff --git a/clippy_utils/src/numeric_literal.rs b/clippy_utils/src/numeric_literal.rs
index 4a28c7dd9a0..68dd1b29845 100644
--- a/clippy_utils/src/numeric_literal.rs
+++ b/clippy_utils/src/numeric_literal.rs
@@ -74,7 +74,7 @@ impl<'a> NumericLiteral<'a> {
         };
 
         // Grab part of the literal after prefix, if present.
-        let (prefix, mut sans_prefix) = if let Radix::Decimal = radix {
+        let (prefix, mut sans_prefix) = if radix == Radix::Decimal {
             (None, lit)
         } else {
             let (p, s) = lit.split_at(2);
@@ -157,8 +157,10 @@ impl<'a> NumericLiteral<'a> {
         }
 
         if let Some((separator, exponent)) = self.exponent {
-            output.push_str(separator);
-            Self::group_digits(&mut output, exponent, group_size, true, false);
+            if exponent != "0" {
+                output.push_str(separator);
+                Self::group_digits(&mut output, exponent, group_size, true, false);
+            }
         }
 
         if let Some(suffix) = self.suffix {
@@ -177,6 +179,13 @@ impl<'a> NumericLiteral<'a> {
 
         let mut digits = input.chars().filter(|&c| c != '_');
 
+        // The exponent may have a sign, output it early, otherwise it will be
+        // treated as a digit
+        if digits.clone().next() == Some('-') {
+            let _ = digits.next();
+            output.push('-');
+        }
+
         let first_group_size;
 
         if partial_group_first {
diff --git a/clippy_utils/src/paths.rs b/clippy_utils/src/paths.rs
index 5e0182ec1b8..e43c5756021 100644
--- a/clippy_utils/src/paths.rs
+++ b/clippy_utils/src/paths.rs
@@ -129,11 +129,17 @@ pub const RANGE_ARGUMENT_TRAIT: [&str; 3] = ["core", "ops", "RangeBounds"];
 pub const RC_PTR_EQ: [&str; 4] = ["alloc", "rc", "Rc", "ptr_eq"];
 pub const REFCELL_REF: [&str; 3] = ["core", "cell", "Ref"];
 pub const REFCELL_REFMUT: [&str; 3] = ["core", "cell", "RefMut"];
+#[allow(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const REGEX_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "unicode", "RegexBuilder", "new"];
+#[allow(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const REGEX_BYTES_BUILDER_NEW: [&str; 5] = ["regex", "re_builder", "bytes", "RegexBuilder", "new"];
+#[allow(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "re_bytes", "Regex", "new"];
+#[allow(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const REGEX_BYTES_SET_NEW: [&str; 5] = ["regex", "re_set", "bytes", "RegexSet", "new"];
+#[allow(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const REGEX_NEW: [&str; 4] = ["regex", "re_unicode", "Regex", "new"];
+#[allow(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const REGEX_SET_NEW: [&str; 5] = ["regex", "re_set", "unicode", "RegexSet", "new"];
 /// Preferably use the diagnostic item `sym::Result` where possible
 pub const RESULT: [&str; 3] = ["core", "result", "Result"];
diff --git a/clippy_utils/src/sugg.rs b/clippy_utils/src/sugg.rs
index ab05a0b4238..5b0efb1fd71 100644
--- a/clippy_utils/src/sugg.rs
+++ b/clippy_utils/src/sugg.rs
@@ -311,7 +311,7 @@ impl<'a> Sugg<'a> {
 /// Return `true` if `sugg` is enclosed in parenthesis.
 fn has_enclosing_paren(sugg: impl AsRef<str>) -> bool {
     let mut chars = sugg.as_ref().chars();
-    if let Some('(') = chars.next() {
+    if chars.next() == Some('(') {
         let mut depth = 1;
         for c in &mut chars {
             if c == '(' {
diff --git a/clippy_utils/src/ty.rs b/clippy_utils/src/ty.rs
index 96cb8a4dae4..6ebe1a0028a 100644
--- a/clippy_utils/src/ty.rs
+++ b/clippy_utils/src/ty.rs
@@ -224,15 +224,15 @@ fn is_normalizable_helper<'tcx>(
     result
 }
 
-/// Returns true iff the given type is a non aggregate primitive (a bool or char, any integer or
-/// floating-point number type). For checking aggregation of primitive types (e.g. tuples and slices
-/// of primitive type) see `is_recursively_primitive_type`
+/// Returns `true` if the given type is a non aggregate primitive (a `bool` or `char`, any
+/// integer or floating-point number type). For checking aggregation of primitive types (e.g.
+/// tuples and slices of primitive type) see `is_recursively_primitive_type`
 pub fn is_non_aggregate_primitive_type(ty: Ty<'_>) -> bool {
     matches!(ty.kind(), ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_))
 }
 
-/// Returns true iff the given type is a primitive (a bool or char, any integer or floating-point
-/// number type, a str, or an array, slice, or tuple of those types).
+/// Returns `true` if the given type is a primitive (a `bool` or `char`, any integer or
+/// floating-point number type, a `str`, or an array, slice, or tuple of those types).
 pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool {
     match ty.kind() {
         ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => true,
diff --git a/clippy_utils/src/usage.rs b/clippy_utils/src/usage.rs
index 098ec175fe2..34206b5ae2b 100644
--- a/clippy_utils/src/usage.rs
+++ b/clippy_utils/src/usage.rs
@@ -65,7 +65,7 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
     fn consume(&mut self, _: &PlaceWithHirId<'tcx>, _: HirId) {}
 
     fn borrow(&mut self, cmt: &PlaceWithHirId<'tcx>, _: HirId, bk: ty::BorrowKind) {
-        if let ty::BorrowKind::MutBorrow = bk {
+        if bk == ty::BorrowKind::MutBorrow {
             self.update(cmt);
         }
     }
diff --git a/rust-toolchain b/rust-toolchain
index 660401ff28c..f98819303e6 100644
--- a/rust-toolchain
+++ b/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2021-09-28"
+channel = "nightly-2021-10-07"
 components = ["llvm-tools-preview", "rustc-dev", "rust-src"]
diff --git a/tests/compile-test.rs b/tests/compile-test.rs
index d7596f6ff0c..e8b1640c869 100644
--- a/tests/compile-test.rs
+++ b/tests/compile-test.rs
@@ -92,7 +92,9 @@ fn extern_flags() -> String {
         .collect();
     assert!(
         not_found.is_empty(),
-        "dependencies not found in depinfo: {:?}",
+        "dependencies not found in depinfo: {:?}\n\
+        help: Make sure the `-Z binary-dep-depinfo` rust flag is enabled\n\
+        help: Try adding to dev-dependencies in Cargo.toml",
         not_found
     );
     crates
diff --git a/tests/ui-toml/strict_non_send_fields_in_send_ty/clippy.toml b/tests/ui-toml/strict_non_send_fields_in_send_ty/clippy.toml
new file mode 100644
index 00000000000..a942709d14a
--- /dev/null
+++ b/tests/ui-toml/strict_non_send_fields_in_send_ty/clippy.toml
@@ -0,0 +1 @@
+enable-raw-pointer-heuristic-for-send = false
diff --git a/tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs b/tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs
new file mode 100644
index 00000000000..90c2439dc34
--- /dev/null
+++ b/tests/ui-toml/strict_non_send_fields_in_send_ty/test.rs
@@ -0,0 +1,43 @@
+#![warn(clippy::non_send_fields_in_send_ty)]
+#![feature(extern_types)]
+
+use std::rc::Rc;
+
+// Basic tests should not be affected
+pub struct NoGeneric {
+    rc_is_not_send: Rc<String>,
+}
+
+unsafe impl Send for NoGeneric {}
+
+pub struct MultiField<T> {
+    field1: T,
+    field2: T,
+    field3: T,
+}
+
+unsafe impl<T> Send for MultiField<T> {}
+
+pub enum MyOption<T> {
+    MySome(T),
+    MyNone,
+}
+
+unsafe impl<T> Send for MyOption<T> {}
+
+// All fields are disallowed when raw pointer heuristic is off
+extern "C" {
+    type NonSend;
+}
+
+pub struct HeuristicTest {
+    field1: Vec<*const NonSend>,
+    field2: [*const NonSend; 3],
+    field3: (*const NonSend, *const NonSend, *const NonSend),
+    field4: (*const NonSend, Rc<u8>),
+    field5: Vec<Vec<*const NonSend>>,
+}
+
+unsafe impl Send for HeuristicTest {}
+
+fn main() {}
diff --git a/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr b/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr
new file mode 100644
index 00000000000..b07f9dd3df3
--- /dev/null
+++ b/tests/ui-toml/strict_non_send_fields_in_send_ty/test.stderr
@@ -0,0 +1,91 @@
+error: this implementation is unsound, as some fields in `NoGeneric` are `!Send`
+  --> $DIR/test.rs:11:1
+   |
+LL | unsafe impl Send for NoGeneric {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
+note: the type of field `rc_is_not_send` is `!Send`
+  --> $DIR/test.rs:8:5
+   |
+LL |     rc_is_not_send: Rc<String>,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use a thread-safe type that implements `Send`
+
+error: this implementation is unsound, as some fields in `MultiField<T>` are `!Send`
+  --> $DIR/test.rs:19:1
+   |
+LL | unsafe impl<T> Send for MultiField<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `field1` is `!Send`
+  --> $DIR/test.rs:14:5
+   |
+LL |     field1: T,
+   |     ^^^^^^^^^
+   = help: add `T: Send` bound in `Send` impl
+note: the type of field `field2` is `!Send`
+  --> $DIR/test.rs:15:5
+   |
+LL |     field2: T,
+   |     ^^^^^^^^^
+   = help: add `T: Send` bound in `Send` impl
+note: the type of field `field3` is `!Send`
+  --> $DIR/test.rs:16:5
+   |
+LL |     field3: T,
+   |     ^^^^^^^^^
+   = help: add `T: Send` bound in `Send` impl
+
+error: this implementation is unsound, as some fields in `MyOption<T>` are `!Send`
+  --> $DIR/test.rs:26:1
+   |
+LL | unsafe impl<T> Send for MyOption<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `0` is `!Send`
+  --> $DIR/test.rs:22:12
+   |
+LL |     MySome(T),
+   |            ^
+   = help: add `T: Send` bound in `Send` impl
+
+error: this implementation is unsound, as some fields in `HeuristicTest` are `!Send`
+  --> $DIR/test.rs:41:1
+   |
+LL | unsafe impl Send for HeuristicTest {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `field1` is `!Send`
+  --> $DIR/test.rs:34:5
+   |
+LL |     field1: Vec<*const NonSend>,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use a thread-safe type that implements `Send`
+note: the type of field `field2` is `!Send`
+  --> $DIR/test.rs:35:5
+   |
+LL |     field2: [*const NonSend; 3],
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use a thread-safe type that implements `Send`
+note: the type of field `field3` is `!Send`
+  --> $DIR/test.rs:36:5
+   |
+LL |     field3: (*const NonSend, *const NonSend, *const NonSend),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use a thread-safe type that implements `Send`
+note: the type of field `field4` is `!Send`
+  --> $DIR/test.rs:37:5
+   |
+LL |     field4: (*const NonSend, Rc<u8>),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use a thread-safe type that implements `Send`
+note: the type of field `field5` is `!Send`
+  --> $DIR/test.rs:38:5
+   |
+LL |     field5: Vec<Vec<*const NonSend>>,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use a thread-safe type that implements `Send`
+
+error: aborting due to 4 previous errors
+
diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index e0029ebeb27..97bab1308aa 100644
--- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -1,4 +1,4 @@
-error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `third-party` at line 5 column 1
+error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown field `foobar`, expected one of `avoid-breaking-exported-api`, `msrv`, `blacklisted-names`, `cognitive-complexity-threshold`, `cyclomatic-complexity-threshold`, `doc-valid-idents`, `too-many-arguments-threshold`, `type-complexity-threshold`, `single-char-binding-names-threshold`, `too-large-for-stack`, `enum-variant-name-threshold`, `enum-variant-size-threshold`, `verbose-bit-mask-threshold`, `literal-representation-threshold`, `trivial-copy-size-limit`, `pass-by-value-size-limit`, `too-many-lines-threshold`, `array-size-threshold`, `vec-box-size-threshold`, `max-trait-bounds`, `max-struct-bools`, `max-fn-params-bools`, `warn-on-all-wildcard-imports`, `disallowed-methods`, `disallowed-types`, `unreadable-literal-lint-fractions`, `upper-case-acronyms-aggressive`, `cargo-ignore-publish`, `standard-macro-braces`, `enforced-import-renames`, `allowed-scripts`, `enable-raw-pointer-heuristic-for-send`, `third-party` at line 5 column 1
 
 error: aborting due to previous error
 
diff --git a/tests/ui/approx_const.rs b/tests/ui/approx_const.rs
index 2ae4d613507..ccdbd34f7ec 100644
--- a/tests/ui/approx_const.rs
+++ b/tests/ui/approx_const.rs
@@ -1,5 +1,5 @@
 #[warn(clippy::approx_constant)]
-#[allow(unused, clippy::shadow_unrelated, clippy::similar_names)]
+#[allow(clippy::similar_names)]
 fn main() {
     let my_e = 2.7182;
     let almost_e = 2.718;
diff --git a/tests/ui/branches_sharing_code/shared_at_bottom.rs b/tests/ui/branches_sharing_code/shared_at_bottom.rs
index ce2040bdeb8..12f550d9c9a 100644
--- a/tests/ui/branches_sharing_code/shared_at_bottom.rs
+++ b/tests/ui/branches_sharing_code/shared_at_bottom.rs
@@ -1,4 +1,4 @@
-#![allow(dead_code)]
+#![allow(dead_code, clippy::equatable_if_let)]
 #![deny(clippy::if_same_then_else, clippy::branches_sharing_code)]
 
 // This tests the branches_sharing_code lint at the end of blocks
diff --git a/tests/ui/collapsible_else_if.fixed b/tests/ui/collapsible_else_if.fixed
index c69a46f0a77..bb6c4c0703d 100644
--- a/tests/ui/collapsible_else_if.fixed
+++ b/tests/ui/collapsible_else_if.fixed
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(clippy::assertions_on_constants)]
+#![allow(clippy::assertions_on_constants, clippy::equatable_if_let)]
 
 #[rustfmt::skip]
 #[warn(clippy::collapsible_if)]
diff --git a/tests/ui/collapsible_else_if.rs b/tests/ui/collapsible_else_if.rs
index 1359c7eb627..6d4f688db8c 100644
--- a/tests/ui/collapsible_else_if.rs
+++ b/tests/ui/collapsible_else_if.rs
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(clippy::assertions_on_constants)]
+#![allow(clippy::assertions_on_constants, clippy::equatable_if_let)]
 
 #[rustfmt::skip]
 #[warn(clippy::collapsible_if)]
diff --git a/tests/ui/collapsible_if.fixed b/tests/ui/collapsible_if.fixed
index e4c088bf6f0..5b0e4a473c4 100644
--- a/tests/ui/collapsible_if.fixed
+++ b/tests/ui/collapsible_if.fixed
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(clippy::assertions_on_constants)]
+#![allow(clippy::assertions_on_constants, clippy::equatable_if_let)]
 
 #[rustfmt::skip]
 #[warn(clippy::collapsible_if)]
diff --git a/tests/ui/collapsible_if.rs b/tests/ui/collapsible_if.rs
index d6cf01c8319..cd231a5d7ab 100644
--- a/tests/ui/collapsible_if.rs
+++ b/tests/ui/collapsible_if.rs
@@ -1,5 +1,5 @@
 // run-rustfix
-#![allow(clippy::assertions_on_constants)]
+#![allow(clippy::assertions_on_constants, clippy::equatable_if_let)]
 
 #[rustfmt::skip]
 #[warn(clippy::collapsible_if)]
diff --git a/tests/ui/collapsible_match.rs b/tests/ui/collapsible_match.rs
index 4ce365cc764..603ae7dc9eb 100644
--- a/tests/ui/collapsible_match.rs
+++ b/tests/ui/collapsible_match.rs
@@ -1,5 +1,10 @@
 #![warn(clippy::collapsible_match)]
-#![allow(clippy::needless_return, clippy::no_effect, clippy::single_match)]
+#![allow(
+    clippy::needless_return,
+    clippy::no_effect,
+    clippy::single_match,
+    clippy::equatable_if_let
+)]
 
 fn lint_cases(opt_opt: Option<Option<u32>>, res_opt: Result<Option<u32>, String>) {
     // match without block
diff --git a/tests/ui/collapsible_match.stderr b/tests/ui/collapsible_match.stderr
index c119570e8ab..5f18b693502 100644
--- a/tests/ui/collapsible_match.stderr
+++ b/tests/ui/collapsible_match.stderr
@@ -1,5 +1,5 @@
 error: this `match` can be collapsed into the outer `match`
-  --> $DIR/collapsible_match.rs:7:20
+  --> $DIR/collapsible_match.rs:12:20
    |
 LL |           Ok(val) => match val {
    |  ____________________^
@@ -10,7 +10,7 @@ LL | |         },
    |
    = note: `-D clippy::collapsible-match` implied by `-D warnings`
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:7:12
+  --> $DIR/collapsible_match.rs:12:12
    |
 LL |         Ok(val) => match val {
    |            ^^^ replace this binding
@@ -18,7 +18,7 @@ LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
 error: this `match` can be collapsed into the outer `match`
-  --> $DIR/collapsible_match.rs:16:20
+  --> $DIR/collapsible_match.rs:21:20
    |
 LL |           Ok(val) => match val {
    |  ____________________^
@@ -28,7 +28,7 @@ LL | |         },
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:16:12
+  --> $DIR/collapsible_match.rs:21:12
    |
 LL |         Ok(val) => match val {
    |            ^^^ replace this binding
@@ -36,7 +36,7 @@ LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
 error: this `if let` can be collapsed into the outer `if let`
-  --> $DIR/collapsible_match.rs:25:9
+  --> $DIR/collapsible_match.rs:30:9
    |
 LL | /         if let Some(n) = val {
 LL | |             take(n);
@@ -44,7 +44,7 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:24:15
+  --> $DIR/collapsible_match.rs:29:15
    |
 LL |     if let Ok(val) = res_opt {
    |               ^^^ replace this binding
@@ -52,7 +52,7 @@ LL |         if let Some(n) = val {
    |                ^^^^^^^ with this pattern
 
 error: this `if let` can be collapsed into the outer `if let`
-  --> $DIR/collapsible_match.rs:32:9
+  --> $DIR/collapsible_match.rs:37:9
    |
 LL | /         if let Some(n) = val {
 LL | |             take(n);
@@ -62,7 +62,7 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:31:15
+  --> $DIR/collapsible_match.rs:36:15
    |
 LL |     if let Ok(val) = res_opt {
    |               ^^^ replace this binding
@@ -70,7 +70,7 @@ LL |         if let Some(n) = val {
    |                ^^^^^^^ with this pattern
 
 error: this `match` can be collapsed into the outer `if let`
-  --> $DIR/collapsible_match.rs:43:9
+  --> $DIR/collapsible_match.rs:48:9
    |
 LL | /         match val {
 LL | |             Some(n) => foo(n),
@@ -79,7 +79,7 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:42:15
+  --> $DIR/collapsible_match.rs:47:15
    |
 LL |     if let Ok(val) = res_opt {
    |               ^^^ replace this binding
@@ -88,7 +88,7 @@ LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
 error: this `if let` can be collapsed into the outer `match`
-  --> $DIR/collapsible_match.rs:52:13
+  --> $DIR/collapsible_match.rs:57:13
    |
 LL | /             if let Some(n) = val {
 LL | |                 take(n);
@@ -96,7 +96,7 @@ LL | |             }
    | |_____________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:51:12
+  --> $DIR/collapsible_match.rs:56:12
    |
 LL |         Ok(val) => {
    |            ^^^ replace this binding
@@ -104,7 +104,7 @@ LL |             if let Some(n) = val {
    |                    ^^^^^^^ with this pattern
 
 error: this `match` can be collapsed into the outer `if let`
-  --> $DIR/collapsible_match.rs:61:9
+  --> $DIR/collapsible_match.rs:66:9
    |
 LL | /         match val {
 LL | |             Some(n) => foo(n),
@@ -113,7 +113,7 @@ LL | |         }
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:60:15
+  --> $DIR/collapsible_match.rs:65:15
    |
 LL |     if let Ok(val) = res_opt {
    |               ^^^ replace this binding
@@ -122,7 +122,7 @@ LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
 error: this `if let` can be collapsed into the outer `match`
-  --> $DIR/collapsible_match.rs:72:13
+  --> $DIR/collapsible_match.rs:77:13
    |
 LL | /             if let Some(n) = val {
 LL | |                 take(n);
@@ -132,7 +132,7 @@ LL | |             }
    | |_____________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:71:12
+  --> $DIR/collapsible_match.rs:76:12
    |
 LL |         Ok(val) => {
    |            ^^^ replace this binding
@@ -140,7 +140,7 @@ LL |             if let Some(n) = val {
    |                    ^^^^^^^ with this pattern
 
 error: this `match` can be collapsed into the outer `match`
-  --> $DIR/collapsible_match.rs:83:20
+  --> $DIR/collapsible_match.rs:88:20
    |
 LL |           Ok(val) => match val {
    |  ____________________^
@@ -150,7 +150,7 @@ LL | |         },
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:83:12
+  --> $DIR/collapsible_match.rs:88:12
    |
 LL |         Ok(val) => match val {
    |            ^^^ replace this binding
@@ -158,7 +158,7 @@ LL |             Some(n) => foo(n),
    |             ^^^^^^^ with this pattern
 
 error: this `match` can be collapsed into the outer `match`
-  --> $DIR/collapsible_match.rs:92:22
+  --> $DIR/collapsible_match.rs:97:22
    |
 LL |           Some(val) => match val {
    |  ______________________^
@@ -168,7 +168,7 @@ LL | |         },
    | |_________^
    |
 help: the outer pattern can be modified to include the inner pattern
-  --> $DIR/collapsible_match.rs:92:14
+  --> $DIR/collapsible_match.rs:97:14
    |
 LL |         Some(val) => match val {
    |              ^^^ replace this binding
diff --git a/tests/ui/crashes/ice-3462.rs b/tests/ui/crashes/ice-3462.rs
index 7d62e315da2..02c49aa0d7c 100644
--- a/tests/ui/crashes/ice-3462.rs
+++ b/tests/ui/crashes/ice-3462.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::all)]
-#![allow(clippy::blacklisted_name)]
+#![allow(clippy::blacklisted_name, clippy::equatable_if_let)]
 #![allow(unused)]
 
 /// Test for https://github.com/rust-lang/rust-clippy/issues/3462
diff --git a/tests/ui/def_id_nocore.rs b/tests/ui/def_id_nocore.rs
index 1ed78547a60..156c88e2e45 100644
--- a/tests/ui/def_id_nocore.rs
+++ b/tests/ui/def_id_nocore.rs
@@ -3,6 +3,7 @@
 
 #![feature(no_core, lang_items, start)]
 #![no_core]
+#![allow(clippy::missing_safety_doc)]
 
 #[link(name = "c")]
 extern "C" {}
diff --git a/tests/ui/def_id_nocore.stderr b/tests/ui/def_id_nocore.stderr
index 6210d7c6cfd..40d355e9a2e 100644
--- a/tests/ui/def_id_nocore.stderr
+++ b/tests/ui/def_id_nocore.stderr
@@ -1,5 +1,5 @@
 error: methods called `as_*` usually take `self` by reference or `self` by mutable reference
-  --> $DIR/def_id_nocore.rs:27:19
+  --> $DIR/def_id_nocore.rs:28:19
    |
 LL |     pub fn as_ref(self) -> &'static str {
    |                   ^^^^
diff --git a/tests/ui/derivable_impls.rs b/tests/ui/derivable_impls.rs
index ebbc0c77e32..a6412004726 100644
--- a/tests/ui/derivable_impls.rs
+++ b/tests/ui/derivable_impls.rs
@@ -207,4 +207,37 @@ impl Default for Color2 {
     }
 }
 
+pub struct RepeatDefault1 {
+    a: [i8; 32],
+}
+
+impl Default for RepeatDefault1 {
+    fn default() -> Self {
+        RepeatDefault1 { a: [0; 32] }
+    }
+}
+
+pub struct RepeatDefault2 {
+    a: [i8; 33],
+}
+
+impl Default for RepeatDefault2 {
+    fn default() -> Self {
+        RepeatDefault2 { a: [0; 33] }
+    }
+}
+
+// https://github.com/rust-lang/rust-clippy/issues/7753
+
+pub enum IntOrString {
+    Int(i32),
+    String(String),
+}
+
+impl Default for IntOrString {
+    fn default() -> Self {
+        IntOrString::Int(0)
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/derivable_impls.stderr b/tests/ui/derivable_impls.stderr
index 4ed64fade02..49fb471a219 100644
--- a/tests/ui/derivable_impls.stderr
+++ b/tests/ui/derivable_impls.stderr
@@ -73,5 +73,17 @@ LL | | }
    |
    = help: try annotating `WithoutSelfParan` with `#[derive(Default)]`
 
-error: aborting due to 6 previous errors
+error: this `impl` can be derived
+  --> $DIR/derivable_impls.rs:214:1
+   |
+LL | / impl Default for RepeatDefault1 {
+LL | |     fn default() -> Self {
+LL | |         RepeatDefault1 { a: [0; 32] }
+LL | |     }
+LL | | }
+   | |_^
+   |
+   = help: try annotating `RepeatDefault1` with `#[derive(Default)]`
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/doc/doc.rs b/tests/ui/doc/doc.rs
index 8b0c0f304fc..342208e52b8 100644
--- a/tests/ui/doc/doc.rs
+++ b/tests/ui/doc/doc.rs
@@ -203,6 +203,11 @@ fn issue_2343() {}
 /// __|_ _|__||_|
 fn pulldown_cmark_crash() {}
 
+/// This should not lint
+/// (regression test for #7758)
+/// [plain text][path::to::item]
+fn intra_doc_link() {}
+
 // issue #7033 - generic_const_exprs ICE
 struct S<T, const N: usize>
 where [(); N.checked_next_power_of_two().unwrap()]: {
diff --git a/tests/ui/doc_unsafe.rs b/tests/ui/doc_unsafe.rs
index 484aa72d59a..8f823f1672b 100644
--- a/tests/ui/doc_unsafe.rs
+++ b/tests/ui/doc_unsafe.rs
@@ -34,16 +34,25 @@ mod private_mod {
 
 pub use private_mod::republished;
 
-pub trait UnsafeTrait {
+pub trait SafeTraitUnsafeMethods {
     unsafe fn woefully_underdocumented(self);
 
     /// # Safety
     unsafe fn at_least_somewhat_documented(self);
 }
 
+pub unsafe trait UnsafeTrait {
+    fn method();
+}
+
+/// # Safety
+pub unsafe trait DocumentedUnsafeTrait {
+    fn method2();
+}
+
 pub struct Struct;
 
-impl UnsafeTrait for Struct {
+impl SafeTraitUnsafeMethods for Struct {
     unsafe fn woefully_underdocumented(self) {
         // all is well
     }
@@ -53,6 +62,14 @@ impl UnsafeTrait for Struct {
     }
 }
 
+unsafe impl UnsafeTrait for Struct {
+    fn method() {}
+}
+
+unsafe impl DocumentedUnsafeTrait for Struct {
+    fn method2() {}
+}
+
 impl Struct {
     pub unsafe fn more_undocumented_unsafe() -> Self {
         unimplemented!();
diff --git a/tests/ui/doc_unsafe.stderr b/tests/ui/doc_unsafe.stderr
index 73b53f3431e..34ca37a6efd 100644
--- a/tests/ui/doc_unsafe.stderr
+++ b/tests/ui/doc_unsafe.stderr
@@ -22,8 +22,16 @@ error: unsafe function's docs miss `# Safety` section
 LL |     unsafe fn woefully_underdocumented(self);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+error: docs for unsafe trait missing `# Safety` section
+  --> $DIR/doc_unsafe.rs:44:1
+   |
+LL | / pub unsafe trait UnsafeTrait {
+LL | |     fn method();
+LL | | }
+   | |_^
+
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:57:5
+  --> $DIR/doc_unsafe.rs:74:5
    |
 LL | /     pub unsafe fn more_undocumented_unsafe() -> Self {
 LL | |         unimplemented!();
@@ -31,7 +39,7 @@ LL | |     }
    | |_____^
 
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:73:9
+  --> $DIR/doc_unsafe.rs:90:9
    |
 LL | /         pub unsafe fn whee() {
 LL | |             unimplemented!()
@@ -43,5 +51,5 @@ LL |   very_unsafe!();
    |
    = note: this error originates in the macro `very_unsafe` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
diff --git a/tests/ui/equatable_if_let.fixed b/tests/ui/equatable_if_let.fixed
new file mode 100644
index 00000000000..ba72cc237b4
--- /dev/null
+++ b/tests/ui/equatable_if_let.fixed
@@ -0,0 +1,69 @@
+// run-rustfix
+
+#![allow(unused_variables, dead_code)]
+#![warn(clippy::equatable_if_let)]
+
+use std::cmp::Ordering;
+
+#[derive(PartialEq)]
+enum Enum {
+    TupleVariant(i32, u64),
+    RecordVariant { a: i64, b: u32 },
+    UnitVariant,
+    Recursive(Struct),
+}
+
+#[derive(PartialEq)]
+struct Struct {
+    a: i32,
+    b: bool,
+}
+
+enum NotPartialEq {
+    A,
+    B,
+}
+
+enum NotStructuralEq {
+    A,
+    B,
+}
+
+impl PartialEq for NotStructuralEq {
+    fn eq(&self, _: &NotStructuralEq) -> bool {
+        false
+    }
+}
+
+fn main() {
+    let a = 2;
+    let b = 3;
+    let c = Some(2);
+    let d = Struct { a: 2, b: false };
+    let e = Enum::UnitVariant;
+    let f = NotPartialEq::A;
+    let g = NotStructuralEq::A;
+
+    // true
+
+    if a == 2 {}
+    if a.cmp(&b) == Ordering::Greater {}
+    if c == Some(2) {}
+    if d == (Struct { a: 2, b: false }) {}
+    if e == Enum::TupleVariant(32, 64) {}
+    if e == (Enum::RecordVariant { a: 64, b: 32 }) {}
+    if e == Enum::UnitVariant {}
+    if (e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false }) {}
+
+    // false
+
+    if let 2 | 3 = a {}
+    if let x @ 2 = a {}
+    if let Some(3 | 4) = c {}
+    if let Struct { a, b: false } = d {}
+    if let Struct { a: 2, b: x } = d {}
+    if let NotPartialEq::A = f {}
+    if g == NotStructuralEq::A {}
+    if let Some(NotPartialEq::A) = Some(f) {}
+    if Some(g) == Some(NotStructuralEq::A) {}
+}
diff --git a/tests/ui/equatable_if_let.rs b/tests/ui/equatable_if_let.rs
new file mode 100644
index 00000000000..12526ca193d
--- /dev/null
+++ b/tests/ui/equatable_if_let.rs
@@ -0,0 +1,69 @@
+// run-rustfix
+
+#![allow(unused_variables, dead_code)]
+#![warn(clippy::equatable_if_let)]
+
+use std::cmp::Ordering;
+
+#[derive(PartialEq)]
+enum Enum {
+    TupleVariant(i32, u64),
+    RecordVariant { a: i64, b: u32 },
+    UnitVariant,
+    Recursive(Struct),
+}
+
+#[derive(PartialEq)]
+struct Struct {
+    a: i32,
+    b: bool,
+}
+
+enum NotPartialEq {
+    A,
+    B,
+}
+
+enum NotStructuralEq {
+    A,
+    B,
+}
+
+impl PartialEq for NotStructuralEq {
+    fn eq(&self, _: &NotStructuralEq) -> bool {
+        false
+    }
+}
+
+fn main() {
+    let a = 2;
+    let b = 3;
+    let c = Some(2);
+    let d = Struct { a: 2, b: false };
+    let e = Enum::UnitVariant;
+    let f = NotPartialEq::A;
+    let g = NotStructuralEq::A;
+
+    // true
+
+    if let 2 = a {}
+    if let Ordering::Greater = a.cmp(&b) {}
+    if let Some(2) = c {}
+    if let Struct { a: 2, b: false } = d {}
+    if let Enum::TupleVariant(32, 64) = e {}
+    if let Enum::RecordVariant { a: 64, b: 32 } = e {}
+    if let Enum::UnitVariant = e {}
+    if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {}
+
+    // false
+
+    if let 2 | 3 = a {}
+    if let x @ 2 = a {}
+    if let Some(3 | 4) = c {}
+    if let Struct { a, b: false } = d {}
+    if let Struct { a: 2, b: x } = d {}
+    if let NotPartialEq::A = f {}
+    if let NotStructuralEq::A = g {}
+    if let Some(NotPartialEq::A) = Some(f) {}
+    if let Some(NotStructuralEq::A) = Some(g) {}
+}
diff --git a/tests/ui/equatable_if_let.stderr b/tests/ui/equatable_if_let.stderr
new file mode 100644
index 00000000000..79ef919384d
--- /dev/null
+++ b/tests/ui/equatable_if_let.stderr
@@ -0,0 +1,64 @@
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:49:8
+   |
+LL |     if let 2 = a {}
+   |        ^^^^^^^^^ help: try: `a == 2`
+   |
+   = note: `-D clippy::equatable-if-let` implied by `-D warnings`
+
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:50:8
+   |
+LL |     if let Ordering::Greater = a.cmp(&b) {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `a.cmp(&b) == Ordering::Greater`
+
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:51:8
+   |
+LL |     if let Some(2) = c {}
+   |        ^^^^^^^^^^^^^^^ help: try: `c == Some(2)`
+
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:52:8
+   |
+LL |     if let Struct { a: 2, b: false } = d {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `d == (Struct { a: 2, b: false })`
+
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:53:8
+   |
+LL |     if let Enum::TupleVariant(32, 64) = e {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::TupleVariant(32, 64)`
+
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:54:8
+   |
+LL |     if let Enum::RecordVariant { a: 64, b: 32 } = e {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == (Enum::RecordVariant { a: 64, b: 32 })`
+
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:55:8
+   |
+LL |     if let Enum::UnitVariant = e {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `e == Enum::UnitVariant`
+
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:56:8
+   |
+LL |     if let (Enum::UnitVariant, &Struct { a: 2, b: false }) = (e, &d) {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(e, &d) == (Enum::UnitVariant, &Struct { a: 2, b: false })`
+
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:66:8
+   |
+LL |     if let NotStructuralEq::A = g {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `g == NotStructuralEq::A`
+
+error: this pattern matching can be expressed using equality
+  --> $DIR/equatable_if_let.rs:68:8
+   |
+LL |     if let Some(NotStructuralEq::A) = Some(g) {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(g) == Some(NotStructuralEq::A)`
+
+error: aborting due to 10 previous errors
+
diff --git a/tests/ui/excessive_precision.fixed b/tests/ui/excessive_precision.fixed
index 90376620a9f..b74bda182be 100644
--- a/tests/ui/excessive_precision.fixed
+++ b/tests/ui/excessive_precision.fixed
@@ -60,4 +60,10 @@ fn main() {
 
     // issue #2840
     let num = 0.000_000_000_01e-10f64;
+
+    // issue #7744
+    let _ = 2.225_073_858_507_201e-308_f64;
+
+    // issue #7745
+    let _ = 0_f64;
 }
diff --git a/tests/ui/excessive_precision.rs b/tests/ui/excessive_precision.rs
index ce4722a90f9..6e84a71f24c 100644
--- a/tests/ui/excessive_precision.rs
+++ b/tests/ui/excessive_precision.rs
@@ -60,4 +60,10 @@ fn main() {
 
     // issue #2840
     let num = 0.000_000_000_01e-10f64;
+
+    // issue #7744
+    let _ = 2.225_073_858_507_201_1e-308_f64;
+
+    // issue #7745
+    let _ = 1.000_000_000_000_001e-324_f64;
 }
diff --git a/tests/ui/excessive_precision.stderr b/tests/ui/excessive_precision.stderr
index e59c20c30b4..42d9d4de193 100644
--- a/tests/ui/excessive_precision.stderr
+++ b/tests/ui/excessive_precision.stderr
@@ -78,5 +78,17 @@ error: float has excessive precision
 LL |     let bad_bige32: f32 = 1.123_456_788_888E-10;
    |                           ^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `1.123_456_8E-10`
 
-error: aborting due to 13 previous errors
+error: float has excessive precision
+  --> $DIR/excessive_precision.rs:65:13
+   |
+LL |     let _ = 2.225_073_858_507_201_1e-308_f64;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `2.225_073_858_507_201e-308_f64`
+
+error: float has excessive precision
+  --> $DIR/excessive_precision.rs:68:13
+   |
+LL |     let _ = 1.000_000_000_000_001e-324_f64;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider changing the type or truncating it to: `0_f64`
+
+error: aborting due to 15 previous errors
 
diff --git a/tests/ui/for_loop_fixable.fixed b/tests/ui/for_loop_fixable.fixed
index f0e4835415f..f373e905d05 100644
--- a/tests/ui/for_loop_fixable.fixed
+++ b/tests/ui/for_loop_fixable.fixed
@@ -23,12 +23,7 @@ impl Unrelated {
     clippy::iter_next_loop,
     clippy::for_kv_map
 )]
-#[allow(
-    clippy::linkedlist,
-    clippy::shadow_unrelated,
-    clippy::unnecessary_mut_passed,
-    clippy::similar_names
-)]
+#[allow(clippy::linkedlist, clippy::unnecessary_mut_passed, clippy::similar_names)]
 #[allow(unused_variables)]
 fn main() {
     let mut vec = vec![1, 2, 3, 4];
diff --git a/tests/ui/for_loop_fixable.rs b/tests/ui/for_loop_fixable.rs
index 1edef175fb9..3814583bb6e 100644
--- a/tests/ui/for_loop_fixable.rs
+++ b/tests/ui/for_loop_fixable.rs
@@ -23,12 +23,7 @@ impl Unrelated {
     clippy::iter_next_loop,
     clippy::for_kv_map
 )]
-#[allow(
-    clippy::linkedlist,
-    clippy::shadow_unrelated,
-    clippy::unnecessary_mut_passed,
-    clippy::similar_names
-)]
+#[allow(clippy::linkedlist, clippy::unnecessary_mut_passed, clippy::similar_names)]
 #[allow(unused_variables)]
 fn main() {
     let mut vec = vec![1, 2, 3, 4];
diff --git a/tests/ui/for_loop_fixable.stderr b/tests/ui/for_loop_fixable.stderr
index ddfe66d675f..009dbe1a0bf 100644
--- a/tests/ui/for_loop_fixable.stderr
+++ b/tests/ui/for_loop_fixable.stderr
@@ -1,5 +1,5 @@
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:43:15
+  --> $DIR/for_loop_fixable.rs:38:15
    |
 LL |     for _v in vec.iter() {}
    |               ^^^^^^^^^^ help: to write this more concisely, try: `&vec`
@@ -7,13 +7,13 @@ LL |     for _v in vec.iter() {}
    = note: `-D clippy::explicit-iter-loop` implied by `-D warnings`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:45:15
+  --> $DIR/for_loop_fixable.rs:40:15
    |
 LL |     for _v in vec.iter_mut() {}
    |               ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut vec`
 
 error: it is more concise to loop over containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:48:15
+  --> $DIR/for_loop_fixable.rs:43:15
    |
 LL |     for _v in out_vec.into_iter() {}
    |               ^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `out_vec`
@@ -21,73 +21,73 @@ LL |     for _v in out_vec.into_iter() {}
    = note: `-D clippy::explicit-into-iter-loop` implied by `-D warnings`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:53:15
+  --> $DIR/for_loop_fixable.rs:48:15
    |
 LL |     for _v in [1, 2, 3].iter() {}
    |               ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[1, 2, 3]`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:57:15
+  --> $DIR/for_loop_fixable.rs:52:15
    |
 LL |     for _v in [0; 32].iter() {}
    |               ^^^^^^^^^^^^^^ help: to write this more concisely, try: `&[0; 32]`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:62:15
+  --> $DIR/for_loop_fixable.rs:57:15
    |
 LL |     for _v in ll.iter() {}
    |               ^^^^^^^^^ help: to write this more concisely, try: `&ll`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:65:15
+  --> $DIR/for_loop_fixable.rs:60:15
    |
 LL |     for _v in vd.iter() {}
    |               ^^^^^^^^^ help: to write this more concisely, try: `&vd`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:68:15
+  --> $DIR/for_loop_fixable.rs:63:15
    |
 LL |     for _v in bh.iter() {}
    |               ^^^^^^^^^ help: to write this more concisely, try: `&bh`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:71:15
+  --> $DIR/for_loop_fixable.rs:66:15
    |
 LL |     for _v in hm.iter() {}
    |               ^^^^^^^^^ help: to write this more concisely, try: `&hm`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:74:15
+  --> $DIR/for_loop_fixable.rs:69:15
    |
 LL |     for _v in bt.iter() {}
    |               ^^^^^^^^^ help: to write this more concisely, try: `&bt`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:77:15
+  --> $DIR/for_loop_fixable.rs:72:15
    |
 LL |     for _v in hs.iter() {}
    |               ^^^^^^^^^ help: to write this more concisely, try: `&hs`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:80:15
+  --> $DIR/for_loop_fixable.rs:75:15
    |
 LL |     for _v in bs.iter() {}
    |               ^^^^^^^^^ help: to write this more concisely, try: `&bs`
 
 error: it is more concise to loop over containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:255:18
+  --> $DIR/for_loop_fixable.rs:250:18
    |
 LL |         for i in iterator.into_iter() {
    |                  ^^^^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `iterator`
 
 error: it is more concise to loop over references to containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:275:18
+  --> $DIR/for_loop_fixable.rs:270:18
    |
 LL |         for _ in t.into_iter() {}
    |                  ^^^^^^^^^^^^^ help: to write this more concisely, try: `&t`
 
 error: it is more concise to loop over containers instead of using explicit iteration methods
-  --> $DIR/for_loop_fixable.rs:277:18
+  --> $DIR/for_loop_fixable.rs:272:18
    |
 LL |         for _ in r.into_iter() {}
    |                  ^^^^^^^^^^^^^ help: to write this more concisely, try: `r`
diff --git a/tests/ui/for_loop_unfixable.rs b/tests/ui/for_loop_unfixable.rs
index e73536052f0..efcaffce24e 100644
--- a/tests/ui/for_loop_unfixable.rs
+++ b/tests/ui/for_loop_unfixable.rs
@@ -7,14 +7,7 @@
     clippy::iter_next_loop,
     clippy::for_kv_map
 )]
-#[allow(
-    clippy::linkedlist,
-    clippy::shadow_unrelated,
-    clippy::unnecessary_mut_passed,
-    clippy::similar_names,
-    unused,
-    dead_code
-)]
+#[allow(clippy::linkedlist, clippy::unnecessary_mut_passed, clippy::similar_names)]
 fn main() {
     let vec = vec![1, 2, 3, 4];
 
diff --git a/tests/ui/for_loop_unfixable.stderr b/tests/ui/for_loop_unfixable.stderr
index 1c9287b6acb..f769b4bdc94 100644
--- a/tests/ui/for_loop_unfixable.stderr
+++ b/tests/ui/for_loop_unfixable.stderr
@@ -1,5 +1,5 @@
 error: you are iterating over `Iterator::next()` which is an Option; this will compile but is probably not what you want
-  --> $DIR/for_loop_unfixable.rs:21:15
+  --> $DIR/for_loop_unfixable.rs:14:15
    |
 LL |     for _v in vec.iter().next() {}
    |               ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/if_same_then_else2.rs b/tests/ui/if_same_then_else2.rs
index e4dc5b647df..69189d9e0c0 100644
--- a/tests/ui/if_same_then_else2.rs
+++ b/tests/ui/if_same_then_else2.rs
@@ -2,6 +2,7 @@
 #![allow(
     clippy::blacklisted_name,
     clippy::collapsible_else_if,
+    clippy::equatable_if_let,
     clippy::collapsible_if,
     clippy::ifs_same_cond,
     clippy::needless_return,
diff --git a/tests/ui/if_same_then_else2.stderr b/tests/ui/if_same_then_else2.stderr
index 6524be0af85..cac788f859d 100644
--- a/tests/ui/if_same_then_else2.stderr
+++ b/tests/ui/if_same_then_else2.stderr
@@ -1,5 +1,5 @@
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:13:13
+  --> $DIR/if_same_then_else2.rs:14:13
    |
 LL |       if true {
    |  _____________^
@@ -13,7 +13,7 @@ LL | |     } else {
    |
    = note: `-D clippy::if-same-then-else` implied by `-D warnings`
 note: same as this
-  --> $DIR/if_same_then_else2.rs:22:12
+  --> $DIR/if_same_then_else2.rs:23:12
    |
 LL |       } else {
    |  ____________^
@@ -26,7 +26,7 @@ LL | |     }
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:34:13
+  --> $DIR/if_same_then_else2.rs:35:13
    |
 LL |       if true {
    |  _____________^
@@ -35,7 +35,7 @@ LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:36:12
+  --> $DIR/if_same_then_else2.rs:37:12
    |
 LL |       } else {
    |  ____________^
@@ -45,7 +45,7 @@ LL | |     }
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:41:13
+  --> $DIR/if_same_then_else2.rs:42:13
    |
 LL |       if true {
    |  _____________^
@@ -54,7 +54,7 @@ LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:43:12
+  --> $DIR/if_same_then_else2.rs:44:12
    |
 LL |       } else {
    |  ____________^
@@ -64,7 +64,7 @@ LL | |     }
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:91:21
+  --> $DIR/if_same_then_else2.rs:92:21
    |
 LL |       let _ = if true {
    |  _____________________^
@@ -73,7 +73,7 @@ LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:93:12
+  --> $DIR/if_same_then_else2.rs:94:12
    |
 LL |       } else {
    |  ____________^
@@ -83,7 +83,7 @@ LL | |     };
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:98:13
+  --> $DIR/if_same_then_else2.rs:99:13
    |
 LL |       if true {
    |  _____________^
@@ -92,7 +92,7 @@ LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:100:12
+  --> $DIR/if_same_then_else2.rs:101:12
    |
 LL |       } else {
    |  ____________^
@@ -102,7 +102,7 @@ LL | |     }
    | |_____^
 
 error: this `if` has identical blocks
-  --> $DIR/if_same_then_else2.rs:122:20
+  --> $DIR/if_same_then_else2.rs:123:20
    |
 LL |       } else if true {
    |  ____________________^
@@ -112,7 +112,7 @@ LL | |     } else {
    | |_____^
    |
 note: same as this
-  --> $DIR/if_same_then_else2.rs:125:12
+  --> $DIR/if_same_then_else2.rs:126:12
    |
 LL |       } else {
    |  ____________^
diff --git a/tests/ui/if_then_panic.fixed b/tests/ui/if_then_panic.fixed
index fc57ae0dfa5..0998f8ffa9d 100644
--- a/tests/ui/if_then_panic.fixed
+++ b/tests/ui/if_then_panic.fixed
@@ -31,4 +31,10 @@ fn main() {
     } else {
         println!("qwq");
     }
+    let b = vec![1, 2, 3];
+    assert!(!b.is_empty(), "panic1");
+    assert!(!(b.is_empty() && a.is_empty()), "panic2");
+    assert!(!(a.is_empty() && !b.is_empty()), "panic3");
+    assert!(!(b.is_empty() || a.is_empty()), "panic4");
+    assert!(!(a.is_empty() || !b.is_empty()), "panic5");
 }
diff --git a/tests/ui/if_then_panic.rs b/tests/ui/if_then_panic.rs
index d1ac93d8d41..10433c8d54f 100644
--- a/tests/ui/if_then_panic.rs
+++ b/tests/ui/if_then_panic.rs
@@ -35,4 +35,20 @@ fn main() {
     } else {
         println!("qwq");
     }
+    let b = vec![1, 2, 3];
+    if b.is_empty() {
+        panic!("panic1");
+    }
+    if b.is_empty() && a.is_empty() {
+        panic!("panic2");
+    }
+    if a.is_empty() && !b.is_empty() {
+        panic!("panic3");
+    }
+    if b.is_empty() || a.is_empty() {
+        panic!("panic4");
+    }
+    if a.is_empty() || !b.is_empty() {
+        panic!("panic5");
+    }
 }
diff --git a/tests/ui/if_then_panic.stderr b/tests/ui/if_then_panic.stderr
index b92c9bdf674..5bb62f87566 100644
--- a/tests/ui/if_then_panic.stderr
+++ b/tests/ui/if_then_panic.stderr
@@ -16,5 +16,45 @@ LL | |         panic!("qwqwq");
 LL | |     }
    | |_____^ help: try: `assert!(a.is_empty(), "qwqwq");`
 
-error: aborting due to 2 previous errors
+error: only a `panic!` in `if`-then statement
+  --> $DIR/if_then_panic.rs:39:5
+   |
+LL | /     if b.is_empty() {
+LL | |         panic!("panic1");
+LL | |     }
+   | |_____^ help: try: `assert!(!b.is_empty(), "panic1");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/if_then_panic.rs:42:5
+   |
+LL | /     if b.is_empty() && a.is_empty() {
+LL | |         panic!("panic2");
+LL | |     }
+   | |_____^ help: try: `assert!(!(b.is_empty() && a.is_empty()), "panic2");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/if_then_panic.rs:45:5
+   |
+LL | /     if a.is_empty() && !b.is_empty() {
+LL | |         panic!("panic3");
+LL | |     }
+   | |_____^ help: try: `assert!(!(a.is_empty() && !b.is_empty()), "panic3");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/if_then_panic.rs:48:5
+   |
+LL | /     if b.is_empty() || a.is_empty() {
+LL | |         panic!("panic4");
+LL | |     }
+   | |_____^ help: try: `assert!(!(b.is_empty() || a.is_empty()), "panic4");`
+
+error: only a `panic!` in `if`-then statement
+  --> $DIR/if_then_panic.rs:51:5
+   |
+LL | /     if a.is_empty() || !b.is_empty() {
+LL | |         panic!("panic5");
+LL | |     }
+   | |_____^ help: try: `assert!(!(a.is_empty() || !b.is_empty()), "panic5");`
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/implicit_hasher.rs b/tests/ui/implicit_hasher.rs
index 97c26bc83ad..aa69b097410 100644
--- a/tests/ui/implicit_hasher.rs
+++ b/tests/ui/implicit_hasher.rs
@@ -1,3 +1,4 @@
+// edition:2018
 // aux-build:implicit_hasher_macros.rs
 #![deny(clippy::implicit_hasher)]
 #![allow(unused)]
@@ -96,4 +97,7 @@ __implicit_hasher_test_macro!(impl<K, V> for HashMap<K, V> where V: test_macro::
 // #4260
 implicit_hasher_fn!();
 
+// #7712
+pub async fn election_vote(_data: HashMap<i32, i32>) {}
+
 fn main() {}
diff --git a/tests/ui/implicit_hasher.stderr b/tests/ui/implicit_hasher.stderr
index 2e62dd30f9f..dad5ab71f15 100644
--- a/tests/ui/implicit_hasher.stderr
+++ b/tests/ui/implicit_hasher.stderr
@@ -1,11 +1,11 @@
 error: impl for `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:16:35
+  --> $DIR/implicit_hasher.rs:17:35
    |
 LL | impl<K: Hash + Eq, V> Foo<i8> for HashMap<K, V> {
    |                                   ^^^^^^^^^^^^^
    |
 note: the lint level is defined here
-  --> $DIR/implicit_hasher.rs:2:9
+  --> $DIR/implicit_hasher.rs:3:9
    |
 LL | #![deny(clippy::implicit_hasher)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^
@@ -19,7 +19,7 @@ LL |         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default:
    |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:25:36
+  --> $DIR/implicit_hasher.rs:26:36
    |
 LL | impl<K: Hash + Eq, V> Foo<i8> for (HashMap<K, V>,) {
    |                                    ^^^^^^^^^^^^^
@@ -34,7 +34,7 @@ LL |         ((HashMap::default(),), (HashMap::with_capacity_and_hasher(10, Defa
    |           ~~~~~~~~~~~~~~~~~~     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:30:19
+  --> $DIR/implicit_hasher.rs:31:19
    |
 LL | impl Foo<i16> for HashMap<String, String> {
    |                   ^^^^^^^^^^^^^^^^^^^^^^^
@@ -49,7 +49,7 @@ LL |         (HashMap::default(), HashMap::with_capacity_and_hasher(10, Default:
    |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashSet` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:47:32
+  --> $DIR/implicit_hasher.rs:48:32
    |
 LL | impl<T: Hash + Eq> Foo<i8> for HashSet<T> {
    |                                ^^^^^^^^^^
@@ -64,7 +64,7 @@ LL |         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default:
    |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: impl for `HashSet` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:52:19
+  --> $DIR/implicit_hasher.rs:53:19
    |
 LL | impl Foo<i16> for HashSet<String> {
    |                   ^^^^^^^^^^^^^^^
@@ -79,7 +79,7 @@ LL |         (HashSet::default(), HashSet::with_capacity_and_hasher(10, Default:
    |          ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:69:23
+  --> $DIR/implicit_hasher.rs:70:23
    |
 LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
    |                       ^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32, S>, _s
    |           +++++++++++++++++++++++++++++            ~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashSet` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:69:53
+  --> $DIR/implicit_hasher.rs:70:53
    |
 LL | pub fn foo(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
    |                                                     ^^^^^^^^^^^^
@@ -101,7 +101,7 @@ LL | pub fn foo<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set:
    |           +++++++++++++++++++++++++++++                                          ~~~~~~~~~~~~~~~
 
 error: impl for `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:73:43
+  --> $DIR/implicit_hasher.rs:74:43
    |
 LL |         impl<K: Hash + Eq, V> Foo<u8> for HashMap<K, V> {
    |                                           ^^^^^^^^^^^^^
@@ -120,7 +120,7 @@ LL |                 (HashMap::default(), HashMap::with_capacity_and_hasher(10,
    |                  ~~~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashMap` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:81:33
+  --> $DIR/implicit_hasher.rs:82:33
    |
 LL |         pub fn $name(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
    |                                 ^^^^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL |         pub fn $name<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i
    |                     +++++++++++++++++++++++++++++            ~~~~~~~~~~~~~~~~~~~~
 
 error: parameter of type `HashSet` should be generalized over different hashers
-  --> $DIR/implicit_hasher.rs:81:63
+  --> $DIR/implicit_hasher.rs:82:63
    |
 LL |         pub fn $name(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32>) {}
    |                                                               ^^^^^^^^^^^^
@@ -149,5 +149,16 @@ help: consider adding a type parameter
 LL |         pub fn $name<S: ::std::hash::BuildHasher>(_map: &mut HashMap<i32, i32>, _set: &mut HashSet<i32, S>) {}
    |                     +++++++++++++++++++++++++++++                                          ~~~~~~~~~~~~~~~
 
-error: aborting due to 10 previous errors
+error: parameter of type `HashMap` should be generalized over different hashers
+  --> $DIR/implicit_hasher.rs:101:35
+   |
+LL | pub async fn election_vote(_data: HashMap<i32, i32>) {}
+   |                                   ^^^^^^^^^^^^^^^^^
+   |
+help: consider adding a type parameter
+   |
+LL | pub async fn election_vote<S: ::std::hash::BuildHasher>(_data: HashMap<i32, i32, S>) {}
+   |                           +++++++++++++++++++++++++++++        ~~~~~~~~~~~~~~~~~~~~
+
+error: aborting due to 11 previous errors
 
diff --git a/tests/ui/integer_arithmetic.rs b/tests/ui/integer_arithmetic.rs
index b74c93dc4a6..67f24b4548a 100644
--- a/tests/ui/integer_arithmetic.rs
+++ b/tests/ui/integer_arithmetic.rs
@@ -1,12 +1,5 @@
 #![warn(clippy::integer_arithmetic, clippy::float_arithmetic)]
-#![allow(
-    unused,
-    clippy::shadow_reuse,
-    clippy::shadow_unrelated,
-    clippy::no_effect,
-    clippy::unnecessary_operation,
-    clippy::op_ref
-)]
+#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::op_ref)]
 
 #[rustfmt::skip]
 fn main() {
diff --git a/tests/ui/integer_arithmetic.stderr b/tests/ui/integer_arithmetic.stderr
index add3b6b90fa..9a795b1f291 100644
--- a/tests/ui/integer_arithmetic.stderr
+++ b/tests/ui/integer_arithmetic.stderr
@@ -1,5 +1,5 @@
 error: this operation will panic at runtime
-  --> $DIR/integer_arithmetic.rs:37:5
+  --> $DIR/integer_arithmetic.rs:30:5
    |
 LL |     i /= 0;
    |     ^^^^^^ attempt to divide `_` by zero
@@ -7,13 +7,13 @@ LL |     i /= 0;
    = note: `#[deny(unconditional_panic)]` on by default
 
 error: this operation will panic at runtime
-  --> $DIR/integer_arithmetic.rs:42:5
+  --> $DIR/integer_arithmetic.rs:35:5
    |
 LL |     i %= 0;
    |     ^^^^^^ attempt to calculate the remainder of `_` with a divisor of zero
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:16:5
+  --> $DIR/integer_arithmetic.rs:9:5
    |
 LL |     1 + i;
    |     ^^^^^
@@ -21,146 +21,146 @@ LL |     1 + i;
    = note: `-D clippy::integer-arithmetic` implied by `-D warnings`
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:17:5
+  --> $DIR/integer_arithmetic.rs:10:5
    |
 LL |     i * 2;
    |     ^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:18:5
+  --> $DIR/integer_arithmetic.rs:11:5
    |
 LL | /     1 %
 LL | |     i / 2; // no error, this is part of the expression in the preceding line
    | |_____^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:20:5
+  --> $DIR/integer_arithmetic.rs:13:5
    |
 LL |     i - 2 + 2 - i;
    |     ^^^^^^^^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:21:5
+  --> $DIR/integer_arithmetic.rs:14:5
    |
 LL |     -i;
    |     ^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:22:5
+  --> $DIR/integer_arithmetic.rs:15:5
    |
 LL |     i >> 1;
    |     ^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:23:5
+  --> $DIR/integer_arithmetic.rs:16:5
    |
 LL |     i << 1;
    |     ^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:33:5
+  --> $DIR/integer_arithmetic.rs:26:5
    |
 LL |     i += 1;
    |     ^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:34:5
+  --> $DIR/integer_arithmetic.rs:27:5
    |
 LL |     i -= 1;
    |     ^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:35:5
+  --> $DIR/integer_arithmetic.rs:28:5
    |
 LL |     i *= 2;
    |     ^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:38:11
+  --> $DIR/integer_arithmetic.rs:31:11
    |
 LL |     i /= -1;
    |           ^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:39:5
+  --> $DIR/integer_arithmetic.rs:32:5
    |
 LL |     i /= var1;
    |     ^^^^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:40:5
+  --> $DIR/integer_arithmetic.rs:33:5
    |
 LL |     i /= var2;
    |     ^^^^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:43:11
+  --> $DIR/integer_arithmetic.rs:36:11
    |
 LL |     i %= -1;
    |           ^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:44:5
+  --> $DIR/integer_arithmetic.rs:37:5
    |
 LL |     i %= var1;
    |     ^^^^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:45:5
+  --> $DIR/integer_arithmetic.rs:38:5
    |
 LL |     i %= var2;
    |     ^^^^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:46:5
+  --> $DIR/integer_arithmetic.rs:39:5
    |
 LL |     i <<= 3;
    |     ^^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:47:5
+  --> $DIR/integer_arithmetic.rs:40:5
    |
 LL |     i >>= 2;
    |     ^^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:89:5
+  --> $DIR/integer_arithmetic.rs:82:5
    |
 LL |     3 + &1;
    |     ^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:90:5
+  --> $DIR/integer_arithmetic.rs:83:5
    |
 LL |     &3 + 1;
    |     ^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:91:5
+  --> $DIR/integer_arithmetic.rs:84:5
    |
 LL |     &3 + &1;
    |     ^^^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:96:5
+  --> $DIR/integer_arithmetic.rs:89:5
    |
 LL |     a + x
    |     ^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:100:5
+  --> $DIR/integer_arithmetic.rs:93:5
    |
 LL |     x + y
    |     ^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:104:5
+  --> $DIR/integer_arithmetic.rs:97:5
    |
 LL |     x + y
    |     ^^^^^
 
 error: integer arithmetic detected
-  --> $DIR/integer_arithmetic.rs:108:5
+  --> $DIR/integer_arithmetic.rs:101:5
    |
 LL |     (&x + &y)
    |     ^^^^^^^^^
diff --git a/tests/ui/large_enum_variant.rs b/tests/ui/large_enum_variant.rs
index d22fee3f27b..b45cc849eae 100644
--- a/tests/ui/large_enum_variant.rs
+++ b/tests/ui/large_enum_variant.rs
@@ -35,6 +35,7 @@ enum LargeEnum2 {
     VariantOk(i32, u32),
     ContainingLargeEnum(LargeEnum),
 }
+
 enum LargeEnum3 {
     ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
     VoidVariant,
@@ -56,6 +57,23 @@ enum LargeEnumOk {
     LargeB([i32; 8001]),
 }
 
+enum LargeEnum6 {
+    A,
+    B([u8; 255]),
+    C([u8; 200]),
+}
+
+enum LargeEnum7 {
+    A,
+    B([u8; 1255]),
+    C([u8; 200]),
+}
+
+enum LargeEnum8 {
+    VariantOk(i32, u32),
+    ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
+}
+
 fn main() {
     large_enum_variant!();
 }
diff --git a/tests/ui/large_enum_variant.stderr b/tests/ui/large_enum_variant.stderr
index 0eac28fbd35..899f97ce2e1 100644
--- a/tests/ui/large_enum_variant.stderr
+++ b/tests/ui/large_enum_variant.stderr
@@ -32,30 +32,45 @@ LL |     ContainingLargeEnum(Box<LargeEnum>),
    |                         ~~~~~~~~~~~~~~
 
 error: large size difference between variants
-  --> $DIR/large_enum_variant.rs:46:5
+  --> $DIR/large_enum_variant.rs:40:5
+   |
+LL |     ContainingMoreThanOneField(i32, [i32; 8000], [i32; 9500]),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 70004 bytes
+   |
+note: and the second-largest variant is 8 bytes:
+  --> $DIR/large_enum_variant.rs:42:5
+   |
+LL |     StructLikeLittle { x: i32, y: i32 },
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider boxing the large fields to reduce the total size of the enum
+   |
+LL |     ContainingMoreThanOneField(i32, Box<[i32; 8000]>, Box<[i32; 9500]>),
+   |                                     ~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+  --> $DIR/large_enum_variant.rs:47:5
    |
 LL |     StructLikeLarge { x: [i32; 8000], y: i32 },
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32004 bytes
    |
 note: and the second-largest variant is 8 bytes:
-  --> $DIR/large_enum_variant.rs:45:5
+  --> $DIR/large_enum_variant.rs:46:5
    |
 LL |     VariantOk(i32, u32),
    |     ^^^^^^^^^^^^^^^^^^^
 help: consider boxing the large fields to reduce the total size of the enum
-  --> $DIR/large_enum_variant.rs:46:5
    |
-LL |     StructLikeLarge { x: [i32; 8000], y: i32 },
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     StructLikeLarge { x: Box<[i32; 8000]>, y: i32 },
+   |                          ~~~~~~~~~~~~~~~~
 
 error: large size difference between variants
-  --> $DIR/large_enum_variant.rs:51:5
+  --> $DIR/large_enum_variant.rs:52:5
    |
 LL |     StructLikeLarge2 { x: [i32; 8000] },
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 32000 bytes
    |
 note: and the second-largest variant is 8 bytes:
-  --> $DIR/large_enum_variant.rs:50:5
+  --> $DIR/large_enum_variant.rs:51:5
    |
 LL |     VariantOk(i32, u32),
    |     ^^^^^^^^^^^^^^^^^^^
@@ -64,5 +79,37 @@ help: consider boxing the large fields to reduce the total size of the enum
 LL |     StructLikeLarge2 { x: Box<[i32; 8000]> },
    |                           ~~~~~~~~~~~~~~~~
 
-error: aborting due to 4 previous errors
+error: large size difference between variants
+  --> $DIR/large_enum_variant.rs:68:5
+   |
+LL |     B([u8; 1255]),
+   |     ^^^^^^^^^^^^^ this variant is 1255 bytes
+   |
+note: and the second-largest variant is 200 bytes:
+  --> $DIR/large_enum_variant.rs:69:5
+   |
+LL |     C([u8; 200]),
+   |     ^^^^^^^^^^^^
+help: consider boxing the large fields to reduce the total size of the enum
+   |
+LL |     B(Box<[u8; 1255]>),
+   |       ~~~~~~~~~~~~~~~
+
+error: large size difference between variants
+  --> $DIR/large_enum_variant.rs:74:5
+   |
+LL |     ContainingMoreThanOneField([i32; 8000], [i32; 2], [i32; 9500], [i32; 30]),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this variant is 70128 bytes
+   |
+note: and the second-largest variant is 8 bytes:
+  --> $DIR/large_enum_variant.rs:73:5
+   |
+LL |     VariantOk(i32, u32),
+   |     ^^^^^^^^^^^^^^^^^^^
+help: consider boxing the large fields to reduce the total size of the enum
+   |
+LL |     ContainingMoreThanOneField(Box<[i32; 8000]>, [i32; 2], Box<[i32; 9500]>, [i32; 30]),
+   |                                ~~~~~~~~~~~~~~~~            ~~~~~~~~~~~~~~~~
+
+error: aborting due to 7 previous errors
 
diff --git a/tests/ui/map_clone.fixed b/tests/ui/map_clone.fixed
index 178d8705c2f..0860dcf8e0d 100644
--- a/tests/ui/map_clone.fixed
+++ b/tests/ui/map_clone.fixed
@@ -1,11 +1,11 @@
 // run-rustfix
-#![warn(clippy::all, clippy::pedantic)]
-#![allow(clippy::iter_cloned_collect)]
-#![allow(clippy::clone_on_copy, clippy::redundant_clone)]
-#![allow(clippy::let_underscore_drop)]
-#![allow(clippy::missing_docs_in_private_items)]
-#![allow(clippy::redundant_closure_for_method_calls)]
-#![allow(clippy::many_single_char_names)]
+#![warn(clippy::map_clone)]
+#![allow(
+    clippy::clone_on_copy,
+    clippy::iter_cloned_collect,
+    clippy::many_single_char_names,
+    clippy::redundant_clone
+)]
 
 fn main() {
     let _: Vec<i8> = vec![5_i8; 6].iter().copied().collect();
diff --git a/tests/ui/map_clone.rs b/tests/ui/map_clone.rs
index c73d81713b8..b6987336834 100644
--- a/tests/ui/map_clone.rs
+++ b/tests/ui/map_clone.rs
@@ -1,11 +1,11 @@
 // run-rustfix
-#![warn(clippy::all, clippy::pedantic)]
-#![allow(clippy::iter_cloned_collect)]
-#![allow(clippy::clone_on_copy, clippy::redundant_clone)]
-#![allow(clippy::let_underscore_drop)]
-#![allow(clippy::missing_docs_in_private_items)]
-#![allow(clippy::redundant_closure_for_method_calls)]
-#![allow(clippy::many_single_char_names)]
+#![warn(clippy::map_clone)]
+#![allow(
+    clippy::clone_on_copy,
+    clippy::iter_cloned_collect,
+    clippy::many_single_char_names,
+    clippy::redundant_clone
+)]
 
 fn main() {
     let _: Vec<i8> = vec![5_i8; 6].iter().map(|x| *x).collect();
diff --git a/tests/ui/match_expr_like_matches_macro.fixed b/tests/ui/match_expr_like_matches_macro.fixed
index 319299862a7..c611f76bf96 100644
--- a/tests/ui/match_expr_like_matches_macro.fixed
+++ b/tests/ui/match_expr_like_matches_macro.fixed
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::match_like_matches_macro)]
-#![allow(unreachable_patterns, dead_code)]
+#![allow(unreachable_patterns, dead_code, clippy::equatable_if_let)]
 
 fn main() {
     let x = Some(5);
diff --git a/tests/ui/match_expr_like_matches_macro.rs b/tests/ui/match_expr_like_matches_macro.rs
index 2ef6cf42387..2deeb84e741 100644
--- a/tests/ui/match_expr_like_matches_macro.rs
+++ b/tests/ui/match_expr_like_matches_macro.rs
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::match_like_matches_macro)]
-#![allow(unreachable_patterns, dead_code)]
+#![allow(unreachable_patterns, dead_code, clippy::equatable_if_let)]
 
 fn main() {
     let x = Some(5);
diff --git a/tests/ui/match_overlapping_arm.rs b/tests/ui/match_overlapping_arm.rs
index c84e31ea482..846d665d1d8 100644
--- a/tests/ui/match_overlapping_arm.rs
+++ b/tests/ui/match_overlapping_arm.rs
@@ -2,7 +2,7 @@
 #![feature(half_open_range_patterns)]
 #![warn(clippy::match_overlapping_arm)]
 #![allow(clippy::redundant_pattern_matching)]
-#![allow(clippy::if_same_then_else)]
+#![allow(clippy::if_same_then_else, clippy::equatable_if_let)]
 
 /// Tests for match_overlapping_arm
 
diff --git a/tests/ui/match_ref_pats.rs b/tests/ui/match_ref_pats.rs
index 5de43733ad3..6cbb4d32b0d 100644
--- a/tests/ui/match_ref_pats.rs
+++ b/tests/ui/match_ref_pats.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::match_ref_pats)]
+#![allow(clippy::equatable_if_let)]
 
 fn ref_pats() {
     {
diff --git a/tests/ui/match_ref_pats.stderr b/tests/ui/match_ref_pats.stderr
index a57a338b276..072aff445e9 100644
--- a/tests/ui/match_ref_pats.stderr
+++ b/tests/ui/match_ref_pats.stderr
@@ -1,5 +1,5 @@
 error: you don't need to add `&` to all patterns
-  --> $DIR/match_ref_pats.rs:6:9
+  --> $DIR/match_ref_pats.rs:7:9
    |
 LL | /         match v {
 LL | |             &Some(v) => println!("{:?}", v),
@@ -16,7 +16,7 @@ LL ~             None => println!("none"),
    |
 
 error: you don't need to add `&` to all patterns
-  --> $DIR/match_ref_pats.rs:17:5
+  --> $DIR/match_ref_pats.rs:18:5
    |
 LL | /     match tup {
 LL | |         &(v, 1) => println!("{}", v),
@@ -31,7 +31,7 @@ LL ~         (v, 1) => println!("{}", v),
    |
 
 error: you don't need to add `&` to both the expression and the patterns
-  --> $DIR/match_ref_pats.rs:23:5
+  --> $DIR/match_ref_pats.rs:24:5
    |
 LL | /     match &w {
 LL | |         &Some(v) => println!("{:?}", v),
@@ -47,7 +47,7 @@ LL ~         None => println!("none"),
    |
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/match_ref_pats.rs:35:12
+  --> $DIR/match_ref_pats.rs:36:12
    |
 LL |     if let &None = a {
    |     -------^^^^^---- help: try this: `if a.is_none()`
@@ -55,7 +55,7 @@ LL |     if let &None = a {
    = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
 
 error: you don't need to add `&` to all patterns
-  --> $DIR/match_ref_pats.rs:35:5
+  --> $DIR/match_ref_pats.rs:36:5
    |
 LL | /     if let &None = a {
 LL | |         println!("none");
@@ -68,13 +68,13 @@ LL |     if let None = *a {
    |            ~~~~   ~~
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/match_ref_pats.rs:40:12
+  --> $DIR/match_ref_pats.rs:41:12
    |
 LL |     if let &None = &b {
    |     -------^^^^^----- help: try this: `if b.is_none()`
 
 error: you don't need to add `&` to both the expression and the patterns
-  --> $DIR/match_ref_pats.rs:40:5
+  --> $DIR/match_ref_pats.rs:41:5
    |
 LL | /     if let &None = &b {
 LL | |         println!("none");
@@ -87,7 +87,7 @@ LL |     if let None = b {
    |            ~~~~   ~
 
 error: you don't need to add `&` to all patterns
-  --> $DIR/match_ref_pats.rs:67:9
+  --> $DIR/match_ref_pats.rs:68:9
    |
 LL | /         match foo_variant!(0) {
 LL | |             &Foo::A => println!("A"),
diff --git a/tests/ui/modulo_arithmetic_float.rs b/tests/ui/modulo_arithmetic_float.rs
index b010b0dbdfa..b1861f07cd1 100644
--- a/tests/ui/modulo_arithmetic_float.rs
+++ b/tests/ui/modulo_arithmetic_float.rs
@@ -1,12 +1,5 @@
 #![warn(clippy::modulo_arithmetic)]
-#![allow(
-    unused,
-    clippy::shadow_reuse,
-    clippy::shadow_unrelated,
-    clippy::no_effect,
-    clippy::unnecessary_operation,
-    clippy::modulo_one
-)]
+#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::modulo_one)]
 
 fn main() {
     // Lint when both sides are const and of the opposite sign
diff --git a/tests/ui/modulo_arithmetic_float.stderr b/tests/ui/modulo_arithmetic_float.stderr
index 7bfdb0bde60..97844aaaa75 100644
--- a/tests/ui/modulo_arithmetic_float.stderr
+++ b/tests/ui/modulo_arithmetic_float.stderr
@@ -1,5 +1,5 @@
 error: you are using modulo operator on constants with different signs: `-1.600 % 2.100`
-  --> $DIR/modulo_arithmetic_float.rs:13:5
+  --> $DIR/modulo_arithmetic_float.rs:6:5
    |
 LL |     -1.6 % 2.1;
    |     ^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     -1.6 % 2.1;
    = note: double check for expected result especially when interoperating with different languages
 
 error: you are using modulo operator on constants with different signs: `1.600 % -2.100`
-  --> $DIR/modulo_arithmetic_float.rs:14:5
+  --> $DIR/modulo_arithmetic_float.rs:7:5
    |
 LL |     1.6 % -2.1;
    |     ^^^^^^^^^^
@@ -16,7 +16,7 @@ LL |     1.6 % -2.1;
    = note: double check for expected result especially when interoperating with different languages
 
 error: you are using modulo operator on constants with different signs: `-1.200 % 3.400`
-  --> $DIR/modulo_arithmetic_float.rs:15:5
+  --> $DIR/modulo_arithmetic_float.rs:8:5
    |
 LL |     (1.1 - 2.3) % (1.1 + 2.3);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ LL |     (1.1 - 2.3) % (1.1 + 2.3);
    = note: double check for expected result especially when interoperating with different languages
 
 error: you are using modulo operator on constants with different signs: `3.400 % -1.200`
-  --> $DIR/modulo_arithmetic_float.rs:16:5
+  --> $DIR/modulo_arithmetic_float.rs:9:5
    |
 LL |     (1.1 + 2.3) % (1.1 - 2.3);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL |     (1.1 + 2.3) % (1.1 - 2.3);
    = note: double check for expected result especially when interoperating with different languages
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_float.rs:21:5
+  --> $DIR/modulo_arithmetic_float.rs:14:5
    |
 LL |     a_f32 % b_f32;
    |     ^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ LL |     a_f32 % b_f32;
    = note: double check for expected result especially when interoperating with different languages
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_float.rs:22:5
+  --> $DIR/modulo_arithmetic_float.rs:15:5
    |
 LL |     b_f32 % a_f32;
    |     ^^^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL |     b_f32 % a_f32;
    = note: double check for expected result especially when interoperating with different languages
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_float.rs:23:5
+  --> $DIR/modulo_arithmetic_float.rs:16:5
    |
 LL |     b_f32 %= a_f32;
    |     ^^^^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL |     b_f32 %= a_f32;
    = note: double check for expected result especially when interoperating with different languages
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_float.rs:27:5
+  --> $DIR/modulo_arithmetic_float.rs:20:5
    |
 LL |     a_f64 % b_f64;
    |     ^^^^^^^^^^^^^
@@ -64,7 +64,7 @@ LL |     a_f64 % b_f64;
    = note: double check for expected result especially when interoperating with different languages
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_float.rs:28:5
+  --> $DIR/modulo_arithmetic_float.rs:21:5
    |
 LL |     b_f64 % a_f64;
    |     ^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     b_f64 % a_f64;
    = note: double check for expected result especially when interoperating with different languages
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_float.rs:29:5
+  --> $DIR/modulo_arithmetic_float.rs:22:5
    |
 LL |     b_f64 %= a_f64;
    |     ^^^^^^^^^^^^^^
diff --git a/tests/ui/modulo_arithmetic_integral.rs b/tests/ui/modulo_arithmetic_integral.rs
index 779d035c5f8..fc1acc39ebc 100644
--- a/tests/ui/modulo_arithmetic_integral.rs
+++ b/tests/ui/modulo_arithmetic_integral.rs
@@ -1,12 +1,5 @@
 #![warn(clippy::modulo_arithmetic)]
-#![allow(
-    unused,
-    clippy::shadow_reuse,
-    clippy::shadow_unrelated,
-    clippy::no_effect,
-    clippy::unnecessary_operation,
-    clippy::modulo_one
-)]
+#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::modulo_one)]
 
 fn main() {
     // Lint on signed integral numbers
diff --git a/tests/ui/modulo_arithmetic_integral.stderr b/tests/ui/modulo_arithmetic_integral.stderr
index e863b838699..f71adf5b0d0 100644
--- a/tests/ui/modulo_arithmetic_integral.stderr
+++ b/tests/ui/modulo_arithmetic_integral.stderr
@@ -1,5 +1,5 @@
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:15:5
+  --> $DIR/modulo_arithmetic_integral.rs:8:5
    |
 LL |     a % b;
    |     ^^^^^
@@ -9,7 +9,7 @@ LL |     a % b;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:16:5
+  --> $DIR/modulo_arithmetic_integral.rs:9:5
    |
 LL |     b % a;
    |     ^^^^^
@@ -18,7 +18,7 @@ LL |     b % a;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:17:5
+  --> $DIR/modulo_arithmetic_integral.rs:10:5
    |
 LL |     b %= a;
    |     ^^^^^^
@@ -27,7 +27,7 @@ LL |     b %= a;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:21:5
+  --> $DIR/modulo_arithmetic_integral.rs:14:5
    |
 LL |     a_i8 % b_i8;
    |     ^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL |     a_i8 % b_i8;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:22:5
+  --> $DIR/modulo_arithmetic_integral.rs:15:5
    |
 LL |     b_i8 %= a_i8;
    |     ^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL |     b_i8 %= a_i8;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:26:5
+  --> $DIR/modulo_arithmetic_integral.rs:19:5
    |
 LL |     a_i16 % b_i16;
    |     ^^^^^^^^^^^^^
@@ -54,7 +54,7 @@ LL |     a_i16 % b_i16;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:27:5
+  --> $DIR/modulo_arithmetic_integral.rs:20:5
    |
 LL |     b_i16 %= a_i16;
    |     ^^^^^^^^^^^^^^
@@ -63,7 +63,7 @@ LL |     b_i16 %= a_i16;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:31:5
+  --> $DIR/modulo_arithmetic_integral.rs:24:5
    |
 LL |     a_i32 % b_i32;
    |     ^^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     a_i32 % b_i32;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:32:5
+  --> $DIR/modulo_arithmetic_integral.rs:25:5
    |
 LL |     b_i32 %= a_i32;
    |     ^^^^^^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     b_i32 %= a_i32;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:36:5
+  --> $DIR/modulo_arithmetic_integral.rs:29:5
    |
 LL |     a_i64 % b_i64;
    |     ^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     a_i64 % b_i64;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:37:5
+  --> $DIR/modulo_arithmetic_integral.rs:30:5
    |
 LL |     b_i64 %= a_i64;
    |     ^^^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL |     b_i64 %= a_i64;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:41:5
+  --> $DIR/modulo_arithmetic_integral.rs:34:5
    |
 LL |     a_i128 % b_i128;
    |     ^^^^^^^^^^^^^^^
@@ -108,7 +108,7 @@ LL |     a_i128 % b_i128;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:42:5
+  --> $DIR/modulo_arithmetic_integral.rs:35:5
    |
 LL |     b_i128 %= a_i128;
    |     ^^^^^^^^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     b_i128 %= a_i128;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:46:5
+  --> $DIR/modulo_arithmetic_integral.rs:39:5
    |
 LL |     a_isize % b_isize;
    |     ^^^^^^^^^^^^^^^^^
@@ -126,7 +126,7 @@ LL |     a_isize % b_isize;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:47:5
+  --> $DIR/modulo_arithmetic_integral.rs:40:5
    |
 LL |     b_isize %= a_isize;
    |     ^^^^^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL |     b_isize %= a_isize;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:51:5
+  --> $DIR/modulo_arithmetic_integral.rs:44:5
    |
 LL |     a % b;
    |     ^^^^^
@@ -144,7 +144,7 @@ LL |     a % b;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on types that might have different signs
-  --> $DIR/modulo_arithmetic_integral.rs:52:5
+  --> $DIR/modulo_arithmetic_integral.rs:45:5
    |
 LL |     b %= a;
    |     ^^^^^^
diff --git a/tests/ui/modulo_arithmetic_integral_const.rs b/tests/ui/modulo_arithmetic_integral_const.rs
index 57a96692c00..047a29fa1e3 100644
--- a/tests/ui/modulo_arithmetic_integral_const.rs
+++ b/tests/ui/modulo_arithmetic_integral_const.rs
@@ -1,12 +1,5 @@
 #![warn(clippy::modulo_arithmetic)]
-#![allow(
-    unused,
-    clippy::shadow_reuse,
-    clippy::shadow_unrelated,
-    clippy::no_effect,
-    clippy::unnecessary_operation,
-    clippy::modulo_one
-)]
+#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::modulo_one)]
 
 fn main() {
     // Lint when both sides are const and of the opposite sign
diff --git a/tests/ui/modulo_arithmetic_integral_const.stderr b/tests/ui/modulo_arithmetic_integral_const.stderr
index de328bb75fe..64335f35f0f 100644
--- a/tests/ui/modulo_arithmetic_integral_const.stderr
+++ b/tests/ui/modulo_arithmetic_integral_const.stderr
@@ -1,5 +1,5 @@
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:13:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:6:5
    |
 LL |     -1 % 2;
    |     ^^^^^^
@@ -9,7 +9,7 @@ LL |     -1 % 2;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:14:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:7:5
    |
 LL |     1 % -2;
    |     ^^^^^^
@@ -18,7 +18,7 @@ LL |     1 % -2;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 3`
-  --> $DIR/modulo_arithmetic_integral_const.rs:15:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:8:5
    |
 LL |     (1 - 2) % (1 + 2);
    |     ^^^^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL |     (1 - 2) % (1 + 2);
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `3 % -1`
-  --> $DIR/modulo_arithmetic_integral_const.rs:16:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:9:5
    |
 LL |     (1 + 2) % (1 - 2);
    |     ^^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL |     (1 + 2) % (1 - 2);
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-35 % 300000`
-  --> $DIR/modulo_arithmetic_integral_const.rs:17:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:10:5
    |
 LL |     35 * (7 - 4 * 2) % (-500 * -600);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL |     35 * (7 - 4 * 2) % (-500 * -600);
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:19:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:12:5
    |
 LL |     -1i8 % 2i8;
    |     ^^^^^^^^^^
@@ -54,7 +54,7 @@ LL |     -1i8 % 2i8;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:20:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:13:5
    |
 LL |     1i8 % -2i8;
    |     ^^^^^^^^^^
@@ -63,7 +63,7 @@ LL |     1i8 % -2i8;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:21:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:14:5
    |
 LL |     -1i16 % 2i16;
    |     ^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     -1i16 % 2i16;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:22:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:15:5
    |
 LL |     1i16 % -2i16;
    |     ^^^^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     1i16 % -2i16;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:23:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:16:5
    |
 LL |     -1i32 % 2i32;
    |     ^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     -1i32 % 2i32;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:24:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:17:5
    |
 LL |     1i32 % -2i32;
    |     ^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL |     1i32 % -2i32;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:25:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:18:5
    |
 LL |     -1i64 % 2i64;
    |     ^^^^^^^^^^^^
@@ -108,7 +108,7 @@ LL |     -1i64 % 2i64;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:26:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:19:5
    |
 LL |     1i64 % -2i64;
    |     ^^^^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     1i64 % -2i64;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:27:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:20:5
    |
 LL |     -1i128 % 2i128;
    |     ^^^^^^^^^^^^^^
@@ -126,7 +126,7 @@ LL |     -1i128 % 2i128;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:28:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:21:5
    |
 LL |     1i128 % -2i128;
    |     ^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL |     1i128 % -2i128;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:29:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:22:5
    |
 LL |     -1isize % 2isize;
    |     ^^^^^^^^^^^^^^^^
@@ -144,7 +144,7 @@ LL |     -1isize % 2isize;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:30:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:23:5
    |
 LL |     1isize % -2isize;
    |     ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/needless_bool/fixable.fixed b/tests/ui/needless_bool/fixable.fixed
index 639eac8b8b3..a2e3988daff 100644
--- a/tests/ui/needless_bool/fixable.fixed
+++ b/tests/ui/needless_bool/fixable.fixed
@@ -6,6 +6,7 @@
     dead_code,
     clippy::no_effect,
     clippy::if_same_then_else,
+    clippy::equatable_if_let,
     clippy::needless_return,
     clippy::self_named_constructors
 )]
diff --git a/tests/ui/needless_bool/fixable.rs b/tests/ui/needless_bool/fixable.rs
index a3ce086a1c9..75805e85789 100644
--- a/tests/ui/needless_bool/fixable.rs
+++ b/tests/ui/needless_bool/fixable.rs
@@ -6,6 +6,7 @@
     dead_code,
     clippy::no_effect,
     clippy::if_same_then_else,
+    clippy::equatable_if_let,
     clippy::needless_return,
     clippy::self_named_constructors
 )]
diff --git a/tests/ui/needless_bool/fixable.stderr b/tests/ui/needless_bool/fixable.stderr
index 8026d643c44..1fa12add167 100644
--- a/tests/ui/needless_bool/fixable.stderr
+++ b/tests/ui/needless_bool/fixable.stderr
@@ -1,5 +1,5 @@
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:40:5
+  --> $DIR/fixable.rs:41:5
    |
 LL | /     if x {
 LL | |         true
@@ -11,7 +11,7 @@ LL | |     };
    = note: `-D clippy::needless-bool` implied by `-D warnings`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:45:5
+  --> $DIR/fixable.rs:46:5
    |
 LL | /     if x {
 LL | |         false
@@ -21,7 +21,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `!x`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:50:5
+  --> $DIR/fixable.rs:51:5
    |
 LL | /     if x && y {
 LL | |         false
@@ -31,7 +31,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `!(x && y)`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:70:5
+  --> $DIR/fixable.rs:71:5
    |
 LL | /     if x {
 LL | |         return true;
@@ -41,7 +41,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `return x`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:78:5
+  --> $DIR/fixable.rs:79:5
    |
 LL | /     if x {
 LL | |         return false;
@@ -51,7 +51,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `return !x`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:86:5
+  --> $DIR/fixable.rs:87:5
    |
 LL | /     if x && y {
 LL | |         return true;
@@ -61,7 +61,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `return x && y`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:94:5
+  --> $DIR/fixable.rs:95:5
    |
 LL | /     if x && y {
 LL | |         return false;
@@ -71,7 +71,7 @@ LL | |     };
    | |_____^ help: you can reduce it to: `return !(x && y)`
 
 error: equality checks against true are unnecessary
-  --> $DIR/fixable.rs:102:8
+  --> $DIR/fixable.rs:103:8
    |
 LL |     if x == true {};
    |        ^^^^^^^^^ help: try simplifying it as shown: `x`
@@ -79,25 +79,25 @@ LL |     if x == true {};
    = note: `-D clippy::bool-comparison` implied by `-D warnings`
 
 error: equality checks against false can be replaced by a negation
-  --> $DIR/fixable.rs:106:8
+  --> $DIR/fixable.rs:107:8
    |
 LL |     if x == false {};
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!x`
 
 error: equality checks against true are unnecessary
-  --> $DIR/fixable.rs:116:8
+  --> $DIR/fixable.rs:117:8
    |
 LL |     if x == true {};
    |        ^^^^^^^^^ help: try simplifying it as shown: `x`
 
 error: equality checks against false can be replaced by a negation
-  --> $DIR/fixable.rs:117:8
+  --> $DIR/fixable.rs:118:8
    |
 LL |     if x == false {};
    |        ^^^^^^^^^^ help: try simplifying it as shown: `!x`
 
 error: this if-then-else expression returns a bool literal
-  --> $DIR/fixable.rs:126:12
+  --> $DIR/fixable.rs:127:12
    |
 LL |       } else if returns_bool() {
    |  ____________^
diff --git a/tests/ui/needless_return.fixed b/tests/ui/needless_return.fixed
index 37efa6274df..9c999e12b4c 100644
--- a/tests/ui/needless_return.fixed
+++ b/tests/ui/needless_return.fixed
@@ -3,7 +3,12 @@
 
 #![feature(let_else)]
 #![allow(unused)]
-#![allow(clippy::if_same_then_else, clippy::single_match, clippy::needless_bool)]
+#![allow(
+    clippy::if_same_then_else,
+    clippy::single_match,
+    clippy::needless_bool,
+    clippy::equatable_if_let
+)]
 #![warn(clippy::needless_return)]
 
 macro_rules! the_answer {
diff --git a/tests/ui/needless_return.rs b/tests/ui/needless_return.rs
index cbf384ac9e4..da7dcf4f0a9 100644
--- a/tests/ui/needless_return.rs
+++ b/tests/ui/needless_return.rs
@@ -3,7 +3,12 @@
 
 #![feature(let_else)]
 #![allow(unused)]
-#![allow(clippy::if_same_then_else, clippy::single_match, clippy::needless_bool)]
+#![allow(
+    clippy::if_same_then_else,
+    clippy::single_match,
+    clippy::needless_bool,
+    clippy::equatable_if_let
+)]
 #![warn(clippy::needless_return)]
 
 macro_rules! the_answer {
diff --git a/tests/ui/needless_return.stderr b/tests/ui/needless_return.stderr
index 7ce7028bbae..2e802cff1e6 100644
--- a/tests/ui/needless_return.stderr
+++ b/tests/ui/needless_return.stderr
@@ -1,5 +1,5 @@
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:20:5
+  --> $DIR/needless_return.rs:25:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^^ help: remove `return`: `true`
@@ -7,187 +7,187 @@ LL |     return true;
    = note: `-D clippy::needless-return` implied by `-D warnings`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:24:5
+  --> $DIR/needless_return.rs:29:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:29:9
+  --> $DIR/needless_return.rs:34:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:31:9
+  --> $DIR/needless_return.rs:36:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^^ help: remove `return`: `false`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:37:17
+  --> $DIR/needless_return.rs:42:17
    |
 LL |         true => return false,
    |                 ^^^^^^^^^^^^ help: remove `return`: `false`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:39:13
+  --> $DIR/needless_return.rs:44:13
    |
 LL |             return true;
    |             ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:46:9
+  --> $DIR/needless_return.rs:51:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:48:16
+  --> $DIR/needless_return.rs:53:16
    |
 LL |     let _ = || return true;
    |                ^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:56:5
+  --> $DIR/needless_return.rs:61:5
    |
 LL |     return;
    |     ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:61:9
+  --> $DIR/needless_return.rs:66:9
    |
 LL |         return;
    |         ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:63:9
+  --> $DIR/needless_return.rs:68:9
    |
 LL |         return;
    |         ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:70:14
+  --> $DIR/needless_return.rs:75:14
    |
 LL |         _ => return,
    |              ^^^^^^ help: replace `return` with an empty block: `{}`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:85:9
+  --> $DIR/needless_return.rs:90:9
    |
 LL |         return String::from("test");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:87:9
+  --> $DIR/needless_return.rs:92:9
    |
 LL |         return String::new();
    |         ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:108:32
+  --> $DIR/needless_return.rs:113:32
    |
 LL |         bar.unwrap_or_else(|_| return)
    |                                ^^^^^^ help: replace `return` with an empty block: `{}`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:113:13
+  --> $DIR/needless_return.rs:118:13
    |
 LL |             return;
    |             ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:115:20
+  --> $DIR/needless_return.rs:120:20
    |
 LL |         let _ = || return;
    |                    ^^^^^^ help: replace `return` with an empty block: `{}`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:121:32
+  --> $DIR/needless_return.rs:126:32
    |
 LL |         res.unwrap_or_else(|_| return Foo)
    |                                ^^^^^^^^^^ help: remove `return`: `Foo`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:130:5
+  --> $DIR/needless_return.rs:135:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:134:5
+  --> $DIR/needless_return.rs:139:5
    |
 LL |     return true;
    |     ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:139:9
+  --> $DIR/needless_return.rs:144:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:141:9
+  --> $DIR/needless_return.rs:146:9
    |
 LL |         return false;
    |         ^^^^^^^^^^^^^ help: remove `return`: `false`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:147:17
+  --> $DIR/needless_return.rs:152:17
    |
 LL |         true => return false,
    |                 ^^^^^^^^^^^^ help: remove `return`: `false`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:149:13
+  --> $DIR/needless_return.rs:154:13
    |
 LL |             return true;
    |             ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:156:9
+  --> $DIR/needless_return.rs:161:9
    |
 LL |         return true;
    |         ^^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:158:16
+  --> $DIR/needless_return.rs:163:16
    |
 LL |     let _ = || return true;
    |                ^^^^^^^^^^^ help: remove `return`: `true`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:166:5
+  --> $DIR/needless_return.rs:171:5
    |
 LL |     return;
    |     ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:171:9
+  --> $DIR/needless_return.rs:176:9
    |
 LL |         return;
    |         ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:173:9
+  --> $DIR/needless_return.rs:178:9
    |
 LL |         return;
    |         ^^^^^^^ help: remove `return`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:180:14
+  --> $DIR/needless_return.rs:185:14
    |
 LL |         _ => return,
    |              ^^^^^^ help: replace `return` with an empty block: `{}`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:195:9
+  --> $DIR/needless_return.rs:200:9
    |
 LL |         return String::from("test");
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::from("test")`
 
 error: unneeded `return` statement
-  --> $DIR/needless_return.rs:197:9
+  --> $DIR/needless_return.rs:202:9
    |
 LL |         return String::new();
    |         ^^^^^^^^^^^^^^^^^^^^^ help: remove `return`: `String::new()`
diff --git a/tests/ui/non_send_fields_in_send_ty.rs b/tests/ui/non_send_fields_in_send_ty.rs
new file mode 100644
index 00000000000..eca7f5e5655
--- /dev/null
+++ b/tests/ui/non_send_fields_in_send_ty.rs
@@ -0,0 +1,127 @@
+#![warn(clippy::non_send_fields_in_send_ty)]
+#![feature(extern_types)]
+
+use std::cell::UnsafeCell;
+use std::ptr::NonNull;
+use std::rc::Rc;
+use std::sync::{Arc, Mutex, MutexGuard};
+
+// disrustor / RUSTSEC-2020-0150
+pub struct RingBuffer<T> {
+    data: Vec<UnsafeCell<T>>,
+    capacity: usize,
+    mask: usize,
+}
+
+unsafe impl<T> Send for RingBuffer<T> {}
+
+// noise_search / RUSTSEC-2020-0141
+pub struct MvccRwLock<T> {
+    raw: *const T,
+    lock: Mutex<Box<T>>,
+}
+
+unsafe impl<T> Send for MvccRwLock<T> {}
+
+// async-coap / RUSTSEC-2020-0124
+pub struct ArcGuard<RC, T> {
+    inner: T,
+    head: Arc<RC>,
+}
+
+unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
+
+// rusb / RUSTSEC-2020-0098
+extern "C" {
+    type libusb_device_handle;
+}
+
+pub trait UsbContext {
+    // some user trait that does not guarantee `Send`
+}
+
+pub struct DeviceHandle<T: UsbContext> {
+    context: T,
+    handle: NonNull<libusb_device_handle>,
+}
+
+unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
+
+// Other basic tests
+pub struct NoGeneric {
+    rc_is_not_send: Rc<String>,
+}
+
+unsafe impl Send for NoGeneric {}
+
+pub struct MultiField<T> {
+    field1: T,
+    field2: T,
+    field3: T,
+}
+
+unsafe impl<T> Send for MultiField<T> {}
+
+pub enum MyOption<T> {
+    MySome(T),
+    MyNone,
+}
+
+unsafe impl<T> Send for MyOption<T> {}
+
+// Multiple type parameters
+pub struct MultiParam<A, B> {
+    vec: Vec<(A, B)>,
+}
+
+unsafe impl<A, B> Send for MultiParam<A, B> {}
+
+// Tests for raw pointer heuristic
+extern "C" {
+    type NonSend;
+}
+
+pub struct HeuristicTest {
+    // raw pointers are allowed
+    field1: Vec<*const NonSend>,
+    field2: [*const NonSend; 3],
+    field3: (*const NonSend, *const NonSend, *const NonSend),
+    // not allowed when it contains concrete `!Send` field
+    field4: (*const NonSend, Rc<u8>),
+    // nested raw pointer is also allowed
+    field5: Vec<Vec<*const NonSend>>,
+}
+
+unsafe impl Send for HeuristicTest {}
+
+// Test attributes
+#[allow(clippy::non_send_fields_in_send_ty)]
+pub struct AttrTest1<T>(T);
+
+pub struct AttrTest2<T> {
+    #[allow(clippy::non_send_fields_in_send_ty)]
+    field: T,
+}
+
+pub enum AttrTest3<T> {
+    #[allow(clippy::non_send_fields_in_send_ty)]
+    Enum1(T),
+    Enum2(T),
+}
+
+unsafe impl<T> Send for AttrTest1<T> {}
+unsafe impl<T> Send for AttrTest2<T> {}
+unsafe impl<T> Send for AttrTest3<T> {}
+
+// Multiple non-overlapping `Send` for a single type
+pub struct Complex<A, B> {
+    field1: A,
+    field2: B,
+}
+
+unsafe impl<P> Send for Complex<P, u32> {}
+
+// `MutexGuard` is non-Send
+unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
+
+fn main() {}
diff --git a/tests/ui/non_send_fields_in_send_ty.stderr b/tests/ui/non_send_fields_in_send_ty.stderr
new file mode 100644
index 00000000000..8b8a1d16d9b
--- /dev/null
+++ b/tests/ui/non_send_fields_in_send_ty.stderr
@@ -0,0 +1,171 @@
+error: this implementation is unsound, as some fields in `RingBuffer<T>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:16:1
+   |
+LL | unsafe impl<T> Send for RingBuffer<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::non-send-fields-in-send-ty` implied by `-D warnings`
+note: the type of field `data` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:11:5
+   |
+LL |     data: Vec<UnsafeCell<T>>,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: add bounds on type parameter `T` that satisfy `Vec<UnsafeCell<T>>: Send`
+
+error: this implementation is unsound, as some fields in `MvccRwLock<T>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:24:1
+   |
+LL | unsafe impl<T> Send for MvccRwLock<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `lock` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:21:5
+   |
+LL |     lock: Mutex<Box<T>>,
+   |     ^^^^^^^^^^^^^^^^^^^
+   = help: add bounds on type parameter `T` that satisfy `Mutex<Box<T>>: Send`
+
+error: this implementation is unsound, as some fields in `ArcGuard<RC, T>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:32:1
+   |
+LL | unsafe impl<RC, T: Send> Send for ArcGuard<RC, T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `head` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:29:5
+   |
+LL |     head: Arc<RC>,
+   |     ^^^^^^^^^^^^^
+   = help: add bounds on type parameter `RC` that satisfy `Arc<RC>: Send`
+
+error: this implementation is unsound, as some fields in `DeviceHandle<T>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:48:1
+   |
+LL | unsafe impl<T: UsbContext> Send for DeviceHandle<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `context` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:44:5
+   |
+LL |     context: T,
+   |     ^^^^^^^^^^
+   = help: add `T: Send` bound in `Send` impl
+
+error: this implementation is unsound, as some fields in `NoGeneric` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:55:1
+   |
+LL | unsafe impl Send for NoGeneric {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `rc_is_not_send` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:52:5
+   |
+LL |     rc_is_not_send: Rc<String>,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use a thread-safe type that implements `Send`
+
+error: this implementation is unsound, as some fields in `MultiField<T>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:63:1
+   |
+LL | unsafe impl<T> Send for MultiField<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `field1` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:58:5
+   |
+LL |     field1: T,
+   |     ^^^^^^^^^
+   = help: add `T: Send` bound in `Send` impl
+note: the type of field `field2` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:59:5
+   |
+LL |     field2: T,
+   |     ^^^^^^^^^
+   = help: add `T: Send` bound in `Send` impl
+note: the type of field `field3` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:60:5
+   |
+LL |     field3: T,
+   |     ^^^^^^^^^
+   = help: add `T: Send` bound in `Send` impl
+
+error: this implementation is unsound, as some fields in `MyOption<T>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:70:1
+   |
+LL | unsafe impl<T> Send for MyOption<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `0` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:66:12
+   |
+LL |     MySome(T),
+   |            ^
+   = help: add `T: Send` bound in `Send` impl
+
+error: this implementation is unsound, as some fields in `MultiParam<A, B>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:77:1
+   |
+LL | unsafe impl<A, B> Send for MultiParam<A, B> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `vec` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:74:5
+   |
+LL |     vec: Vec<(A, B)>,
+   |     ^^^^^^^^^^^^^^^^
+   = help: add bounds on type parameters `A, B` that satisfy `Vec<(A, B)>: Send`
+
+error: this implementation is unsound, as some fields in `HeuristicTest` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:95:1
+   |
+LL | unsafe impl Send for HeuristicTest {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `field4` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:90:5
+   |
+LL |     field4: (*const NonSend, Rc<u8>),
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = help: use a thread-safe type that implements `Send`
+
+error: this implementation is unsound, as some fields in `AttrTest3<T>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:114:1
+   |
+LL | unsafe impl<T> Send for AttrTest3<T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `0` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:109:11
+   |
+LL |     Enum2(T),
+   |           ^
+   = help: add `T: Send` bound in `Send` impl
+
+error: this implementation is unsound, as some fields in `Complex<P, u32>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:122:1
+   |
+LL | unsafe impl<P> Send for Complex<P, u32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `field1` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:118:5
+   |
+LL |     field1: A,
+   |     ^^^^^^^^^
+   = help: add `P: Send` bound in `Send` impl
+
+error: this implementation is unsound, as some fields in `Complex<Q, MutexGuard<'static, bool>>` are `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:125:1
+   |
+LL | unsafe impl<Q: Send> Send for Complex<Q, MutexGuard<'static, bool>> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: the type of field `field2` is `!Send`
+  --> $DIR/non_send_fields_in_send_ty.rs:119:5
+   |
+LL |     field2: B,
+   |     ^^^^^^^^^
+   = help: use a thread-safe type that implements `Send`
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed
index d1815d0aec3..a3ebe5d0703 100644
--- a/tests/ui/option_if_let_else.fixed
+++ b/tests/ui/option_if_let_else.fixed
@@ -2,7 +2,7 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
 #![allow(clippy::redundant_closure)]
-#![allow(clippy::ref_option_ref)]
+#![allow(clippy::ref_option_ref, clippy::equatable_if_let)]
 
 fn bad1(string: Option<&str>) -> (bool, &str) {
     string.map_or((false, "hello"), |x| (true, x))
diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs
index a15627338cb..b11df3db60f 100644
--- a/tests/ui/option_if_let_else.rs
+++ b/tests/ui/option_if_let_else.rs
@@ -2,7 +2,7 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
 #![allow(clippy::redundant_closure)]
-#![allow(clippy::ref_option_ref)]
+#![allow(clippy::ref_option_ref, clippy::equatable_if_let)]
 
 fn bad1(string: Option<&str>) -> (bool, &str) {
     if let Some(x) = string {
diff --git a/tests/ui/redundant_pattern_matching_drop_order.fixed b/tests/ui/redundant_pattern_matching_drop_order.fixed
index 794ed542435..ce3229f1759 100644
--- a/tests/ui/redundant_pattern_matching_drop_order.fixed
+++ b/tests/ui/redundant_pattern_matching_drop_order.fixed
@@ -2,7 +2,7 @@
 
 // Issue #5746
 #![warn(clippy::redundant_pattern_matching)]
-#![allow(clippy::if_same_then_else)]
+#![allow(clippy::if_same_then_else, clippy::equatable_if_let)]
 use std::task::Poll::{Pending, Ready};
 
 fn main() {
diff --git a/tests/ui/redundant_pattern_matching_drop_order.rs b/tests/ui/redundant_pattern_matching_drop_order.rs
index b9c82d86f61..29b8543cf47 100644
--- a/tests/ui/redundant_pattern_matching_drop_order.rs
+++ b/tests/ui/redundant_pattern_matching_drop_order.rs
@@ -2,7 +2,7 @@
 
 // Issue #5746
 #![warn(clippy::redundant_pattern_matching)]
-#![allow(clippy::if_same_then_else)]
+#![allow(clippy::if_same_then_else, clippy::equatable_if_let)]
 use std::task::Poll::{Pending, Ready};
 
 fn main() {
diff --git a/tests/ui/redundant_pattern_matching_option.fixed b/tests/ui/redundant_pattern_matching_option.fixed
index 99714477266..813e268a60c 100644
--- a/tests/ui/redundant_pattern_matching_option.fixed
+++ b/tests/ui/redundant_pattern_matching_option.fixed
@@ -6,6 +6,7 @@
     unused_must_use,
     clippy::needless_bool,
     clippy::match_like_matches_macro,
+    clippy::equatable_if_let,
     clippy::if_same_then_else
 )]
 
diff --git a/tests/ui/redundant_pattern_matching_option.rs b/tests/ui/redundant_pattern_matching_option.rs
index 8309847e181..82a98468943 100644
--- a/tests/ui/redundant_pattern_matching_option.rs
+++ b/tests/ui/redundant_pattern_matching_option.rs
@@ -6,6 +6,7 @@
     unused_must_use,
     clippy::needless_bool,
     clippy::match_like_matches_macro,
+    clippy::equatable_if_let,
     clippy::if_same_then_else
 )]
 
diff --git a/tests/ui/redundant_pattern_matching_option.stderr b/tests/ui/redundant_pattern_matching_option.stderr
index 613a30d4a48..3a58e5ad7be 100644
--- a/tests/ui/redundant_pattern_matching_option.stderr
+++ b/tests/ui/redundant_pattern_matching_option.stderr
@@ -1,5 +1,5 @@
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:13:12
+  --> $DIR/redundant_pattern_matching_option.rs:14:12
    |
 LL |     if let None = None::<()> {}
    |     -------^^^^------------- help: try this: `if None::<()>.is_none()`
@@ -7,43 +7,43 @@ LL |     if let None = None::<()> {}
    = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:15:12
+  --> $DIR/redundant_pattern_matching_option.rs:16:12
    |
 LL |     if let Some(_) = Some(42) {}
    |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:17:12
+  --> $DIR/redundant_pattern_matching_option.rs:18:12
    |
 LL |     if let Some(_) = Some(42) {
    |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:23:15
+  --> $DIR/redundant_pattern_matching_option.rs:24:15
    |
 LL |     while let Some(_) = Some(42) {}
    |     ----------^^^^^^^----------- help: try this: `while Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:25:15
+  --> $DIR/redundant_pattern_matching_option.rs:26:15
    |
 LL |     while let None = Some(42) {}
    |     ----------^^^^----------- help: try this: `while Some(42).is_none()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:27:15
+  --> $DIR/redundant_pattern_matching_option.rs:28:15
    |
 LL |     while let None = None::<()> {}
    |     ----------^^^^------------- help: try this: `while None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:30:15
+  --> $DIR/redundant_pattern_matching_option.rs:31:15
    |
 LL |     while let Some(_) = v.pop() {
    |     ----------^^^^^^^---------- help: try this: `while v.pop().is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:38:5
+  --> $DIR/redundant_pattern_matching_option.rs:39:5
    |
 LL | /     match Some(42) {
 LL | |         Some(_) => true,
@@ -52,7 +52,7 @@ LL | |     };
    | |_____^ help: try this: `Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:43:5
+  --> $DIR/redundant_pattern_matching_option.rs:44:5
    |
 LL | /     match None::<()> {
 LL | |         Some(_) => false,
@@ -61,7 +61,7 @@ LL | |     };
    | |_____^ help: try this: `None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:48:13
+  --> $DIR/redundant_pattern_matching_option.rs:49:13
    |
 LL |       let _ = match None::<()> {
    |  _____________^
@@ -71,49 +71,49 @@ LL | |     };
    | |_____^ help: try this: `None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:54:20
+  --> $DIR/redundant_pattern_matching_option.rs:55:20
    |
 LL |     let _ = if let Some(_) = opt { true } else { false };
    |             -------^^^^^^^------ help: try this: `if opt.is_some()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:58:20
+  --> $DIR/redundant_pattern_matching_option.rs:59:20
    |
 LL |     let _ = if let Some(_) = gen_opt() {
    |             -------^^^^^^^------------ help: try this: `if gen_opt().is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:60:19
+  --> $DIR/redundant_pattern_matching_option.rs:61:19
    |
 LL |     } else if let None = gen_opt() {
    |            -------^^^^------------ help: try this: `if gen_opt().is_none()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:79:12
+  --> $DIR/redundant_pattern_matching_option.rs:80:12
    |
 LL |     if let Some(_) = Some(42) {}
    |     -------^^^^^^^----------- help: try this: `if Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:81:12
+  --> $DIR/redundant_pattern_matching_option.rs:82:12
    |
 LL |     if let None = None::<()> {}
    |     -------^^^^------------- help: try this: `if None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:83:15
+  --> $DIR/redundant_pattern_matching_option.rs:84:15
    |
 LL |     while let Some(_) = Some(42) {}
    |     ----------^^^^^^^----------- help: try this: `while Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:85:15
+  --> $DIR/redundant_pattern_matching_option.rs:86:15
    |
 LL |     while let None = None::<()> {}
    |     ----------^^^^------------- help: try this: `while None::<()>.is_none()`
 
 error: redundant pattern matching, consider using `is_some()`
-  --> $DIR/redundant_pattern_matching_option.rs:87:5
+  --> $DIR/redundant_pattern_matching_option.rs:88:5
    |
 LL | /     match Some(42) {
 LL | |         Some(_) => true,
@@ -122,7 +122,7 @@ LL | |     };
    | |_____^ help: try this: `Some(42).is_some()`
 
 error: redundant pattern matching, consider using `is_none()`
-  --> $DIR/redundant_pattern_matching_option.rs:92:5
+  --> $DIR/redundant_pattern_matching_option.rs:93:5
    |
 LL | /     match None::<()> {
 LL | |         Some(_) => false,
diff --git a/tests/ui/redundant_pattern_matching_poll.fixed b/tests/ui/redundant_pattern_matching_poll.fixed
index c2977453804..3645f2c4bfd 100644
--- a/tests/ui/redundant_pattern_matching_poll.fixed
+++ b/tests/ui/redundant_pattern_matching_poll.fixed
@@ -6,6 +6,7 @@
     unused_must_use,
     clippy::needless_bool,
     clippy::match_like_matches_macro,
+    clippy::equatable_if_let,
     clippy::if_same_then_else
 )]
 
diff --git a/tests/ui/redundant_pattern_matching_poll.rs b/tests/ui/redundant_pattern_matching_poll.rs
index 665c8c41750..866c71b7cfa 100644
--- a/tests/ui/redundant_pattern_matching_poll.rs
+++ b/tests/ui/redundant_pattern_matching_poll.rs
@@ -6,6 +6,7 @@
     unused_must_use,
     clippy::needless_bool,
     clippy::match_like_matches_macro,
+    clippy::equatable_if_let,
     clippy::if_same_then_else
 )]
 
diff --git a/tests/ui/redundant_pattern_matching_poll.stderr b/tests/ui/redundant_pattern_matching_poll.stderr
index 5ecf024a733..1b480f3157f 100644
--- a/tests/ui/redundant_pattern_matching_poll.stderr
+++ b/tests/ui/redundant_pattern_matching_poll.stderr
@@ -1,5 +1,5 @@
 error: redundant pattern matching, consider using `is_pending()`
-  --> $DIR/redundant_pattern_matching_poll.rs:15:12
+  --> $DIR/redundant_pattern_matching_poll.rs:16:12
    |
 LL |     if let Pending = Pending::<()> {}
    |     -------^^^^^^^---------------- help: try this: `if Pending::<()>.is_pending()`
@@ -7,37 +7,37 @@ LL |     if let Pending = Pending::<()> {}
    = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings`
 
 error: redundant pattern matching, consider using `is_ready()`
-  --> $DIR/redundant_pattern_matching_poll.rs:17:12
+  --> $DIR/redundant_pattern_matching_poll.rs:18:12
    |
 LL |     if let Ready(_) = Ready(42) {}
    |     -------^^^^^^^^------------ help: try this: `if Ready(42).is_ready()`
 
 error: redundant pattern matching, consider using `is_ready()`
-  --> $DIR/redundant_pattern_matching_poll.rs:19:12
+  --> $DIR/redundant_pattern_matching_poll.rs:20:12
    |
 LL |     if let Ready(_) = Ready(42) {
    |     -------^^^^^^^^------------ help: try this: `if Ready(42).is_ready()`
 
 error: redundant pattern matching, consider using `is_ready()`
-  --> $DIR/redundant_pattern_matching_poll.rs:25:15
+  --> $DIR/redundant_pattern_matching_poll.rs:26:15
    |
 LL |     while let Ready(_) = Ready(42) {}
    |     ----------^^^^^^^^------------ help: try this: `while Ready(42).is_ready()`
 
 error: redundant pattern matching, consider using `is_pending()`
-  --> $DIR/redundant_pattern_matching_poll.rs:27:15
+  --> $DIR/redundant_pattern_matching_poll.rs:28:15
    |
 LL |     while let Pending = Ready(42) {}
    |     ----------^^^^^^^------------ help: try this: `while Ready(42).is_pending()`
 
 error: redundant pattern matching, consider using `is_pending()`
-  --> $DIR/redundant_pattern_matching_poll.rs:29:15
+  --> $DIR/redundant_pattern_matching_poll.rs:30:15
    |
 LL |     while let Pending = Pending::<()> {}
    |     ----------^^^^^^^---------------- help: try this: `while Pending::<()>.is_pending()`
 
 error: redundant pattern matching, consider using `is_ready()`
-  --> $DIR/redundant_pattern_matching_poll.rs:35:5
+  --> $DIR/redundant_pattern_matching_poll.rs:36:5
    |
 LL | /     match Ready(42) {
 LL | |         Ready(_) => true,
@@ -46,7 +46,7 @@ LL | |     };
    | |_____^ help: try this: `Ready(42).is_ready()`
 
 error: redundant pattern matching, consider using `is_pending()`
-  --> $DIR/redundant_pattern_matching_poll.rs:40:5
+  --> $DIR/redundant_pattern_matching_poll.rs:41:5
    |
 LL | /     match Pending::<()> {
 LL | |         Ready(_) => false,
@@ -55,7 +55,7 @@ LL | |     };
    | |_____^ help: try this: `Pending::<()>.is_pending()`
 
 error: redundant pattern matching, consider using `is_pending()`
-  --> $DIR/redundant_pattern_matching_poll.rs:45:13
+  --> $DIR/redundant_pattern_matching_poll.rs:46:13
    |
 LL |       let _ = match Pending::<()> {
    |  _____________^
@@ -65,49 +65,49 @@ LL | |     };
    | |_____^ help: try this: `Pending::<()>.is_pending()`
 
 error: redundant pattern matching, consider using `is_ready()`
-  --> $DIR/redundant_pattern_matching_poll.rs:51:20
+  --> $DIR/redundant_pattern_matching_poll.rs:52:20
    |
 LL |     let _ = if let Ready(_) = poll { true } else { false };
    |             -------^^^^^^^^------- help: try this: `if poll.is_ready()`
 
 error: redundant pattern matching, consider using `is_ready()`
-  --> $DIR/redundant_pattern_matching_poll.rs:55:20
+  --> $DIR/redundant_pattern_matching_poll.rs:56:20
    |
 LL |     let _ = if let Ready(_) = gen_poll() {
    |             -------^^^^^^^^------------- help: try this: `if gen_poll().is_ready()`
 
 error: redundant pattern matching, consider using `is_pending()`
-  --> $DIR/redundant_pattern_matching_poll.rs:57:19
+  --> $DIR/redundant_pattern_matching_poll.rs:58:19
    |
 LL |     } else if let Pending = gen_poll() {
    |            -------^^^^^^^------------- help: try this: `if gen_poll().is_pending()`
 
 error: redundant pattern matching, consider using `is_ready()`
-  --> $DIR/redundant_pattern_matching_poll.rs:73:12
+  --> $DIR/redundant_pattern_matching_poll.rs:74:12
    |
 LL |     if let Ready(_) = Ready(42) {}
    |     -------^^^^^^^^------------ help: try this: `if Ready(42).is_ready()`
 
 error: redundant pattern matching, consider using `is_pending()`
-  --> $DIR/redundant_pattern_matching_poll.rs:75:12
+  --> $DIR/redundant_pattern_matching_poll.rs:76:12
    |
 LL |     if let Pending = Pending::<()> {}
    |     -------^^^^^^^---------------- help: try this: `if Pending::<()>.is_pending()`
 
 error: redundant pattern matching, consider using `is_ready()`
-  --> $DIR/redundant_pattern_matching_poll.rs:77:15
+  --> $DIR/redundant_pattern_matching_poll.rs:78:15
    |
 LL |     while let Ready(_) = Ready(42) {}
    |     ----------^^^^^^^^------------ help: try this: `while Ready(42).is_ready()`
 
 error: redundant pattern matching, consider using `is_pending()`
-  --> $DIR/redundant_pattern_matching_poll.rs:79:15
+  --> $DIR/redundant_pattern_matching_poll.rs:80:15
    |
 LL |     while let Pending = Pending::<()> {}
    |     ----------^^^^^^^---------------- help: try this: `while Pending::<()>.is_pending()`
 
 error: redundant pattern matching, consider using `is_ready()`
-  --> $DIR/redundant_pattern_matching_poll.rs:81:5
+  --> $DIR/redundant_pattern_matching_poll.rs:82:5
    |
 LL | /     match Ready(42) {
 LL | |         Ready(_) => true,
@@ -116,7 +116,7 @@ LL | |     };
    | |_____^ help: try this: `Ready(42).is_ready()`
 
 error: redundant pattern matching, consider using `is_pending()`
-  --> $DIR/redundant_pattern_matching_poll.rs:86:5
+  --> $DIR/redundant_pattern_matching_poll.rs:87:5
    |
 LL | /     match Pending::<()> {
 LL | |         Ready(_) => false,
diff --git a/tests/ui/shadow.rs b/tests/ui/shadow.rs
index e366c75335c..02e838456d0 100644
--- a/tests/ui/shadow.rs
+++ b/tests/ui/shadow.rs
@@ -1,54 +1,77 @@
-#![warn(
-    clippy::all,
-    clippy::pedantic,
-    clippy::shadow_same,
-    clippy::shadow_reuse,
-    clippy::shadow_unrelated
-)]
-#![allow(
-    unused_parens,
-    unused_variables,
-    clippy::manual_unwrap_or,
-    clippy::missing_docs_in_private_items,
-    clippy::single_match
-)]
+#![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)]
 
-fn id<T>(x: T) -> T {
-    x
-}
-
-#[must_use]
-fn first(x: (isize, isize)) -> isize {
-    x.0
-}
-
-fn main() {
-    let mut x = 1;
+fn shadow_same() {
+    let x = 1;
+    let x = x;
+    let mut x = &x;
     let x = &mut x;
-    let x = { x };
-    let x = (&*x);
-    let x = { *x + 1 };
-    let x = id(x);
-    let x = (1, x);
-    let x = first(x);
-    let y = 1;
-    let x = y;
-
-    let x;
-    x = 42;
-
-    let o = Some(1_u8);
-
-    if let Some(p) = o {
-        assert_eq!(1, p);
-    }
-    match o {
-        Some(p) => p, // no error, because the p above is in its own scope
-        None => 0,
-    };
-
-    match (x, o) {
-        (1, Some(a)) | (a, Some(1)) => (), // no error though `a` appears twice
-        _ => (),
-    }
+    let x = *x;
 }
+
+fn shadow_reuse() -> Option<()> {
+    let x = ([[0]], ());
+    let x = x.0;
+    let x = x[0];
+    let [x] = x;
+    let x = Some(x);
+    let x = foo(x);
+    let x = || x;
+    let x = Some(1).map(|_| x)?;
+    None
+}
+
+fn shadow_unrelated() {
+    let x = 1;
+    let x = 2;
+}
+
+fn syntax() {
+    fn f(x: u32) {
+        let x = 1;
+    }
+    let x = 1;
+    match Some(1) {
+        Some(1) => {},
+        Some(x) => {
+            let x = 1;
+        },
+        _ => {},
+    }
+    if let Some(x) = Some(1) {}
+    while let Some(x) = Some(1) {}
+    let _ = |[x]: [u32; 1]| {
+        let x = 1;
+    };
+}
+
+fn negative() {
+    match Some(1) {
+        Some(x) if x == 1 => {},
+        Some(x) => {},
+        None => {},
+    }
+    match [None, Some(1)] {
+        [Some(x), None] | [None, Some(x)] => {},
+        _ => {},
+    }
+    if let Some(x) = Some(1) {
+        let y = 1;
+    } else {
+        let x = 1;
+        let y = 1;
+    }
+    let x = 1;
+    #[allow(clippy::shadow_unrelated)]
+    let x = 1;
+}
+
+fn foo<T>(_: T) {}
+
+fn question_mark() -> Option<()> {
+    let val = 1;
+    // `?` expands with a `val` binding
+    None?;
+    None
+}
+
+fn main() {}
diff --git a/tests/ui/shadow.stderr b/tests/ui/shadow.stderr
index 7c1ad2949e9..8b60e072c93 100644
--- a/tests/ui/shadow.stderr
+++ b/tests/ui/shadow.stderr
@@ -1,138 +1,233 @@
-error: `x` is shadowed by itself in `&mut x`
-  --> $DIR/shadow.rs:27:5
+error: `x` is shadowed by itself in `x`
+  --> $DIR/shadow.rs:5:9
    |
-LL |     let x = &mut x;
-   |     ^^^^^^^^^^^^^^^
+LL |     let x = x;
+   |         ^
    |
    = note: `-D clippy::shadow-same` implied by `-D warnings`
 note: previous binding is here
-  --> $DIR/shadow.rs:26:13
+  --> $DIR/shadow.rs:4:9
    |
-LL |     let mut x = 1;
-   |             ^
+LL |     let x = 1;
+   |         ^
 
-error: `x` is shadowed by itself in `{ x }`
-  --> $DIR/shadow.rs:28:5
+error: `mut x` is shadowed by itself in `&x`
+  --> $DIR/shadow.rs:6:13
    |
-LL |     let x = { x };
-   |     ^^^^^^^^^^^^^^
+LL |     let mut x = &x;
+   |             ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:27:9
+  --> $DIR/shadow.rs:5:9
+   |
+LL |     let x = x;
+   |         ^
+
+error: `x` is shadowed by itself in `&mut x`
+  --> $DIR/shadow.rs:7:9
+   |
+LL |     let x = &mut x;
+   |         ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:6:9
+   |
+LL |     let mut x = &x;
+   |         ^^^^^
+
+error: `x` is shadowed by itself in `*x`
+  --> $DIR/shadow.rs:8:9
+   |
+LL |     let x = *x;
+   |         ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:7:9
    |
 LL |     let x = &mut x;
    |         ^
 
-error: `x` is shadowed by itself in `(&*x)`
-  --> $DIR/shadow.rs:29:5
+error: `x` is shadowed by `x.0` which reuses the original value
+  --> $DIR/shadow.rs:13:9
    |
-LL |     let x = (&*x);
-   |     ^^^^^^^^^^^^^^
-   |
-note: previous binding is here
-  --> $DIR/shadow.rs:28:9
-   |
-LL |     let x = { x };
-   |         ^
-
-error: `x` is shadowed by `{ *x + 1 }` which reuses the original value
-  --> $DIR/shadow.rs:30:9
-   |
-LL |     let x = { *x + 1 };
+LL |     let x = x.0;
    |         ^
    |
    = note: `-D clippy::shadow-reuse` implied by `-D warnings`
-note: initialization happens here
-  --> $DIR/shadow.rs:30:13
-   |
-LL |     let x = { *x + 1 };
-   |             ^^^^^^^^^^
 note: previous binding is here
-  --> $DIR/shadow.rs:29:9
+  --> $DIR/shadow.rs:12:9
    |
-LL |     let x = (&*x);
+LL |     let x = ([[0]], ());
    |         ^
 
-error: `x` is shadowed by `id(x)` which reuses the original value
-  --> $DIR/shadow.rs:31:9
+error: `x` is shadowed by `x[0]` which reuses the original value
+  --> $DIR/shadow.rs:14:9
    |
-LL |     let x = id(x);
+LL |     let x = x[0];
    |         ^
    |
-note: initialization happens here
-  --> $DIR/shadow.rs:31:13
-   |
-LL |     let x = id(x);
-   |             ^^^^^
 note: previous binding is here
-  --> $DIR/shadow.rs:30:9
+  --> $DIR/shadow.rs:13:9
    |
-LL |     let x = { *x + 1 };
+LL |     let x = x.0;
    |         ^
 
-error: `x` is shadowed by `(1, x)` which reuses the original value
-  --> $DIR/shadow.rs:32:9
+error: `x` is shadowed by `x` which reuses the original value
+  --> $DIR/shadow.rs:15:10
    |
-LL |     let x = (1, x);
-   |         ^
+LL |     let [x] = x;
+   |          ^
    |
-note: initialization happens here
-  --> $DIR/shadow.rs:32:13
-   |
-LL |     let x = (1, x);
-   |             ^^^^^^
 note: previous binding is here
-  --> $DIR/shadow.rs:31:9
+  --> $DIR/shadow.rs:14:9
    |
-LL |     let x = id(x);
+LL |     let x = x[0];
    |         ^
 
-error: `x` is shadowed by `first(x)` which reuses the original value
-  --> $DIR/shadow.rs:33:9
+error: `x` is shadowed by `Some(x)` which reuses the original value
+  --> $DIR/shadow.rs:16:9
    |
-LL |     let x = first(x);
+LL |     let x = Some(x);
    |         ^
    |
-note: initialization happens here
-  --> $DIR/shadow.rs:33:13
-   |
-LL |     let x = first(x);
-   |             ^^^^^^^^
 note: previous binding is here
-  --> $DIR/shadow.rs:32:9
+  --> $DIR/shadow.rs:15:10
    |
-LL |     let x = (1, x);
+LL |     let [x] = x;
+   |          ^
+
+error: `x` is shadowed by `foo(x)` which reuses the original value
+  --> $DIR/shadow.rs:17:9
+   |
+LL |     let x = foo(x);
+   |         ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:16:9
+   |
+LL |     let x = Some(x);
    |         ^
 
-error: `x` is being shadowed
-  --> $DIR/shadow.rs:35:9
+error: `x` is shadowed by `|| x` which reuses the original value
+  --> $DIR/shadow.rs:18:9
    |
-LL |     let x = y;
+LL |     let x = || x;
+   |         ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:17:9
+   |
+LL |     let x = foo(x);
+   |         ^
+
+error: `x` is shadowed by `Some(1).map(|_| x)?` which reuses the original value
+  --> $DIR/shadow.rs:19:9
+   |
+LL |     let x = Some(1).map(|_| x)?;
+   |         ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:18:9
+   |
+LL |     let x = || x;
+   |         ^
+
+error: `x` shadows a previous, unrelated binding
+  --> $DIR/shadow.rs:25:9
+   |
+LL |     let x = 2;
    |         ^
    |
    = note: `-D clippy::shadow-unrelated` implied by `-D warnings`
-note: initialization happens here
-  --> $DIR/shadow.rs:35:13
+note: previous binding is here
+  --> $DIR/shadow.rs:24:9
    |
-LL |     let x = y;
+LL |     let x = 1;
+   |         ^
+
+error: `x` shadows a previous, unrelated binding
+  --> $DIR/shadow.rs:30:13
+   |
+LL |         let x = 1;
    |             ^
-note: previous binding is here
-  --> $DIR/shadow.rs:33:9
-   |
-LL |     let x = first(x);
-   |         ^
-
-error: `x` shadows a previous declaration
-  --> $DIR/shadow.rs:37:5
-   |
-LL |     let x;
-   |     ^^^^^^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:35:9
+  --> $DIR/shadow.rs:29:10
    |
-LL |     let x = y;
+LL |     fn f(x: u32) {
+   |          ^
+
+error: `x` shadows a previous, unrelated binding
+  --> $DIR/shadow.rs:35:14
+   |
+LL |         Some(x) => {
+   |              ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:32:9
+   |
+LL |     let x = 1;
    |         ^
 
-error: aborting due to 9 previous errors
+error: `x` shadows a previous, unrelated binding
+  --> $DIR/shadow.rs:36:17
+   |
+LL |             let x = 1;
+   |                 ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:35:14
+   |
+LL |         Some(x) => {
+   |              ^
+
+error: `x` shadows a previous, unrelated binding
+  --> $DIR/shadow.rs:40:17
+   |
+LL |     if let Some(x) = Some(1) {}
+   |                 ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:32:9
+   |
+LL |     let x = 1;
+   |         ^
+
+error: `x` shadows a previous, unrelated binding
+  --> $DIR/shadow.rs:41:20
+   |
+LL |     while let Some(x) = Some(1) {}
+   |                    ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:32:9
+   |
+LL |     let x = 1;
+   |         ^
+
+error: `x` shadows a previous, unrelated binding
+  --> $DIR/shadow.rs:42:15
+   |
+LL |     let _ = |[x]: [u32; 1]| {
+   |               ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:32:9
+   |
+LL |     let x = 1;
+   |         ^
+
+error: `x` shadows a previous, unrelated binding
+  --> $DIR/shadow.rs:43:13
+   |
+LL |         let x = 1;
+   |             ^
+   |
+note: previous binding is here
+  --> $DIR/shadow.rs:42:15
+   |
+LL |     let _ = |[x]: [u32; 1]| {
+   |               ^
+
+error: aborting due to 19 previous errors
 
diff --git a/tests/ui/suspicious_map.stderr b/tests/ui/suspicious_map.stderr
index 8c3f36584a5..3ffcd1a9031 100644
--- a/tests/ui/suspicious_map.stderr
+++ b/tests/ui/suspicious_map.stderr
@@ -5,7 +5,7 @@ LL |     let _ = (0..3).map(|x| x + 2).count();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::suspicious-map` implied by `-D warnings`
-   = help: make sure you did not confuse `map` with `filter` or `for_each`
+   = help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect`
 
 error: this call to `map()` won't have an effect on the call to `count()`
   --> $DIR/suspicious_map.rs:7:13
@@ -13,7 +13,7 @@ error: this call to `map()` won't have an effect on the call to `count()`
 LL |     let _ = (0..3).map(f).count();
    |             ^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: make sure you did not confuse `map` with `filter` or `for_each`
+   = help: make sure you did not confuse `map` with `filter`, `for_each` or `inspect`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/while_let_on_iterator.fixed b/tests/ui/while_let_on_iterator.fixed
index f5a34190902..1e74ad2de65 100644
--- a/tests/ui/while_let_on_iterator.fixed
+++ b/tests/ui/while_let_on_iterator.fixed
@@ -1,7 +1,13 @@
 // run-rustfix
 
 #![warn(clippy::while_let_on_iterator)]
-#![allow(clippy::never_loop, unreachable_code, unused_mut, dead_code)]
+#![allow(
+    clippy::never_loop,
+    unreachable_code,
+    unused_mut,
+    dead_code,
+    clippy::equatable_if_let
+)]
 
 fn base() {
     let mut iter = 1..20;
diff --git a/tests/ui/while_let_on_iterator.rs b/tests/ui/while_let_on_iterator.rs
index 72f34257d1f..69cb636cee8 100644
--- a/tests/ui/while_let_on_iterator.rs
+++ b/tests/ui/while_let_on_iterator.rs
@@ -1,7 +1,13 @@
 // run-rustfix
 
 #![warn(clippy::while_let_on_iterator)]
-#![allow(clippy::never_loop, unreachable_code, unused_mut, dead_code)]
+#![allow(
+    clippy::never_loop,
+    unreachable_code,
+    unused_mut,
+    dead_code,
+    clippy::equatable_if_let
+)]
 
 fn base() {
     let mut iter = 1..20;
diff --git a/tests/ui/while_let_on_iterator.stderr b/tests/ui/while_let_on_iterator.stderr
index 5e2fce4491a..1a11ba26eef 100644
--- a/tests/ui/while_let_on_iterator.stderr
+++ b/tests/ui/while_let_on_iterator.stderr
@@ -1,5 +1,5 @@
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:8:5
+  --> $DIR/while_let_on_iterator.rs:14:5
    |
 LL |     while let Option::Some(x) = iter.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter`
@@ -7,85 +7,85 @@ LL |     while let Option::Some(x) = iter.next() {
    = note: `-D clippy::while-let-on-iterator` implied by `-D warnings`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:13:5
+  --> $DIR/while_let_on_iterator.rs:19:5
    |
 LL |     while let Some(x) = iter.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in iter`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:18:5
+  --> $DIR/while_let_on_iterator.rs:24:5
    |
 LL |     while let Some(_) = iter.next() {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in iter`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:94:9
+  --> $DIR/while_let_on_iterator.rs:100:9
    |
 LL |         while let Some([..]) = it.next() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [..] in it`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:101:9
+  --> $DIR/while_let_on_iterator.rs:107:9
    |
 LL |         while let Some([_x]) = it.next() {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for [_x] in it`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:114:9
+  --> $DIR/while_let_on_iterator.rs:120:9
    |
 LL |         while let Some(x @ [_]) = it.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x @ [_] in it`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:134:9
+  --> $DIR/while_let_on_iterator.rs:140:9
    |
 LL |         while let Some(_) = y.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in y`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:191:9
+  --> $DIR/while_let_on_iterator.rs:197:9
    |
 LL |         while let Some(m) = it.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:202:5
+  --> $DIR/while_let_on_iterator.rs:208:5
    |
 LL |     while let Some(n) = it.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:204:9
+  --> $DIR/while_let_on_iterator.rs:210:9
    |
 LL |         while let Some(m) = it.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:213:9
+  --> $DIR/while_let_on_iterator.rs:219:9
    |
 LL |         while let Some(m) = it.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:222:9
+  --> $DIR/while_let_on_iterator.rs:228:9
    |
 LL |         while let Some(m) = it.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:239:9
+  --> $DIR/while_let_on_iterator.rs:245:9
    |
 LL |         while let Some(m) = it.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for m in it.by_ref()`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:254:13
+  --> $DIR/while_let_on_iterator.rs:260:13
    |
 LL |             while let Some(i) = self.0.next() {
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.by_ref()`
 
 error: manual `!RangeInclusive::contains` implementation
-  --> $DIR/while_let_on_iterator.rs:255:20
+  --> $DIR/while_let_on_iterator.rs:261:20
    |
 LL |                 if i < 3 || i > 7 {
    |                    ^^^^^^^^^^^^^^ help: use: `!(3..=7).contains(&i)`
@@ -93,37 +93,37 @@ LL |                 if i < 3 || i > 7 {
    = note: `-D clippy::manual-range-contains` implied by `-D warnings`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:286:13
+  --> $DIR/while_let_on_iterator.rs:292:13
    |
 LL |             while let Some(i) = self.0.0.0.next() {
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for i in self.0.0.0.by_ref()`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:315:5
+  --> $DIR/while_let_on_iterator.rs:321:5
    |
 LL |     while let Some(n) = it.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for n in it.by_ref()`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:327:9
+  --> $DIR/while_let_on_iterator.rs:333:9
    |
 LL |         while let Some(x) = it.next() {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:341:5
+  --> $DIR/while_let_on_iterator.rs:347:5
    |
 LL |     while let Some(x) = it.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.by_ref()`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:352:5
+  --> $DIR/while_let_on_iterator.rs:358:5
    |
 LL |     while let Some(x) = it.0.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for x in it.0.by_ref()`
 
 error: this loop could be written as a `for` loop
-  --> $DIR/while_let_on_iterator.rs:371:5
+  --> $DIR/while_let_on_iterator.rs:377:5
    |
 LL |     while let Some(..) = it.next() {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for _ in it`
diff --git a/util/etc/pre-commit.sh b/util/etc/pre-commit.sh
index 528f8953b25..5dd2ba3d5f5 100755
--- a/util/etc/pre-commit.sh
+++ b/util/etc/pre-commit.sh
@@ -6,6 +6,7 @@ set -e
 # Update lints
 cargo dev update_lints
 git add clippy_lints/src/lib.rs
+git add clippy_lints/src/lib.*.rs
 
 # Formatting:
 #     Git will not automatically add the formatted code to the staged changes once