Skip to content

Commit 92704b4

Browse files
author
Evan Typanski
committed
Split constant check functions and simplify
1 parent 0447cc7 commit 92704b4

File tree

1 file changed

+21
-31
lines changed

1 file changed

+21
-31
lines changed

clippy_lints/src/manual_rem_euclid.rs

+21-31
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,16 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
5555
return;
5656
}
5757

58-
if let ExprKind::Binary(op1, ..) = expr.kind
58+
if let ExprKind::Binary(op1, expr1, right) = expr.kind
5959
&& 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
6262
&& 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
6565
&& 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
6768
&& const1 == const2 && const2 == const3
6869
&& let Some(hir_id) = path_to_local(expr3)
6970
&& let Some(Node::Binding(_)) = cx.tcx.hir().find(hir_id) {
@@ -96,33 +97,22 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
9697
extract_msrv_attr!(LateContext);
9798
}
9899

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>(
103103
cx: &'a LateContext<'_>,
104-
expr: &'a Expr<'_>,
105-
is_commutative: bool,
104+
left: &'a Expr<'_>,
105+
right: &'a Expr<'_>,
106106
) -> 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+
}
118111

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),
127117
}
128118
}

0 commit comments

Comments
 (0)