@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::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:: { SpanlessEq , contains_name, higher, is_integer_const, sugg} ;
6
+ use clippy_utils:: { SpanlessEq , contains_name, higher, is_integer_const, peel_hir_expr_while , sugg} ;
7
7
use rustc_ast:: ast;
8
8
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexMap } ;
9
9
use rustc_errors:: Applicability ;
@@ -253,12 +253,38 @@ struct VarVisitor<'a, 'tcx> {
253
253
254
254
impl < ' tcx > VarVisitor < ' _ , ' tcx > {
255
255
fn check ( & mut self , idx : & ' tcx Expr < ' _ > , seqexpr : & ' tcx Expr < ' _ > , expr : & ' tcx Expr < ' _ > ) -> bool {
256
- let index_used_directly = matches ! ( idx. kind, ExprKind :: Path ( _) ) ;
256
+ let mut used_cnt = 0 ;
257
+ // It is `true` if all indices are direct
258
+ let mut index_used_directly = true ;
259
+
260
+ // Handle initial index
261
+ if is_local_used ( self . cx , idx, self . var ) {
262
+ used_cnt += 1 ;
263
+ index_used_directly &= matches ! ( idx. kind, ExprKind :: Path ( _) ) ;
264
+ }
265
+ // Handle nested indices
266
+ let seqexpr = peel_hir_expr_while ( seqexpr, |e| {
267
+ if let ExprKind :: Index ( e, idx, _) = e. kind {
268
+ if is_local_used ( self . cx , idx, self . var ) {
269
+ used_cnt += 1 ;
270
+ index_used_directly &= matches ! ( idx. kind, ExprKind :: Path ( _) ) ;
271
+ }
272
+ Some ( e)
273
+ } else {
274
+ None
275
+ }
276
+ } ) ;
277
+
278
+ match used_cnt {
279
+ 0 => return true ,
280
+ n if n > 1 => self . nonindex = true , // Optimize code like `a[i][i]`
281
+ _ => { } ,
282
+ }
283
+
257
284
if let ExprKind :: Path ( ref seqpath) = seqexpr. kind
258
285
// the indexed container is referenced by a name
259
286
&& let QPath :: Resolved ( None , seqvar) = * seqpath
260
287
&& seqvar. segments . len ( ) == 1
261
- && is_local_used ( self . cx , idx, self . var )
262
288
{
263
289
if self . prefer_mutable {
264
290
self . indexed_mut . insert ( seqvar. segments [ 0 ] . ident . name ) ;
@@ -312,7 +338,6 @@ impl<'tcx> VarVisitor<'_, 'tcx> {
312
338
impl < ' tcx > Visitor < ' tcx > for VarVisitor < ' _ , ' tcx > {
313
339
fn visit_expr ( & mut self , expr : & ' tcx Expr < ' _ > ) {
314
340
if let ExprKind :: MethodCall ( meth, args_0, [ args_1, ..] , _) = & expr. kind
315
- // a range index op
316
341
&& let Some ( trait_id) = self
317
342
. cx
318
343
. typeck_results ( )
0 commit comments