Skip to content

Commit 4be0e62

Browse files
authored
correct suggestion for manual_div_ceil lint (#13864)
fix #13843 The `manual_div_ceil` lint makes incorrect suggestion when type suffixes need to be made explicit in the suggested code. changelog: [`manual_div_ceil`]: suggested code now includes appropriate type suffixes where necessary
2 parents 553a381 + de86302 commit 4be0e62

7 files changed

+255
-5
lines changed

clippy_lints/src/manual_div_ceil.rs

+35-3
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@ use clippy_utils::SpanlessEq;
22
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::msrvs::{self, Msrv};
44
use clippy_utils::source::snippet_with_applicability;
5-
use clippy_utils::sugg::Sugg;
6-
use rustc_ast::{BinOpKind, LitKind};
5+
use clippy_utils::sugg::{Sugg, has_enclosing_paren};
6+
use rustc_ast::{BinOpKind, LitIntType, LitKind, UnOp};
77
use rustc_data_structures::packed::Pu128;
88
use rustc_errors::Applicability;
99
use rustc_hir::{Expr, ExprKind};
1010
use rustc_lint::{LateContext, LateLintPass};
1111
use rustc_middle::ty::{self};
1212
use rustc_session::impl_lint_pass;
13+
use rustc_span::source_map::Spanned;
1314
use rustc_span::symbol::Symbol;
1415

1516
use clippy_config::Conf;
@@ -138,9 +139,40 @@ fn build_suggestion(
138139
applicability: &mut Applicability,
139140
) {
140141
let dividend_sugg = Sugg::hir_with_applicability(cx, lhs, "..", applicability).maybe_par();
142+
let type_suffix = if cx.typeck_results().expr_ty(lhs).is_numeric()
143+
&& matches!(
144+
lhs.kind,
145+
ExprKind::Lit(Spanned {
146+
node: LitKind::Int(_, LitIntType::Unsuffixed),
147+
..
148+
}) | ExprKind::Unary(UnOp::Neg, Expr {
149+
kind: ExprKind::Lit(Spanned {
150+
node: LitKind::Int(_, LitIntType::Unsuffixed),
151+
..
152+
}),
153+
..
154+
})
155+
) {
156+
format!("_{}", cx.typeck_results().expr_ty(rhs))
157+
} else {
158+
String::new()
159+
};
160+
let dividend_sugg_str = dividend_sugg.into_string();
161+
// If `dividend_sugg` has enclosing paren like `(-2048)` and we need to add type suffix in the
162+
// suggestion message, we want to make a suggestion string before `div_ceil` like
163+
// `(-2048_{type_suffix})`.
164+
let suggestion_before_div_ceil = if has_enclosing_paren(&dividend_sugg_str) {
165+
format!(
166+
"{}{})",
167+
&dividend_sugg_str[..dividend_sugg_str.len() - 1].to_string(),
168+
type_suffix
169+
)
170+
} else {
171+
format!("{dividend_sugg_str}{type_suffix}")
172+
};
141173
let divisor_snippet = snippet_with_applicability(cx, rhs.span.source_callsite(), "..", applicability);
142174

143-
let sugg = format!("{dividend_sugg}.div_ceil({divisor_snippet})");
175+
let sugg = format!("{suggestion_before_div_ceil}.div_ceil({divisor_snippet})");
144176

145177
span_lint_and_sugg(
146178
cx,

tests/ui/manual_div_ceil.fixed

+22
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,25 @@ fn main() {
2828
let _ = (7_u32 as i32 + (y_i - 1)) / y_i;
2929
let _ = (7_u32 as i32 + (4 - 1)) / 4;
3030
}
31+
32+
fn issue_13843() {
33+
let x = 3usize;
34+
let _ = 2048_usize.div_ceil(x);
35+
36+
let x = 5usize;
37+
let _ = 2048usize.div_ceil(x);
38+
39+
let x = 5usize;
40+
let _ = 2048_usize.div_ceil(x);
41+
42+
let x = 2048usize;
43+
let _ = x.div_ceil(4);
44+
45+
let _: u32 = 2048_u32.div_ceil(6);
46+
let _: usize = 2048_usize.div_ceil(6);
47+
let _: u32 = 0x2048_u32.div_ceil(0x6);
48+
49+
let _ = 2048_u32.div_ceil(6u32);
50+
51+
let _ = 1_000_000_u32.div_ceil(6u32);
52+
}

tests/ui/manual_div_ceil.rs

+22
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,25 @@ fn main() {
2828
let _ = (7_u32 as i32 + (y_i - 1)) / y_i;
2929
let _ = (7_u32 as i32 + (4 - 1)) / 4;
3030
}
31+
32+
fn issue_13843() {
33+
let x = 3usize;
34+
let _ = (2048 + x - 1) / x;
35+
36+
let x = 5usize;
37+
let _ = (2048usize + x - 1) / x;
38+
39+
let x = 5usize;
40+
let _ = (2048_usize + x - 1) / x;
41+
42+
let x = 2048usize;
43+
let _ = (x + 4 - 1) / 4;
44+
45+
let _: u32 = (2048 + 6 - 1) / 6;
46+
let _: usize = (2048 + 6 - 1) / 6;
47+
let _: u32 = (0x2048 + 0x6 - 1) / 0x6;
48+
49+
let _ = (2048 + 6u32 - 1) / 6u32;
50+
51+
let _ = (1_000_000 + 6u32 - 1) / 6u32;
52+
}

tests/ui/manual_div_ceil.stderr

+55-1
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,59 @@ error: manually reimplementing `div_ceil`
3131
LL | let _ = (7_i32 as u32 + (4 - 1)) / 4;
3232
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)`
3333

34-
error: aborting due to 5 previous errors
34+
error: manually reimplementing `div_ceil`
35+
--> tests/ui/manual_div_ceil.rs:34:13
36+
|
37+
LL | let _ = (2048 + x - 1) / x;
38+
| ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)`
39+
40+
error: manually reimplementing `div_ceil`
41+
--> tests/ui/manual_div_ceil.rs:37:13
42+
|
43+
LL | let _ = (2048usize + x - 1) / x;
44+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048usize.div_ceil(x)`
45+
46+
error: manually reimplementing `div_ceil`
47+
--> tests/ui/manual_div_ceil.rs:40:13
48+
|
49+
LL | let _ = (2048_usize + x - 1) / x;
50+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)`
51+
52+
error: manually reimplementing `div_ceil`
53+
--> tests/ui/manual_div_ceil.rs:43:13
54+
|
55+
LL | let _ = (x + 4 - 1) / 4;
56+
| ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(4)`
57+
58+
error: manually reimplementing `div_ceil`
59+
--> tests/ui/manual_div_ceil.rs:45:18
60+
|
61+
LL | let _: u32 = (2048 + 6 - 1) / 6;
62+
| ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6)`
63+
64+
error: manually reimplementing `div_ceil`
65+
--> tests/ui/manual_div_ceil.rs:46:20
66+
|
67+
LL | let _: usize = (2048 + 6 - 1) / 6;
68+
| ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(6)`
69+
70+
error: manually reimplementing `div_ceil`
71+
--> tests/ui/manual_div_ceil.rs:47:18
72+
|
73+
LL | let _: u32 = (0x2048 + 0x6 - 1) / 0x6;
74+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `0x2048_u32.div_ceil(0x6)`
75+
76+
error: manually reimplementing `div_ceil`
77+
--> tests/ui/manual_div_ceil.rs:49:13
78+
|
79+
LL | let _ = (2048 + 6u32 - 1) / 6u32;
80+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6u32)`
81+
82+
error: manually reimplementing `div_ceil`
83+
--> tests/ui/manual_div_ceil.rs:51:13
84+
|
85+
LL | let _ = (1_000_000 + 6u32 - 1) / 6u32;
86+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)`
87+
88+
error: aborting due to 14 previous errors
3589

tests/ui/manual_div_ceil_with_feature.fixed

+27
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,30 @@ fn main() {
2323

2424
let _ = (x + (y - 1)) / z;
2525
}
26+
27+
fn issue_13843() {
28+
let x = 3usize;
29+
let _ = 2048_usize.div_ceil(x);
30+
31+
let x = 5usize;
32+
let _ = 2048usize.div_ceil(x);
33+
34+
let x = 5usize;
35+
let _ = 2048_usize.div_ceil(x);
36+
37+
let x = 2048usize;
38+
let _ = x.div_ceil(4);
39+
40+
let _ = 2048_i32.div_ceil(4);
41+
42+
let _: u32 = 2048_u32.div_ceil(6);
43+
let _: usize = 2048_usize.div_ceil(6);
44+
let _: u32 = 0x2048_u32.div_ceil(0x6);
45+
46+
let _ = 2048_u32.div_ceil(6u32);
47+
48+
let x = -2;
49+
let _ = (-2048_i32).div_ceil(x);
50+
51+
let _ = 1_000_000_u32.div_ceil(6u32);
52+
}

tests/ui/manual_div_ceil_with_feature.rs

+27
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,30 @@ fn main() {
2323

2424
let _ = (x + (y - 1)) / z;
2525
}
26+
27+
fn issue_13843() {
28+
let x = 3usize;
29+
let _ = (2048 + x - 1) / x;
30+
31+
let x = 5usize;
32+
let _ = (2048usize + x - 1) / x;
33+
34+
let x = 5usize;
35+
let _ = (2048_usize + x - 1) / x;
36+
37+
let x = 2048usize;
38+
let _ = (x + 4 - 1) / 4;
39+
40+
let _ = (2048 + 4 - 1) / 4;
41+
42+
let _: u32 = (2048 + 6 - 1) / 6;
43+
let _: usize = (2048 + 6 - 1) / 6;
44+
let _: u32 = (0x2048 + 0x6 - 1) / 0x6;
45+
46+
let _ = (2048 + 6u32 - 1) / 6u32;
47+
48+
let x = -2;
49+
let _ = (-2048 + x - 1) / x;
50+
51+
let _ = (1_000_000 + 6u32 - 1) / 6u32;
52+
}

tests/ui/manual_div_ceil_with_feature.stderr

+67-1
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,71 @@ error: manually reimplementing `div_ceil`
4343
LL | let _ = (z_u + (4 - 1)) / 4;
4444
| ^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `z_u.div_ceil(4)`
4545

46-
error: aborting due to 7 previous errors
46+
error: manually reimplementing `div_ceil`
47+
--> tests/ui/manual_div_ceil_with_feature.rs:29:13
48+
|
49+
LL | let _ = (2048 + x - 1) / x;
50+
| ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)`
51+
52+
error: manually reimplementing `div_ceil`
53+
--> tests/ui/manual_div_ceil_with_feature.rs:32:13
54+
|
55+
LL | let _ = (2048usize + x - 1) / x;
56+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048usize.div_ceil(x)`
57+
58+
error: manually reimplementing `div_ceil`
59+
--> tests/ui/manual_div_ceil_with_feature.rs:35:13
60+
|
61+
LL | let _ = (2048_usize + x - 1) / x;
62+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)`
63+
64+
error: manually reimplementing `div_ceil`
65+
--> tests/ui/manual_div_ceil_with_feature.rs:38:13
66+
|
67+
LL | let _ = (x + 4 - 1) / 4;
68+
| ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(4)`
69+
70+
error: manually reimplementing `div_ceil`
71+
--> tests/ui/manual_div_ceil_with_feature.rs:40:13
72+
|
73+
LL | let _ = (2048 + 4 - 1) / 4;
74+
| ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_i32.div_ceil(4)`
75+
76+
error: manually reimplementing `div_ceil`
77+
--> tests/ui/manual_div_ceil_with_feature.rs:42:18
78+
|
79+
LL | let _: u32 = (2048 + 6 - 1) / 6;
80+
| ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6)`
81+
82+
error: manually reimplementing `div_ceil`
83+
--> tests/ui/manual_div_ceil_with_feature.rs:43:20
84+
|
85+
LL | let _: usize = (2048 + 6 - 1) / 6;
86+
| ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(6)`
87+
88+
error: manually reimplementing `div_ceil`
89+
--> tests/ui/manual_div_ceil_with_feature.rs:44:18
90+
|
91+
LL | let _: u32 = (0x2048 + 0x6 - 1) / 0x6;
92+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `0x2048_u32.div_ceil(0x6)`
93+
94+
error: manually reimplementing `div_ceil`
95+
--> tests/ui/manual_div_ceil_with_feature.rs:46:13
96+
|
97+
LL | let _ = (2048 + 6u32 - 1) / 6u32;
98+
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6u32)`
99+
100+
error: manually reimplementing `div_ceil`
101+
--> tests/ui/manual_div_ceil_with_feature.rs:49:13
102+
|
103+
LL | let _ = (-2048 + x - 1) / x;
104+
| ^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(-2048_i32).div_ceil(x)`
105+
106+
error: manually reimplementing `div_ceil`
107+
--> tests/ui/manual_div_ceil_with_feature.rs:51:13
108+
|
109+
LL | let _ = (1_000_000 + 6u32 - 1) / 6u32;
110+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)`
111+
112+
error: aborting due to 18 previous errors
47113

0 commit comments

Comments
 (0)