1+ use crate :: utils:: { match_type, paths, span_lint_and_help, SpanlessEq } ;
12use if_chain:: if_chain;
2- use crate :: utils:: { match_type, paths, span_lint_and_help} ;
33use rustc_hir:: intravisit:: { self as visit, NestedVisitorMap , Visitor } ;
4- use rustc_hir:: { Arm , Expr , ExprKind , MatchSource , StmtKind } ;
4+ use rustc_hir:: { Expr , ExprKind , MatchSource } ;
55use rustc_lint:: { LateContext , LateLintPass } ;
66use rustc_middle:: hir:: map:: Map ;
77use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
@@ -44,10 +44,12 @@ impl LateLintPass<'_, '_> for IfLetMutex {
4444 fn check_expr ( & mut self , cx : & LateContext < ' _ , ' _ > , ex : & ' _ Expr < ' _ > ) {
4545 let mut arm_visit = ArmVisitor {
4646 mutex_lock_called : false ,
47+ found_mutex : None ,
4748 cx,
4849 } ;
4950 let mut op_visit = OppVisitor {
5051 mutex_lock_called : false ,
52+ found_mutex : None ,
5153 cx,
5254 } ;
5355 if let ExprKind :: Match (
@@ -64,7 +66,7 @@ impl LateLintPass<'_, '_> for IfLetMutex {
6466 arm_visit. visit_arm ( arm) ;
6567 }
6668
67- if arm_visit. mutex_lock_called {
69+ if arm_visit. mutex_lock_called && arm_visit . same_mutex ( cx , op_visit . found_mutex . unwrap ( ) ) {
6870 span_lint_and_help (
6971 cx,
7072 IF_LET_MUTEX ,
@@ -80,8 +82,9 @@ impl LateLintPass<'_, '_> for IfLetMutex {
8082
8183/// Checks if `Mutex::lock` is called in the `if let _ = expr.
8284pub struct OppVisitor < ' tcx , ' l > {
83- pub mutex_lock_called : bool ,
84- pub cx : & ' tcx LateContext < ' tcx , ' l > ,
85+ mutex_lock_called : bool ,
86+ found_mutex : Option < & ' tcx Expr < ' tcx > > ,
87+ cx : & ' tcx LateContext < ' tcx , ' l > ,
8588}
8689
8790impl < ' tcx , ' l > Visitor < ' tcx > for OppVisitor < ' tcx , ' l > {
@@ -94,6 +97,7 @@ impl<'tcx, 'l> Visitor<'tcx> for OppVisitor<'tcx, 'l> {
9497 let ty = self . cx. tables. expr_ty( & args[ 0 ] ) ;
9598 if match_type( self . cx, ty, & paths:: MUTEX ) ;
9699 then {
100+ self . found_mutex = Some ( & args[ 0 ] ) ;
97101 self . mutex_lock_called = true ;
98102 return ;
99103 }
@@ -108,46 +112,40 @@ impl<'tcx, 'l> Visitor<'tcx> for OppVisitor<'tcx, 'l> {
108112
109113/// Checks if `Mutex::lock` is called in any of the branches.
110114pub struct ArmVisitor < ' tcx , ' l > {
111- pub mutex_lock_called : bool ,
112- pub cx : & ' tcx LateContext < ' tcx , ' l > ,
115+ mutex_lock_called : bool ,
116+ found_mutex : Option < & ' tcx Expr < ' tcx > > ,
117+ cx : & ' tcx LateContext < ' tcx , ' l > ,
113118}
114119
115120impl < ' tcx , ' l > Visitor < ' tcx > for ArmVisitor < ' tcx , ' l > {
116121 type Map = Map < ' tcx > ;
117122
118- fn visit_expr ( & mut self , expr : & ' tcx Expr < ' _ > ) {
123+ fn visit_expr ( & mut self , expr : & ' tcx Expr < ' tcx > ) {
119124 if_chain ! {
120125 if let ExprKind :: MethodCall ( path, _span, args) = & expr. kind;
121126 if path. ident. to_string( ) == "lock" ;
122127 let ty = self . cx. tables. expr_ty( & args[ 0 ] ) ;
123128 if match_type( self . cx, ty, & paths:: MUTEX ) ;
124129 then {
130+ self . found_mutex = Some ( & args[ 0 ] ) ;
125131 self . mutex_lock_called = true ;
126132 return ;
127133 }
128134 }
129135 visit:: walk_expr ( self , expr) ;
130136 }
131137
132- fn visit_arm ( & mut self , arm : & ' tcx Arm < ' _ > ) {
133- if let ExprKind :: Block ( ref block, _l) = arm. body . kind {
134- for stmt in block. stmts {
135- match stmt. kind {
136- StmtKind :: Local ( loc) => {
137- if let Some ( expr) = loc. init {
138- self . visit_expr ( expr)
139- }
140- } ,
141- StmtKind :: Expr ( expr) | StmtKind :: Semi ( expr) => self . visit_expr ( expr) ,
142- // we don't care about `Item`
143- _ => { } ,
144- }
145- }
146- } ;
147- visit:: walk_arm ( self , arm) ;
148- }
149-
150138 fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
151139 NestedVisitorMap :: None
152140 }
153141}
142+
143+ impl < ' tcx , ' l > ArmVisitor < ' tcx , ' l > {
144+ fn same_mutex ( & self , cx : & LateContext < ' _ , ' _ > , op_mutex : & Expr < ' _ > ) -> bool {
145+ if let Some ( arm_mutex) = self . found_mutex {
146+ SpanlessEq :: new ( cx) . eq_expr ( op_mutex, arm_mutex)
147+ } else {
148+ false
149+ }
150+ }
151+ }
0 commit comments