1- use rustc_hir:: { BinOpKind , Expr , ExprKind } ;
1+ use if_chain:: if_chain;
2+ use rustc_hir:: { BinOp , BinOpKind , Expr , ExprKind } ;
23use rustc_lint:: { LateContext , LateLintPass } ;
34use rustc_middle:: ty;
45use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
@@ -32,7 +33,10 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp {
3233 if e. span . from_expansion ( ) {
3334 return ;
3435 }
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+ }
3640 match cmp. node {
3741 BinOpKind :: Add | BinOpKind :: BitOr | BinOpKind :: BitXor => {
3842 check ( cx, left, 0 , e. span , right. span ) ;
@@ -54,6 +58,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityOp {
5458 }
5559}
5660
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+
5775#[ allow( clippy:: cast_possible_wrap) ]
5876fn check ( cx : & LateContext < ' _ , ' _ > , e : & Expr < ' _ > , m : i8 , span : Span , arg : Span ) {
5977 if let Some ( Constant :: Int ( v) ) = constant_simple ( cx, cx. tables , e) {
0 commit comments