From 9bd70dbb8855580ca75d37211fce74adc8fda734 Mon Sep 17 00:00:00 2001 From: est31 Date: Sat, 8 Oct 2022 02:50:30 +0200 Subject: [PATCH] Make the match checking configurable --- clippy_lints/src/lib.rs | 3 +- clippy_lints/src/manual_let_else.rs | 29 ++++++++++++++++--- clippy_lints/src/utils/conf.rs | 6 ++++ .../toml_unknown_key/conf_unknown_key.stderr | 1 + 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index b261beab793..5716ef71641 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -604,7 +604,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: )) }); store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv))); - store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv))); + let matches_for_let_else = conf.matches_for_let_else; + store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv, matches_for_let_else))); store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv))); store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv))); store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv))); diff --git a/clippy_lints/src/manual_let_else.rs b/clippy_lints/src/manual_let_else.rs index e366d6db774..13a734818a7 100644 --- a/clippy_lints/src/manual_let_else.rs +++ b/clippy_lints/src/manual_let_else.rs @@ -11,6 +11,7 @@ use rustc_semver::RustcVersion; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::sym; +use serde::Deserialize; use std::ops::ControlFlow; declare_clippy_lint! { @@ -47,12 +48,16 @@ pub struct ManualLetElse { msrv: Option, + matches_behaviour: MatchLintBehaviour, } impl ManualLetElse { #[must_use] - pub fn new(msrv: Option) -> Self { - Self { msrv } + pub fn new(msrv: Option, matches_behaviour: MatchLintBehaviour) -> Self { + Self { + msrv, + matches_behaviour, + } } } @@ -89,6 +94,9 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) { } }, IfLetOrMatch::Match(_match_expr, arms, source) => { + if self.matches_behaviour == MatchLintBehaviour::Never { + return; + } if source != MatchSource::Normal { return; } @@ -97,6 +105,7 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) { if arms.len() != 2 { return; } + let check_types = self.matches_behaviour == MatchLintBehaviour::WellKnownTypes; // We iterate over both arms, trying to find one that is an identity, // one that diverges. Our check needs to work regardless of the order // of both arms. @@ -109,7 +118,7 @@ fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &'tcx Stmt<'tcx>) { } if expr_is_simple_identity(arm.pat, arm.body) { found_identity_arm = true; - } else if expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat) { + } else if expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat, check_types) { found_diverging_arm = true; } } @@ -178,7 +187,7 @@ fn is_never(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool { .is_some() } -fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>) -> bool { +fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: bool) -> bool { // Check whether the pattern contains any bindings, as the // binding might potentially be used in the body. // TODO: only look for *used* bindings. @@ -188,6 +197,11 @@ fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>) -> bool { return false; } + // If we shouldn't check the types, exit early. + if !check_types { + return true; + } + // Check whether any possibly "unknown" patterns are included, // because users might not know which values some enum has. // Well-known enums are excepted, as we assume people know them. @@ -245,3 +259,10 @@ fn expr_is_simple_identity(pat: &'_ Pat<'_>, expr: &'_ Expr<'_>) -> bool { } true } + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize)] +pub enum MatchLintBehaviour { + AllTypes, + WellKnownTypes, + Never, +} diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 1aa86efd38f..ef6de7d333d 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -335,6 +335,12 @@ pub(crate) fn get_configuration_metadata() -> Vec { /// /// Enables verbose mode. Triggers if there is more than one uppercase char next to each other (upper_case_acronyms_aggressive: bool = false), + /// Lint: MANUAL_LET_ELSE. + /// + /// Whether the matches should be considered by the lint, and whether there should + /// be filtering for common types. + (matches_for_let_else: crate::manual_let_else::MatchLintBehaviour = + crate::manual_let_else::MatchLintBehaviour::WellKnownTypes), /// Lint: _CARGO_COMMON_METADATA. /// /// For internal testing only, ignores the current `publish` settings in the Cargo manifest. diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 82ee8054132..7db2e11225b 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -22,6 +22,7 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie enum-variant-size-threshold large-error-threshold literal-representation-threshold + matches-for-let-else max-fn-params-bools max-include-file-size max-struct-bools