Skip to content

Commit 95dd88d

Browse files
refactor(manual_div_ceil_: move to under operators/ (rust-lang#15909)
changelog: none
2 parents 1ac3cc1 + 9ee9fd0 commit 95dd88d

File tree

4 files changed

+83
-98
lines changed

4 files changed

+83
-98
lines changed

clippy_lints/src/declared_lints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
298298
crate::manual_async_fn::MANUAL_ASYNC_FN_INFO,
299299
crate::manual_bits::MANUAL_BITS_INFO,
300300
crate::manual_clamp::MANUAL_CLAMP_INFO,
301-
crate::manual_div_ceil::MANUAL_DIV_CEIL_INFO,
302301
crate::manual_float_methods::MANUAL_IS_FINITE_INFO,
303302
crate::manual_float_methods::MANUAL_IS_INFINITE_INFO,
304303
crate::manual_hash_one::MANUAL_HASH_ONE_INFO,
@@ -592,6 +591,7 @@ pub static LINTS: &[&::declare_clippy_lint::LintInfo] = &[
592591
crate::operators::IMPOSSIBLE_COMPARISONS_INFO,
593592
crate::operators::INEFFECTIVE_BIT_MASK_INFO,
594593
crate::operators::INTEGER_DIVISION_INFO,
594+
crate::operators::MANUAL_DIV_CEIL_INFO,
595595
crate::operators::MANUAL_IS_MULTIPLE_OF_INFO,
596596
crate::operators::MANUAL_MIDPOINT_INFO,
597597
crate::operators::MISREFACTORED_ASSIGN_OP_INFO,

clippy_lints/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,6 @@ mod manual_assert;
203203
mod manual_async_fn;
204204
mod manual_bits;
205205
mod manual_clamp;
206-
mod manual_div_ceil;
207206
mod manual_float_methods;
208207
mod manual_hash_one;
209208
mod manual_ignore_case_cmp;
@@ -807,7 +806,6 @@ pub fn register_lint_passes(store: &mut rustc_lint::LintStore, conf: &'static Co
807806
store.register_early_pass(|| Box::new(cfg_not_test::CfgNotTest));
808807
store.register_late_pass(|_| Box::new(zombie_processes::ZombieProcesses));
809808
store.register_late_pass(|_| Box::new(pointers_in_nomem_asm_block::PointersInNomemAsmBlock));
810-
store.register_late_pass(move |_| Box::new(manual_div_ceil::ManualDivCeil::new(conf)));
811809
store.register_late_pass(move |_| Box::new(manual_is_power_of_two::ManualIsPowerOfTwo::new(conf)));
812810
store.register_late_pass(|_| Box::new(non_zero_suggestions::NonZeroSuggestions));
813811
store.register_late_pass(|_| Box::new(literal_string_with_formatting_args::LiteralStringWithFormattingArg));

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

Lines changed: 52 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
use clippy_config::Conf;
21
use clippy_utils::diagnostics::span_lint_and_sugg;
32
use clippy_utils::msrvs::{self, Msrv};
43
use clippy_utils::sugg::{Sugg, has_enclosing_paren};
@@ -7,111 +6,69 @@ use rustc_ast::{BinOpKind, LitIntType, LitKind, UnOp};
76
use rustc_data_structures::packed::Pu128;
87
use rustc_errors::Applicability;
98
use rustc_hir::{Expr, ExprKind};
10-
use rustc_lint::{LateContext, LateLintPass};
9+
use rustc_lint::LateContext;
1110
use rustc_middle::ty::{self};
12-
use rustc_session::impl_lint_pass;
1311
use rustc_span::source_map::Spanned;
1412

15-
declare_clippy_lint! {
16-
/// ### What it does
17-
/// Checks for an expression like `(x + (y - 1)) / y` which is a common manual reimplementation
18-
/// of `x.div_ceil(y)`.
19-
///
20-
/// ### Why is this bad?
21-
/// It's simpler, clearer and more readable.
22-
///
23-
/// ### Example
24-
/// ```no_run
25-
/// let x: i32 = 7;
26-
/// let y: i32 = 4;
27-
/// let div = (x + (y - 1)) / y;
28-
/// ```
29-
/// Use instead:
30-
/// ```no_run
31-
/// #![feature(int_roundings)]
32-
/// let x: i32 = 7;
33-
/// let y: i32 = 4;
34-
/// let div = x.div_ceil(y);
35-
/// ```
36-
#[clippy::version = "1.83.0"]
37-
pub MANUAL_DIV_CEIL,
38-
complexity,
39-
"manually reimplementing `div_ceil`"
40-
}
41-
42-
pub struct ManualDivCeil {
43-
msrv: Msrv,
44-
}
45-
46-
impl ManualDivCeil {
47-
#[must_use]
48-
pub fn new(conf: &'static Conf) -> Self {
49-
Self { msrv: conf.msrv }
50-
}
51-
}
13+
use super::MANUAL_DIV_CEIL;
5214

53-
impl_lint_pass!(ManualDivCeil => [MANUAL_DIV_CEIL]);
15+
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &Expr<'_>, msrv: Msrv) {
16+
let mut applicability = Applicability::MachineApplicable;
5417

55-
impl<'tcx> LateLintPass<'tcx> for ManualDivCeil {
56-
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
57-
let mut applicability = Applicability::MachineApplicable;
58-
59-
if let ExprKind::Binary(div_op, div_lhs, div_rhs) = expr.kind
60-
&& div_op.node == BinOpKind::Div
61-
&& check_int_ty_and_feature(cx, div_lhs)
62-
&& check_int_ty_and_feature(cx, div_rhs)
63-
&& let ExprKind::Binary(inner_op, inner_lhs, inner_rhs) = div_lhs.kind
64-
&& self.msrv.meets(cx, msrvs::DIV_CEIL)
18+
if op == BinOpKind::Div
19+
&& check_int_ty_and_feature(cx, lhs)
20+
&& check_int_ty_and_feature(cx, rhs)
21+
&& let ExprKind::Binary(inner_op, inner_lhs, inner_rhs) = lhs.kind
22+
&& msrv.meets(cx, msrvs::DIV_CEIL)
23+
{
24+
// (x + (y - 1)) / y
25+
if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind
26+
&& inner_op.node == BinOpKind::Add
27+
&& sub_op.node == BinOpKind::Sub
28+
&& check_literal(sub_rhs)
29+
&& check_eq_expr(cx, sub_lhs, rhs)
6530
{
66-
// (x + (y - 1)) / y
67-
if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_rhs.kind
68-
&& inner_op.node == BinOpKind::Add
69-
&& sub_op.node == BinOpKind::Sub
70-
&& check_literal(sub_rhs)
71-
&& check_eq_expr(cx, sub_lhs, div_rhs)
72-
{
73-
build_suggestion(cx, expr, inner_lhs, div_rhs, &mut applicability);
74-
return;
75-
}
31+
build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability);
32+
return;
33+
}
7634

77-
// ((y - 1) + x) / y
78-
if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_lhs.kind
79-
&& inner_op.node == BinOpKind::Add
80-
&& sub_op.node == BinOpKind::Sub
81-
&& check_literal(sub_rhs)
82-
&& check_eq_expr(cx, sub_lhs, div_rhs)
83-
{
84-
build_suggestion(cx, expr, inner_rhs, div_rhs, &mut applicability);
85-
return;
86-
}
35+
// ((y - 1) + x) / y
36+
if let ExprKind::Binary(sub_op, sub_lhs, sub_rhs) = inner_lhs.kind
37+
&& inner_op.node == BinOpKind::Add
38+
&& sub_op.node == BinOpKind::Sub
39+
&& check_literal(sub_rhs)
40+
&& check_eq_expr(cx, sub_lhs, rhs)
41+
{
42+
build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability);
43+
return;
44+
}
8745

88-
// (x + y - 1) / y
89-
if let ExprKind::Binary(add_op, add_lhs, add_rhs) = inner_lhs.kind
90-
&& inner_op.node == BinOpKind::Sub
91-
&& add_op.node == BinOpKind::Add
92-
&& check_literal(inner_rhs)
93-
&& check_eq_expr(cx, add_rhs, div_rhs)
94-
{
95-
build_suggestion(cx, expr, add_lhs, div_rhs, &mut applicability);
96-
}
46+
// (x + y - 1) / y
47+
if let ExprKind::Binary(add_op, add_lhs, add_rhs) = inner_lhs.kind
48+
&& inner_op.node == BinOpKind::Sub
49+
&& add_op.node == BinOpKind::Add
50+
&& check_literal(inner_rhs)
51+
&& check_eq_expr(cx, add_rhs, rhs)
52+
{
53+
build_suggestion(cx, expr, add_lhs, rhs, &mut applicability);
54+
}
9755

98-
// (x + (Y - 1)) / Y
99-
if inner_op.node == BinOpKind::Add && differ_by_one(inner_rhs, div_rhs) {
100-
build_suggestion(cx, expr, inner_lhs, div_rhs, &mut applicability);
101-
}
56+
// (x + (Y - 1)) / Y
57+
if inner_op.node == BinOpKind::Add && differ_by_one(inner_rhs, rhs) {
58+
build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability);
59+
}
10260

103-
// ((Y - 1) + x) / Y
104-
if inner_op.node == BinOpKind::Add && differ_by_one(inner_lhs, div_rhs) {
105-
build_suggestion(cx, expr, inner_rhs, div_rhs, &mut applicability);
106-
}
61+
// ((Y - 1) + x) / Y
62+
if inner_op.node == BinOpKind::Add && differ_by_one(inner_lhs, rhs) {
63+
build_suggestion(cx, expr, inner_rhs, rhs, &mut applicability);
64+
}
10765

108-
// (x - (-Y - 1)) / Y
109-
if inner_op.node == BinOpKind::Sub
110-
&& let ExprKind::Unary(UnOp::Neg, abs_div_rhs) = div_rhs.kind
111-
&& differ_by_one(abs_div_rhs, inner_rhs)
112-
{
113-
build_suggestion(cx, expr, inner_lhs, div_rhs, &mut applicability);
114-
}
66+
// (x - (-Y - 1)) / Y
67+
if inner_op.node == BinOpKind::Sub
68+
&& let ExprKind::Unary(UnOp::Neg, abs_div_rhs) = rhs.kind
69+
&& differ_by_one(abs_div_rhs, inner_rhs)
70+
{
71+
build_suggestion(cx, expr, inner_lhs, rhs, &mut applicability);
11572
}
11673
}
11774
}

clippy_lints/src/operators/mod.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ mod float_cmp;
1111
mod float_equality_without_abs;
1212
mod identity_op;
1313
mod integer_division;
14+
mod manual_div_ceil;
1415
mod manual_is_multiple_of;
1516
mod manual_midpoint;
1617
mod misrefactored_assign_op;
@@ -860,6 +861,33 @@ declare_clippy_lint! {
860861
"manual implementation of `.is_multiple_of()`"
861862
}
862863

864+
declare_clippy_lint! {
865+
/// ### What it does
866+
/// Checks for an expression like `(x + (y - 1)) / y` which is a common manual reimplementation
867+
/// of `x.div_ceil(y)`.
868+
///
869+
/// ### Why is this bad?
870+
/// It's simpler, clearer and more readable.
871+
///
872+
/// ### Example
873+
/// ```no_run
874+
/// let x: i32 = 7;
875+
/// let y: i32 = 4;
876+
/// let div = (x + (y - 1)) / y;
877+
/// ```
878+
/// Use instead:
879+
/// ```no_run
880+
/// #![feature(int_roundings)]
881+
/// let x: i32 = 7;
882+
/// let y: i32 = 4;
883+
/// let div = x.div_ceil(y);
884+
/// ```
885+
#[clippy::version = "1.83.0"]
886+
pub MANUAL_DIV_CEIL,
887+
complexity,
888+
"manually reimplementing `div_ceil`"
889+
}
890+
863891
pub struct Operators {
864892
arithmetic_context: numeric_arithmetic::Context,
865893
verbose_bit_mask_threshold: u64,
@@ -906,6 +934,7 @@ impl_lint_pass!(Operators => [
906934
SELF_ASSIGNMENT,
907935
MANUAL_MIDPOINT,
908936
MANUAL_IS_MULTIPLE_OF,
937+
MANUAL_DIV_CEIL,
909938
]);
910939

911940
impl<'tcx> LateLintPass<'tcx> for Operators {
@@ -944,6 +973,7 @@ impl<'tcx> LateLintPass<'tcx> for Operators {
944973
rhs,
945974
self.modulo_arithmetic_allow_comparison_to_zero,
946975
);
976+
manual_div_ceil::check(cx, e, op.node, lhs, rhs, self.msrv);
947977
},
948978
ExprKind::AssignOp(op, lhs, rhs) => {
949979
let bin_op = op.node.into();

0 commit comments

Comments
 (0)