Skip to content

Commit 0f4cd13

Browse files
committed
manual_rem_euclid: Check HIR tree first.
1 parent 44f87e8 commit 0f4cd13

File tree

1 file changed

+22
-27
lines changed

1 file changed

+22
-27
lines changed

clippy_lints/src/manual_rem_euclid.rs

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -48,35 +48,30 @@ impl_lint_pass!(ManualRemEuclid => [MANUAL_REM_EUCLID]);
4848

4949
impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
5050
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
51-
if !self.msrv.meets(msrvs::REM_EUCLID) {
52-
return;
53-
}
54-
55-
if in_constant(cx, expr.hir_id) && !self.msrv.meets(msrvs::REM_EUCLID_CONST) {
56-
return;
57-
}
58-
59-
if in_external_macro(cx.sess(), expr.span) {
60-
return;
61-
}
62-
6351
// (x % c + c) % c
64-
if let ExprKind::Binary(op1, expr1, right) = expr.kind
65-
&& op1.node == BinOpKind::Rem
52+
if let ExprKind::Binary(rem_op, rem_lhs, rem_rhs) = expr.kind
53+
&& rem_op.node == BinOpKind::Rem
54+
&& let ExprKind::Binary(add_op, add_lhs, add_rhs) = rem_lhs.kind
55+
&& add_op.node == BinOpKind::Add
6656
&& let ctxt = expr.span.ctxt()
67-
&& expr1.span.ctxt() == ctxt
68-
&& let Some(const1) = check_for_unsigned_int_constant(cx, right)
69-
&& let ExprKind::Binary(op2, left, right) = expr1.kind
70-
&& op2.node == BinOpKind::Add
71-
&& let Some((const2, expr2)) = check_for_either_unsigned_int_constant(cx, left, right)
72-
&& expr2.span.ctxt() == ctxt
73-
&& let ExprKind::Binary(op3, expr3, right) = expr2.kind
74-
&& op3.node == BinOpKind::Rem
75-
&& let Some(const3) = check_for_unsigned_int_constant(cx, right)
57+
&& rem_lhs.span.ctxt() == ctxt
58+
&& rem_rhs.span.ctxt() == ctxt
59+
&& add_lhs.span.ctxt() == ctxt
60+
&& add_rhs.span.ctxt() == ctxt
61+
&& !in_external_macro(cx.sess(), expr.span)
62+
&& self.msrv.meets(msrvs::REM_EUCLID)
63+
&& (self.msrv.meets(msrvs::REM_EUCLID_CONST) || !in_constant(cx, expr.hir_id))
64+
&& let Some(const1) = check_for_unsigned_int_constant(cx, rem_rhs)
65+
&& let Some((const2, add_other)) = check_for_either_unsigned_int_constant(cx, add_lhs, add_rhs)
66+
&& let ExprKind::Binary(rem2_op, rem2_lhs, rem2_rhs) = add_other.kind
67+
&& rem2_op.node == BinOpKind::Rem
68+
&& const1 == const2
69+
&& let Some(hir_id) = path_to_local(rem2_lhs)
70+
&& let Some(const3) = check_for_unsigned_int_constant(cx, rem2_rhs)
7671
// Also ensures the const is nonzero since zero can't be a divisor
77-
&& const1 == const2 && const2 == const3
78-
&& let Some(hir_id) = path_to_local(expr3)
79-
&& let Node::Pat(_) = cx.tcx.hir_node(hir_id)
72+
&& const2 == const3
73+
&& rem2_lhs.span.ctxt() == ctxt
74+
&& rem2_rhs.span.ctxt() == ctxt
8075
{
8176
// Apply only to params or locals with annotated types
8277
match cx.tcx.parent_hir_node(hir_id) {
@@ -91,7 +86,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid {
9186
};
9287

9388
let mut app = Applicability::MachineApplicable;
94-
let rem_of = snippet_with_context(cx, expr3.span, ctxt, "_", &mut app).0;
89+
let rem_of = snippet_with_context(cx, rem2_lhs.span, ctxt, "_", &mut app).0;
9590
span_lint_and_sugg(
9691
cx,
9792
MANUAL_REM_EUCLID,

0 commit comments

Comments
 (0)