@@ -21,17 +21,64 @@ pub(crate) fn check_if_let<'tcx>(
2121 then_expr : & ' tcx Expr < ' _ > ,
2222 else_expr : & ' tcx Expr < ' _ > ,
2323) {
24- find_matches_sugg (
25- cx,
26- let_expr,
27- [
28- ( & [ ] [ ..] , Some ( let_pat) , then_expr, None ) ,
29- ( & [ ] [ ..] , None , else_expr, None ) ,
30- ]
31- . into_iter ( ) ,
32- expr,
33- true ,
34- ) ;
24+ let mut arms = [ ( Some ( let_pat) , then_expr) , ( None , else_expr) ] . into_iter ( ) ;
25+ let is_if_let = true ;
26+ if !span_contains_comment ( cx. sess ( ) . source_map ( ) , expr. span )
27+ && cx. typeck_results ( ) . expr_ty ( expr) . is_bool ( )
28+ && let Some ( ( None , else_expr) ) = arms. next_back ( )
29+ && let arms_without_last = [ ( Some ( let_pat) , then_expr) ]
30+ && let Some ( ( _, first_expr) ) = arms. next ( )
31+ && let Some ( b0) = find_bool_lit ( first_expr)
32+ && let Some ( b1) = find_bool_lit ( else_expr)
33+ && b0 != b1
34+ && arms. all ( |( _, expr) | find_bool_lit ( expr) == Some ( b0) )
35+ {
36+ for arm in & arms_without_last {
37+ if let Some ( pat) = arm. 0
38+ && !is_lint_allowed ( cx, REDUNDANT_PATTERN_MATCHING , pat. hir_id )
39+ && is_some_wild ( pat. kind )
40+ {
41+ return ;
42+ }
43+ }
44+
45+ // The suggestion may be incorrect, because some arms can have `cfg` attributes
46+ // evaluated into `false` and so such arms will be stripped before.
47+ let mut applicability = Applicability :: MaybeIncorrect ;
48+ let pat = {
49+ use itertools:: Itertools as _;
50+ arms_without_last
51+ . into_iter ( )
52+ . filter_map ( |arm| arm. 0 )
53+ . map ( |pat| snippet_with_applicability ( cx, pat. span , ".." , & mut applicability) )
54+ . join ( " | " )
55+ } ;
56+ let pat_and_guard = pat;
57+
58+ // strip potential borrows (#6503), but only if the type is a reference
59+ let mut ex_new = let_expr;
60+ if let ExprKind :: AddrOf ( BorrowKind :: Ref , .., ex_inner) = let_expr. kind
61+ && let ty:: Ref ( ..) = cx. typeck_results ( ) . expr_ty ( ex_inner) . kind ( )
62+ {
63+ ex_new = ex_inner;
64+ }
65+ span_lint_and_sugg (
66+ cx,
67+ MATCH_LIKE_MATCHES_MACRO ,
68+ expr. span ,
69+ format ! (
70+ "{} expression looks like `matches!` macro" ,
71+ if is_if_let { "if let .. else" } else { "match" }
72+ ) ,
73+ "try" ,
74+ format ! (
75+ "{}matches!({}, {pat_and_guard})" ,
76+ if b0 { "" } else { "!" } ,
77+ snippet_with_applicability( cx, ex_new. span, ".." , & mut applicability) ,
78+ ) ,
79+ applicability,
80+ ) ;
81+ }
3582}
3683
3784pub ( super ) fn check_match < ' tcx > (
0 commit comments