Skip to content

Commit 9bd70db

Browse files
committed
Make the match checking configurable
1 parent 173a8e0 commit 9bd70db

File tree

4 files changed

+34
-5
lines changed

4 files changed

+34
-5
lines changed

clippy_lints/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -604,7 +604,8 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
604604
))
605605
});
606606
store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv)));
607-
store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv)));
607+
let matches_for_let_else = conf.matches_for_let_else;
608+
store.register_late_pass(move |_| Box::new(manual_let_else::ManualLetElse::new(msrv, matches_for_let_else)));
608609
store.register_early_pass(move || Box::new(manual_non_exhaustive::ManualNonExhaustiveStruct::new(msrv)));
609610
store.register_late_pass(move |_| Box::new(manual_non_exhaustive::ManualNonExhaustiveEnum::new(msrv)));
610611
store.register_late_pass(move |_| Box::new(manual_strip::ManualStrip::new(msrv)));

clippy_lints/src/manual_let_else.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use rustc_middle::lint::in_external_macro;
1111
use rustc_semver::RustcVersion;
1212
use rustc_session::{declare_tool_lint, impl_lint_pass};
1313
use rustc_span::symbol::sym;
14+
use serde::Deserialize;
1415
use std::ops::ControlFlow;
1516

1617
declare_clippy_lint! {
@@ -47,12 +48,16 @@ declare_clippy_lint! {
4748

4849
pub struct ManualLetElse {
4950
msrv: Option<RustcVersion>,
51+
matches_behaviour: MatchLintBehaviour,
5052
}
5153

5254
impl ManualLetElse {
5355
#[must_use]
54-
pub fn new(msrv: Option<RustcVersion>) -> Self {
55-
Self { msrv }
56+
pub fn new(msrv: Option<RustcVersion>, matches_behaviour: MatchLintBehaviour) -> Self {
57+
Self {
58+
msrv,
59+
matches_behaviour,
60+
}
5661
}
5762
}
5863

@@ -89,6 +94,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualLetElse {
8994
}
9095
},
9196
IfLetOrMatch::Match(_match_expr, arms, source) => {
97+
if self.matches_behaviour == MatchLintBehaviour::Never {
98+
return;
99+
}
92100
if source != MatchSource::Normal {
93101
return;
94102
}
@@ -97,6 +105,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualLetElse {
97105
if arms.len() != 2 {
98106
return;
99107
}
108+
let check_types = self.matches_behaviour == MatchLintBehaviour::WellKnownTypes;
100109
// We iterate over both arms, trying to find one that is an identity,
101110
// one that diverges. Our check needs to work regardless of the order
102111
// of both arms.
@@ -109,7 +118,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualLetElse {
109118
}
110119
if expr_is_simple_identity(arm.pat, arm.body) {
111120
found_identity_arm = true;
112-
} else if expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat) {
121+
} else if expr_diverges(cx, arm.body) && pat_allowed_for_else(cx, arm.pat, check_types) {
113122
found_diverging_arm = true;
114123
}
115124
}
@@ -178,7 +187,7 @@ fn expr_diverges(cx: &LateContext<'_>, expr: &'_ Expr<'_>) -> bool {
178187
.is_some()
179188
}
180189

181-
fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>) -> bool {
190+
fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>, check_types: bool) -> bool {
182191
// Check whether the pattern contains any bindings, as the
183192
// binding might potentially be used in the body.
184193
// TODO: only look for *used* bindings.
@@ -188,6 +197,11 @@ fn pat_allowed_for_else(cx: &LateContext<'_>, pat: &'_ Pat<'_>) -> bool {
188197
return false;
189198
}
190199

200+
// If we shouldn't check the types, exit early.
201+
if !check_types {
202+
return true;
203+
}
204+
191205
// Check whether any possibly "unknown" patterns are included,
192206
// because users might not know which values some enum has.
193207
// 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 {
245259
}
246260
true
247261
}
262+
263+
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Deserialize)]
264+
pub enum MatchLintBehaviour {
265+
AllTypes,
266+
WellKnownTypes,
267+
Never,
268+
}

clippy_lints/src/utils/conf.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,12 @@ define_Conf! {
335335
///
336336
/// Enables verbose mode. Triggers if there is more than one uppercase char next to each other
337337
(upper_case_acronyms_aggressive: bool = false),
338+
/// Lint: MANUAL_LET_ELSE.
339+
///
340+
/// Whether the matches should be considered by the lint, and whether there should
341+
/// be filtering for common types.
342+
(matches_for_let_else: crate::manual_let_else::MatchLintBehaviour =
343+
crate::manual_let_else::MatchLintBehaviour::WellKnownTypes),
338344
/// Lint: _CARGO_COMMON_METADATA.
339345
///
340346
/// For internal testing only, ignores the current `publish` settings in the Cargo manifest.

tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie
2222
enum-variant-size-threshold
2323
large-error-threshold
2424
literal-representation-threshold
25+
matches-for-let-else
2526
max-fn-params-bools
2627
max-include-file-size
2728
max-struct-bools

0 commit comments

Comments
 (0)