11use clippy_utils:: diagnostics:: span_lint_and_sugg;
22use clippy_utils:: source:: { reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context} ;
3+ use clippy_utils:: visitors:: for_each_expr;
34use clippy_utils:: {
45 SpanlessEq , can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified,
56 peel_hir_expr_while,
@@ -12,6 +13,7 @@ use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp};
1213use rustc_lint:: { LateContext , LateLintPass } ;
1314use rustc_session:: declare_lint_pass;
1415use rustc_span:: { DUMMY_SP , Span , SyntaxContext , sym} ;
16+ use std:: ops:: ControlFlow ;
1517
1618declare_clippy_lint ! {
1719 /// ### What it does
@@ -500,7 +502,7 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
500502 self . visit_non_tail_expr ( insert_expr. value ) ;
501503 self . is_single_insert = is_single_insert;
502504 } ,
503- _ if SpanlessEq :: new ( self . cx ) . eq_expr ( self . map , expr) => {
505+ _ if is_any_expr_in_map_used ( self . cx , self . map , expr) => {
504506 self . is_map_used = true ;
505507 } ,
506508 _ => match expr. kind {
@@ -562,6 +564,19 @@ impl<'tcx> Visitor<'tcx> for InsertSearcher<'_, 'tcx> {
562564 }
563565}
564566
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+
565580struct InsertSearchResults < ' tcx > {
566581 edits : Vec < Edit < ' tcx > > ,
567582 allow_insert_closure : bool ,
0 commit comments