diff --git a/clippy_lints/src/manual_rem_euclid.rs b/clippy_lints/src/manual_rem_euclid.rs index ab9bca170cf..b518dc26937 100644 --- a/clippy_lints/src/manual_rem_euclid.rs +++ b/clippy_lints/src/manual_rem_euclid.rs @@ -48,35 +48,30 @@ pub fn new(msrv: Msrv) -> Self { impl<'tcx> LateLintPass<'tcx> for ManualRemEuclid { fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { - if !self.msrv.meets(msrvs::REM_EUCLID) { - return; - } - - if in_constant(cx, expr.hir_id) && !self.msrv.meets(msrvs::REM_EUCLID_CONST) { - return; - } - - if in_external_macro(cx.sess(), expr.span) { - return; - } - // (x % c + c) % c - if let ExprKind::Binary(op1, expr1, right) = expr.kind - && op1.node == BinOpKind::Rem + if let ExprKind::Binary(rem_op, rem_lhs, rem_rhs) = expr.kind + && rem_op.node == BinOpKind::Rem + && let ExprKind::Binary(add_op, add_lhs, add_rhs) = rem_lhs.kind + && add_op.node == BinOpKind::Add && let ctxt = expr.span.ctxt() - && expr1.span.ctxt() == ctxt - && let Some(const1) = check_for_unsigned_int_constant(cx, right) - && let ExprKind::Binary(op2, left, right) = expr1.kind - && op2.node == BinOpKind::Add - && let Some((const2, expr2)) = check_for_either_unsigned_int_constant(cx, left, right) - && expr2.span.ctxt() == ctxt - && let ExprKind::Binary(op3, expr3, right) = expr2.kind - && op3.node == BinOpKind::Rem - && let Some(const3) = check_for_unsigned_int_constant(cx, right) + && rem_lhs.span.ctxt() == ctxt + && rem_rhs.span.ctxt() == ctxt + && add_lhs.span.ctxt() == ctxt + && add_rhs.span.ctxt() == ctxt + && !in_external_macro(cx.sess(), expr.span) + && self.msrv.meets(msrvs::REM_EUCLID) + && (self.msrv.meets(msrvs::REM_EUCLID_CONST) || !in_constant(cx, expr.hir_id)) + && let Some(const1) = check_for_unsigned_int_constant(cx, rem_rhs) + && let Some((const2, add_other)) = check_for_either_unsigned_int_constant(cx, add_lhs, add_rhs) + && let ExprKind::Binary(rem2_op, rem2_lhs, rem2_rhs) = add_other.kind + && rem2_op.node == BinOpKind::Rem + && const1 == const2 + && let Some(hir_id) = path_to_local(rem2_lhs) + && let Some(const3) = check_for_unsigned_int_constant(cx, rem2_rhs) // Also ensures the const is nonzero since zero can't be a divisor - && const1 == const2 && const2 == const3 - && let Some(hir_id) = path_to_local(expr3) - && let Node::Pat(_) = cx.tcx.hir_node(hir_id) + && const2 == const3 + && rem2_lhs.span.ctxt() == ctxt + && rem2_rhs.span.ctxt() == ctxt { // Apply only to params or locals with annotated types match cx.tcx.parent_hir_node(hir_id) { @@ -91,7 +86,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { }; let mut app = Applicability::MachineApplicable; - let rem_of = snippet_with_context(cx, expr3.span, ctxt, "_", &mut app).0; + let rem_of = snippet_with_context(cx, rem2_lhs.span, ctxt, "_", &mut app).0; span_lint_and_sugg( cx, MANUAL_REM_EUCLID,