]> git.lizzy.rs Git - rust.git/commitdiff
Add match_wild lint (#3649).
authorAlex Hamilton <alex.hamilton@ou.edu>
Thu, 10 Jan 2019 20:56:28 +0000 (14:56 -0600)
committerAlex Hamilton <alex.hamilton@ou.edu>
Tue, 29 Jan 2019 21:33:04 +0000 (15:33 -0600)
This lint prevents using a wildcard in a match.

clippy_lints/src/matches.rs

index b290980fc36151f0432351b473a706891fedbfd4..4be045175bb2ec7063ef8cb711b2aa9af4c538b2 100644 (file)
     "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;
 
@@ -199,7 +218,8 @@ fn get_lints(&self) -> LintArray {
             SINGLE_MATCH_ELSE,
             MATCH_OVERLAPPING_ARM,
             MATCH_WILD_ERR_ARM,
-            MATCH_AS_REF
+            MATCH_AS_REF,
+            MATCH_WILD
         )
     }
 
@@ -218,6 +238,7 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
             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 {
@@ -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()) {