11use clippy_utils:: diagnostics:: span_lint_and_then;
2- use clippy_utils:: visitors:: LocalUsedVisitor ;
2+ use clippy_utils:: visitors:: is_local_used ;
33use clippy_utils:: { higher, is_lang_ctor, is_unit_expr, path_to_local, peel_ref_operators, SpanlessEq } ;
44use if_chain:: if_chain;
55use rustc_hir:: LangItem :: OptionNone ;
@@ -56,11 +56,11 @@ impl<'tcx> LateLintPass<'tcx> for CollapsibleMatch {
5656 check_arm ( cx, true , arm. pat , arm. body , arm. guard . as_ref ( ) , Some ( els_arm. body ) ) ;
5757 }
5858 }
59- }
59+ } ,
6060 Some ( IfLetOrMatch :: IfLet ( _, pat, body, els) ) => {
6161 check_arm ( cx, false , pat, body, None , els) ;
62- }
63- None => { }
62+ } ,
63+ None => { } ,
6464 }
6565 }
6666}
@@ -71,7 +71,7 @@ fn check_arm<'tcx>(
7171 outer_pat : & ' tcx Pat < ' tcx > ,
7272 outer_then_body : & ' tcx Expr < ' tcx > ,
7373 outer_guard : Option < & ' tcx Guard < ' tcx > > ,
74- outer_else_body : Option < & ' tcx Expr < ' tcx > >
74+ outer_else_body : Option < & ' tcx Expr < ' tcx > > ,
7575) {
7676 let inner_expr = strip_singleton_blocks ( outer_then_body) ;
7777 if_chain ! {
@@ -106,14 +106,13 @@ fn check_arm<'tcx>(
106106 ( Some ( a) , Some ( b) ) => SpanlessEq :: new( cx) . eq_expr( a, b) ,
107107 } ;
108108 // the binding must not be used in the if guard
109- let mut used_visitor = LocalUsedVisitor :: new( cx, binding_id) ;
110- if outer_guard. map_or( true , |( Guard :: If ( e) | Guard :: IfLet ( _, e) ) | !used_visitor. check_expr( e) ) ;
109+ if outer_guard. map_or( true , |( Guard :: If ( e) | Guard :: IfLet ( _, e) ) | !is_local_used( cx, * e, binding_id) ) ;
111110 // ...or anywhere in the inner expression
112111 if match inner {
113112 IfLetOrMatch :: IfLet ( _, _, body, els) => {
114- !used_visitor . check_expr ( body) && els. map_or( true , |e| !used_visitor . check_expr ( e ) )
113+ !is_local_used ( cx , body, binding_id ) && els. map_or( true , |e| !is_local_used ( cx , e , binding_id ) )
115114 } ,
116- IfLetOrMatch :: Match ( _, arms, ..) => !arms. iter( ) . any( |arm| used_visitor . check_arm ( arm) ) ,
115+ IfLetOrMatch :: Match ( _, arms, ..) => !arms. iter( ) . any( |arm| is_local_used ( cx , arm, binding_id ) ) ,
117116 } ;
118117 then {
119118 let msg = format!(
@@ -154,16 +153,26 @@ fn strip_singleton_blocks<'hir>(mut expr: &'hir Expr<'hir>) -> &'hir Expr<'hir>
154153enum IfLetOrMatch < ' hir > {
155154 Match ( & ' hir Expr < ' hir > , & ' hir [ Arm < ' hir > ] , MatchSource ) ,
156155 /// scrutinee, pattern, then block, else block
157- IfLet ( & ' hir Expr < ' hir > , & ' hir Pat < ' hir > , & ' hir Expr < ' hir > , Option < & ' hir Expr < ' hir > > ) ,
156+ IfLet (
157+ & ' hir Expr < ' hir > ,
158+ & ' hir Pat < ' hir > ,
159+ & ' hir Expr < ' hir > ,
160+ Option < & ' hir Expr < ' hir > > ,
161+ ) ,
158162}
159163
160164impl < ' hir > IfLetOrMatch < ' hir > {
161165 fn parse ( cx : & LateContext < ' _ > , expr : & Expr < ' hir > ) -> Option < Self > {
162166 match expr. kind {
163167 ExprKind :: Match ( expr, arms, source) => Some ( Self :: Match ( expr, arms, source) ) ,
164- _ => higher:: IfLet :: hir ( cx, expr) . map ( |higher:: IfLet { let_expr, let_pat, if_then, if_else } | {
165- Self :: IfLet ( let_expr, let_pat, if_then, if_else)
166- } )
168+ _ => higher:: IfLet :: hir ( cx, expr) . map (
169+ |higher:: IfLet {
170+ let_expr,
171+ let_pat,
172+ if_then,
173+ if_else,
174+ } | { Self :: IfLet ( let_expr, let_pat, if_then, if_else) } ,
175+ ) ,
167176 }
168177 }
169178}
0 commit comments