Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 71c2daa

Browse files
committed
Move ModuloArithmetic into Operators lint pass
1 parent c0b0ee5 commit 71c2daa

File tree

5 files changed

+53
-53
lines changed

5 files changed

+53
-53
lines changed

clippy_lints/src/lib.register_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,6 @@ store.register_lints(&[
379379
mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION,
380380
module_style::MOD_MODULE_FILES,
381381
module_style::SELF_NAMED_MODULE_FILES,
382-
modulo_arithmetic::MODULO_ARITHMETIC,
383382
mut_key::MUTABLE_KEY_TYPE,
384383
mut_mut::MUT_MUT,
385384
mut_mutex_lock::MUT_MUTEX_LOCK,
@@ -434,6 +433,7 @@ store.register_lints(&[
434433
operators::INTEGER_ARITHMETIC,
435434
operators::INTEGER_DIVISION,
436435
operators::MISREFACTORED_ASSIGN_OP,
436+
operators::MODULO_ARITHMETIC,
437437
operators::MODULO_ONE,
438438
operators::OP_REF,
439439
operators::VERBOSE_BIT_MASK,

clippy_lints/src/lib.register_restriction.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ store.register_group(true, "clippy::restriction", Some("clippy_restriction"), ve
4747
LintId::of(mixed_read_write_in_expression::MIXED_READ_WRITE_IN_EXPRESSION),
4848
LintId::of(module_style::MOD_MODULE_FILES),
4949
LintId::of(module_style::SELF_NAMED_MODULE_FILES),
50-
LintId::of(modulo_arithmetic::MODULO_ARITHMETIC),
5150
LintId::of(operators::FLOAT_ARITHMETIC),
5251
LintId::of(operators::FLOAT_CMP_CONST),
5352
LintId::of(operators::INTEGER_ARITHMETIC),
5453
LintId::of(operators::INTEGER_DIVISION),
54+
LintId::of(operators::MODULO_ARITHMETIC),
5555
LintId::of(panic_in_result_fn::PANIC_IN_RESULT_FN),
5656
LintId::of(panic_unimplemented::PANIC),
5757
LintId::of(panic_unimplemented::TODO),

clippy_lints/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,6 @@ mod missing_enforced_import_rename;
295295
mod missing_inline;
296296
mod mixed_read_write_in_expression;
297297
mod module_style;
298-
mod modulo_arithmetic;
299298
mod mut_key;
300299
mod mut_mut;
301300
mod mut_mutex_lock;
@@ -738,7 +737,6 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
738737
store.register_late_pass(move || Box::new(trait_bounds::TraitBounds::new(max_trait_bounds)));
739738
store.register_late_pass(|| Box::new(comparison_chain::ComparisonChain));
740739
store.register_late_pass(|| Box::new(mut_key::MutableKeyType));
741-
store.register_late_pass(|| Box::new(modulo_arithmetic::ModuloArithmetic));
742740
store.register_early_pass(|| Box::new(reference::DerefAddrOf));
743741
store.register_early_pass(|| Box::new(double_parens::DoubleParens));
744742
store.register_late_pass(|| Box::new(format_impl::FormatImpl::new()));

clippy_lints/src/operators/mod.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ mod float_equality_without_abs;
1616
mod identity_op;
1717
mod integer_division;
1818
mod misrefactored_assign_op;
19+
mod modulo_arithmetic;
1920
mod modulo_one;
2021
mod numeric_arithmetic;
2122
mod op_ref;
@@ -618,6 +619,28 @@ declare_clippy_lint! {
618619
"taking a number modulo +/-1, which can either panic/overflow or always returns 0"
619620
}
620621

622+
declare_clippy_lint! {
623+
/// ### What it does
624+
/// Checks for modulo arithmetic.
625+
///
626+
/// ### Why is this bad?
627+
/// The results of modulo (%) operation might differ
628+
/// depending on the language, when negative numbers are involved.
629+
/// If you interop with different languages it might be beneficial
630+
/// to double check all places that use modulo arithmetic.
631+
///
632+
/// For example, in Rust `17 % -3 = 2`, but in Python `17 % -3 = -1`.
633+
///
634+
/// ### Example
635+
/// ```rust
636+
/// let x = -17 % 3;
637+
/// ```
638+
#[clippy::version = "1.42.0"]
639+
pub MODULO_ARITHMETIC,
640+
restriction,
641+
"any modulo arithmetic statement"
642+
}
643+
621644
pub struct Operators {
622645
arithmetic_context: numeric_arithmetic::Context,
623646
verbose_bit_mask_threshold: u64,
@@ -644,6 +667,7 @@ impl_lint_pass!(Operators => [
644667
FLOAT_CMP,
645668
FLOAT_CMP_CONST,
646669
MODULO_ONE,
670+
MODULO_ARITHMETIC,
647671
]);
648672
impl Operators {
649673
pub fn new(verbose_bit_mask_threshold: u64) -> Self {
@@ -678,10 +702,12 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
678702
cmp_owned::check(cx, op.node, lhs, rhs);
679703
float_cmp::check(cx, e, op.node, lhs, rhs);
680704
modulo_one::check(cx, e, op.node, rhs);
705+
modulo_arithmetic::check(cx, e, op.node, lhs, rhs);
681706
},
682707
ExprKind::AssignOp(op, lhs, rhs) => {
683708
self.arithmetic_context.check_binary(cx, e, op.node, lhs, rhs);
684709
misrefactored_assign_op::check(cx, e, op.node, lhs, rhs);
710+
modulo_arithmetic::check(cx, e, op.node, lhs, rhs);
685711
},
686712
ExprKind::Assign(lhs, rhs, _) => {
687713
assign_op_pattern::check(cx, e, lhs, rhs);

clippy_lints/src/modulo_arithmetic.rs renamed to clippy_lints/src/operators/modulo_arithmetic.rs

Lines changed: 25 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,35 +2,35 @@ use clippy_utils::consts::{constant, Constant};
22
use clippy_utils::diagnostics::span_lint_and_then;
33
use clippy_utils::sext;
44
use if_chain::if_chain;
5-
use rustc_hir::{BinOpKind, Expr, ExprKind};
6-
use rustc_lint::{LateContext, LateLintPass};
5+
use rustc_hir::{BinOpKind, Expr};
6+
use rustc_lint::LateContext;
77
use rustc_middle::ty::{self, Ty};
8-
use rustc_session::{declare_lint_pass, declare_tool_lint};
98
use std::fmt::Display;
109

11-
declare_clippy_lint! {
12-
/// ### What it does
13-
/// Checks for modulo arithmetic.
14-
///
15-
/// ### Why is this bad?
16-
/// The results of modulo (%) operation might differ
17-
/// depending on the language, when negative numbers are involved.
18-
/// If you interop with different languages it might be beneficial
19-
/// to double check all places that use modulo arithmetic.
20-
///
21-
/// For example, in Rust `17 % -3 = 2`, but in Python `17 % -3 = -1`.
22-
///
23-
/// ### Example
24-
/// ```rust
25-
/// let x = -17 % 3;
26-
/// ```
27-
#[clippy::version = "1.42.0"]
28-
pub MODULO_ARITHMETIC,
29-
restriction,
30-
"any modulo arithmetic statement"
31-
}
10+
use super::MODULO_ARITHMETIC;
3211

33-
declare_lint_pass!(ModuloArithmetic => [MODULO_ARITHMETIC]);
12+
pub(super) fn check<'tcx>(
13+
cx: &LateContext<'tcx>,
14+
e: &'tcx Expr<'_>,
15+
op: BinOpKind,
16+
lhs: &'tcx Expr<'_>,
17+
rhs: &'tcx Expr<'_>,
18+
) {
19+
if op == BinOpKind::Rem {
20+
let lhs_operand = analyze_operand(lhs, cx, e);
21+
let rhs_operand = analyze_operand(rhs, cx, e);
22+
if_chain! {
23+
if let Some(lhs_operand) = lhs_operand;
24+
if let Some(rhs_operand) = rhs_operand;
25+
then {
26+
check_const_operands(cx, e, &lhs_operand, &rhs_operand);
27+
}
28+
else {
29+
check_non_const_operands(cx, e, lhs);
30+
}
31+
}
32+
};
33+
}
3434

3535
struct OperandInfo {
3636
string_representation: Option<String>,
@@ -124,27 +124,3 @@ fn check_non_const_operands<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>,
124124
);
125125
}
126126
}
127-
128-
impl<'tcx> LateLintPass<'tcx> for ModuloArithmetic {
129-
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
130-
match &expr.kind {
131-
ExprKind::Binary(op, lhs, rhs) | ExprKind::AssignOp(op, lhs, rhs) => {
132-
if op.node == BinOpKind::Rem {
133-
let lhs_operand = analyze_operand(lhs, cx, expr);
134-
let rhs_operand = analyze_operand(rhs, cx, expr);
135-
if_chain! {
136-
if let Some(lhs_operand) = lhs_operand;
137-
if let Some(rhs_operand) = rhs_operand;
138-
then {
139-
check_const_operands(cx, expr, &lhs_operand, &rhs_operand);
140-
}
141-
else {
142-
check_non_const_operands(cx, expr, lhs);
143-
}
144-
}
145-
};
146-
},
147-
_ => {},
148-
}
149-
}
150-
}

0 commit comments

Comments
 (0)