11use  clippy_utils:: diagnostics:: span_lint_and_sugg; 
22use  clippy_utils:: source:: snippet_with_applicability; 
3+ use  rustc_ast:: ast:: BinOpKind :: { Add ,  BitAnd ,  BitOr ,  BitXor ,  Div ,  Mul ,  Rem ,  Shl ,  Shr ,  Sub } ; 
34use  rustc_ast:: ast:: { BinOpKind ,  Expr ,  ExprKind } ; 
45use  rustc_errors:: Applicability ; 
56use  rustc_lint:: { EarlyContext ,  EarlyLintPass } ; 
@@ -12,6 +13,7 @@ declare_clippy_lint! {
1213     /// and suggests to add parentheses. Currently it catches the following: 
1314     /// * mixed usage of arithmetic and bit shifting/combining operators without 
1415     /// parentheses 
16+      /// * mixed usage of bitmasking and bit shifting operators without parentheses 
1517     /// 
1618     /// ### Why is this bad? 
1719     /// Not everyone knows the precedence of those operators by 
@@ -20,6 +22,7 @@ declare_clippy_lint! {
2022     /// 
2123     /// ### Example 
2224     /// * `1 << 2 + 3` equals 32, while `(1 << 2) + 3` equals 7 
25+      /// * `0x2345 & 0xF000 >> 12` equals 5, while `(0x2345 & 0xF000) >> 12` equals 2 
2326     #[ clippy:: version = "pre 1.29.0" ] 
2427    pub  PRECEDENCE , 
2528    complexity, 
@@ -51,8 +54,13 @@ impl EarlyLintPass for Precedence {
5154                return ; 
5255            } 
5356            let  mut  applicability = Applicability :: MachineApplicable ; 
54-             match  ( is_arith_expr ( left) ,  is_arith_expr ( right) )  { 
55-                 ( true ,  true )  => { 
57+             match  ( op,  get_bin_opt ( left) ,  get_bin_opt ( right) )  { 
58+                 ( 
59+                     BitAnd  | BitOr  | BitXor , 
60+                     Some ( Shl  | Shr  | Add  | Div  | Mul  | Rem  | Sub ) , 
61+                     Some ( Shl  | Shr  | Add  | Div  | Mul  | Rem  | Sub ) , 
62+                 ) 
63+                 | ( Shl  | Shr ,  Some ( Add  | Div  | Mul  | Rem  | Sub ) ,  Some ( Add  | Div  | Mul  | Rem  | Sub ) )  => { 
5664                    let  sugg = format ! ( 
5765                        "({}) {} ({})" , 
5866                        snippet_with_applicability( cx,  left. span,  ".." ,  & mut  applicability) , 
@@ -61,7 +69,8 @@ impl EarlyLintPass for Precedence {
6169                    ) ; 
6270                    span_sugg ( expr,  sugg,  applicability) ; 
6371                } , 
64-                 ( true ,  false )  => { 
72+                 ( BitAnd  | BitOr  | BitXor ,  Some ( Shl  | Shr  | Add  | Div  | Mul  | Rem  | Sub ) ,  _) 
73+                 | ( Shl  | Shr ,  Some ( Add  | Div  | Mul  | Rem  | Sub ) ,  _)  => { 
6574                    let  sugg = format ! ( 
6675                        "({}) {} {}" , 
6776                        snippet_with_applicability( cx,  left. span,  ".." ,  & mut  applicability) , 
@@ -70,7 +79,8 @@ impl EarlyLintPass for Precedence {
7079                    ) ; 
7180                    span_sugg ( expr,  sugg,  applicability) ; 
7281                } , 
73-                 ( false ,  true )  => { 
82+                 ( BitAnd  | BitOr  | BitXor ,  _,  Some ( Shl  | Shr  | Add  | Div  | Mul  | Rem  | Sub ) ) 
83+                 | ( Shl  | Shr ,  _,  Some ( Add  | Div  | Mul  | Rem  | Sub ) )  => { 
7484                    let  sugg = format ! ( 
7585                        "{} {} ({})" , 
7686                        snippet_with_applicability( cx,  left. span,  ".." ,  & mut  applicability) , 
@@ -79,27 +89,20 @@ impl EarlyLintPass for Precedence {
7989                    ) ; 
8090                    span_sugg ( expr,  sugg,  applicability) ; 
8191                } , 
82-                 ( false ,   false )  => ( ) , 
92+                 _  => ( ) , 
8393            } 
8494        } 
8595    } 
8696} 
8797
88- fn  is_arith_expr ( expr :  & Expr )  -> bool  { 
98+ fn  get_bin_opt ( expr :  & Expr )  -> Option < BinOpKind >  { 
8999    match  expr. kind  { 
90-         ExprKind :: Binary ( Spanned  {  node :  op,  .. } ,  _,  _)  => is_arith_op ( op) , 
91-         _ => false , 
100+         ExprKind :: Binary ( Spanned  {  node :  op,  .. } ,  _,  _)  => Some ( op) , 
101+         _ => None , 
92102    } 
93103} 
94104
95105#[ must_use]  
96106fn  is_bit_op ( op :  BinOpKind )  -> bool  { 
97-     use  rustc_ast:: ast:: BinOpKind :: { BitAnd ,  BitOr ,  BitXor ,  Shl ,  Shr } ; 
98107    matches ! ( op,  BitXor  | BitAnd  | BitOr  | Shl  | Shr ) 
99108} 
100- 
101- #[ must_use]  
102- fn  is_arith_op ( op :  BinOpKind )  -> bool  { 
103-     use  rustc_ast:: ast:: BinOpKind :: { Add ,  Div ,  Mul ,  Rem ,  Sub } ; 
104-     matches ! ( op,  Add  | Sub  | Mul  | Div  | Rem ) 
105- } 
0 commit comments