about summary refs log tree commit diff
path: root/clippy_dev
diff options
context:
space:
mode:
authorPhilipp Krones <hello@philkrones.com>2024-05-21 10:39:30 -0700
committerPhilipp Krones <hello@philkrones.com>2024-05-21 10:39:30 -0700
commit4363278c73cf506f71215e9e21af90e31c4d74ea (patch)
treea16a543b17791ff520a8f7f265e44fbea06dcfd2 /clippy_dev
parentca1337a7bc08ab59472a701ee0b843d7ac10a5bc (diff)
downloadrust-4363278c73cf506f71215e9e21af90e31c4d74ea.tar.gz
rust-4363278c73cf506f71215e9e21af90e31c4d74ea.zip
Merge commit '2efebd2f0c03dabbe5c3ad7b4ebfbd99238d1fb2' into clippy-subtree-update
Diffstat (limited to 'clippy_dev')
-rw-r--r--clippy_dev/Cargo.toml3
-rw-r--r--clippy_dev/src/main.rs570
-rw-r--r--clippy_dev/src/new_lint.rs14
-rw-r--r--clippy_dev/src/serve.rs2
-rw-r--r--clippy_dev/src/update_lints.rs4
5 files changed, 265 insertions, 328 deletions
diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml
index 42a953039b1..4104e7d94f1 100644
--- a/clippy_dev/Cargo.toml
+++ b/clippy_dev/Cargo.toml
@@ -1,11 +1,12 @@
 [package]
 name = "clippy_dev"
+description = "Clippy developer tooling"
 version = "0.0.1"
 edition = "2021"
 
 [dependencies]
 aho-corasick = "1.0"
-clap = "4.1.4"
+clap = { version = "4.4", features = ["derive"] }
 indoc = "1.0"
 itertools = "0.12"
 opener = "0.6"
diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs
index 397a0e99082..366b52b25df 100644
--- a/clippy_dev/src/main.rs
+++ b/clippy_dev/src/main.rs
@@ -2,350 +2,292 @@
 // warn on lints, that are included in `rust-lang/rust`s bootstrap
 #![warn(rust_2018_idioms, unused_lifetimes)]
 
-use clap::{Arg, ArgAction, ArgMatches, Command};
+use clap::{Args, Parser, Subcommand};
 use clippy_dev::{dogfood, fmt, lint, new_lint, serve, setup, update_lints};
