@@ -3,7 +3,9 @@ use clippy_utils::diagnostics::{multispan_sugg, span_lint_and_then};
3
3
use clippy_utils:: source:: snippet;
4
4
use clippy_utils:: ty:: has_iter_method;
5
5
use clippy_utils:: visitors:: is_local_used;
6
- use clippy_utils:: { contains_name, higher, is_integer_const, match_trait_method, paths, sugg, SpanlessEq } ;
6
+ use clippy_utils:: {
7
+ contains_name, higher, is_integer_const, match_trait_method, paths, sugg, SpanlessEq ,
8
+ } ;
7
9
use if_chain:: if_chain;
8
10
use rustc_ast:: ast;
9
11
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
@@ -27,12 +29,7 @@ pub(super) fn check<'tcx>(
27
29
body : & ' tcx Expr < ' _ > ,
28
30
expr : & ' tcx Expr < ' _ > ,
29
31
) {
30
- if let Some ( higher:: Range {
31
- start : Some ( start) ,
32
- ref end,
33
- limits,
34
- } ) = higher:: Range :: hir ( arg)
35
- {
32
+ if let Some ( higher:: Range { start : Some ( start) , ref end, limits } ) = higher:: Range :: hir ( arg) {
36
33
// the var must be a single name
37
34
if let PatKind :: Binding ( _, canonical_id, ident, _) = pat. kind {
38
35
let mut visitor = VarVisitor {
@@ -58,7 +55,11 @@ pub(super) fn check<'tcx>(
58
55
// ensure that the indexed variable was declared before the loop, see #601
59
56
if let Some ( indexed_extent) = indexed_extent {
60
57
let parent_def_id = cx. tcx . hir ( ) . get_parent_item ( expr. hir_id ) ;
61
- let region_scope_tree = cx. tcx . region_scope_tree ( parent_def_id) ;
58
+ let parent_body_id = cx
59
+ . tcx
60
+ . hir ( )
61
+ . body_owned_by ( cx. tcx . hir ( ) . local_def_id_to_hir_id ( parent_def_id) ) ;
62
+ let region_scope_tree = & cx. tcx . typeck_body ( parent_body_id) . region_scope_tree ;
62
63
let pat_extent = region_scope_tree. var_scope ( pat. hir_id . local_id ) . unwrap ( ) ;
63
64
if region_scope_tree. is_subscope_of ( indexed_extent, pat_extent) {
64
65
return ;
@@ -107,17 +108,22 @@ pub(super) fn check<'tcx>(
107
108
}
108
109
}
109
110
110
- if is_len_call ( end, indexed) || is_end_eq_array_len ( cx, end, limits, indexed_ty) {
111
+ if is_len_call ( end, indexed) || is_end_eq_array_len ( cx, end, limits, indexed_ty)
112
+ {
111
113
String :: new ( )
112
- } else if visitor. indexed_mut . contains ( & indexed) && contains_name ( indexed, take_expr) {
114
+ } else if visitor. indexed_mut . contains ( & indexed)
115
+ && contains_name ( indexed, take_expr)
116
+ {
113
117
return ;
114
118
} else {
115
119
match limits {
116
120
ast:: RangeLimits :: Closed => {
117
121
let take_expr = sugg:: Sugg :: hir ( cx, take_expr, "<count>" ) ;
118
122
format ! ( ".take({})" , take_expr + sugg:: ONE )
119
- } ,
120
- ast:: RangeLimits :: HalfOpen => format ! ( ".take({})" , snippet( cx, take_expr. span, ".." ) ) ,
123
+ }
124
+ ast:: RangeLimits :: HalfOpen => {
125
+ format ! ( ".take({})" , snippet( cx, take_expr. span, ".." ) )
126
+ }
121
127
}
122
128
}
123
129
} else {
@@ -143,7 +149,10 @@ pub(super) fn check<'tcx>(
143
149
cx,
144
150
NEEDLESS_RANGE_LOOP ,
145
151
arg. span ,
146
- & format ! ( "the loop variable `{}` is used to index `{}`" , ident. name, indexed) ,
152
+ & format ! (
153
+ "the loop variable `{}` is used to index `{}`" ,
154
+ ident. name, indexed
155
+ ) ,
147
156
|diag| {
148
157
multispan_sugg (
149
158
diag,
@@ -152,7 +161,10 @@ pub(super) fn check<'tcx>(
152
161
( pat. span, format!( "({}, <item>)" , ident. name) ) ,
153
162
(
154
163
arg. span,
155
- format!( "{}.{}().enumerate(){}{}" , indexed, method, method_1, method_2) ,
164
+ format!(
165
+ "{}.{}().enumerate(){}{}" ,
166
+ indexed, method, method_1, method_2
167
+ ) ,
156
168
) ,
157
169
] ,
158
170
) ;
@@ -169,7 +181,10 @@ pub(super) fn check<'tcx>(
169
181
cx,
170
182
NEEDLESS_RANGE_LOOP ,
171
183
arg. span ,
172
- & format ! ( "the loop variable `{}` is only used to index `{}`" , ident. name, indexed) ,
184
+ & format ! (
185
+ "the loop variable `{}` is only used to index `{}`" ,
186
+ ident. name, indexed
187
+ ) ,
173
188
|diag| {
174
189
multispan_sugg (
175
190
diag,
@@ -246,7 +261,12 @@ struct VarVisitor<'a, 'tcx> {
246
261
}
247
262
248
263
impl < ' a , ' tcx > VarVisitor < ' a , ' tcx > {
249
- fn check ( & mut self , idx : & ' tcx Expr < ' _ > , seqexpr : & ' tcx Expr < ' _ > , expr : & ' tcx Expr < ' _ > ) -> bool {
264
+ fn check (
265
+ & mut self ,
266
+ idx : & ' tcx Expr < ' _ > ,
267
+ seqexpr : & ' tcx Expr < ' _ > ,
268
+ expr : & ' tcx Expr < ' _ > ,
269
+ ) -> bool {
250
270
if_chain ! {
251
271
// the indexed container is referenced by a name
252
272
if let ExprKind :: Path ( ref seqpath) = seqexpr. kind;
@@ -262,7 +282,16 @@ impl<'a, 'tcx> VarVisitor<'a, 'tcx> {
262
282
match res {
263
283
Res :: Local ( hir_id) => {
264
284
let parent_def_id = self . cx. tcx. hir( ) . get_parent_item( expr. hir_id) ;
265
- let extent = self . cx. tcx. region_scope_tree( parent_def_id) . var_scope( hir_id. local_id) . unwrap( ) ;
285
+ let parent_body_id = self . cx
286
+ . tcx
287
+ . hir( )
288
+ . body_owned_by( self . cx. tcx. hir( ) . local_def_id_to_hir_id( parent_def_id) ) ;
289
+ let extent = self . cx
290
+ . tcx
291
+ . typeck_body( parent_body_id)
292
+ . region_scope_tree
293
+ . var_scope( hir_id. local_id)
294
+ . unwrap( ) ;
266
295
if index_used_directly {
267
296
self . indexed_directly. insert(
268
297
seqvar. segments[ 0 ] . ident. name,
@@ -331,13 +360,13 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
331
360
self . visit_expr ( lhs) ;
332
361
self . prefer_mutable = false ;
333
362
self . visit_expr ( rhs) ;
334
- } ,
363
+ }
335
364
ExprKind :: AddrOf ( BorrowKind :: Ref , mutbl, expr) => {
336
365
if mutbl == Mutability :: Mut {
337
366
self . prefer_mutable = true ;
338
367
}
339
368
self . visit_expr ( expr) ;
340
- } ,
369
+ }
341
370
ExprKind :: Call ( f, args) => {
342
371
self . visit_expr ( f) ;
343
372
for expr in args {
@@ -350,10 +379,11 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
350
379
}
351
380
self . visit_expr ( expr) ;
352
381
}
353
- } ,
382
+ }
354
383
ExprKind :: MethodCall ( _, args, _) => {
355
384
let def_id = self . cx . typeck_results ( ) . type_dependent_def_id ( expr. hir_id ) . unwrap ( ) ;
356
- for ( ty, expr) in iter:: zip ( self . cx . tcx . fn_sig ( def_id) . inputs ( ) . skip_binder ( ) , args) {
385
+ for ( ty, expr) in iter:: zip ( self . cx . tcx . fn_sig ( def_id) . inputs ( ) . skip_binder ( ) , args)
386
+ {
357
387
self . prefer_mutable = false ;
358
388
if let ty:: Ref ( _, _, mutbl) = * ty. kind ( ) {
359
389
if mutbl == Mutability :: Mut {
@@ -362,11 +392,11 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
362
392
}
363
393
self . visit_expr ( expr) ;
364
394
}
365
- } ,
395
+ }
366
396
ExprKind :: Closure ( _, _, body_id, ..) => {
367
397
let body = self . cx . tcx . hir ( ) . body ( body_id) ;
368
398
self . visit_expr ( & body. value ) ;
369
- } ,
399
+ }
370
400
_ => walk_expr ( self , expr) ,
371
401
}
372
402
self . prefer_mutable = old;
0 commit comments