Handle case for non-exhaustive enums

This commit is contained in:
ThibsG 2020-01-02 20:00:27 +01:00
parent d60c6f9398
commit 58deaad42d
2 changed files with 43 additions and 18 deletions

View file

@ -267,7 +267,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Matches {
check_wild_err_arm(cx, ex, arms); check_wild_err_arm(cx, ex, arms);
check_wild_enum_match(cx, ex, arms); check_wild_enum_match(cx, ex, arms);
check_match_as_ref(cx, ex, arms, expr); check_match_as_ref(cx, ex, arms, expr);
check_pats_wild_match(cx, arms); check_pats_wild_match(cx, ex, arms);
} }
if let ExprKind::Match(ref ex, ref arms, _) = expr.kind { if let ExprKind::Match(ref ex, ref arms, _) = expr.kind {
check_match_ref_pats(cx, ex, arms, expr); check_match_ref_pats(cx, ex, arms, expr);
@ -686,20 +686,45 @@ fn check_match_as_ref(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>],
} }
} }
fn check_pats_wild_match(cx: &LateContext<'_, '_>, arms: &[Arm]) { fn check_pats_wild_match(cx: &LateContext<'_, '_>, ex: &Expr<'_>, arms: &[Arm<'_>]) {
let mut is_non_exhaustive_enum = false;
let ty = cx.tables.expr_ty(ex);
if ty.is_enum() {
if let ty::Adt(def, _) = ty.kind {
if def.is_variant_list_non_exhaustive() {
is_non_exhaustive_enum = true;
}
}
}
for arm in arms { for arm in arms {
if let PatKind::Or(ref fields) = arm.pat.kind { if let PatKind::Or(ref fields) = arm.pat.kind {
// look for multiple fields where one at least matches Wild pattern // look for multiple fields in this arm that contains at least one Wild pattern
if fields.len() > 1 && fields.into_iter().any(is_wild) { if fields.len() > 1 && fields.iter().any(is_wild) {
span_lint_and_sugg( span_lint_and_then(
cx, cx,
PATS_WITH_WILD_MATCH_ARM, PATS_WITH_WILD_MATCH_ARM,
arm.pat.span, arm.pat.span,
"wildcard pattern covers any other pattern as it will match anyway. Consider replacing with wildcard pattern only", "wildcard pattern covers any other pattern as it will match anyway.",
"try this", |db| {
"_".to_string(), // handle case where a non exhaustive enum is being used
Applicability::MachineApplicable, if is_non_exhaustive_enum {
) db.span_suggestion(
arm.pat.span,
"consider handling `_` separately.",
"_ => ...".to_string(),
Applicability::MaybeIncorrect,
);
} else {
db.span_suggestion(
arm.pat.span,
"consider replacing with wildcard pattern only",
"_".to_string(),
Applicability::MachineApplicable,
);
}
},
);
} }
} }
} }

View file

@ -1,28 +1,28 @@
error: wildcard pattern covers any other pattern as it will match anyway. Consider replacing with wildcard pattern only error: wildcard pattern covers any other pattern as it will match anyway.
--> $DIR/pats_with_wild_match_arm.rs:10:9 --> $DIR/pats_with_wild_match_arm.rs:10:9
| |
LL | "bar" | _ => { LL | "bar" | _ => {
| ^^^^^^^^^ help: try this: `_` | ^^^^^^^^^ help: consider replacing with wildcard pattern only: `_`
| |
= note: `-D clippy::pats-with-wild-match-arm` implied by `-D warnings` = note: `-D clippy::pats-with-wild-match-arm` implied by `-D warnings`
error: wildcard pattern covers any other pattern as it will match anyway. Consider replacing with wildcard pattern only error: wildcard pattern covers any other pattern as it will match anyway.
--> $DIR/pats_with_wild_match_arm.rs:18:9 --> $DIR/pats_with_wild_match_arm.rs:18:9
| |
LL | "bar" | "bar2" | _ => { LL | "bar" | "bar2" | _ => {
| ^^^^^^^^^^^^^^^^^^ help: try this: `_` | ^^^^^^^^^^^^^^^^^^ help: consider replacing with wildcard pattern only: `_`
error: wildcard pattern covers any other pattern as it will match anyway. Consider replacing with wildcard pattern only error: wildcard pattern covers any other pattern as it will match anyway.
--> $DIR/pats_with_wild_match_arm.rs:26:9 --> $DIR/pats_with_wild_match_arm.rs:26:9
| |
LL | _ | "bar" | _ => { LL | _ | "bar" | _ => {
| ^^^^^^^^^^^^^ help: try this: `_` | ^^^^^^^^^^^^^ help: consider replacing with wildcard pattern only: `_`
error: wildcard pattern covers any other pattern as it will match anyway. Consider replacing with wildcard pattern only error: wildcard pattern covers any other pattern as it will match anyway.
--> $DIR/pats_with_wild_match_arm.rs:34:9 --> $DIR/pats_with_wild_match_arm.rs:34:9
| |
LL | _ | "bar" => { LL | _ | "bar" => {
| ^^^^^^^^^ help: try this: `_` | ^^^^^^^^^ help: consider replacing with wildcard pattern only: `_`
error: aborting due to 4 previous errors error: aborting due to 4 previous errors