@@ -37,83 +37,75 @@ declare_lint_pass!(NeedlessBorrowedRef => [NEEDLESS_BORROWED_REFERENCE]);
37
37
38
38
impl < ' tcx > LateLintPass < ' tcx > for NeedlessBorrowedRef {
39
39
fn check_pat ( & mut self , cx : & LateContext < ' tcx > , ref_pat : & ' tcx Pat < ' _ > ) {
40
- if ref_pat. span . from_expansion ( ) {
41
- // OK, simple enough, lints doesn't check in macro.
42
- return ;
43
- }
44
-
45
- // Do not lint patterns that are part of an OR `|` pattern, the binding mode must match in all arms
46
- for ( _, node) in cx. tcx . hir ( ) . parent_iter ( ref_pat. hir_id ) {
47
- let Node :: Pat ( pat) = node else { break } ;
48
-
49
- if matches ! ( pat. kind, PatKind :: Or ( _) ) {
50
- return ;
40
+ if let PatKind :: Ref ( pat, Mutability :: Not ) = ref_pat. kind
41
+ && !ref_pat. span . from_expansion ( )
42
+ && cx
43
+ . tcx
44
+ . hir ( )
45
+ . parent_iter ( ref_pat. hir_id )
46
+ . map_while ( |( _, parent) | if let Node :: Pat ( pat) = parent { Some ( pat) } else { None } )
47
+ // Do not lint patterns that are part of an OR `|` pattern, the binding mode must match in all arms
48
+ . all ( |pat| !matches ! ( pat. kind, PatKind :: Or ( _) ) )
49
+ {
50
+ match pat. kind {
51
+ // Check sub_pat got a `ref` keyword (excluding `ref mut`).
52
+ PatKind :: Binding ( BindingMode :: REF , _, ident, None ) => {
53
+ span_lint_and_then (
54
+ cx,
55
+ NEEDLESS_BORROWED_REFERENCE ,
56
+ ref_pat. span ,
57
+ "this pattern takes a reference on something that is being dereferenced" ,
58
+ |diag| {
59
+ // `&ref ident`
60
+ // ^^^^^
61
+ let span = ref_pat. span . until ( ident. span ) ;
62
+ diag. span_suggestion_verbose (
63
+ span,
64
+ "try removing the `&ref` part" ,
65
+ String :: new ( ) ,
66
+ Applicability :: MachineApplicable ,
67
+ ) ;
68
+ } ,
69
+ ) ;
70
+ } ,
71
+ // Slices where each element is `ref`: `&[ref a, ref b, ..., ref z]`
72
+ PatKind :: Slice (
73
+ before,
74
+ None
75
+ | Some ( Pat {
76
+ kind : PatKind :: Wild , ..
77
+ } ) ,
78
+ after,
79
+ ) => {
80
+ check_subpatterns (
81
+ cx,
82
+ "dereferencing a slice pattern where every element takes a reference" ,
83
+ ref_pat,
84
+ pat,
85
+ itertools:: chain ( before, after) ,
86
+ ) ;
87
+ } ,
88
+ PatKind :: Tuple ( subpatterns, _) | PatKind :: TupleStruct ( _, subpatterns, _) => {
89
+ check_subpatterns (
90
+ cx,
91
+ "dereferencing a tuple pattern where every element takes a reference" ,
92
+ ref_pat,
93
+ pat,
94
+ subpatterns,
95
+ ) ;
96
+ } ,
97
+ PatKind :: Struct ( _, fields, _) => {
98
+ check_subpatterns (
99
+ cx,
100
+ "dereferencing a struct pattern where every field's pattern takes a reference" ,
101
+ ref_pat,
102
+ pat,
103
+ fields. iter ( ) . map ( |field| field. pat ) ,
104
+ ) ;
105
+ } ,
106
+ _ => { } ,
51
107
}
52
108
}
53
-
54
- // Only lint immutable refs, because `&mut ref T` may be useful.
55
- let PatKind :: Ref ( pat, Mutability :: Not ) = ref_pat. kind else {
56
- return ;
57
- } ;
58
-
59
- match pat. kind {
60
- // Check sub_pat got a `ref` keyword (excluding `ref mut`).
61
- PatKind :: Binding ( BindingMode :: REF , _, ident, None ) => {
62
- span_lint_and_then (
63
- cx,
64
- NEEDLESS_BORROWED_REFERENCE ,
65
- ref_pat. span ,
66
- "this pattern takes a reference on something that is being dereferenced" ,
67
- |diag| {
68
- // `&ref ident`
69
- // ^^^^^
70
- let span = ref_pat. span . until ( ident. span ) ;
71
- diag. span_suggestion_verbose (
72
- span,
73
- "try removing the `&ref` part" ,
74
- String :: new ( ) ,
75
- Applicability :: MachineApplicable ,
76
- ) ;
77
- } ,
78
- ) ;
79
- } ,
80
- // Slices where each element is `ref`: `&[ref a, ref b, ..., ref z]`
81
- PatKind :: Slice (
82
- before,
83
- None
84
- | Some ( Pat {
85
- kind : PatKind :: Wild , ..
86
- } ) ,
87
- after,
88
- ) => {
89
- check_subpatterns (
90
- cx,
91
- "dereferencing a slice pattern where every element takes a reference" ,
92
- ref_pat,
93
- pat,
94
- itertools:: chain ( before, after) ,
95
- ) ;
96
- } ,
97
- PatKind :: Tuple ( subpatterns, _) | PatKind :: TupleStruct ( _, subpatterns, _) => {
98
- check_subpatterns (
99
- cx,
100
- "dereferencing a tuple pattern where every element takes a reference" ,
101
- ref_pat,
102
- pat,
103
- subpatterns,
104
- ) ;
105
- } ,
106
- PatKind :: Struct ( _, fields, _) => {
107
- check_subpatterns (
108
- cx,
109
- "dereferencing a struct pattern where every field's pattern takes a reference" ,
110
- ref_pat,
111
- pat,
112
- fields. iter ( ) . map ( |field| field. pat ) ,
113
- ) ;
114
- } ,
115
- _ => { } ,
116
- }
117
109
}
118
110
}
119
111
0 commit comments