Skip to content

Commit 0da1867

Browse files
committed
Add match_wild lint (#3649).
This lint prevents using a wildcard in a match.
1 parent 6b1a2a9 commit 0da1867

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

clippy_lints/src/matches.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,25 @@ declare_clippy_lint! {
187187
"a match on an Option value instead of using `as_ref()` or `as_mut`"
188188
}
189189

190+
/// **What it does:** Checks for wildcard matches using `_`.
191+
///
192+
/// **Why is this bad?** New variants added by library updates can be missed.
193+
///
194+
/// **Known problems:** None.
195+
///
196+
/// **Example:**
197+
/// ```rust
198+
/// match x {
199+
/// A => {},
200+
/// _ => {}
201+
/// }
202+
/// ```
203+
declare_clippy_lint! {
204+
pub MATCH_WILD,
205+
restriction,
206+
"a wildcard match arm using `_`"
207+
}
208+
190209
#[allow(missing_copy_implementations)]
191210
pub struct MatchPass;
192211

@@ -199,7 +218,8 @@ impl LintPass for MatchPass {
199218
SINGLE_MATCH_ELSE,
200219
MATCH_OVERLAPPING_ARM,
201220
MATCH_WILD_ERR_ARM,
202-
MATCH_AS_REF
221+
MATCH_AS_REF,
222+
MATCH_WILD
203223
)
204224
}
205225

@@ -218,6 +238,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchPass {
218238
check_match_bool(cx, ex, arms, expr);
219239
check_overlapping_arms(cx, ex, arms);
220240
check_wild_err_arm(cx, ex, arms);
241+
check_wild_arm(cx, ex, arms);
221242
check_match_as_ref(cx, ex, arms, expr);
222243
}
223244
if let ExprKind::Match(ref ex, ref arms, _) = expr.node {
@@ -442,6 +463,22 @@ fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
442463
}
443464
}
444465

466+
fn check_wild_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
467+
let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex));
468+
if match_type(cx, ex_ty, &paths::RESULT) {
469+
for arm in arms {
470+
if is_wild(&arm.pats[0]) {
471+
span_note_and_lint(cx,
472+
MATCH_WILD,
473+
arm.pats[0].span,
474+
"Wildcard match will miss any future added variants.",
475+
arm.pats[0].span,
476+
"to resolve, match each variant explicitly");
477+
}
478+
}
479+
}
480+
}
481+
445482
// If the block contains only a `panic!` macro (as expression or statement)
446483
fn is_panic_block(block: &Block) -> bool {
447484
match (&block.expr, block.stmts.len(), block.stmts.first()) {

0 commit comments

Comments
 (0)