@@ -4,7 +4,8 @@ use clippy_utils::msrvs::Msrv;
4
4
use clippy_utils:: source:: snippet;
5
5
use clippy_utils:: visitors:: is_local_used;
6
6
use 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,
8
9
} ;
9
10
use rustc_errors:: MultiSpan ;
10
11
use rustc_hir:: LangItem :: OptionNone ;
@@ -14,10 +15,10 @@ use rustc_span::Span;
14
15
15
16
use super :: { COLLAPSIBLE_MATCH , pat_contains_disallowed_or} ;
16
17
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 ) {
18
19
if let Some ( els_arm) = arms. iter ( ) . rfind ( |arm| arm_is_wild_like ( cx, arm) ) {
19
20
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) ;
21
22
}
22
23
}
23
24
}
@@ -27,15 +28,18 @@ pub(super) fn check_if_let<'tcx>(
27
28
pat : & ' tcx Pat < ' _ > ,
28
29
body : & ' tcx Expr < ' _ > ,
29
30
else_expr : Option < & ' tcx Expr < ' _ > > ,
31
+ let_expr : & ' tcx Expr < ' _ > ,
30
32
msrv : & Msrv ,
31
33
) {
32
- check_arm ( cx, false , pat, body, None , else_expr, msrv) ;
34
+ check_arm ( cx, false , pat, let_expr , body, None , else_expr, msrv) ;
33
35
}
34
36
37
+ #[ allow( clippy:: too_many_arguments) ]
35
38
fn check_arm < ' tcx > (
36
39
cx : & LateContext < ' tcx > ,
37
40
outer_is_match : bool ,
38
41
outer_pat : & ' tcx Pat < ' tcx > ,
42
+ outer_cond : & ' tcx Expr < ' tcx > ,
39
43
outer_then_body : & ' tcx Expr < ' tcx > ,
40
44
outer_guard : Option < & ' tcx Expr < ' tcx > > ,
41
45
outer_else_body : Option < & ' tcx Expr < ' tcx > > ,
@@ -99,10 +103,22 @@ fn check_arm<'tcx>(
99
103
} else {
100
104
String :: new ( )
101
105
} ;
106
+
107
+ let refs_count = count_ref_operators ( cx, inner_scrutinee) ;
102
108
span_lint_and_then ( cx, COLLAPSIBLE_MATCH , inner_expr. span , msg, |diag| {
103
109
let mut help_span = MultiSpan :: from_spans ( vec ! [ binding_span, inner_then_pat. span] ) ;
104
110
help_span. push_span_label ( binding_span, "replace this binding" ) ;
105
111
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
+ }
106
122
diag. span_help (
107
123
help_span,
108
124
"the outer pattern can be modified to include the inner pattern" ,
0 commit comments