Skip to content

Commit

Permalink
Add match_wild lint (rust-lang#3649).
Browse files Browse the repository at this point in the history
This lint prevents using a wildcard in a match.
  • Loading branch information
Aehmlo authored and Grzegorz committed Feb 7, 2019
1 parent 2ba20fa commit 54cf8e4
Showing 1 changed file with 38 additions and 1 deletion.
39 changes: 38 additions & 1 deletion clippy_lints/src/matches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,25 @@ declare_clippy_lint! {
"a match on an Option value instead of using `as_ref()` or `as_mut`"
}

/// **What it does:** Checks for wildcard matches using `_`.
///
/// **Why is this bad?** New variants added by library updates can be missed.
///
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// match x {
/// A => {},
/// _ => {}
/// }
/// ```
declare_clippy_lint! {
pub MATCH_WILD,
restriction,
"a wildcard match arm using `_`"
}

#[allow(missing_copy_implementations)]
pub struct MatchPass;

Expand All @@ -199,7 +218,8 @@ impl LintPass for MatchPass {
SINGLE_MATCH_ELSE,
MATCH_OVERLAPPING_ARM,
MATCH_WILD_ERR_ARM,
MATCH_AS_REF
MATCH_AS_REF,
MATCH_WILD
)
}

Expand All @@ -218,6 +238,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchPass {
check_match_bool(cx, ex, arms, expr);
check_overlapping_arms(cx, ex, arms);
check_wild_err_arm(cx, ex, arms);
check_wild_arm(cx, ex, arms);
check_match_as_ref(cx, ex, arms, expr);
}
if let ExprKind::Match(ref ex, ref arms, _) = expr.node {
Expand Down Expand Up @@ -442,6 +463,22 @@ fn check_wild_err_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
}
}

fn check_wild_arm(cx: &LateContext<'_, '_>, ex: &Expr, arms: &[Arm]) {
let ex_ty = walk_ptrs_ty(cx.tables.expr_ty(ex));
if match_type(cx, ex_ty, &paths::RESULT) {
for arm in arms {
if is_wild(&arm.pats[0]) {
span_note_and_lint(cx,
MATCH_WILD,
arm.pats[0].span,
"Wildcard match will miss any future added variants.",
arm.pats[0].span,
"to resolve, match each variant explicitly");
}
}
}
}

// If the block contains only a `panic!` macro (as expression or statement)
fn is_panic_block(block: &Block) -> bool {
match (&block.expr, block.stmts.len(), block.stmts.first()) {
Expand Down

0 comments on commit 54cf8e4

Please sign in to comment.