@@ -64,26 +64,22 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
64
64
| hir:: BinOpKind :: Gt => return ,
65
65
_ => { } ,
66
66
}
67
- // Check if the binary expression is part of another bi/unary expression
68
- // or operator assignment as a child node
69
- let mut parent_expr = cx. tcx . hir ( ) . get_parent_node ( expr. hir_id ) ;
70
- while parent_expr != hir:: CRATE_HIR_ID {
71
- if let hir:: Node :: Expr ( e) = cx. tcx . hir ( ) . get ( parent_expr) {
72
- match e. kind {
73
- hir:: ExprKind :: Binary ( ..)
74
- | hir:: ExprKind :: Unary ( hir:: UnOp :: UnNot | hir:: UnOp :: UnNeg , _)
75
- | hir:: ExprKind :: AssignOp ( ..) => return ,
76
- _ => { } ,
67
+
68
+ // Check for more than one binary operation in the implemented function
69
+ // Linting when multiple operations are involved can result in false positives
70
+ if_chain ! {
71
+ let parent_fn = cx. tcx. hir( ) . get_parent_item( expr. hir_id) ;
72
+ if let hir:: Node :: ImplItem ( impl_item) = cx. tcx. hir( ) . get( parent_fn) ;
73
+ if let hir:: ImplItemKind :: Fn ( _, body_id) = impl_item. kind;
74
+ let body = cx. tcx. hir( ) . body( body_id) ;
75
+ let mut visitor = BinaryExprVisitor { nb_binops: 0 } ;
76
+
77
+ then {
78
+ walk_expr( & mut visitor, & body. value) ;
79
+ if visitor. nb_binops > 1 {
80
+ return ;
77
81
}
78
82
}
79
- parent_expr = cx. tcx . hir ( ) . get_parent_node ( parent_expr) ;
80
- }
81
- // as a parent node
82
- let mut visitor = BinaryExprVisitor { in_binary_expr : false } ;
83
- walk_expr ( & mut visitor, expr) ;
84
-
85
- if visitor. in_binary_expr {
86
- return ;
87
83
}
88
84
89
85
if let Some ( impl_trait) = check_binop (
@@ -181,7 +177,7 @@ fn check_binop(
181
177
}
182
178
183
179
struct BinaryExprVisitor {
184
- in_binary_expr : bool ,
180
+ nb_binops : u32 ,
185
181
}
186
182
187
183
impl < ' tcx > Visitor < ' tcx > for BinaryExprVisitor {
@@ -191,12 +187,13 @@ impl<'tcx> Visitor<'tcx> for BinaryExprVisitor {
191
187
match expr. kind {
192
188
hir:: ExprKind :: Binary ( ..)
193
189
| hir:: ExprKind :: Unary ( hir:: UnOp :: UnNot | hir:: UnOp :: UnNeg , _)
194
- | hir:: ExprKind :: AssignOp ( ..) => self . in_binary_expr = true ,
190
+ | hir:: ExprKind :: AssignOp ( ..) => self . nb_binops += 1 ,
195
191
_ => { } ,
196
192
}
197
193
198
194
walk_expr ( self , expr) ;
199
195
}
196
+
200
197
fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
201
198
NestedVisitorMap :: None
202
199
}
0 commit comments