about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-06-13 08:51:53 +0000
committerbors <bors@rust-lang.org>2019-06-13 08:51:53 +0000
commitbd39cea01ce5c539fa109f9ab576f5cf8cf329dc (patch)
tree6ef0121dcebc9da5d4cef2c0b40da75554d0d6c0
parent7b2a7a225700d972313e23a042f8dbc6adabfbd8 (diff)
parent2719c1e6a3bd9a5bf76c510cf30c6d103e24ade2 (diff)
downloadrust-bd39cea01ce5c539fa109f9ab576f5cf8cf329dc.tar.gz
rust-bd39cea01ce5c539fa109f9ab576f5cf8cf329dc.zip
Auto merge of #4175 - yaahallo:master, r=oli-obk
Implement better help for clippy-driver

https://github.com/rust-lang/rust-clippy/issues/4173
-rw-r--r--clippy_dev/src/main.rs22
-rw-r--r--src/driver.rs167
-rw-r--r--src/lintlist/lint.rs27
-rw-r--r--src/lintlist/mod.rs2137
4 files changed, 2349 insertions, 4 deletions
diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs
index 45d4d13ed86..fedbb661763 100644
--- a/clippy_dev/src/main.rs
+++ b/clippy_dev/src/main.rs
@@ -87,9 +87,31 @@ fn print_lints() {
 
 fn update_lints(update_mode: &UpdateMode) {
     let lint_list: Vec<Lint> = gather_all().collect();
+
     let usable_lints: Vec<Lint> = Lint::usable_lints(lint_list.clone().into_iter()).collect();
     let lint_count = usable_lints.len();
 
+    let mut sorted_usable_lints = usable_lints.clone();
+    sorted_usable_lints.sort_by_key(|lint| lint.name.clone());
+
+    std::fs::write(
+        "../src/lintlist/mod.rs",
+        &format!(
+            "\
+//! This file is managed by `util/dev update_lints`. Do not edit.
+
+pub mod lint;
+pub use lint::Level;
+pub use lint::Lint;
+pub use lint::LINT_LEVELS;
+
+pub const ALL_LINTS: [Lint; {}] = {:#?};\n",
+            sorted_usable_lints.len(),
+            sorted_usable_lints
+        ),
+    )
+    .expect("can write to file");
+
     let mut file_change = replace_region_in_file(
         "../README.md",
         r#"\[There are \d+ lints included in this crate!\]\(https://rust-lang.github.io/rust-clippy/master/index.html\)"#,
diff --git a/src/driver.rs b/src/driver.rs
index f4a656722b9..e6b04bf0cfd 100644
--- a/src/driver.rs
+++ b/src/driver.rs
@@ -15,6 +15,8 @@ use rustc_tools_util::*;
 use std::path::Path;
 use std::process::{exit, Command};
 
+mod lintlist;
+
 /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
 /// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
 fn arg_value<'a>(
@@ -108,6 +110,142 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
     }
 }
 
+#[allow(clippy::find_map, clippy::filter_map)]
+fn describe_lints() {
+    use lintlist::*;
+    use std::collections::HashSet;
+
+    println!(
+        "
+Available lint options:
+    -W <foo>           Warn about <foo>
+    -A <foo>           Allow <foo>
+    -D <foo>           Deny <foo>
+    -F <foo>           Forbid <foo> (deny <foo> and all attempts to override)
+
+"
+    );
+
+    let lint_level = |lint: &Lint| {
+        LINT_LEVELS
+            .iter()
+            .find(|level_mapping| level_mapping.0 == lint.group)
+            .map(|(_, level)| match level {
+                Level::Allow => "allow",
+                Level::Warn => "warn",
+                Level::Deny => "deny",
+            })
+            .unwrap()
+    };
+
+    let mut lints: Vec<_> = ALL_LINTS.iter().collect();
+    // The sort doesn't case-fold but it's doubtful we care.
+    lints.sort_by_cached_key(|x: &&Lint| (lint_level(x), x.name));
+
+    let max_lint_name_len = lints
+        .iter()
+        .map(|lint| lint.name.len())
+        .map(|len| len + "clippy::".len())
+        .max()
+        .unwrap_or(0);
+
+    let padded = |x: &str| {
+        let mut s = " ".repeat(max_lint_name_len - x.chars().count());
+        s.push_str(x);
+        s
+    };
+
+    let scoped = |x: &str| format!("clippy::{}", x);
+
+    let lint_groups: HashSet<_> = lints.iter().map(|lint| lint.group).collect();
+
+    println!("Lint checks provided by clippy:\n");
+    println!("    {}  {:7.7}  meaning", padded("name"), "default");
+    println!("    {}  {:7.7}  -------", padded("----"), "-------");
+
+    let print_lints = |lints: &[&Lint]| {
+        for lint in lints {
+            let name = lint.name.replace("_", "-");
+            println!(
+                "    {}  {:7.7}  {}",
+                padded(&scoped(&name)),
+                lint_level(lint),
+                lint.desc
+            );
+        }
+        println!("\n");
+    };
+
+    print_lints(&lints);
+
+    let max_group_name_len = std::cmp::max(
+        "clippy::all".len(),
+        lint_groups
+            .iter()
+            .map(|group| group.len())
+            .map(|len| len + "clippy::".len())
+            .max()
+            .unwrap_or(0),
+    );
+
+    let padded_group = |x: &str| {
+        let mut s = " ".repeat(max_group_name_len - x.chars().count());
+        s.push_str(x);
+        s
+    };
+
+    println!("Lint groups provided by clippy:\n");
+    println!("    {}  sub-lints", padded_group("name"));
+    println!("    {}  ---------", padded_group("----"));
+    println!("    {}  the set of all clippy lints", padded_group("clippy::all"));
+
+    let print_lint_groups = || {
+        for group in lint_groups {
+            let name = group.to_lowercase().replace("_", "-");
+            let desc = lints
+                .iter()
+                .filter(|&lint| lint.group == group)
+                .map(|lint| lint.name)
+                .map(|name| name.replace("_", "-"))
+                .collect::<Vec<String>>()
+                .join(", ");
+            println!("    {}  {}", padded_group(&scoped(&name)), desc);
+        }
+        println!("\n");
+    };
+
+    print_lint_groups();
+}
+
+fn display_help() {
+    println!(
+        "\
+Checks a package to catch common mistakes and improve your Rust code.
+
+Usage:
+    cargo clippy [options] [--] [<opts>...]
+
+Common options:
+    -h, --help               Print this message
+    -V, --version            Print version info and exit
+
+Other options are the same as `cargo check`.
+
+To allow or deny a lint from the command line you can use `cargo clippy --`
+with:
+
+    -W --warn OPT       Set lint warnings
+    -A --allow OPT      Set lint allowed
+    -D --deny OPT       Set lint denied
+    -F --forbid OPT     Set lint forbidden
+
+You can use tool lints to allow or deny lints from your code, eg.:
+
+    #[allow(clippy::needless_lifetimes)]
+"
+    );
+}
+
 pub fn main() {
     rustc_driver::init_rustc_env_logger();
     exit(
@@ -153,13 +291,34 @@ pub fn main() {
 
             // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
             // We're invoking the compiler programmatically, so we ignore this/
-            if orig_args.len() <= 1 {
-                std::process::exit(1);
-            }
-            if Path::new(&orig_args[1]).file_stem() == Some("rustc".as_ref()) {
+            let wrapper_mode = Path::new(&orig_args[1]).file_stem() == Some("rustc".as_ref());
+
+            if wrapper_mode {
                 // we still want to be able to invoke it normally though
                 orig_args.remove(1);
             }
+
+            if !wrapper_mode && std::env::args().any(|a| a == "--help" || a == "-h") {
+                display_help();
+                exit(0);
+            }
+
+            let should_describe_lints = || {
+                let args: Vec<_> = std::env::args().collect();
+                args.windows(2).any(|args| {
+                    args[1] == "help"
+                        && match args[0].as_str() {
+                            "-W" | "-A" | "-D" | "-F" => true,
+                            _ => false,
+                        }
+                })
+            };
+
+            if !wrapper_mode && should_describe_lints() {
+                describe_lints();
+                exit(0);
+            }
+
             // this conditional check for the --sysroot flag is there so users can call
             // `clippy_driver` directly
             // without having to pass --sysroot or anything
diff --git a/src/lintlist/lint.rs b/src/lintlist/lint.rs
new file mode 100644
index 00000000000..c817d83b33a
--- /dev/null
+++ b/src/lintlist/lint.rs
@@ -0,0 +1,27 @@
+/// Lint data parsed from the Clippy source code.
+#[derive(Clone, PartialEq, Debug)]
+pub struct Lint {
+    pub name: &'static str,
+    pub group: &'static str,
+    pub desc: &'static str,
+    pub deprecation: Option<&'static str>,
+    pub module: &'static str,
+}
+
+#[derive(PartialOrd, PartialEq, Ord, Eq)]
+pub enum Level {
+    Allow,
+    Warn,
+    Deny,
+}
+
+pub const LINT_LEVELS: [(&str, Level); 8] = [
+    ("correctness", Level::Deny),
+    ("style", Level::Warn),
+    ("complexity", Level::Warn),
+    ("perf", Level::Warn),
+    ("restriction", Level::Allow),
+    ("pedantic", Level::Allow),
+    ("nursery", Level::Allow),
+    ("cargo", Level::Allow),
+];
diff --git a/src/lintlist/mod.rs b/src/lintlist/mod.rs
new file mode 100644
index 00000000000..3317ccb5ed0
--- /dev/null
+++ b/src/lintlist/mod.rs
@@ -0,0 +1,2137 @@
+//! This file is managed by `util/dev update_lints`. Do not edit.
+
+pub mod lint;
+pub use lint::Level;
+pub use lint::Lint;
+pub use lint::LINT_LEVELS;
+
+pub const ALL_LINTS: [Lint; 304] = [
+    Lint {
+        name: "absurd_extreme_comparisons",
+        group: "correctness",
+        desc: "a comparison with a maximum or minimum value that is always true or false",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "almost_swapped",
+        group: "correctness",
+        desc: "`foo = bar; bar = foo` sequence",
+        deprecation: None,
+        module: "swap",
+    },
+    Lint {
+        name: "approx_constant",
+        group: "correctness",
+        desc: "the approximate of a known float constant (in `std::fXX::consts`)",
+        deprecation: None,
+        module: "approx_const",
+    },
+    Lint {
+        name: "assertions_on_constants",
+        group: "style",
+        desc: "`assert!(true)` / `assert!(false)` will be optimized out by the compiler, and should probably be replaced by a `panic!()` or `unreachable!()`",
+        deprecation: None,
+        module: "assertions_on_constants",
+    },
+    Lint {
+        name: "assign_op_pattern",
+        group: "style",
+        desc: "assigning the result of an operation on a variable to that same variable",
+        deprecation: None,
+        module: "assign_ops",
+    },
+    Lint {
+        name: "bad_bit_mask",
+        group: "correctness",
+        desc: "expressions of the form `_ & mask == select` that will only ever return `true` or `false`",
+        deprecation: None,
+        module: "bit_mask",
+    },
+    Lint {
+        name: "blacklisted_name",
+        group: "style",
+        desc: "usage of a blacklisted/placeholder name",
+        deprecation: None,
+        module: "blacklisted_name",
+    },
+    Lint {
+        name: "block_in_if_condition_expr",
+        group: "style",
+        desc: "braces that can be eliminated in conditions, e.g., `if { true } ...`",
+        deprecation: None,
+        module: "block_in_if_condition",
+    },
+    Lint {
+        name: "block_in_if_condition_stmt",
+        group: "style",
+        desc: "complex blocks in conditions, e.g., `if { let x = true; x } ...`",
+        deprecation: None,
+        module: "block_in_if_condition",
+    },
+    Lint {
+        name: "bool_comparison",
+        group: "complexity",
+        desc: "comparing a variable to a boolean, e.g., `if x == true` or `if x != true`",
+        deprecation: None,
+        module: "needless_bool",
+    },
+    Lint {
+        name: "borrow_interior_mutable_const",
+        group: "correctness",
+        desc: "referencing const with interior mutability",
+        deprecation: None,
+        module: "non_copy_const",
+    },
+    Lint {
+        name: "borrowed_box",
+        group: "complexity",
+        desc: "a borrow of a boxed type",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "box_vec",
+        group: "perf",
+        desc: "usage of `Box<Vec<T>>`, vector elements are already on the heap",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "boxed_local",
+        group: "perf",
+        desc: "using `Box<T>` where unnecessary",
+        deprecation: None,
+        module: "escape",
+    },
+    Lint {
+        name: "builtin_type_shadow",
+        group: "style",
+        desc: "shadowing a builtin type",
+        deprecation: None,
+        module: "misc_early",
+    },
+    Lint {
+        name: "cargo_common_metadata",
+        group: "cargo",
+        desc: "common metadata is defined in `Cargo.toml`",
+        deprecation: None,
+        module: "cargo_common_metadata",
+    },
+    Lint {
+        name: "cast_lossless",
+        group: "complexity",
+        desc: "casts using `as` that are known to be lossless, e.g., `x as u64` where `x: u8`",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "cast_possible_truncation",
+        group: "pedantic",
+        desc: "casts that may cause truncation of the value, e.g., `x as u8` where `x: u32`, or `x as i32` where `x: f32`",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "cast_possible_wrap",
+        group: "pedantic",
+        desc: "casts that may cause wrapping around the value, e.g., `x as i32` where `x: u32` and `x > i32::MAX`",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "cast_precision_loss",
+        group: "pedantic",
+        desc: "casts that cause loss of precision, e.g., `x as f32` where `x: u64`",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "cast_ptr_alignment",
+        group: "correctness",
+        desc: "cast from a pointer to a more-strictly-aligned pointer",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "cast_ref_to_mut",
+        group: "correctness",
+        desc: "a cast of reference to a mutable pointer",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "cast_sign_loss",
+        group: "pedantic",
+        desc: "casts from signed types to unsigned types, e.g., `x as u32` where `x: i32`",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "char_lit_as_u8",
+        group: "complexity",
+        desc: "casting a character literal to u8",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "chars_last_cmp",
+        group: "style",
+        desc: "using `.chars().last()` or `.chars().next_back()` to check if a string ends with a char",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "chars_next_cmp",
+        group: "complexity",
+        desc: "using `.chars().next()` to check if a string starts with a char",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "checked_conversions",
+        group: "pedantic",
+        desc: "`try_from` could replace manual bounds checking when casting",
+        deprecation: None,
+        module: "checked_conversions",
+    },
+    Lint {
+        name: "clone_double_ref",
+        group: "correctness",
+        desc: "using `clone` on `&&T`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "clone_on_copy",
+        group: "complexity",
+        desc: "using `clone` on a `Copy` type",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "clone_on_ref_ptr",
+        group: "restriction",
+        desc: "using \'clone\' on a ref-counted pointer",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "cmp_nan",
+        group: "correctness",
+        desc: "comparisons to NAN, which will always return false, probably not intended",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "cmp_null",
+        group: "style",
+        desc: "comparing a pointer to a null pointer, suggesting to use `.is_null()` instead.",
+        deprecation: None,
+        module: "ptr",
+    },
+    Lint {
+        name: "cmp_owned",
+        group: "perf",
+        desc: "creating owned instances for comparing with others, e.g., `x == \"foo\".to_string()`",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "cognitive_complexity",
+        group: "complexity",
+        desc: "functions that should be split up into multiple functions",
+        deprecation: None,
+        module: "cognitive_complexity",
+    },
+    Lint {
+        name: "collapsible_if",
+        group: "style",
+        desc: "`if`s that can be collapsed (e.g., `if x { if y { ... } }` and `else { if x { ... } }`)",
+        deprecation: None,
+        module: "collapsible_if",
+    },
+    Lint {
+        name: "const_static_lifetime",
+        group: "style",
+        desc: "Using explicit `\'static` lifetime for constants when elision rules would allow omitting them.",
+        deprecation: None,
+        module: "const_static_lifetime",
+    },
+    Lint {
+        name: "copy_iterator",
+        group: "pedantic",
+        desc: "implementing `Iterator` on a `Copy` type",
+        deprecation: None,
+        module: "copy_iterator",
+    },
+    Lint {
+        name: "crosspointer_transmute",
+        group: "complexity",
+        desc: "transmutes that have to or from types that are a pointer to the other",
+        deprecation: None,
+        module: "transmute",
+    },
+    Lint {
+        name: "dbg_macro",
+        group: "restriction",
+        desc: "`dbg!` macro is intended as a debugging tool",
+        deprecation: None,
+        module: "dbg_macro",
+    },
+    Lint {
+        name: "decimal_literal_representation",
+        group: "restriction",
+        desc: "using decimal representation when hexadecimal would be better",
+        deprecation: None,
+        module: "literal_representation",
+    },
+    Lint {
+        name: "declare_interior_mutable_const",
+        group: "correctness",
+        desc: "declaring const with interior mutability",
+        deprecation: None,
+        module: "non_copy_const",
+    },
+    Lint {
+        name: "default_trait_access",
+        group: "pedantic",
+        desc: "checks for literal calls to Default::default()",
+        deprecation: None,
+        module: "default_trait_access",
+    },
+    Lint {
+        name: "deprecated_cfg_attr",
+        group: "complexity",
+        desc: "usage of `cfg_attr(rustfmt)` instead of `tool_attributes`",
+        deprecation: None,
+        module: "attrs",
+    },
+    Lint {
+        name: "deprecated_semver",
+        group: "correctness",
+        desc: "use of `#[deprecated(since = \"x\")]` where x is not semver",
+        deprecation: None,
+        module: "attrs",
+    },
+    Lint {
+        name: "deref_addrof",
+        group: "complexity",
+        desc: "use of `*&` or `*&mut` in an expression",
+        deprecation: None,
+        module: "reference",
+    },
+    Lint {
+        name: "derive_hash_xor_eq",
+        group: "correctness",
+        desc: "deriving `Hash` but implementing `PartialEq` explicitly",
+        deprecation: None,
+        module: "derive",
+    },
+    Lint {
+        name: "diverging_sub_expression",
+        group: "complexity",
+        desc: "whether an expression contains a diverging sub expression",
+        deprecation: None,
+        module: "eval_order_dependence",
+    },
+    Lint {
+        name: "doc_markdown",
+        group: "pedantic",
+        desc: "presence of `_`, `::` or camel-case outside backticks in documentation",
+        deprecation: None,
+        module: "doc",
+    },
+    Lint {
+        name: "double_comparisons",
+        group: "complexity",
+        desc: "unnecessary double comparisons that can be simplified",
+        deprecation: None,
+        module: "double_comparison",
+    },
+    Lint {
+        name: "double_neg",
+        group: "style",
+        desc: "`--x`, which is a double negation of `x` and not a pre-decrement as in C/C++",
+        deprecation: None,
+        module: "misc_early",
+    },
+    Lint {
+        name: "double_parens",
+        group: "complexity",
+        desc: "Warn on unnecessary double parentheses",
+        deprecation: None,
+        module: "double_parens",
+    },
+    Lint {
+        name: "drop_bounds",
+        group: "correctness",
+        desc: "Bounds of the form `T: Drop` are useless",
+        deprecation: None,
+        module: "drop_bounds",
+    },
+    Lint {
+        name: "drop_copy",
+        group: "correctness",
+        desc: "calls to `std::mem::drop` with a value that implements Copy",
+        deprecation: None,
+        module: "drop_forget_ref",
+    },
+    Lint {
+        name: "drop_ref",
+        group: "correctness",
+        desc: "calls to `std::mem::drop` with a reference instead of an owned value",
+        deprecation: None,
+        module: "drop_forget_ref",
+    },
+    Lint {
+        name: "duplicate_underscore_argument",
+        group: "style",
+        desc: "function arguments having names which only differ by an underscore",
+        deprecation: None,
+        module: "misc_early",
+    },
+    Lint {
+        name: "duration_subsec",
+        group: "complexity",
+        desc: "checks for calculation of subsecond microseconds or milliseconds",
+        deprecation: None,
+        module: "duration_subsec",
+    },
+    Lint {
+        name: "else_if_without_else",
+        group: "restriction",
+        desc: "if expression with an `else if`, but without a final `else` branch",
+        deprecation: None,
+        module: "else_if_without_else",
+    },
+    Lint {
+        name: "empty_enum",
+        group: "pedantic",
+        desc: "enum with no variants",
+        deprecation: None,
+        module: "empty_enum",
+    },
+    Lint {
+        name: "empty_line_after_outer_attr",
+        group: "nursery",
+        desc: "empty line after outer attribute",
+        deprecation: None,
+        module: "attrs",
+    },
+    Lint {
+        name: "empty_loop",
+        group: "style",
+        desc: "empty `loop {}`, which should block or sleep",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "enum_clike_unportable_variant",
+        group: "correctness",
+        desc: "C-like enums that are `repr(isize/usize)` and have values that don\'t fit into an `i32`",
+        deprecation: None,
+        module: "enum_clike",
+    },
+    Lint {
+        name: "enum_glob_use",
+        group: "pedantic",
+        desc: "use items that import all variants of an enum",
+        deprecation: None,
+        module: "enum_glob_use",
+    },
+    Lint {
+        name: "enum_variant_names",
+        group: "style",
+        desc: "enums where all variants share a prefix/postfix",
+        deprecation: None,
+        module: "enum_variants",
+    },
+    Lint {
+        name: "eq_op",
+        group: "correctness",
+        desc: "equal operands on both sides of a comparison or bitwise combination (e.g., `x == x`)",
+        deprecation: None,
+        module: "eq_op",
+    },
+    Lint {
+        name: "erasing_op",
+        group: "correctness",
+        desc: "using erasing operations, e.g., `x * 0` or `y & 0`",
+        deprecation: None,
+        module: "erasing_op",
+    },
+    Lint {
+        name: "eval_order_dependence",
+        group: "complexity",
+        desc: "whether a variable read occurs before a write depends on sub-expression evaluation order",
+        deprecation: None,
+        module: "eval_order_dependence",
+    },
+    Lint {
+        name: "excessive_precision",
+        group: "style",
+        desc: "excessive precision for float literal",
+        deprecation: None,
+        module: "excessive_precision",
+    },
+    Lint {
+        name: "expect_fun_call",
+        group: "perf",
+        desc: "using any `expect` method with a function call",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "expl_impl_clone_on_copy",
+        group: "pedantic",
+        desc: "implementing `Clone` explicitly on `Copy` types",
+        deprecation: None,
+        module: "derive",
+    },
+    Lint {
+        name: "explicit_counter_loop",
+        group: "complexity",
+        desc: "for-looping with an explicit counter when `_.enumerate()` would do",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "explicit_into_iter_loop",
+        group: "pedantic",
+        desc: "for-looping over `_.into_iter()` when `_` would do",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "explicit_iter_loop",
+        group: "pedantic",
+        desc: "for-looping over `_.iter()` or `_.iter_mut()` when `&_` or `&mut _` would do",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "explicit_write",
+        group: "complexity",
+        desc: "using the `write!()` family of functions instead of the `print!()` family of functions, when using the latter would work",
+        deprecation: None,
+        module: "explicit_write",
+    },
+    Lint {
+        name: "extra_unused_lifetimes",
+        group: "complexity",
+        desc: "unused lifetimes in function definitions",
+        deprecation: None,
+        module: "lifetimes",
+    },
+    Lint {
+        name: "fallible_impl_from",
+        group: "nursery",
+        desc: "Warn on impls of `From<..>` that contain `panic!()` or `unwrap()`",
+        deprecation: None,
+        module: "fallible_impl_from",
+    },
+    Lint {
+        name: "filter_map",
+        group: "pedantic",
+        desc: "using combinations of `filter`, `map`, `filter_map` and `flat_map` which can usually be written as a single method call",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "filter_map_next",
+        group: "pedantic",
+        desc: "using combination of `filter_map` and `next` which can usually be written as a single method call",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "filter_next",
+        group: "complexity",
+        desc: "using `filter(p).next()`, which is more succinctly expressed as `.find(p)`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "find_map",
+        group: "pedantic",
+        desc: "using a combination of `find` and `map` can usually be written as a single method call",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "float_arithmetic",
+        group: "restriction",
+        desc: "any floating-point arithmetic statement",
+        deprecation: None,
+        module: "arithmetic",
+    },
+    Lint {
+        name: "float_cmp",
+        group: "correctness",
+        desc: "using `==` or `!=` on float values instead of comparing difference with an epsilon",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "float_cmp_const",
+        group: "restriction",
+        desc: "using `==` or `!=` on float constants instead of comparing difference with an epsilon",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "fn_to_numeric_cast",
+        group: "style",
+        desc: "casting a function pointer to a numeric type other than usize",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "fn_to_numeric_cast_with_truncation",
+        group: "style",
+        desc: "casting a function pointer to a numeric type not wide enough to store the address",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "for_kv_map",
+        group: "style",
+        desc: "looping on a map using `iter` when `keys` or `values` would do",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "for_loop_over_option",
+        group: "correctness",
+        desc: "for-looping over an `Option`, which is more clearly expressed as an `if let`",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "for_loop_over_result",
+        group: "correctness",
+        desc: "for-looping over a `Result`, which is more clearly expressed as an `if let`",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "forget_copy",
+        group: "correctness",
+        desc: "calls to `std::mem::forget` with a value that implements Copy",
+        deprecation: None,
+        module: "drop_forget_ref",
+    },
+    Lint {
+        name: "forget_ref",
+        group: "correctness",
+        desc: "calls to `std::mem::forget` with a reference instead of an owned value",
+        deprecation: None,
+        module: "drop_forget_ref",
+    },
+    Lint {
+        name: "get_last_with_len",
+        group: "complexity",
+        desc: "Using `x.get(x.len() - 1)` when `x.last()` is correct and simpler",
+        deprecation: None,
+        module: "get_last_with_len",
+    },
+    Lint {
+        name: "get_unwrap",
+        group: "restriction",
+        desc: "using `.get().unwrap()` or `.get_mut().unwrap()` when using `[]` would work instead",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "identity_conversion",
+        group: "complexity",
+        desc: "using always-identical `Into`/`From`/`IntoIter` conversions",
+        deprecation: None,
+        module: "identity_conversion",
+    },
+    Lint {
+        name: "identity_op",
+        group: "complexity",
+        desc: "using identity operations, e.g., `x + 0` or `y / 1`",
+        deprecation: None,
+        module: "identity_op",
+    },
+    Lint {
+        name: "if_let_some_result",
+        group: "style",
+        desc: "usage of `ok()` in `if let Some(pat)` statements is unnecessary, match on `Ok(pat)` instead",
+        deprecation: None,
+        module: "ok_if_let",
+    },
+    Lint {
+        name: "if_not_else",
+        group: "pedantic",
+        desc: "`if` branches that could be swapped so no negation operation is necessary on the condition",
+        deprecation: None,
+        module: "if_not_else",
+    },
+    Lint {
+        name: "if_same_then_else",
+        group: "correctness",
+        desc: "if with the same *then* and *else* blocks",
+        deprecation: None,
+        module: "copies",
+    },
+    Lint {
+        name: "ifs_same_cond",
+        group: "correctness",
+        desc: "consecutive `ifs` with the same condition",
+        deprecation: None,
+        module: "copies",
+    },
+    Lint {
+        name: "implicit_hasher",
+        group: "style",
+        desc: "missing generalization over different hashers",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "implicit_return",
+        group: "restriction",
+        desc: "use a return statement like `return expr` instead of an expression",
+        deprecation: None,
+        module: "implicit_return",
+    },
+    Lint {
+        name: "inconsistent_digit_grouping",
+        group: "style",
+        desc: "integer literals with digits grouped inconsistently",
+        deprecation: None,
+        module: "literal_representation",
+    },
+    Lint {
+        name: "indexing_slicing",
+        group: "restriction",
+        desc: "indexing/slicing usage",
+        deprecation: None,
+        module: "indexing_slicing",
+    },
+    Lint {
+        name: "ineffective_bit_mask",
+        group: "correctness",
+        desc: "expressions where a bit mask will be rendered useless by a comparison, e.g., `(x | 1) > 2`",
+        deprecation: None,
+        module: "bit_mask",
+    },
+    Lint {
+        name: "infallible_destructuring_match",
+        group: "style",
+        desc: "a match statement with a single infallible arm instead of a `let`",
+        deprecation: None,
+        module: "infallible_destructuring_match",
+    },
+    Lint {
+        name: "infinite_iter",
+        group: "correctness",
+        desc: "infinite iteration",
+        deprecation: None,
+        module: "infinite_iter",
+    },
+    Lint {
+        name: "inline_always",
+        group: "pedantic",
+        desc: "use of `#[inline(always)]`",
+        deprecation: None,
+        module: "attrs",
+    },
+    Lint {
+        name: "inline_fn_without_body",
+        group: "correctness",
+        desc: "use of `#[inline]` on trait methods without bodies",
+        deprecation: None,
+        module: "inline_fn_without_body",
+    },
+    Lint {
+        name: "int_plus_one",
+        group: "complexity",
+        desc: "instead of using x >= y + 1, use x > y",
+        deprecation: None,
+        module: "int_plus_one",
+    },
+    Lint {
+        name: "integer_arithmetic",
+        group: "restriction",
+        desc: "any integer arithmetic statement",
+        deprecation: None,
+        module: "arithmetic",
+    },
+    Lint {
+        name: "into_iter_on_array",
+        group: "correctness",
+        desc: "using `.into_iter()` on an array",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "into_iter_on_ref",
+        group: "style",
+        desc: "using `.into_iter()` on a reference",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "invalid_ref",
+        group: "correctness",
+        desc: "creation of invalid reference",
+        deprecation: None,
+        module: "invalid_ref",
+    },
+    Lint {
+        name: "invalid_regex",
+        group: "correctness",
+        desc: "invalid regular expressions",
+        deprecation: None,
+        module: "regex",
+    },
+    Lint {
+        name: "invalid_upcast_comparisons",
+        group: "pedantic",
+        desc: "a comparison involving an upcast which is always true or false",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "items_after_statements",
+        group: "pedantic",
+        desc: "blocks where an item comes after a statement",
+        deprecation: None,
+        module: "items_after_statements",
+    },
+    Lint {
+        name: "iter_cloned_collect",
+        group: "style",
+        desc: "using `.cloned().collect()` on slice to create a `Vec`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "iter_next_loop",
+        group: "correctness",
+        desc: "for-looping over `_.next()` which is probably not intended",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "iter_nth",
+        group: "perf",
+        desc: "using `.iter().nth()` on a standard library type with O(1) element access",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "iter_skip_next",
+        group: "style",
+        desc: "using `.skip(x).next()` on an iterator",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "iterator_step_by_zero",
+        group: "correctness",
+        desc: "using `Iterator::step_by(0)`, which produces an infinite iterator",
+        deprecation: None,
+        module: "ranges",
+    },
+    Lint {
+        name: "just_underscores_and_digits",
+        group: "style",
+        desc: "unclear name",
+        deprecation: None,
+        module: "non_expressive_names",
+    },
+    Lint {
+        name: "large_digit_groups",
+        group: "pedantic",
+        desc: "grouping digits into groups that are too large",
+        deprecation: None,
+        module: "literal_representation",
+    },
+    Lint {
+        name: "large_enum_variant",
+        group: "perf",
+        desc: "large size difference between variants on an enum",
+        deprecation: None,
+        module: "large_enum_variant",
+    },
+    Lint {
+        name: "len_without_is_empty",
+        group: "style",
+        desc: "traits or impls with a public `len` method but no corresponding `is_empty` method",
+        deprecation: None,
+        module: "len_zero",
+    },
+    Lint {
+        name: "len_zero",
+        group: "style",
+        desc: "checking `.len() == 0` or `.len() > 0` (or similar) when `.is_empty()` could be used instead",
+        deprecation: None,
+        module: "len_zero",
+    },
+    Lint {
+        name: "let_and_return",
+        group: "style",
+        desc: "creating a let-binding and then immediately returning it like `let x = expr; x` at the end of a block",
+        deprecation: None,
+        module: "returns",
+    },
+    Lint {
+        name: "let_unit_value",
+        group: "style",
+        desc: "creating a let binding to a value of unit type, which usually can\'t be used afterwards",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "linkedlist",
+        group: "pedantic",
+        desc: "usage of LinkedList, usually a vector is faster, or a more specialized data structure like a VecDeque",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "logic_bug",
+        group: "correctness",
+        desc: "boolean expressions that contain terminals which can be eliminated",
+        deprecation: None,
+        module: "booleans",
+    },
+    Lint {
+        name: "manual_memcpy",
+        group: "perf",
+        desc: "manually copying items between slices",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "manual_swap",
+        group: "complexity",
+        desc: "manual swap of two variables",
+        deprecation: None,
+        module: "swap",
+    },
+    Lint {
+        name: "many_single_char_names",
+        group: "style",
+        desc: "too many single character bindings",
+        deprecation: None,
+        module: "non_expressive_names",
+    },
+    Lint {
+        name: "map_clone",
+        group: "style",
+        desc: "using `iterator.map(|x| x.clone())`, or dereferencing closures for `Copy` types",
+        deprecation: None,
+        module: "map_clone",
+    },
+    Lint {
+        name: "map_entry",
+        group: "perf",
+        desc: "use of `contains_key` followed by `insert` on a `HashMap` or `BTreeMap`",
+        deprecation: None,
+        module: "entry",
+    },
+    Lint {
+        name: "map_flatten",
+        group: "pedantic",
+        desc: "using combinations of `flatten` and `map` which can usually be written as a single method call",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "match_as_ref",
+        group: "complexity",
+        desc: "a match on an Option value instead of using `as_ref()` or `as_mut`",
+        deprecation: None,
+        module: "matches",
+    },
+    Lint {
+        name: "match_bool",
+        group: "style",
+        desc: "a match on a boolean expression instead of an `if..else` block",
+        deprecation: None,
+        module: "matches",
+    },
+    Lint {
+        name: "match_overlapping_arm",
+        group: "style",
+        desc: "a match with overlapping arms",
+        deprecation: None,
+        module: "matches",
+    },
+    Lint {
+        name: "match_ref_pats",
+        group: "style",
+        desc: "a match or `if let` with all arms prefixed with `&` instead of deref-ing the match expression",
+        deprecation: None,
+        module: "matches",
+    },
+    Lint {
+        name: "match_same_arms",
+        group: "pedantic",
+        desc: "`match` with identical arm bodies",
+        deprecation: None,
+        module: "copies",
+    },
+    Lint {
+        name: "match_wild_err_arm",
+        group: "style",
+        desc: "a match with `Err(_)` arm and take drastic actions",
+        deprecation: None,
+        module: "matches",
+    },
+    Lint {
+        name: "maybe_infinite_iter",
+        group: "pedantic",
+        desc: "possible infinite iteration",
+        deprecation: None,
+        module: "infinite_iter",
+    },
+    Lint {
+        name: "mem_discriminant_non_enum",
+        group: "correctness",
+        desc: "calling mem::descriminant on non-enum type",
+        deprecation: None,
+        module: "mem_discriminant",
+    },
+    Lint {
+        name: "mem_forget",
+        group: "restriction",
+        desc: "`mem::forget` usage on `Drop` types, likely to cause memory leaks",
+        deprecation: None,
+        module: "mem_forget",
+    },
+    Lint {
+        name: "mem_replace_option_with_none",
+        group: "style",
+        desc: "replacing an `Option` with `None` instead of `take()`",
+        deprecation: None,
+        module: "mem_replace",
+    },
+    Lint {
+        name: "min_max",
+        group: "correctness",
+        desc: "`min(_, max(_, _))` (or vice versa) with bounds clamping the result to a constant",
+        deprecation: None,
+        module: "minmax",
+    },
+    Lint {
+        name: "misrefactored_assign_op",
+        group: "complexity",
+        desc: "having a variable on both sides of an assign op",
+        deprecation: None,
+        module: "assign_ops",
+    },
+    Lint {
+        name: "missing_const_for_fn",
+        group: "nursery",
+        desc: "Lint functions definitions that could be made `const fn`",
+        deprecation: None,
+        module: "missing_const_for_fn",
+    },
+    Lint {
+        name: "missing_docs_in_private_items",
+        group: "restriction",
+        desc: "detects missing documentation for public and private members",
+        deprecation: None,
+        module: "missing_doc",
+    },
+    Lint {
+        name: "missing_inline_in_public_items",
+        group: "restriction",
+        desc: "detects missing #[inline] attribute for public callables (functions, trait methods, methods...)",
+        deprecation: None,
+        module: "missing_inline",
+    },
+    Lint {
+        name: "mistyped_literal_suffixes",
+        group: "correctness",
+        desc: "mistyped literal suffix",
+        deprecation: None,
+        module: "literal_representation",
+    },
+    Lint {
+        name: "mixed_case_hex_literals",
+        group: "style",
+        desc: "hex literals whose letter digits are not consistently upper- or lowercased",
+        deprecation: None,
+        module: "misc_early",
+    },
+    Lint {
+        name: "module_inception",
+        group: "style",
+        desc: "modules that have the same name as their parent module",
+        deprecation: None,
+        module: "enum_variants",
+    },
+    Lint {
+        name: "module_name_repetitions",
+        group: "pedantic",
+        desc: "type names prefixed/postfixed with their containing module\'s name",
+        deprecation: None,
+        module: "enum_variants",
+    },
+    Lint {
+        name: "modulo_one",
+        group: "correctness",
+        desc: "taking a number modulo 1, which always returns 0",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "multiple_crate_versions",
+        group: "cargo",
+        desc: "multiple versions of the same crate being used",
+        deprecation: None,
+        module: "multiple_crate_versions",
+    },
+    Lint {
+        name: "multiple_inherent_impl",
+        group: "restriction",
+        desc: "Multiple inherent impl that could be grouped",
+        deprecation: None,
+        module: "inherent_impl",
+    },
+    Lint {
+        name: "mut_from_ref",
+        group: "correctness",
+        desc: "fns that create mutable refs from immutable ref args",
+        deprecation: None,
+        module: "ptr",
+    },
+    Lint {
+        name: "mut_mut",
+        group: "pedantic",
+        desc: "usage of double-mut refs, e.g., `&mut &mut ...`",
+        deprecation: None,
+        module: "mut_mut",
+    },
+    Lint {
+        name: "mut_range_bound",
+        group: "complexity",
+        desc: "for loop over a range where one of the bounds is a mutable variable",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "mutex_atomic",
+        group: "perf",
+        desc: "using a mutex where an atomic value could be used instead",
+        deprecation: None,
+        module: "mutex_atomic",
+    },
+    Lint {
+        name: "mutex_integer",
+        group: "nursery",
+        desc: "using a mutex for an integer type",
+        deprecation: None,
+        module: "mutex_atomic",
+    },
+    Lint {
+        name: "naive_bytecount",
+        group: "perf",
+        desc: "use of naive `<slice>.filter(|&x| x == y).count()` to count byte values",
+        deprecation: None,
+        module: "bytecount",
+    },
+    Lint {
+        name: "needless_bool",
+        group: "complexity",
+        desc: "if-statements with plain booleans in the then- and else-clause, e.g., `if p { true } else { false }`",
+        deprecation: None,
+        module: "needless_bool",
+    },
+    Lint {
+        name: "needless_borrow",
+        group: "nursery",
+        desc: "taking a reference that is going to be automatically dereferenced",
+        deprecation: None,
+        module: "needless_borrow",
+    },
+    Lint {
+        name: "needless_borrowed_reference",
+        group: "complexity",
+        desc: "taking a needless borrowed reference",
+        deprecation: None,
+        module: "needless_borrowed_ref",
+    },
+    Lint {
+        name: "needless_collect",
+        group: "perf",
+        desc: "collecting an iterator when collect is not needed",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "needless_continue",
+        group: "pedantic",
+        desc: "`continue` statements that can be replaced by a rearrangement of code",
+        deprecation: None,
+        module: "needless_continue",
+    },
+    Lint {
+        name: "needless_lifetimes",
+        group: "complexity",
+        desc: "using explicit lifetimes for references in function arguments when elision rules would allow omitting them",
+        deprecation: None,
+        module: "lifetimes",
+    },
+    Lint {
+        name: "needless_pass_by_value",
+        group: "pedantic",
+        desc: "functions taking arguments by value, but not consuming them in its body",
+        deprecation: None,
+        module: "needless_pass_by_value",
+    },
+    Lint {
+        name: "needless_range_loop",
+        group: "style",
+        desc: "for-looping over a range of indices where an iterator over items would do",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "needless_return",
+        group: "style",
+        desc: "using a return statement like `return expr;` where an expression would suffice",
+        deprecation: None,
+        module: "returns",
+    },
+    Lint {
+        name: "needless_update",
+        group: "complexity",
+        desc: "using `Foo { ..base }` when there are no missing fields",
+        deprecation: None,
+        module: "needless_update",
+    },
+    Lint {
+        name: "neg_cmp_op_on_partial_ord",
+        group: "complexity",
+        desc: "The use of negated comparison operators on partially ordered types may produce confusing code.",
+        deprecation: None,
+        module: "neg_cmp_op_on_partial_ord",
+    },
+    Lint {
+        name: "neg_multiply",
+        group: "style",
+        desc: "multiplying integers with -1",
+        deprecation: None,
+        module: "neg_multiply",
+    },
+    Lint {
+        name: "never_loop",
+        group: "correctness",
+        desc: "any loop that will always `break` or `return`",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "new_ret_no_self",
+        group: "style",
+        desc: "not returning `Self` in a `new` method",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "new_without_default",
+        group: "style",
+        desc: "`fn new() -> Self` method without `Default` implementation",
+        deprecation: None,
+        module: "new_without_default",
+    },
+    Lint {
+        name: "no_effect",
+        group: "complexity",
+        desc: "statements with no effect",
+        deprecation: None,
+        module: "no_effect",
+    },
+    Lint {
+        name: "non_ascii_literal",
+        group: "pedantic",
+        desc: "using any literal non-ASCII chars in a string literal instead of using the `\\\\u` escape",
+        deprecation: None,
+        module: "unicode",
+    },
+    Lint {
+        name: "nonminimal_bool",
+        group: "complexity",
+        desc: "boolean expressions that can be written more concisely",
+        deprecation: None,
+        module: "booleans",
+    },
+    Lint {
+        name: "nonsensical_open_options",
+        group: "correctness",
+        desc: "nonsensical combination of options for opening a file",
+        deprecation: None,
+        module: "open_options",
+    },
+    Lint {
+        name: "not_unsafe_ptr_arg_deref",
+        group: "correctness",
+        desc: "public functions dereferencing raw pointer arguments but not marked `unsafe`",
+        deprecation: None,
+        module: "functions",
+    },
+    Lint {
+        name: "ok_expect",
+        group: "style",
+        desc: "using `ok().expect()`, which gives worse error messages than calling `expect` directly on the Result",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "op_ref",
+        group: "style",
+        desc: "taking a reference to satisfy the type constraints on `==`",
+        deprecation: None,
+        module: "eq_op",
+    },
+    Lint {
+        name: "option_map_or_none",
+        group: "style",
+        desc: "using `Option.map_or(None, f)`, which is more succinctly expressed as `and_then(f)`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "option_map_unit_fn",
+        group: "complexity",
+        desc: "using `option.map(f)`, where f is a function or closure that returns ()",
+        deprecation: None,
+        module: "map_unit_fn",
+    },
+    Lint {
+        name: "option_map_unwrap_or",
+        group: "pedantic",
+        desc: "using `Option.map(f).unwrap_or(a)`, which is more succinctly expressed as `map_or(a, f)`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "option_map_unwrap_or_else",
+        group: "pedantic",
+        desc: "using `Option.map(f).unwrap_or_else(g)`, which is more succinctly expressed as `map_or_else(g, f)`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "option_option",
+        group: "complexity",
+        desc: "usage of `Option<Option<T>>`",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "option_unwrap_used",
+        group: "restriction",
+        desc: "using `Option.unwrap()`, which should at least get a better message using `expect()`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "or_fun_call",
+        group: "perf",
+        desc: "using any `*or` method with a function call, which suggests `*or_else`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "out_of_bounds_indexing",
+        group: "correctness",
+        desc: "out of bounds constant indexing",
+        deprecation: None,
+        module: "indexing_slicing",
+    },
+    Lint {
+        name: "overflow_check_conditional",
+        group: "complexity",
+        desc: "overflow checks inspired by C which are likely to panic",
+        deprecation: None,
+        module: "overflow_check_conditional",
+    },
+    Lint {
+        name: "panic_params",
+        group: "style",
+        desc: "missing parameters in `panic!` calls",
+        deprecation: None,
+        module: "panic_unimplemented",
+    },
+    Lint {
+        name: "panicking_unwrap",
+        group: "nursery",
+        desc: "checks for calls of unwrap[_err]() that will always fail",
+        deprecation: None,
+        module: "unwrap",
+    },
+    Lint {
+        name: "partialeq_ne_impl",
+        group: "complexity",
+        desc: "re-implementing `PartialEq::ne`",
+        deprecation: None,
+        module: "partialeq_ne_impl",
+    },
+    Lint {
+        name: "path_buf_push_overwrite",
+        group: "nursery",
+        desc: "calling `push` with file system root on `PathBuf` can overwrite it",
+        deprecation: None,
+        module: "path_buf_push_overwrite",
+    },
+    Lint {
+        name: "possible_missing_comma",
+        group: "correctness",
+        desc: "possible missing comma in array",
+        deprecation: None,
+        module: "formatting",
+    },
+    Lint {
+        name: "precedence",
+        group: "complexity",
+        desc: "operations where precedence may be unclear",
+        deprecation: None,
+        module: "precedence",
+    },
+    Lint {
+        name: "print_literal",
+        group: "style",
+        desc: "printing a literal with a format string",
+        deprecation: None,
+        module: "write",
+    },
+    Lint {
+        name: "print_stdout",
+        group: "restriction",
+        desc: "printing on stdout",
+        deprecation: None,
+        module: "write",
+    },
+    Lint {
+        name: "print_with_newline",
+        group: "style",
+        desc: "using `print!()` with a format string that ends in a single newline",
+        deprecation: None,
+        module: "write",
+    },
+    Lint {
+        name: "println_empty_string",
+        group: "style",
+        desc: "using `println!(\"\")` with an empty string",
+        deprecation: None,
+        module: "write",
+    },
+    Lint {
+        name: "ptr_arg",
+        group: "style",
+        desc: "fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` instead, respectively",
+        deprecation: None,
+        module: "ptr",
+    },
+    Lint {
+        name: "ptr_offset_with_cast",
+        group: "complexity",
+        desc: "unneeded pointer offset cast",
+        deprecation: None,
+        module: "ptr_offset_with_cast",
+    },
+    Lint {
+        name: "pub_enum_variant_names",
+        group: "pedantic",
+        desc: "enums where all variants share a prefix/postfix",
+        deprecation: None,
+        module: "enum_variants",
+    },
+    Lint {
+        name: "question_mark",
+        group: "style",
+        desc: "checks for expressions that could be replaced by the question mark operator",
+        deprecation: None,
+        module: "question_mark",
+    },
+    Lint {
+        name: "range_minus_one",
+        group: "complexity",
+        desc: "`x..=(y-1)` reads better as `x..y`",
+        deprecation: None,
+        module: "ranges",
+    },
+    Lint {
+        name: "range_plus_one",
+        group: "complexity",
+        desc: "`x..(y+1)` reads better as `x..=y`",
+        deprecation: None,
+        module: "ranges",
+    },
+    Lint {
+        name: "range_zip_with_len",
+        group: "complexity",
+        desc: "zipping iterator with a range when `enumerate()` would do",
+        deprecation: None,
+        module: "ranges",
+    },
+    Lint {
+        name: "redundant_clone",
+        group: "nursery",
+        desc: "`clone()` of an owned value that is going to be dropped immediately",
+        deprecation: None,
+        module: "redundant_clone",
+    },
+    Lint {
+        name: "redundant_closure",
+        group: "style",
+        desc: "redundant closures, i.e., `|a| foo(a)` (which can be written as just `foo`)",
+        deprecation: None,
+        module: "eta_reduction",
+    },
+    Lint {
+        name: "redundant_closure_call",
+        group: "complexity",
+        desc: "throwaway closures called in the expression they are defined",
+        deprecation: None,
+        module: "misc_early",
+    },
+    Lint {
+        name: "redundant_closure_for_method_calls",
+        group: "pedantic",
+        desc: "redundant closures for method calls",
+        deprecation: None,
+        module: "eta_reduction",
+    },
+    Lint {
+        name: "redundant_field_names",
+        group: "style",
+        desc: "checks for fields in struct literals where shorthands could be used",
+        deprecation: None,
+        module: "redundant_field_names",
+    },
+    Lint {
+        name: "redundant_pattern",
+        group: "style",
+        desc: "using `name @ _` in a pattern",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "redundant_pattern_matching",
+        group: "style",
+        desc: "use the proper utility function avoiding an `if let`",
+        deprecation: None,
+        module: "redundant_pattern_matching",
+    },
+    Lint {
+        name: "ref_in_deref",
+        group: "complexity",
+        desc: "Use of reference in auto dereference expression.",
+        deprecation: None,
+        module: "reference",
+    },
+    Lint {
+        name: "regex_macro",
+        group: "style",
+        desc: "use of `regex!(_)` instead of `Regex::new(_)`",
+        deprecation: None,
+        module: "regex",
+    },
+    Lint {
+        name: "replace_consts",
+        group: "pedantic",
+        desc: "Lint usages of standard library `const`s that could be replaced by `const fn`s",
+        deprecation: None,
+        module: "replace_consts",
+    },
+    Lint {
+        name: "result_map_unit_fn",
+        group: "complexity",
+        desc: "using `result.map(f)`, where f is a function or closure that returns ()",
+        deprecation: None,
+        module: "map_unit_fn",
+    },
+    Lint {
+        name: "result_map_unwrap_or_else",
+        group: "pedantic",
+        desc: "using `Result.map(f).unwrap_or_else(g)`, which is more succinctly expressed as `.ok().map_or_else(g, f)`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "result_unwrap_used",
+        group: "restriction",
+        desc: "using `Result.unwrap()`, which might be better handled",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "reverse_range_loop",
+        group: "correctness",
+        desc: "iteration over an empty range, such as `10..0` or `5..5`",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "search_is_some",
+        group: "complexity",
+        desc: "using an iterator search followed by `is_some()`, which is more succinctly expressed as a call to `any()`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "serde_api_misuse",
+        group: "correctness",
+        desc: "various things that will negatively affect your serde experience",
+        deprecation: None,
+        module: "serde_api",
+    },
+    Lint {
+        name: "shadow_reuse",
+        group: "restriction",
+        desc: "rebinding a name to an expression that re-uses the original value, e.g., `let x = x + 1`",
+        deprecation: None,
+        module: "shadow",
+    },
+    Lint {
+        name: "shadow_same",
+        group: "restriction",
+        desc: "rebinding a name to itself, e.g., `let mut x = &mut x`",
+        deprecation: None,
+        module: "shadow",
+    },
+    Lint {
+        name: "shadow_unrelated",
+        group: "pedantic",
+        desc: "rebinding a name without even using the original value",
+        deprecation: None,
+        module: "shadow",
+    },
+    Lint {
+        name: "short_circuit_statement",
+        group: "complexity",
+        desc: "using a short circuit boolean condition as a statement",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "should_implement_trait",
+        group: "style",
+        desc: "defining a method that should be implementing a std trait",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "similar_names",
+        group: "pedantic",
+        desc: "similarly named items and bindings",
+        deprecation: None,
+        module: "non_expressive_names",
+    },
+    Lint {
+        name: "single_char_pattern",
+        group: "perf",
+        desc: "using a single-character str where a char could be used, e.g., `_.split(\"x\")`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "single_match",
+        group: "style",
+        desc: "a match statement with a single nontrivial arm (i.e., where the other arm is `_ => {}`) instead of `if let`",
+        deprecation: None,
+        module: "matches",
+    },
+    Lint {
+        name: "single_match_else",
+        group: "pedantic",
+        desc: "a match statement with a two arms where the second arm\'s pattern is a placeholder instead of a specific match pattern",
+        deprecation: None,
+        module: "matches",
+    },
+    Lint {
+        name: "slow_vector_initialization",
+        group: "perf",
+        desc: "slow vector initialization",
+        deprecation: None,
+        module: "slow_vector_initialization",
+    },
+    Lint {
+        name: "string_add",
+        group: "restriction",
+        desc: "using `x + ..` where x is a `String` instead of `push_str()`",
+        deprecation: None,
+        module: "strings",
+    },
+    Lint {
+        name: "string_add_assign",
+        group: "pedantic",
+        desc: "using `x = x + ..` where x is a `String` instead of `push_str()`",
+        deprecation: None,
+        module: "strings",
+    },
+    Lint {
+        name: "string_extend_chars",
+        group: "style",
+        desc: "using `x.extend(s.chars())` where s is a `&str` or `String`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "string_lit_as_bytes",
+        group: "style",
+        desc: "calling `as_bytes` on a string literal instead of using a byte string literal",
+        deprecation: None,
+        module: "strings",
+    },
+    Lint {
+        name: "suspicious_arithmetic_impl",
+        group: "correctness",
+        desc: "suspicious use of operators in impl of arithmetic trait",
+        deprecation: None,
+        module: "suspicious_trait_impl",
+    },
+    Lint {
+        name: "suspicious_assignment_formatting",
+        group: "style",
+        desc: "suspicious formatting of `*=`, `-=` or `!=`",
+        deprecation: None,
+        module: "formatting",
+    },
+    Lint {
+        name: "suspicious_else_formatting",
+        group: "style",
+        desc: "suspicious formatting of `else`",
+        deprecation: None,
+        module: "formatting",
+    },
+    Lint {
+        name: "suspicious_op_assign_impl",
+        group: "correctness",
+        desc: "suspicious use of operators in impl of OpAssign trait",
+        deprecation: None,
+        module: "suspicious_trait_impl",
+    },
+    Lint {
+        name: "temporary_assignment",
+        group: "complexity",
+        desc: "assignments to temporaries",
+        deprecation: None,
+        module: "temporary_assignment",
+    },
+    Lint {
+        name: "temporary_cstring_as_ptr",
+        group: "correctness",
+        desc: "getting the inner pointer of a temporary `CString`",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "too_many_arguments",
+        group: "complexity",
+        desc: "functions with too many arguments",
+        deprecation: None,
+        module: "functions",
+    },
+    Lint {
+        name: "too_many_lines",
+        group: "pedantic",
+        desc: "functions with too many lines",
+        deprecation: None,
+        module: "functions",
+    },
+    Lint {
+        name: "toplevel_ref_arg",
+        group: "style",
+        desc: "an entire binding declared as `ref`, in a function argument or a `let` statement",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "transmute_bytes_to_str",
+        group: "complexity",
+        desc: "transmutes from a `&[u8]` to a `&str`",
+        deprecation: None,
+        module: "transmute",
+    },
+    Lint {
+        name: "transmute_int_to_bool",
+        group: "complexity",
+        desc: "transmutes from an integer to a `bool`",
+        deprecation: None,
+        module: "transmute",
+    },
+    Lint {
+        name: "transmute_int_to_char",
+        group: "complexity",
+        desc: "transmutes from an integer to a `char`",
+        deprecation: None,
+        module: "transmute",
+    },
+    Lint {
+        name: "transmute_int_to_float",
+        group: "complexity",
+        desc: "transmutes from an integer to a float",
+        deprecation: None,
+        module: "transmute",
+    },
+    Lint {
+        name: "transmute_ptr_to_ptr",
+        group: "complexity",
+        desc: "transmutes from a pointer to a pointer / a reference to a reference",
+        deprecation: None,
+        module: "transmute",
+    },
+    Lint {
+        name: "transmute_ptr_to_ref",
+        group: "complexity",
+        desc: "transmutes from a pointer to a reference type",
+        deprecation: None,
+        module: "transmute",
+    },
+    Lint {
+        name: "transmuting_null",
+        group: "correctness",
+        desc: "transmutes from a null pointer to a reference, which is undefined behavior",
+        deprecation: None,
+        module: "transmuting_null",
+    },
+    Lint {
+        name: "trivial_regex",
+        group: "style",
+        desc: "trivial regular expressions",
+        deprecation: None,
+        module: "regex",
+    },
+    Lint {
+        name: "trivially_copy_pass_by_ref",
+        group: "perf",
+        desc: "functions taking small copyable arguments by reference",
+        deprecation: None,
+        module: "trivially_copy_pass_by_ref",
+    },
+    Lint {
+        name: "type_complexity",
+        group: "complexity",
+        desc: "usage of very complex types that might be better factored into `type` definitions",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "unicode_not_nfc",
+        group: "pedantic",
+        desc: "using a unicode literal not in NFC normal form (see [unicode tr15](http://www.unicode.org/reports/tr15/) for further information)",
+        deprecation: None,
+        module: "unicode",
+    },
+    Lint {
+        name: "unimplemented",
+        group: "restriction",
+        desc: "`unimplemented!` should not be present in production code",
+        deprecation: None,
+        module: "panic_unimplemented",
+    },
+    Lint {
+        name: "unit_arg",
+        group: "complexity",
+        desc: "passing unit to a function",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "unit_cmp",
+        group: "correctness",
+        desc: "comparing unit values",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "unknown_clippy_lints",
+        group: "style",
+        desc: "unknown_lints for scoped Clippy lints",
+        deprecation: None,
+        module: "attrs",
+    },
+    Lint {
+        name: "unnecessary_cast",
+        group: "complexity",
+        desc: "cast to the same type, e.g., `x as i32` where `x: i32`",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "unnecessary_filter_map",
+        group: "complexity",
+        desc: "using `filter_map` when a more succinct alternative exists",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "unnecessary_fold",
+        group: "style",
+        desc: "using `fold` when a more succinct alternative exists",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "unnecessary_mut_passed",
+        group: "style",
+        desc: "an argument passed as a mutable reference although the callee only demands an immutable reference",
+        deprecation: None,
+        module: "mut_reference",
+    },
+    Lint {
+        name: "unnecessary_operation",
+        group: "complexity",
+        desc: "outer expressions with no effect",
+        deprecation: None,
+        module: "no_effect",
+    },
+    Lint {
+        name: "unnecessary_unwrap",
+        group: "nursery",
+        desc: "checks for calls of unwrap[_err]() that cannot fail",
+        deprecation: None,
+        module: "unwrap",
+    },
+    Lint {
+        name: "unneeded_field_pattern",
+        group: "style",
+        desc: "struct fields bound to a wildcard instead of using `..`",
+        deprecation: None,
+        module: "misc_early",
+    },
+    Lint {
+        name: "unreadable_literal",
+        group: "style",
+        desc: "long integer literal without underscores",
+        deprecation: None,
+        module: "literal_representation",
+    },
+    Lint {
+        name: "unsafe_removed_from_name",
+        group: "style",
+        desc: "`unsafe` removed from API names on import",
+        deprecation: None,
+        module: "unsafe_removed_from_name",
+    },
+    Lint {
+        name: "unseparated_literal_suffix",
+        group: "pedantic",
+        desc: "literals whose suffix is not separated by an underscore",
+        deprecation: None,
+        module: "misc_early",
+    },
+    Lint {
+        name: "unused_collect",
+        group: "perf",
+        desc: "`collect()`ing an iterator without using the result; this is usually better written as a for loop",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "unused_io_amount",
+        group: "correctness",
+        desc: "unused written/read amount",
+        deprecation: None,
+        module: "unused_io_amount",
+    },
+    Lint {
+        name: "unused_label",
+        group: "complexity",
+        desc: "unused labels",
+        deprecation: None,
+        module: "unused_label",
+    },
+    Lint {
+        name: "unused_unit",
+        group: "style",
+        desc: "needless unit expression",
+        deprecation: None,
+        module: "returns",
+    },
+    Lint {
+        name: "use_debug",
+        group: "restriction",
+        desc: "use of `Debug`-based formatting",
+        deprecation: None,
+        module: "write",
+    },
+    Lint {
+        name: "use_self",
+        group: "pedantic",
+        desc: "Unnecessary structure name repetition whereas `Self` is applicable",
+        deprecation: None,
+        module: "use_self",
+    },
+    Lint {
+        name: "used_underscore_binding",
+        group: "pedantic",
+        desc: "using a binding which is prefixed with an underscore",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "useless_asref",
+        group: "complexity",
+        desc: "using `as_ref` where the types before and after the call are the same",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "useless_attribute",
+        group: "correctness",
+        desc: "use of lint attributes on `extern crate` items",
+        deprecation: None,
+        module: "attrs",
+    },
+    Lint {
+        name: "useless_format",
+        group: "complexity",
+        desc: "useless use of `format!`",
+        deprecation: None,
+        module: "format",
+    },
+    Lint {
+        name: "useless_let_if_seq",
+        group: "style",
+        desc: "unidiomatic `let mut` declaration followed by initialization in `if`",
+        deprecation: None,
+        module: "let_if_seq",
+    },
+    Lint {
+        name: "useless_transmute",
+        group: "complexity",
+        desc: "transmutes that have the same to and from types or could be a cast/coercion",
+        deprecation: None,
+        module: "transmute",
+    },
+    Lint {
+        name: "useless_vec",
+        group: "perf",
+        desc: "useless `vec!`",
+        deprecation: None,
+        module: "vec",
+    },
+    Lint {
+        name: "vec_box",
+        group: "complexity",
+        desc: "usage of `Vec<Box<T>>` where T: Sized, vector elements are already on the heap",
+        deprecation: None,
+        module: "types",
+    },
+    Lint {
+        name: "verbose_bit_mask",
+        group: "style",
+        desc: "expressions where a bit mask is less readable than the corresponding method call",
+        deprecation: None,
+        module: "bit_mask",
+    },
+    Lint {
+        name: "while_immutable_condition",
+        group: "correctness",
+        desc: "variables used within while expression are not mutated in the body",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "while_let_loop",
+        group: "complexity",
+        desc: "`loop { if let { ... } else break }`, which can be written as a `while let` loop",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "while_let_on_iterator",
+        group: "style",
+        desc: "using a while-let loop instead of a for loop on an iterator",
+        deprecation: None,
+        module: "loops",
+    },
+    Lint {
+        name: "wildcard_dependencies",
+        group: "cargo",
+        desc: "wildcard dependencies being used",
+        deprecation: None,
+        module: "wildcard_dependencies",
+    },
+    Lint {
+        name: "wildcard_enum_match_arm",
+        group: "restriction",
+        desc: "a wildcard enum match arm using `_`",
+        deprecation: None,
+        module: "matches",
+    },
+    Lint {
+        name: "write_literal",
+        group: "style",
+        desc: "writing a literal with a format string",
+        deprecation: None,
+        module: "write",
+    },
+    Lint {
+        name: "write_with_newline",
+        group: "style",
+        desc: "using `write!()` with a format string that ends in a single newline",
+        deprecation: None,
+        module: "write",
+    },
+    Lint {
+        name: "writeln_empty_string",
+        group: "style",
+        desc: "using `writeln!(buf, \"\")` with an empty string",
+        deprecation: None,
+        module: "write",
+    },
+    Lint {
+        name: "wrong_pub_self_convention",
+        group: "restriction",
+        desc: "defining a public method named with an established prefix (like \"into_\") that takes `self` with the wrong convention",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "wrong_self_convention",
+        group: "style",
+        desc: "defining a method named with an established prefix (like \"into_\") that takes `self` with the wrong convention",
+        deprecation: None,
+        module: "methods",
+    },
+    Lint {
+        name: "wrong_transmute",
+        group: "correctness",
+        desc: "transmutes that are confusing at best, undefined behaviour at worst and always useless",
+        deprecation: None,
+        module: "transmute",
+    },
+    Lint {
+        name: "zero_divided_by_zero",
+        group: "complexity",
+        desc: "usage of `0.0 / 0.0` to obtain NaN instead of std::f32::NaN or std::f64::NaN",
+        deprecation: None,
+        module: "zero_div_zero",
+    },
+    Lint {
+        name: "zero_prefixed_literal",
+        group: "complexity",
+        desc: "integer literals starting with `0`",
+        deprecation: None,
+        module: "misc_early",
+    },
+    Lint {
+        name: "zero_ptr",
+        group: "style",
+        desc: "using 0 as *{const, mut} T",
+        deprecation: None,
+        module: "misc",
+    },
+    Lint {
+        name: "zero_width_space",
+        group: "correctness",
+        desc: "using a zero-width space in a string literal, which is confusing",
+        deprecation: None,
+        module: "unicode",
+    },
+];