@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
33use clippy_utils:: source:: snippet;
44use clippy_utils:: ty:: has_iter_method;
55use 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} ;
77use rustc_ast:: ast;
88use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexMap } ;
99use rustc_errors:: Applicability ;
@@ -253,12 +253,38 @@ struct VarVisitor<'a, 'tcx> {
253253
254254impl < ' tcx > VarVisitor < ' _ , ' tcx > {
255255 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+
257284 if let ExprKind :: Path ( ref seqpath) = seqexpr. kind
258285 // the indexed container is referenced by a name
259286 && let QPath :: Resolved ( None , seqvar) = * seqpath
260287 && seqvar. segments . len ( ) == 1
261- && is_local_used ( self . cx , idx, self . var )
262288 {
263289 if self . prefer_mutable {
264290 self . indexed_mut . insert ( seqvar. segments [ 0 ] . ident . name ) ;
@@ -312,7 +338,6 @@ impl<'tcx> VarVisitor<'_, 'tcx> {
312338impl < ' tcx > Visitor < ' tcx > for VarVisitor < ' _ , ' tcx > {
313339 fn visit_expr ( & mut self , expr : & ' tcx Expr < ' _ > ) {
314340 if let ExprKind :: MethodCall ( meth, args_0, [ args_1, ..] , _) = & expr. kind
315- // a range index op
316341 && let Some ( trait_id) = self
317342 . cx
318343 . typeck_results ( )
0 commit comments