@@ -55,15 +55,16 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
55
55
return ;
56
56
}
57
57
58
- if let ExprKind :: Binary ( op1, .. ) = expr. kind
58
+ if let ExprKind :: Binary ( op1, expr1 , right ) = expr. kind
59
59
&& op1. node == BinOpKind :: Rem
60
- && let Some ( ( const1, expr1 ) ) = check_for_positive_int_constant ( cx, expr , false )
61
- && let ExprKind :: Binary ( op2, .. ) = expr1. kind
60
+ && let Some ( const1) = check_for_unsigned_int_constant ( cx, right )
61
+ && let ExprKind :: Binary ( op2, left , right ) = expr1. kind
62
62
&& op2. node == BinOpKind :: Add
63
- && let Some ( ( const2, expr2) ) = check_for_positive_int_constant ( cx, expr1 , true )
64
- && let ExprKind :: Binary ( op3, .. ) = expr2. kind
63
+ && let Some ( ( const2, expr2) ) = check_for_either_unsigned_int_constant ( cx, left , right )
64
+ && let ExprKind :: Binary ( op3, expr3 , right ) = expr2. kind
65
65
&& op3. node == BinOpKind :: Rem
66
- && let Some ( ( const3, expr3) ) = check_for_positive_int_constant ( cx, expr2, false )
66
+ && let Some ( const3) = check_for_unsigned_int_constant ( cx, right)
67
+ // Also ensures the const is nonzero since zero can't be a divisor
67
68
&& const1 == const2 && const2 == const3
68
69
&& let Some ( hir_id) = path_to_local ( expr3)
69
70
&& let Some ( Node :: Binding ( _) ) = cx. tcx . hir ( ) . find ( hir_id) {
@@ -96,33 +97,22 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
96
97
extract_msrv_attr ! ( LateContext ) ;
97
98
}
98
99
99
- // Takes a binary expression and separates the operands into the int constant and the other
100
- // operand. Ensures the int constant is positive. Operators that are not commutative must have the
101
- // constant appear on the right hand side to return a value.
102
- fn check_for_positive_int_constant < ' a > (
100
+ // Checks if either the left or right expressions can be an unsigned int constant and returns that
101
+ // constant along with the other expression unchanged if so
102
+ fn check_for_either_unsigned_int_constant < ' a > (
103
103
cx : & ' a LateContext < ' _ > ,
104
- expr : & ' a Expr < ' _ > ,
105
- is_commutative : bool ,
104
+ left : & ' a Expr < ' _ > ,
105
+ right : & ' a Expr < ' _ > ,
106
106
) -> Option < ( u128 , & ' a Expr < ' a > ) > {
107
- let ( int_const, other_op) = if let ExprKind :: Binary ( _, left, right) = expr. kind {
108
- if let Some ( int_const) = constant_full_int ( cx, cx. typeck_results ( ) , right) {
109
- ( int_const, left)
110
- } else if is_commutative && let Some ( int_const) = constant_full_int ( cx, cx. typeck_results ( ) , left) {
111
- ( int_const, right)
112
- } else {
113
- return None ;
114
- }
115
- } else {
116
- return None ;
117
- } ;
107
+ check_for_unsigned_int_constant ( cx, left)
108
+ . map ( |int_const| ( int_const, right) )
109
+ . or_else ( || check_for_unsigned_int_constant ( cx, right) . map ( |int_const| ( int_const, left) ) )
110
+ }
118
111
119
- if int_const > FullInt :: S ( 0 ) {
120
- let val = match int_const {
121
- FullInt :: S ( s) => s. try_into ( ) . ok ( ) ?,
122
- FullInt :: U ( u) => u,
123
- } ;
124
- Some ( ( val, other_op) )
125
- } else {
126
- None
112
+ fn check_for_unsigned_int_constant < ' a > ( cx : & ' a LateContext < ' _ > , expr : & ' a Expr < ' _ > ) -> Option < u128 > {
113
+ let Some ( int_const) = constant_full_int ( cx, cx. typeck_results ( ) , expr) else { return None } ;
114
+ match int_const {
115
+ FullInt :: S ( s) => s. try_into ( ) . ok ( ) ,
116
+ FullInt :: U ( u) => Some ( u) ,
127
117
}
128
118
}
0 commit comments