@@ -187,6 +187,25 @@ declare_clippy_lint! {
187
187
"a match on an Option value instead of using `as_ref()` or `as_mut`"
188
188
}
189
189
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
+
190
209
#[ allow( missing_copy_implementations) ]
191
210
pub struct MatchPass ;
192
211
@@ -199,7 +218,8 @@ impl LintPass for MatchPass {
199
218
SINGLE_MATCH_ELSE ,
200
219
MATCH_OVERLAPPING_ARM ,
201
220
MATCH_WILD_ERR_ARM ,
202
- MATCH_AS_REF
221
+ MATCH_AS_REF ,
222
+ MATCH_WILD
203
223
)
204
224
}
205
225
@@ -218,6 +238,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MatchPass {
218
238
check_match_bool ( cx, ex, arms, expr) ;
219
239
check_overlapping_arms ( cx, ex, arms) ;
220
240
check_wild_err_arm ( cx, ex, arms) ;
241
+ check_wild_arm ( cx, ex, arms) ;
221
242
check_match_as_ref ( cx, ex, arms, expr) ;
222
243
}
223
244
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]) {
442
463
}
443
464
}
444
465
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
+
445
482
// If the block contains only a `panic!` macro (as expression or statement)
446
483
fn is_panic_block ( block : & Block ) -> bool {
447
484
match ( & block. expr , block. stmts . len ( ) , block. stmts . first ( ) ) {
0 commit comments