Skip to content

Commit 13e5caf

Browse files
committed
correct suggestion for manual_div_ceil lint
1 parent 0f9cc8d commit 13e5caf

7 files changed

+259
-5
lines changed

clippy_lints/src/manual_div_ceil.rs

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use clippy_utils::SpanlessEq;
22
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::msrvs::{self, Msrv};
4-
use clippy_utils::source::snippet_with_applicability;
5-
use clippy_utils::sugg::Sugg;
4+
use clippy_utils::source::{snippet, snippet_with_applicability};
5+
use clippy_utils::sugg::{Sugg, has_enclosing_paren};
66
use rustc_ast::{BinOpKind, LitKind};
77
use rustc_data_structures::packed::Pu128;
88
use rustc_errors::Applicability;
@@ -130,6 +130,22 @@ fn check_eq_expr(cx: &LateContext<'_>, lhs: &Expr<'_>, rhs: &Expr<'_>) -> bool {
130130
SpanlessEq::new(cx).eq_expr(lhs, rhs)
131131
}
132132

133+
// Check if the literal contains type suffix like `7_i32` or `7u32`
134+
fn is_include_type_suffix(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
135+
let snip = snippet(cx, expr.span, "..");
136+
let numeric_types = [
137+
"i8", "i16", "i32", "i64", "i128", "isize", "u8", "u16", "u32", "u64", "u128", "usize",
138+
];
139+
140+
for ty in numeric_types {
141+
if snip.ends_with(ty) {
142+
return true;
143+
}
144+
}
145+
146+
false
147+
}
148+
133149
fn build_suggestion(
134150
cx: &LateContext<'_>,
135151
expr: &Expr<'_>,
@@ -138,9 +154,29 @@ fn build_suggestion(
138154
applicability: &mut Applicability,
139155
) {
140156
let dividend_sugg = Sugg::hir_with_applicability(cx, lhs, "..", applicability).maybe_par();
157+
let mut type_suffix = String::new();
158+
if cx.typeck_results().expr_ty(lhs).is_numeric()
159+
&& !is_include_type_suffix(cx, lhs)
160+
&& matches!(lhs.kind, ExprKind::Lit(_) | ExprKind::Unary(_, _))
161+
{
162+
type_suffix = format!("_{}", cx.typeck_results().expr_ty(rhs));
163+
}
164+
let dividend_sugg_str = dividend_sugg.into_string();
165+
// If `dividend_sugg` has enclosing paren like `(-2048)` and we need to add type suffix in the
166+
// suggestion message, we want to make a suggestion string before `div_ceil` like
167+
// `(-2048_{type_suffix})`.
168+
let suggestion_before_div_ceil = if has_enclosing_paren(&dividend_sugg_str) {
169+
format!(
170+
"{}{})",
171+
&dividend_sugg_str[..dividend_sugg_str.len() - 1].to_string(),
172+
type_suffix
173+
)
174+
} else {
175+
format!("{dividend_sugg_str}{type_suffix}")
176+
};
141177
let divisor_snippet = snippet_with_applicability(cx, rhs.span.source_callsite(), "..", applicability);
142178

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

145181
span_lint_and_sugg(
146182
cx,

tests/ui/manual_div_ceil.fixed

Lines changed: 22 additions & 0 deletions
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

Lines changed: 22 additions & 0 deletions
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

Lines changed: 55 additions & 1 deletion
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

Lines changed: 27 additions & 0 deletions
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

Lines changed: 27 additions & 0 deletions
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

Lines changed: 67 additions & 1 deletion
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)