1- use clippy_config:: Conf ;
21use clippy_utils:: diagnostics:: span_lint_and_sugg;
32use clippy_utils:: msrvs:: { self , Msrv } ;
43use clippy_utils:: sugg:: { Sugg , has_enclosing_paren} ;
@@ -7,111 +6,69 @@ use rustc_ast::{BinOpKind, LitIntType, LitKind, UnOp};
76use rustc_data_structures:: packed:: Pu128 ;
87use rustc_errors:: Applicability ;
98use rustc_hir:: { Expr , ExprKind } ;
10- use rustc_lint:: { LateContext , LateLintPass } ;
9+ use rustc_lint:: LateContext ;
1110use rustc_middle:: ty:: { self } ;
12- use rustc_session:: impl_lint_pass;
1311use 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}
0 commit comments