@@ -64,26 +64,22 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
6464 | hir:: BinOpKind :: Gt => return ,
6565 _ => { } ,
6666 }
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 ;
7781 }
7882 }
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 ;
8783 }
8884
8985 if let Some ( impl_trait) = check_binop (
@@ -181,7 +177,7 @@ fn check_binop(
181177}
182178
183179struct BinaryExprVisitor {
184- in_binary_expr : bool ,
180+ nb_binops : u32 ,
185181}
186182
187183impl < ' tcx > Visitor < ' tcx > for BinaryExprVisitor {
@@ -191,12 +187,13 @@ impl<'tcx> Visitor<'tcx> for BinaryExprVisitor {
191187 match expr. kind {
192188 hir:: ExprKind :: Binary ( ..)
193189 | 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 ,
195191 _ => { } ,
196192 }
197193
198194 walk_expr ( self , expr) ;
199195 }
196+
200197 fn nested_visit_map ( & mut self ) -> NestedVisitorMap < Self :: Map > {
201198 NestedVisitorMap :: None
202199 }
0 commit comments