1
- use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
1
+ use if_chain:: if_chain;
2
+ use rustc_hir:: { BinOp , BinOpKind , Expr , ExprKind } ;
2
3
use rustc_lint:: { LateContext , LateLintPass } ;
3
4
use rustc_middle:: ty;
4
5
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
@@ -32,7 +33,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp {
32
33
if e. span . from_expansion ( ) {
33
34
return ;
34
35
}
35
- if let ExprKind :: Binary ( ref cmp, ref left, ref right) = e. kind {
36
+ if let ExprKind :: Binary ( cmp, ref left, ref right) = e. kind {
37
+ if is_allowed ( cx, cmp, left, right) {
38
+ return ;
39
+ }
36
40
match cmp. node {
37
41
BinOpKind :: Add | BinOpKind :: BitOr | BinOpKind :: BitXor => {
38
42
check ( cx, left, 0 , e. span , right. span ) ;
@@ -54,6 +58,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp {
54
58
}
55
59
}
56
60
61
+ fn is_allowed ( cx : & LateContext < ' _ , ' _ > , cmp : BinOp , left : & Expr < ' _ > , right : & Expr < ' _ > ) -> bool {
62
+ // `1 << 0` is a common pattern in bit manipulation code
63
+ if_chain ! {
64
+ if let BinOpKind :: Shl = cmp. node;
65
+ if let Some ( Constant :: Int ( 0 ) ) = constant_simple( cx, cx. tables, right) ;
66
+ if let Some ( Constant :: Int ( 1 ) ) = constant_simple( cx, cx. tables, left) ;
67
+ then {
68
+ return true ;
69
+ }
70
+ }
71
+
72
+ false
73
+ }
74
+
57
75
#[ allow( clippy:: cast_possible_wrap) ]
58
76
fn check ( cx : & LateContext < ' _ , ' _ > , e : & Expr < ' _ > , m : i8 , span : Span , arg : Span ) {
59
77
if let Some ( Constant :: Int ( v) ) = constant_simple ( cx, cx. tables , e) {
0 commit comments