diff --git a/clippy_lints/src/matches.rs b/clippy_lints/src/matches.rs index 04b35835c6b8..6372cb86616e 100644 --- a/clippy_lints/src/matches.rs +++ b/clippy_lints/src/matches.rs @@ -1185,6 +1185,14 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr } else { pat }; + + // strip potential borrows (#6503), but only if the type is a reference + let mut ex_new = ex; + if let ExprKind::AddrOf(BorrowKind::Ref, .., ex_inner) = ex.kind { + if let ty::Ref(..) = cx.typeck_results().expr_ty(&ex_inner).kind() { + ex_new = ex_inner; + } + }; span_lint_and_sugg( cx, MATCH_LIKE_MATCHES_MACRO, @@ -1194,7 +1202,7 @@ fn find_matches_sugg(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr format!( "{}matches!({}, {})", if b0 { "" } else { "!" }, - snippet_with_applicability(cx, ex.span, "..", &mut applicability), + snippet_with_applicability(cx, ex_new.span, "..", &mut applicability), pat_and_guard, ), applicability, diff --git a/tests/ui/match_expr_like_matches_macro.fixed b/tests/ui/match_expr_like_matches_macro.fixed index 84981a525973..dd97ad0150fd 100644 --- a/tests/ui/match_expr_like_matches_macro.fixed +++ b/tests/ui/match_expr_like_matches_macro.fixed @@ -99,4 +99,32 @@ fn main() { _ => false, }; } + + { + // should print "z" in suggestion (#6503) + let z = &Some(3); + let _z = matches!(z, Some(3)); + } + + { + // this could also print "z" in suggestion..? + let z = Some(3); + let _z = matches!(&z, Some(3)); + } + + { + enum AnEnum { + X, + Y, + } + + fn foo(_x: AnEnum) {} + + fn main() { + let z = AnEnum::X; + // we can't remove the reference here! + let _ = matches!(&z, AnEnum::X); + foo(z); + } + } } diff --git a/tests/ui/match_expr_like_matches_macro.rs b/tests/ui/match_expr_like_matches_macro.rs index 94c7c3cadacf..d9eb7f54c652 100644 --- a/tests/ui/match_expr_like_matches_macro.rs +++ b/tests/ui/match_expr_like_matches_macro.rs @@ -119,4 +119,41 @@ fn main() { _ => false, }; } + + { + // should print "z" in suggestion (#6503) + let z = &Some(3); + let _z = match &z { + Some(3) => true, + _ => false, + }; + } + + { + // this could also print "z" in suggestion..? + let z = Some(3); + let _z = match &z { + Some(3) => true, + _ => false, + }; + } + + { + enum AnEnum { + X, + Y, + } + + fn foo(_x: AnEnum) {} + + fn main() { + let z = AnEnum::X; + // we can't remove the reference here! + let _ = match &z { + AnEnum::X => true, + _ => false, + }; + foo(z); + } + } } diff --git a/tests/ui/match_expr_like_matches_macro.stderr b/tests/ui/match_expr_like_matches_macro.stderr index c52e41c78894..550318d6225f 100644 --- a/tests/ui/match_expr_like_matches_macro.stderr +++ b/tests/ui/match_expr_like_matches_macro.stderr @@ -70,5 +70,35 @@ LL | | _ => true, LL | | }; | |_________^ help: try this: `!matches!(x, E::B(_) | E::C)` -error: aborting due to 7 previous errors +error: match expression looks like `matches!` macro + --> $DIR/match_expr_like_matches_macro.rs:126:18 + | +LL | let _z = match &z { + | __________________^ +LL | | Some(3) => true, +LL | | _ => false, +LL | | }; + | |_________^ help: try this: `matches!(z, Some(3))` + +error: match expression looks like `matches!` macro + --> $DIR/match_expr_like_matches_macro.rs:135:18 + | +LL | let _z = match &z { + | __________________^ +LL | | Some(3) => true, +LL | | _ => false, +LL | | }; + | |_________^ help: try this: `matches!(&z, Some(3))` + +error: match expression looks like `matches!` macro + --> $DIR/match_expr_like_matches_macro.rs:152:21 + | +LL | let _ = match &z { + | _____________________^ +LL | | AnEnum::X => true, +LL | | _ => false, +LL | | }; + | |_____________^ help: try this: `matches!(&z, AnEnum::X)` + +error: aborting due to 10 previous errors