-use indoc::indoc;
 use std::convert::Infallible;
 
 fn main() {
-    let matches = get_clap_config();
+    let dev = Dev::parse();
 
-    match matches.subcommand() {
-        Some(("bless", _)) => {
+    match dev.command {
+        DevCommand::Bless => {
             eprintln!("use `cargo bless` to automatically replace `.stderr` and `.fixed` files as tests are being run");
         },
-        Some(("dogfood", matches)) => {
-            dogfood::dogfood(
-                matches.get_flag("fix"),
-                matches.get_flag("allow-dirty"),
-                matches.get_flag("allow-staged"),
-            );
-        },
-        Some(("fmt", matches)) => {
-            fmt::run(matches.get_flag("check"), matches.get_flag("verbose"));
-        },
-        Some(("update_lints", matches)) => {
-            if matches.get_flag("print-only") {
+        DevCommand::Dogfood {
+            fix,
+            allow_dirty,
+            allow_staged,
+        } => dogfood::dogfood(fix, allow_dirty, allow_staged),
+        DevCommand::Fmt { check, verbose } => fmt::run(check, verbose),
+        DevCommand::UpdateLints { print_only, check } => {
+            if print_only {
                 update_lints::print_lints();
-            } else if matches.get_flag("check") {
+            } else if check {
                 update_lints::update(update_lints::UpdateMode::Check);
             } else {
                 update_lints::update(update_lints::UpdateMode::Change);
             }
         },
-        Some(("new_lint", matches)) => {
-            match new_lint::create(
-                matches.get_one::<String>("pass").unwrap(),
-                matches.get_one::<String>("name"),
-                matches.get_one::<String>("category").map(String::as_str),
-                matches.get_one::<String>("type").map(String::as_str),
-                matches.get_flag("msrv"),
-            ) {
-                Ok(()) => update_lints::update(update_lints::UpdateMode::Change),
-                Err(e) => eprintln!("Unable to create lint: {e}"),
-            }
+        DevCommand::NewLint {
+            pass,
+            name,
+            category,
+            r#type,
+            msrv,
+        } => match new_lint::create(&pass, &name, &category, r#type.as_deref(), msrv) {
+            Ok(()) => update_lints::update(update_lints::UpdateMode::Change),
+            Err(e) => eprintln!("Unable to create lint: {e}"),
         },
-        Some(("setup", sub_command)) => match sub_command.subcommand() {
-            Some(("git-hook", matches)) => {
-                if matches.get_flag("remove") {
-                    setup::git_hook::remove_hook();
+        DevCommand::Setup(SetupCommand { subcommand }) => match subcommand {
+            SetupSubcommand::Intellij { remove, repo_path } => {
+                if remove {
+                    setup::intellij::remove_rustc_src();
                 } else {
-                    setup::git_hook::install_hook(matches.get_flag("force-override"));
+                    setup::intellij::setup_rustc_src(&repo_path);
                 }
             },
-            Some(("intellij", matches)) => {
-                if matches.get_flag("remove") {
-                    setup::intellij::remove_rustc_src();
+            SetupSubcommand::GitHook { remove, force_override } => {
+                if remove {
+                    setup::git_hook::remove_hook();
                 } else {
-                    setup::intellij::setup_rustc_src(
-                        matches
-                            .get_one::<String>("rustc-repo-path")
-                            .expect("this field is mandatory and therefore always valid"),
-                    );
+                    setup::git_hook::install_hook(force_override);
                 }
             },
-            Some(("toolchain", matches)) => {
-                setup::toolchain::create(
-                    matches.get_flag("force"),
-                    matches.get_flag("release"),
-                    matches.get_one::<String>("name").unwrap(),
-                );
-            },
-            Some(("vscode-tasks", matches)) => {
-                if matches.get_flag("remove") {
+            SetupSubcommand::Toolchain { force, release, name } => setup::toolchain::create(force, release, &name),
+            SetupSubcommand::VscodeTasks { remove, force_override } => {
+                if remove {
                     setup::vscode::remove_tasks();
                 } else {
-                    setup::vscode::install_tasks(matches.get_flag("force-override"));
+                    setup::vscode::install_tasks(force_override);
                 }
             },
-            _ => {},
-        },
-        Some(("remove", sub_command)) => match sub_command.subcommand() {
-            Some(("git-hook", _)) => setup::git_hook::remove_hook(),
-            Some(("intellij", _)) => setup::intellij::remove_rustc_src(),
-            Some(("vscode-tasks", _)) => setup::vscode::remove_tasks(),
-            _ => {},
-        },
-        Some(("serve", matches)) => {
-            let port = *matches.get_one::<u16>("port").unwrap();
-            let lint = matches.get_one::<String>("lint");
-            serve::run(port, lint);
         },
-        Some(("lint", matches)) => {
-            let path = matches.get_one::<String>("path").unwrap();
-            let args = matches.get_many::<String>("args").into_iter().flatten();
-            lint::run(path, args);
+        DevCommand::Remove(RemoveCommand { subcommand }) => match subcommand {
+            RemoveSubcommand::Intellij => setup::intellij::remove_rustc_src(),
+            RemoveSubcommand::GitHook => setup::git_hook::remove_hook(),
+            RemoveSubcommand::VscodeTasks => setup::vscode::remove_tasks(),
         },
-        Some(("rename_lint", matches)) => {
-            let old_name = matches.get_one::<String>("old_name").unwrap();
-            let new_name = matches.get_one::<String>("new_name").unwrap_or(old_name);
-            let uplift = matches.get_flag("uplift");
-            update_lints::rename(old_name, new_name, uplift);
-        },
-        Some(("deprecate", matches)) => {
-            let name = matches.get_one::<String>("name").unwrap();
-            let reason = matches.get_one("reason");
-            update_lints::deprecate(name, reason);
-        },
-        _ => {},
+        DevCommand::Serve { port, lint } => serve::run(port, lint),
+        DevCommand::Lint { path, args } => lint::run(&path, args.iter()),
+        DevCommand::RenameLint {
+            old_name,
+            new_name,
+            uplift,
+        } => update_lints::rename(&old_name, new_name.as_ref().unwrap_or(&old_name), uplift),
+        DevCommand::Deprecate { name, reason } => update_lints::deprecate(&name, reason.as_deref()),
     }
 }
 
-fn get_clap_config() -> ArgMatches {
-    Command::new("Clippy developer tooling")
-        .arg_required_else_help(true)
-        .subcommands([
-            Command::new("bless").about("bless the test output changes").arg(
-                Arg::new("ignore-timestamp")
-                    .long("ignore-timestamp")
-                    .action(ArgAction::SetTrue)
-                    .help("Include files updated before clippy was built"),
-            ),
-            Command::new("dogfood").about("Runs the dogfood test").args([
-                Arg::new("fix")
-                    .long("fix")
-                    .action(ArgAction::SetTrue)
-                    .help("Apply the suggestions when possible"),
-                Arg::new("allow-dirty")
-                    .long("allow-dirty")
-                    .action(ArgAction::SetTrue)
-                    .help("Fix code even if the working directory has changes")
-                    .requires("fix"),
-                Arg::new("allow-staged")
-                    .long("allow-staged")
-                    .action(ArgAction::SetTrue)
-                    .help("Fix code even if the working directory has staged changes")
-                    .requires("fix"),
-            ]),
-            Command::new("fmt")
-                .about("Run rustfmt on all projects and tests")
-                .args([
-                    Arg::new("check")
-                        .long("check")
-                        .action(ArgAction::SetTrue)
-                        .help("Use the rustfmt --check option"),
-                    Arg::new("verbose")
-                        .short('v')
-                        .long("verbose")
-                        .action(ArgAction::SetTrue)
-                        .help("Echo commands run"),
-                ]),
-            Command::new("update_lints")
-                .about("Updates lint registration and information from the source code")
-                .long_about(
-                    "Makes sure that:\n \
-                    * the lint count in README.md is correct\n \
-                    * the changelog contains markdown link references at the bottom\n \
-                    * all lint groups include the correct lints\n \
-                    * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod`\n \
-                    * all lints are registered in the lint store",
-                )
-                .args([
-                    Arg::new("print-only")
-                        .long("print-only")
-                        .action(ArgAction::SetTrue)
-                        .help(
-                            "Print a table of lints to STDOUT. \
-                            This does not include deprecated and internal lints. \
-                            (Does not modify any files)",
-                        ),
-                    Arg::new("check")
-                        .long("check")
-                        .action(ArgAction::SetTrue)
-                        .help("Checks that `cargo dev update_lints` has been run. Used on CI."),
-                ]),
-            Command::new("new_lint")
-                .about("Create new lint and run `cargo dev update_lints`")
-                .args([
-                    Arg::new("pass")
-                        .short('p')
-                        .long("pass")
-                        .help("Specify whether the lint runs during the early or late pass")
-                        .value_parser(["early", "late"])
-                        .conflicts_with("type")
-                        .default_value("late"),
-                    Arg::new("name")
-                        .short('n')
-                        .long("name")
-                        .help("Name of the new lint in snake case, ex: fn_too_long")
-                        .required(true)
-                        .value_parser(|name: &str| Ok::<_, Infallible>(name.replace('-', "_"))),
-                    Arg::new("category")
-                        .short('c')
-                        .long("category")
-                        .help("What category the lint belongs to")
-                        .default_value("nursery")
-                        .value_parser([
-                            "style",
-                            "correctness",
-                            "suspicious",
-                            "complexity",
-                            "perf",
-                            "pedantic",
-                            "restriction",
-                            "cargo",
-                            "nursery",
-                            "internal",
-                        ]),
-                    Arg::new("type").long("type").help("What directory the lint belongs in"),
-                    Arg::new("msrv")
-                        .long("msrv")
-                        .action(ArgAction::SetTrue)
-                        .help("Add MSRV config code to the lint"),
-                ]),
-            Command::new("setup")
-                .about("Support for setting up your personal development environment")
-                .arg_required_else_help(true)
-                .subcommands([
-                    Command::new("git-hook")
-                        .about("Add a pre-commit git hook that formats your code to make it look pretty")
-                        .args([
-                            Arg::new("remove")
-                                .long("remove")
-                                .action(ArgAction::SetTrue)
-                                .help("Remove the pre-commit hook added with 'cargo dev setup git-hook'"),
-                            Arg::new("force-override")
-                                .long("force-override")
-                                .short('f')
-                                .action(ArgAction::SetTrue)
-                                .help("Forces the override of an existing git pre-commit hook"),
-                        ]),
-                    Command::new("intellij")
-                        .about("Alter dependencies so Intellij Rust can find rustc internals")
-                        .args([
-                            Arg::new("remove")
-                                .long("remove")
-                                .action(ArgAction::SetTrue)
-                                .help("Remove the dependencies added with 'cargo dev setup intellij'"),
-                            Arg::new("rustc-repo-path")
-                                .long("repo-path")
-                                .short('r')
-                                .help("The path to a rustc repo that will be used for setting the dependencies")
-                                .value_name("path")
-                                .conflicts_with("remove")
-                                .required(true),
-                        ]),
-                    Command::new("toolchain")
-                        .about("Install a rustup toolchain pointing to the local clippy build")
-                        .args([
-                            Arg::new("force")
-                                .long("force")
-                                .short('f')
-                                .action(ArgAction::SetTrue)
-                                .help("Override an existing toolchain"),
-                            Arg::new("release")
-                                .long("release")
-                                .short('r')
-                                .action(ArgAction::SetTrue)
-                                .help("Point to --release clippy binaries"),
-                            Arg::new("name")
-                                .long("name")
-                                .default_value("clippy")
-                                .help("The name of the created toolchain"),
-                        ]),
-                    Command::new("vscode-tasks")
-                        .about("Add several tasks to vscode for formatting, validation and testing")
-                        .args([
-                            Arg::new("remove")
-                                .long("remove")
-                                .action(ArgAction::SetTrue)
-                                .help("Remove the tasks added with 'cargo dev setup vscode-tasks'"),
-                            Arg::new("force-override")
-                                .long("force-override")
-                                .short('f')
-                                .action(ArgAction::SetTrue)
-                                .help("Forces the override of existing vscode tasks"),
-                        ]),
-                ]),
-            Command::new("remove")
-                .about("Support for undoing changes done by the setup command")
-                .arg_required_else_help(true)
-                .subcommands([
-                    Command::new("git-hook").about("Remove any existing pre-commit git hook"),
-                    Command::new("vscode-tasks").about("Remove any existing vscode tasks"),
-                    Command::new("intellij").about("Removes rustc source paths added via `cargo dev setup intellij`"),
-                ]),
-            Command::new("serve")
-                .about("Launch a local 'ALL the Clippy Lints' website in a browser")
-                .args([
-                    Arg::new("port")
-                        .long("port")
-                        .short('p')
-                        .help("Local port for the http server")
-                        .default_value("8000")
-                        .value_parser(clap::value_parser!(u16)),
-                    Arg::new("lint").help("Which lint's page to load initially (optional)"),
-                ]),
-            Command::new("lint")
-                .about("Manually run clippy on a file or package")
-                .after_help(indoc! {"
-                    EXAMPLES
-                        Lint a single file:
-                            cargo dev lint tests/ui/attrs.rs
+#[derive(Parser)]
+#[command(name = "dev", about)]
+struct Dev {
+    #[command(subcommand)]
+    command: DevCommand,
+}
 
-                        Lint a package directory:
-                            cargo dev lint tests/ui-cargo/wildcard_dependencies/fail
-                            cargo dev lint ~/my-project
+#[derive(Subcommand)]
+enum DevCommand {
+    /// Bless the test output changes
+    Bless,
+    /// Runs the dogfood test
+    Dogfood {
+        #[arg(long)]
+        /// Apply the suggestions when possible
+        fix: bool,
+        #[arg(long, requires = "fix")]
+        /// Fix code even if the working directory has changes
+        allow_dirty: bool,
+        #[arg(long, requires = "fix")]
+        /// Fix code even if the working directory has staged changes
+        allow_staged: bool,
+    },
+    /// Run rustfmt on all projects and tests
+    Fmt {
+        #[arg(long)]
+        /// Use the rustfmt --check option
+        check: bool,
+        #[arg(short, long)]
+        /// Echo commands run
+        verbose: bool,
+    },
+    #[command(name = "update_lints")]
+    /// Updates lint registration and information from the source code
+    ///
+    /// Makes sure that: {n}
+    /// * the lint count in README.md is correct {n}
+    /// * the changelog contains markdown link references at the bottom {n}
+    /// * all lint groups include the correct lints {n}
+    /// * lint modules in `clippy_lints/*` are visible in `src/lib.rs` via `pub mod` {n}
+    /// * all lints are registered in the lint store
+    UpdateLints {
+        #[arg(long)]
+        /// Print a table of lints to STDOUT
+        ///
+        /// This does not include deprecated and internal lints. (Does not modify any files)
+        print_only: bool,
+        #[arg(long)]
+        /// Checks that `cargo dev update_lints` has been run. Used on CI.
+        check: bool,
+    },
+    #[command(name = "new_lint")]
+    /// Create a new lint and run `cargo dev update_lints`
+    NewLint {
+        #[arg(short, long, value_parser = ["early", "late"], conflicts_with = "type", default_value = "late")]
+        /// Specify whether the lint runs during the early or late pass
+        pass: String,
+        #[arg(
+            short,
+            long,
+            value_parser = |name: &str| Ok::<_, Infallible>(name.replace('-', "_")),
+        )]
+        /// Name of the new lint in snake case, ex: `fn_too_long`
+        name: String,
+        #[arg(
+            short,
+            long,
+            value_parser = [
+                "style",
+                "correctness",
+                "suspicious",
+                "complexity",
+                "perf",
+                "pedantic",
+                "restriction",
+                "cargo",
+                "nursery",
+                "internal",
+            ],
+            default_value = "nursery",
+        )]
+        /// What category the lint belongs to
+        category: String,
+        #[arg(long)]
+        /// What directory the lint belongs in
+        r#type: Option<String>,
+        #[arg(long)]
+        /// Add MSRV config code to the lint
+        msrv: bool,
+    },
+    /// Support for setting up your personal development environment
+    Setup(SetupCommand),
+    /// Support for removing changes done by the setup command
+    Remove(RemoveCommand),
+    /// Launch a local 'ALL the Clippy Lints' website in a browser
+    Serve {
+        #[arg(short, long, default_value = "8000")]
+        /// Local port for the http server
+        port: u16,
+        #[arg(long)]
+        /// Which lint's page to load initially (optional)
+        lint: Option<String>,
+    },
+    #[allow(clippy::doc_markdown)]
+    /// Manually run clippy on a file or package
+    ///
+    /// ## Examples
+    ///
+    /// Lint a single file: {n}
+    ///     cargo dev lint tests/ui/attrs.rs
+    ///
+    /// Lint a package directory: {n}
+    ///     cargo dev lint tests/ui-cargo/wildcard_dependencies/fail {n}
+    ///     cargo dev lint ~/my-project
+    ///
+    /// Run rustfix: {n}
+    ///     cargo dev lint ~/my-project -- --fix
+    ///
+    /// Set lint levels: {n}
+    ///     cargo dev lint file.rs -- -W clippy::pedantic {n}
+    ///     cargo dev lint ~/my-project -- -- -W clippy::pedantic
+    Lint {
+        /// The path to a file or package directory to lint
+        path: String,
+        /// Pass extra arguments to cargo/clippy-driver
+        args: Vec<String>,
+    },
+    #[command(name = "rename_lint")]
+    /// Rename a lint
+    RenameLint {
+        /// The name of the lint to rename
+        old_name: String,
+        #[arg(required_unless_present = "uplift")]
+        /// The new name of the lint
+        new_name: Option<String>,
+        #[arg(long)]
+        /// This lint will be uplifted into rustc
+        uplift: bool,
+    },
+    /// Deprecate the given lint
+    Deprecate {
+        /// The name of the lint to deprecate
+        name: String,
+        #[arg(long, short)]
+        /// The reason for deprecation
+        reason: Option<String>,
+    },
+}
 
-                        Run rustfix:
-                            cargo dev lint ~/my-project -- --fix
+#[derive(Args)]
+struct SetupCommand {
+    #[command(subcommand)]
+    subcommand: SetupSubcommand,
+}
+
+#[derive(Subcommand)]
+enum SetupSubcommand {
+    /// Alter dependencies so Intellij Rust can find rustc internals
+    Intellij {
+        #[arg(long)]
+        /// Remove the dependencies added with 'cargo dev setup intellij'
+        remove: bool,
+        #[arg(long, short, conflicts_with = "remove")]
+        /// The path to a rustc repo that will be used for setting the dependencies
+        repo_path: String,
+    },
+    /// Add a pre-commit git hook that formats your code to make it look pretty
+    GitHook {
+        #[arg(long)]
+        /// Remove the pre-commit hook added with 'cargo dev setup git-hook'
+        remove: bool,
+        #[arg(long, short)]
+        /// Forces the override of an existing git pre-commit hook
+        force_override: bool,
+    },
+    /// Install a rustup toolchain pointing to the local clippy build
+    Toolchain {
+        #[arg(long, short)]
+        /// Override an existing toolchain
+        force: bool,
+        #[arg(long, short)]
+        /// Point to --release clippy binary
+        release: bool,
+        #[arg(long, default_value = "clippy")]
+        /// Name of the toolchain
+        name: String,
+    },
+    /// Add several tasks to vscode for formatting, validation and testing
+    VscodeTasks {
+        #[arg(long)]
+        /// Remove the tasks added with 'cargo dev setup vscode-tasks'
+        remove: bool,
+        #[arg(long, short)]
+        /// Forces the override of existing vscode tasks
+        force_override: bool,
+    },
+}
+
+#[derive(Args)]
+struct RemoveCommand {
+    #[command(subcommand)]
+    subcommand: RemoveSubcommand,
+}
 
-                        Set lint levels:
-                            cargo dev lint file.rs -- -W clippy::pedantic
-                            cargo dev lint ~/my-project -- -- -W clippy::pedantic
-                "})
-                .args([
-                    Arg::new("path")
-                        .required(true)
-                        .help("The path to a file or package directory to lint"),
-                    Arg::new("args")
-                        .action(ArgAction::Append)
-                        .help("Pass extra arguments to cargo/clippy-driver"),
-                ]),
-            Command::new("rename_lint").about("Renames the given lint").args([
-                Arg::new("old_name")
-                    .index(1)
-                    .required(true)
-                    .help("The name of the lint to rename"),
-                Arg::new("new_name")
-                    .index(2)
-                    .required_unless_present("uplift")
-                    .help("The new name of the lint"),
-                Arg::new("uplift")
-                    .long("uplift")
-                    .action(ArgAction::SetTrue)
-                    .help("This lint will be uplifted into rustc"),
-            ]),
-            Command::new("deprecate").about("Deprecates the given lint").args([
-                Arg::new("name")
-                    .index(1)
-                    .required(true)
-                    .help("The name of the lint to deprecate"),
-                Arg::new("reason")
-                    .long("reason")
-                    .short('r')
-                    .help("The reason for deprecation"),
-            ]),
-        ])
-        .get_matches()
+#[derive(Subcommand)]
+enum RemoveSubcommand {
+    /// Remove the dependencies added with 'cargo dev setup intellij'
+    Intellij,
+    /// Remove the pre-commit git hook
+    GitHook,
+    /// Remove the tasks added with 'cargo dev setup vscode-tasks'
+    VscodeTasks,
 }
diff --git a/clippy_dev/src/new_lint.rs b/clippy_dev/src/new_lint.rs
index 2940d56350f..b6481dde4dd 100644
--- a/clippy_dev/src/new_lint.rs
+++ b/clippy_dev/src/new_lint.rs
@@ -36,22 +36,16 @@ impl<T> Context for io::Result<T> {
 /// # Errors
 ///
 /// This function errors out if the files couldn't be created or written to.
-pub fn create(
-    pass: &String,
-    lint_name: Option<&String>,
-    category: Option<&str>,
-    mut ty: Option<&str>,
-    msrv: bool,
-) -> io::Result<()> {
-    if category == Some("cargo") && ty.is_none() {
+pub fn create(pass: &str, name: &str, category: &str, mut ty: Option<&str>, msrv: bool) -> io::Result<()> {
+    if category == "cargo" && ty.is_none() {
         // `cargo` is a special category, these lints should always be in `clippy_lints/src/cargo`
         ty = Some("cargo");
     }
 
     let lint = LintData {
         pass,
-        name: lint_name.expect("`name` argument is validated by clap"),
-        category: category.expect("`category` argument is validated by clap"),
+        name,
+        category,
         ty,
         project_root: clippy_project_root(),
     };
diff --git a/clippy_dev/src/serve.rs b/clippy_dev/src/serve.rs
index ea925f6709f..4a4261d1a1e 100644
--- a/clippy_dev/src/serve.rs
+++ b/clippy_dev/src/serve.rs
@@ -8,7 +8,7 @@ use std::{env, thread};
 /// # Panics
 ///
 /// Panics if the python commands could not be spawned
-pub fn run(port: u16, lint: Option<&String>) -> ! {
+pub fn run(port: u16, lint: Option<String>) -> ! {
     let mut url = Some(match lint {
         None => format!("http://localhost:{port}"),
         Some(lint) => format!("http://localhost:{port}/#{lint}"),
diff --git a/clippy_dev/src/update_lints.rs b/clippy_dev/src/update_lints.rs
index 625b1339591..45353901c98 100644
--- a/clippy_dev/src/update_lints.rs
+++ b/clippy_dev/src/update_lints.rs
@@ -314,7 +314,7 @@ const DEFAULT_DEPRECATION_REASON: &str = "default deprecation note";
 /// # Panics
 ///
 /// If a file path could not read from or written to
-pub fn deprecate(name: &str, reason: Option<&String>) {
+pub fn deprecate(name: &str, reason: Option<&str>) {
     fn finish(
         (lints, mut deprecated_lints, renamed_lints): (Vec<Lint>, Vec<DeprecatedLint>, Vec<RenamedLint>),
         name: &str,
@@ -335,7 +335,7 @@ pub fn deprecate(name: &str, reason: Option<&String>) {
         println!("note: you must run `cargo uitest` to update the test results");
     }
 
-    let reason = reason.map_or(DEFAULT_DEPRECATION_REASON, String::as_str);
+    let reason = reason.unwrap_or(DEFAULT_DEPRECATION_REASON);
     let name_lower = name.to_lowercase();
     let name_upper = name.to_uppercase();