@@ -4,7 +4,8 @@ use clippy_utils::msrvs::Msrv;
44use clippy_utils:: source:: snippet;
55use clippy_utils:: visitors:: is_local_used;
66use clippy_utils:: {
7- SpanlessEq , is_res_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_stmt, peel_ref_operators,
7+ SpanlessEq , count_ref_operators, is_res_lang_ctor, is_unit_expr, path_to_local, peel_blocks_with_stmt,
8+ peel_ref_operators,
89} ;
910use rustc_errors:: MultiSpan ;
1011use rustc_hir:: LangItem :: OptionNone ;
@@ -14,10 +15,10 @@ use rustc_span::Span;
1415
1516use super :: { COLLAPSIBLE_MATCH , pat_contains_disallowed_or} ;
1617
17- pub ( super ) fn check_match < ' tcx > ( cx : & LateContext < ' tcx > , arms : & ' tcx [ Arm < ' _ > ] , msrv : & Msrv ) {
18+ pub ( super ) fn check_match < ' tcx > ( cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > , arms : & ' tcx [ Arm < ' _ > ] , msrv : & Msrv ) {
1819 if let Some ( els_arm) = arms. iter ( ) . rfind ( |arm| arm_is_wild_like ( cx, arm) ) {
1920 for arm in arms {
20- check_arm ( cx, true , arm. pat , arm. body , arm. guard , Some ( els_arm. body ) , msrv) ;
21+ check_arm ( cx, true , arm. pat , expr , arm. body , arm. guard , Some ( els_arm. body ) , msrv) ;
2122 }
2223 }
2324}
@@ -27,15 +28,18 @@ pub(super) fn check_if_let<'tcx>(
2728 pat : & ' tcx Pat < ' _ > ,
2829 body : & ' tcx Expr < ' _ > ,
2930 else_expr : Option < & ' tcx Expr < ' _ > > ,
31+ let_expr : & ' tcx Expr < ' _ > ,
3032 msrv : & Msrv ,
3133) {
32- check_arm ( cx, false , pat, body, None , else_expr, msrv) ;
34+ check_arm ( cx, false , pat, let_expr , body, None , else_expr, msrv) ;
3335}
3436
37+ #[ allow( clippy:: too_many_arguments) ]
3538fn check_arm < ' tcx > (
3639 cx : & LateContext < ' tcx > ,
3740 outer_is_match : bool ,
3841 outer_pat : & ' tcx Pat < ' tcx > ,
42+ outer_cond : & ' tcx Expr < ' tcx > ,
3943 outer_then_body : & ' tcx Expr < ' tcx > ,
4044 outer_guard : Option < & ' tcx Expr < ' tcx > > ,
4145 outer_else_body : Option < & ' tcx Expr < ' tcx > > ,
@@ -99,10 +103,22 @@ fn check_arm<'tcx>(
99103 } else {
100104 String :: new ( )
101105 } ;
106+
107+ let refs_count = count_ref_operators ( cx, inner_scrutinee) ;
102108 span_lint_and_then ( cx, COLLAPSIBLE_MATCH , inner_expr. span , msg, |diag| {
103109 let mut help_span = MultiSpan :: from_spans ( vec ! [ binding_span, inner_then_pat. span] ) ;
104110 help_span. push_span_label ( binding_span, "replace this binding" ) ;
105111 help_span. push_span_label ( inner_then_pat. span , format ! ( "with this pattern{replace_msg}" ) ) ;
112+
113+ if refs_count != 0 {
114+ let method = if refs_count < 0 { ".copied()" } else { ".as_ref()" } ;
115+ let outer_cond_msg = format ! (
116+ "use: `{}{}`" ,
117+ snippet( cx, outer_cond. span, ".." ) ,
118+ method. repeat( refs_count. unsigned_abs( ) )
119+ ) ;
120+ help_span. push_span_label ( outer_cond. span , outer_cond_msg) ;
121+ }
106122 diag. span_help (
107123 help_span,
108124 "the outer pattern can be modified to include the inner pattern" ,
0 commit comments