1
1
use clippy_utils:: diagnostics:: span_lint_and_sugg;
2
2
use clippy_utils:: source:: { reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context} ;
3
+ use clippy_utils:: visitors:: for_each_expr;
3
4
use clippy_utils:: {
4
5
SpanlessEq , can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified,
5
6
peel_hir_expr_while,
@@ -12,6 +13,7 @@ use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp};
12
13
use rustc_lint:: { LateContext , LateLintPass } ;
13
14
use rustc_session:: declare_lint_pass;
14
15
use rustc_span:: { DUMMY_SP , Span , SyntaxContext , sym} ;
16
+ use std:: ops:: ControlFlow ;
15
17
16
18
declare_clippy_lint ! {
17
19
/// ### What it does
@@ -500,7 +502,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
500
502
self . visit_non_tail_expr ( insert_expr. value ) ;
501
503
self . is_single_insert = is_single_insert;
502
504
} ,
503
- _ if SpanlessEq :: new ( self . cx ) . eq_expr ( self . map , expr) => {
505
+ _ if is_any_expr_in_map_used ( self . cx , self . map , expr) => {
504
506
self . is_map_used = true ;
505
507
} ,
506
508
_ => match expr. kind {
@@ -562,6 +564,19 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
562
564
}
563
565
}
564
566
567
+ /// Check if the given expression is used for each sub-expression in the given map.
568
+ /// For example, in map `a.b.c.my_map`, The expression `a.b.c.my_map`, `a.b.c`, `a.b`, and `a` are
569
+ /// all checked.
570
+ fn is_any_expr_in_map_used < ' tcx > ( cx : & LateContext < ' tcx > , map : & ' tcx Expr < ' tcx > , expr : & ' tcx Expr < ' tcx > ) -> bool {
571
+ for_each_expr ( cx, map, |e| {
572
+ if SpanlessEq :: new ( cx) . eq_expr ( e, expr) {
573
+ return ControlFlow :: Break ( ( ) ) ;
574
+ }
575
+ ControlFlow :: Continue ( ( ) )
576
+ } )
577
+ . is_some ( )
578
+ }
579
+
565
580
struct InsertSearchResults < ' tcx > {
566
581
edits : Vec < Edit < ' tcx > > ,
567
582
allow_insert_closure : bool ,
0 commit comments