@@ -56,20 +56,14 @@ impl Display for ShiftDirection {
5656 }
5757}
5858
59- fn parse_shift < ' tcx > (
60- cx : & LateContext < ' tcx > ,
61- expr : & ' tcx Expr < ' tcx > ,
62- ) -> Option < ( ShiftDirection , u128 , & ' tcx Expr < ' tcx > ) > {
59+ fn parse_shift < ' tcx > ( expr : & ' tcx Expr < ' tcx > ) -> Option < ( ShiftDirection , & ' tcx Expr < ' tcx > , & ' tcx Expr < ' tcx > ) > {
6360 if let ExprKind :: Binary ( op, l, r) = expr. kind {
6461 let dir = match op. node {
6562 BinOpKind :: Shl => ShiftDirection :: Left ,
6663 BinOpKind :: Shr => ShiftDirection :: Right ,
6764 _ => return None ,
6865 } ;
69- let const_expr = ConstEvalCtxt :: new ( cx) . eval_local ( r, expr. span . ctxt ( ) ) ?;
70- if let Constant :: Int ( shift) = const_expr {
71- return Some ( ( dir, shift, l) ) ;
72- }
66+ return Some ( ( dir, l, r) ) ;
7367 }
7468 None
7569}
@@ -78,33 +72,40 @@ impl LateLintPass<'_> for ManualRotate {
7872 fn check_expr < ' tcx > ( & mut self , cx : & LateContext < ' tcx > , expr : & Expr < ' tcx > ) {
7973 if let ExprKind :: Binary ( op, l, r) = expr. kind
8074 && let BinOpKind :: Add | BinOpKind :: BitOr = op. node
81- && let Some ( ( l_shift_dir, l_amount , l_expr ) ) = parse_shift ( cx , l)
82- && let Some ( ( r_shift_dir, r_amount , r_expr ) ) = parse_shift ( cx , r)
75+ && let Some ( ( l_shift_dir, l_expr , l_amount ) ) = parse_shift ( l)
76+ && let Some ( ( r_shift_dir, r_expr , r_amount ) ) = parse_shift ( r)
8377 && l_shift_dir != r_shift_dir
8478 && clippy_utils:: eq_expr_value ( cx, l_expr, r_expr)
8579 && let Some ( bit_width) = match cx. typeck_results ( ) . expr_ty ( expr) . kind ( ) {
8680 ty:: Int ( itype) => itype. bit_width ( ) ,
8781 ty:: Uint ( itype) => itype. bit_width ( ) ,
8882 _ => return ,
8983 }
90- && l_amount + r_amount == u128:: from ( bit_width)
9184 {
92- let ( shift_function, amount) = if l_amount < r_amount {
93- ( l_shift_dir, l_amount)
94- } else {
95- ( r_shift_dir, r_amount)
96- } ;
97- let mut applicability = Applicability :: MachineApplicable ;
98- let expr_sugg = sugg:: Sugg :: hir_with_applicability ( cx, l_expr, "_" , & mut applicability) . maybe_paren ( ) ;
99- span_lint_and_sugg (
100- cx,
101- MANUAL_ROTATE ,
102- expr. span ,
103- "there is no need to manually implement bit rotation" ,
104- "this expression can be rewritten as" ,
105- format ! ( "{expr_sugg}.{shift_function}({amount})" ) ,
106- Applicability :: MachineApplicable ,
107- ) ;
85+ let const_eval = ConstEvalCtxt :: new ( cx) ;
86+
87+ let ctxt = expr. span . ctxt ( ) ;
88+ if let Some ( Constant :: Int ( l_amount) ) = const_eval. eval_local ( l_amount, ctxt)
89+ && let Some ( Constant :: Int ( r_amount) ) = const_eval. eval_local ( r_amount, ctxt)
90+ && l_amount + r_amount == u128:: from ( bit_width)
91+ {
92+ let ( shift_function, amount) = if l_amount < r_amount {
93+ ( l_shift_dir, l_amount)
94+ } else {
95+ ( r_shift_dir, r_amount)
96+ } ;
97+ let mut applicability = Applicability :: MachineApplicable ;
98+ let expr_sugg = sugg:: Sugg :: hir_with_applicability ( cx, l_expr, "_" , & mut applicability) . maybe_paren ( ) ;
99+ span_lint_and_sugg (
100+ cx,
101+ MANUAL_ROTATE ,
102+ expr. span ,
103+ "there is no need to manually implement bit rotation" ,
104+ "this expression can be rewritten as" ,
105+ format ! ( "{expr_sugg}.{shift_function}({amount})" ) ,
106+ Applicability :: MachineApplicable ,
107+ ) ;
108+ }
108109 }
109110 }
110111}
0 commit comments