@@ -10,7 +10,6 @@ use rustc_errors::Applicability;
10
10
use rustc_hir:: { Block , Expr , ExprKind , LetStmt , Node , UnOp } ;
11
11
use rustc_lint:: { LateContext , LateLintPass } ;
12
12
use rustc_middle:: ty:: adjustment:: { Adjust , AutoBorrow , AutoBorrowMutability } ;
13
- use rustc_middle:: ty:: { self } ;
14
13
use rustc_session:: declare_lint_pass;
15
14
use rustc_span:: sym;
16
15
@@ -53,20 +52,14 @@ impl LateLintPass<'_> for UnnecessaryIndexing {
53
52
// check for call of is_empty
54
53
&& let ExprKind :: MethodCall ( method, conditional_receiver, _, _) = unary_inner. kind
55
54
&& method. ident . as_str ( ) == "is_empty"
56
- && let typeck_results = cx. typeck_results ( )
57
- && let expr_ty = typeck_results. expr_ty ( conditional_receiver)
55
+ && let expr_ty = cx. typeck_results ( ) . expr_ty ( conditional_receiver)
58
56
&& let peeled = expr_ty. peel_refs ( )
59
57
&& ( peeled. is_slice ( ) || peeled. is_array ( ) || is_type_diagnostic_item ( cx, peeled, sym:: Vec ) )
60
58
&& let ExprKind :: Block ( block, _) = if_expr. then . kind
61
- {
62
59
// do not lint if conditional receiver is mutable reference
63
- if let ty:: Ref ( _, _, Mutability :: Mut ) = expr_ty. kind ( ) {
64
- return ;
65
- }
66
-
67
- let result = process_indexing ( cx, block, conditional_receiver) ;
68
-
69
- if let Some ( r) = result
60
+ && expr_ty. ref_mutability ( ) != Some ( Mutability :: Mut )
61
+ {
62
+ if let Some ( r) = process_indexing ( cx, block, conditional_receiver)
70
63
&& let Some ( receiver) = r. index_receiver
71
64
{
72
65
span_lint_and_then (
@@ -87,23 +80,26 @@ impl LateLintPass<'_> for UnnecessaryIndexing {
87
80
Applicability :: Unspecified ,
88
81
) ;
89
82
diag. span_suggestion ( first_local. span , "remove this line" , "" , Applicability :: Unspecified ) ;
90
- if !r. extra_locals . is_empty ( ) {
83
+ if !r. extra_exprs . is_empty ( ) {
91
84
let extra_local_suggestions = r
92
- . extra_locals
85
+ . extra_exprs
93
86
. iter ( )
94
- . map ( |x| {
95
- (
96
- x. init . unwrap ( ) . span ,
97
- snippet ( cx, first_local. pat . span , ".." ) . to_string ( ) ,
98
- )
87
+ . filter_map ( |x| {
88
+ if let ExprKind :: Let ( l) = x. kind {
89
+ Some ( ( l. init . span , snippet ( cx, first_local. pat . span , ".." ) . to_string ( ) ) )
90
+ } else {
91
+ None
92
+ }
99
93
} )
100
94
. collect :: < Vec < _ > > ( ) ;
101
95
102
- diag. multipart_suggestion (
103
- "initialize this variable to be the `Some` variant (may need dereferencing)" ,
104
- extra_local_suggestions,
105
- Applicability :: Unspecified ,
106
- ) ;
96
+ if !extra_local_suggestions. is_empty ( ) {
97
+ diag. multipart_suggestion (
98
+ "initialize this variable to be the `Some` variant (may need dereferencing)" ,
99
+ extra_local_suggestions,
100
+ Applicability :: Unspecified ,
101
+ ) ;
102
+ }
107
103
}
108
104
if !r. extra_exprs . is_empty ( ) {
109
105
let index_accesses = r
@@ -140,20 +136,17 @@ impl LateLintPass<'_> for UnnecessaryIndexing {
140
136
141
137
struct IndexCheckResult < ' a > {
142
138
// the receiver for the index operation
143
- pub index_receiver : Option < & ' a Expr < ' a > > ,
139
+ index_receiver : Option < & ' a Expr < ' a > > ,
144
140
// first local in the block - used as pattern for `Some(pat)`
145
- pub first_local : Option < & ' a LetStmt < ' a > > ,
146
- // any other locals to be aware of, these are set to the value of `pat`
147
- pub extra_locals : Vec < & ' a LetStmt < ' a > > ,
141
+ first_local : Option < & ' a LetStmt < ' a > > ,
148
142
// any other index expressions to replace with `pat` (or "element" if no local exists)
149
- pub extra_exprs : Vec < & ' a Expr < ' a > > ,
143
+ extra_exprs : Vec < & ' a Expr < ' a > > ,
150
144
}
151
145
impl < ' a > IndexCheckResult < ' a > {
152
146
pub fn new ( ) -> Self {
153
147
IndexCheckResult {
154
148
index_receiver : None ,
155
149
first_local : None ,
156
- extra_locals : vec ! [ ] ,
157
150
extra_exprs : vec ! [ ] ,
158
151
}
159
152
}
@@ -170,7 +163,6 @@ fn process_indexing<'a>(
170
163
171
164
let mut index_receiver: Option < & Expr < ' _ > > = None ;
172
165
let mut first_local: Option < & LetStmt < ' _ > > = None ;
173
- let mut extra_locals: Vec < & LetStmt < ' _ > > = vec ! [ ] ;
174
166
let mut extra_exprs: Vec < & Expr < ' _ > > = vec ! [ ] ;
175
167
176
168
// if res == Some(()), then mutation occurred
@@ -190,7 +182,7 @@ fn process_indexing<'a>(
190
182
if first_local. is_none ( ) {
191
183
first_local = Some ( local) ;
192
184
} else {
193
- extra_locals . push ( local ) ;
185
+ extra_exprs . push ( x ) ;
194
186
} ;
195
187
} else {
196
188
extra_exprs. push ( x) ;
@@ -214,7 +206,6 @@ fn process_indexing<'a>(
214
206
215
207
if res. is_none ( ) {
216
208
result. extra_exprs = extra_exprs;
217
- result. extra_locals = extra_locals;
218
209
result. first_local = first_local;
219
210
result. index_receiver = index_receiver;
220
211
Some ( result)
0 commit comments