diff --git a/clippy_lints/src/matches/match_like_matches.rs b/clippy_lints/src/matches/match_like_matches.rs index 33bc20dad6b..107c2cd844b 100644 --- a/clippy_lints/src/matches/match_like_matches.rs +++ b/clippy_lints/src/matches/match_like_matches.rs @@ -1,10 +1,12 @@ +use super::REDUNDANT_PATTERN_MATCHING; use clippy_utils::diagnostics::span_lint_and_sugg; +use clippy_utils::is_lint_allowed; use clippy_utils::is_wild; use clippy_utils::source::snippet_with_applicability; use clippy_utils::span_contains_comment; use rustc_ast::{Attribute, LitKind}; use rustc_errors::Applicability; -use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Guard, Pat}; +use rustc_hir::{Arm, BorrowKind, Expr, ExprKind, Guard, Pat, PatKind, QPath}; use rustc_lint::{LateContext, LintContext}; use rustc_middle::ty; use rustc_span::source_map::Spanned; @@ -99,6 +101,14 @@ where } } + for arm in iter_without_last.clone() { + if let Some(pat) = arm.1 { + if !is_lint_allowed(cx, REDUNDANT_PATTERN_MATCHING, pat.hir_id) && is_some(pat.kind) { + return false; + } + } + } + // The suggestion may be incorrect, because some arms can have `cfg` attributes // evaluated into `false` and so such arms will be stripped before. let mut applicability = Applicability::MaybeIncorrect; @@ -170,3 +180,19 @@ fn find_bool_lit(ex: &ExprKind<'_>) -> Option { _ => None, } } + +fn is_some(path_kind: PatKind<'_>) -> bool { + match path_kind { + PatKind::TupleStruct(ref path_left, patterns, _) if is_wild(&patterns[0]) => match path_left { + QPath::Resolved(_, path) => { + let name = path.segments[0].ident; + if name.as_str() == "Some" { + return true; + } + return false; + }, + _ => false, + }, + _ => false, + } +} diff --git a/clippy_lints/src/matches/redundant_pattern_match.rs b/clippy_lints/src/matches/redundant_pattern_match.rs index 53480a257c5..2ad11995325 100644 --- a/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/clippy_lints/src/matches/redundant_pattern_match.rs @@ -186,7 +186,6 @@ fn find_sugg_for_if_let<'tcx>( } pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op: &Expr<'_>, arms: &[Arm<'_>]) { - //eprintln!("{:#?}", expr); if arms.len() == 2 { let node_pair = (&arms[0].pat.kind, &arms[1].pat.kind); let found_good_method = match node_pair { diff --git a/tests/ui/match_expr_like_matches_macro.fixed b/tests/ui/match_expr_like_matches_macro.fixed index 7215660da67..60f59066173 100644 --- a/tests/ui/match_expr_like_matches_macro.fixed +++ b/tests/ui/match_expr_like_matches_macro.fixed @@ -15,7 +15,7 @@ fn main() { let _y = matches!(x, Some(0)); // Lint - let _w = matches!(x, Some(_)); + let _w = x.is_some(); // Turn into is_none let _z = x.is_none(); diff --git a/tests/ui/match_expr_like_matches_macro.stderr b/tests/ui/match_expr_like_matches_macro.stderr index 46f67ef4900..b72fe10b748 100644 --- a/tests/ui/match_expr_like_matches_macro.stderr +++ b/tests/ui/match_expr_like_matches_macro.stderr @@ -10,7 +10,7 @@ LL | | }; | = note: `-D clippy::match-like-matches-macro` implied by `-D warnings` -error: match expression looks like `matches!` macro +error: redundant pattern matching, consider using `is_some()` --> $DIR/match_expr_like_matches_macro.rs:21:14 | LL | let _w = match x { @@ -18,7 +18,9 @@ LL | let _w = match x { LL | | Some(_) => true, LL | | _ => false, LL | | }; - | |_____^ help: try this: `matches!(x, Some(_))` + | |_____^ help: try this: `x.is_some()` + | + = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: redundant pattern matching, consider using `is_none()` --> $DIR/match_expr_like_matches_macro.rs:27:14 @@ -29,8 +31,6 @@ LL | | Some(_) => false, LL | | None => true, LL | | }; | |_____^ help: try this: `x.is_none()` - | - = note: `-D clippy::redundant-pattern-matching` implied by `-D warnings` error: match expression looks like `matches!` macro --> $DIR/match_expr_like_matches_macro.rs:33:15