From de863026912d9fa86db10003825273697218a6e4 Mon Sep 17 00:00:00 2001 From: lapla-cogito Date: Mon, 23 Dec 2024 00:44:15 +0900 Subject: [PATCH] correct suggestion for manual_div_ceil lint --- clippy_lints/src/manual_div_ceil.rs | 38 ++++++++++- tests/ui/manual_div_ceil.fixed | 22 +++++++ tests/ui/manual_div_ceil.rs | 22 +++++++ tests/ui/manual_div_ceil.stderr | 56 +++++++++++++++- tests/ui/manual_div_ceil_with_feature.fixed | 27 ++++++++ tests/ui/manual_div_ceil_with_feature.rs | 27 ++++++++ tests/ui/manual_div_ceil_with_feature.stderr | 68 +++++++++++++++++++- 7 files changed, 255 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/manual_div_ceil.rs b/clippy_lints/src/manual_div_ceil.rs index bbb89bee8355d..aa59b047b169a 100644 --- a/clippy_lints/src/manual_div_ceil.rs +++ b/clippy_lints/src/manual_div_ceil.rs @@ -2,14 +2,15 @@ use clippy_utils::SpanlessEq; use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::msrvs::{self, Msrv}; use clippy_utils::source::snippet_with_applicability; -use clippy_utils::sugg::Sugg; -use rustc_ast::{BinOpKind, LitKind}; +use clippy_utils::sugg::{Sugg, has_enclosing_paren}; +use rustc_ast::{BinOpKind, LitIntType, LitKind, UnOp}; use rustc_data_structures::packed::Pu128; use rustc_errors::Applicability; use rustc_hir::{Expr, ExprKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::{self}; use rustc_session::impl_lint_pass; +use rustc_span::source_map::Spanned; use rustc_span::symbol::Symbol; use clippy_config::Conf; @@ -138,9 +139,40 @@ fn build_suggestion( applicability: &mut Applicability, ) { let dividend_sugg = Sugg::hir_with_applicability(cx, lhs, "..", applicability).maybe_par(); + let type_suffix = if cx.typeck_results().expr_ty(lhs).is_numeric() + && matches!( + lhs.kind, + ExprKind::Lit(Spanned { + node: LitKind::Int(_, LitIntType::Unsuffixed), + .. + }) | ExprKind::Unary(UnOp::Neg, Expr { + kind: ExprKind::Lit(Spanned { + node: LitKind::Int(_, LitIntType::Unsuffixed), + .. + }), + .. + }) + ) { + format!("_{}", cx.typeck_results().expr_ty(rhs)) + } else { + String::new() + }; + let dividend_sugg_str = dividend_sugg.into_string(); + // If `dividend_sugg` has enclosing paren like `(-2048)` and we need to add type suffix in the + // suggestion message, we want to make a suggestion string before `div_ceil` like + // `(-2048_{type_suffix})`. + let suggestion_before_div_ceil = if has_enclosing_paren(÷nd_sugg_str) { + format!( + "{}{})", + ÷nd_sugg_str[..dividend_sugg_str.len() - 1].to_string(), + type_suffix + ) + } else { + format!("{dividend_sugg_str}{type_suffix}") + }; let divisor_snippet = snippet_with_applicability(cx, rhs.span.source_callsite(), "..", applicability); - let sugg = format!("{dividend_sugg}.div_ceil({divisor_snippet})"); + let sugg = format!("{suggestion_before_div_ceil}.div_ceil({divisor_snippet})"); span_lint_and_sugg( cx, diff --git a/tests/ui/manual_div_ceil.fixed b/tests/ui/manual_div_ceil.fixed index e7801f7376aaf..1fb1df5b44253 100644 --- a/tests/ui/manual_div_ceil.fixed +++ b/tests/ui/manual_div_ceil.fixed @@ -28,3 +28,25 @@ fn main() { let _ = (7_u32 as i32 + (y_i - 1)) / y_i; let _ = (7_u32 as i32 + (4 - 1)) / 4; } + +fn issue_13843() { + let x = 3usize; + let _ = 2048_usize.div_ceil(x); + + let x = 5usize; + let _ = 2048usize.div_ceil(x); + + let x = 5usize; + let _ = 2048_usize.div_ceil(x); + + let x = 2048usize; + let _ = x.div_ceil(4); + + let _: u32 = 2048_u32.div_ceil(6); + let _: usize = 2048_usize.div_ceil(6); + let _: u32 = 0x2048_u32.div_ceil(0x6); + + let _ = 2048_u32.div_ceil(6u32); + + let _ = 1_000_000_u32.div_ceil(6u32); +} diff --git a/tests/ui/manual_div_ceil.rs b/tests/ui/manual_div_ceil.rs index 2de74c7eaa881..4f6d38f0d1450 100644 --- a/tests/ui/manual_div_ceil.rs +++ b/tests/ui/manual_div_ceil.rs @@ -28,3 +28,25 @@ fn main() { let _ = (7_u32 as i32 + (y_i - 1)) / y_i; let _ = (7_u32 as i32 + (4 - 1)) / 4; } + +fn issue_13843() { + let x = 3usize; + let _ = (2048 + x - 1) / x; + + let x = 5usize; + let _ = (2048usize + x - 1) / x; + + let x = 5usize; + let _ = (2048_usize + x - 1) / x; + + let x = 2048usize; + let _ = (x + 4 - 1) / 4; + + let _: u32 = (2048 + 6 - 1) / 6; + let _: usize = (2048 + 6 - 1) / 6; + let _: u32 = (0x2048 + 0x6 - 1) / 0x6; + + let _ = (2048 + 6u32 - 1) / 6u32; + + let _ = (1_000_000 + 6u32 - 1) / 6u32; +} diff --git a/tests/ui/manual_div_ceil.stderr b/tests/ui/manual_div_ceil.stderr index dc652dff405f2..3d87fe8e04090 100644 --- a/tests/ui/manual_div_ceil.stderr +++ b/tests/ui/manual_div_ceil.stderr @@ -31,5 +31,59 @@ error: manually reimplementing `div_ceil` LL | let _ = (7_i32 as u32 + (4 - 1)) / 4; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(7_i32 as u32).div_ceil(4)` -error: aborting due to 5 previous errors +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:34:13 + | +LL | let _ = (2048 + x - 1) / x; + | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:37:13 + | +LL | let _ = (2048usize + x - 1) / x; + | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048usize.div_ceil(x)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:40:13 + | +LL | let _ = (2048_usize + x - 1) / x; + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:43:13 + | +LL | let _ = (x + 4 - 1) / 4; + | ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(4)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:45:18 + | +LL | let _: u32 = (2048 + 6 - 1) / 6; + | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:46:20 + | +LL | let _: usize = (2048 + 6 - 1) / 6; + | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(6)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:47:18 + | +LL | let _: u32 = (0x2048 + 0x6 - 1) / 0x6; + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `0x2048_u32.div_ceil(0x6)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:49:13 + | +LL | let _ = (2048 + 6u32 - 1) / 6u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6u32)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil.rs:51:13 + | +LL | let _ = (1_000_000 + 6u32 - 1) / 6u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)` + +error: aborting due to 14 previous errors diff --git a/tests/ui/manual_div_ceil_with_feature.fixed b/tests/ui/manual_div_ceil_with_feature.fixed index a1d678c66898c..f32b78aa14d08 100644 --- a/tests/ui/manual_div_ceil_with_feature.fixed +++ b/tests/ui/manual_div_ceil_with_feature.fixed @@ -23,3 +23,30 @@ fn main() { let _ = (x + (y - 1)) / z; } + +fn issue_13843() { + let x = 3usize; + let _ = 2048_usize.div_ceil(x); + + let x = 5usize; + let _ = 2048usize.div_ceil(x); + + let x = 5usize; + let _ = 2048_usize.div_ceil(x); + + let x = 2048usize; + let _ = x.div_ceil(4); + + let _ = 2048_i32.div_ceil(4); + + let _: u32 = 2048_u32.div_ceil(6); + let _: usize = 2048_usize.div_ceil(6); + let _: u32 = 0x2048_u32.div_ceil(0x6); + + let _ = 2048_u32.div_ceil(6u32); + + let x = -2; + let _ = (-2048_i32).div_ceil(x); + + let _ = 1_000_000_u32.div_ceil(6u32); +} diff --git a/tests/ui/manual_div_ceil_with_feature.rs b/tests/ui/manual_div_ceil_with_feature.rs index 58cb1dbe34d1c..54d89fcbd4622 100644 --- a/tests/ui/manual_div_ceil_with_feature.rs +++ b/tests/ui/manual_div_ceil_with_feature.rs @@ -23,3 +23,30 @@ fn main() { let _ = (x + (y - 1)) / z; } + +fn issue_13843() { + let x = 3usize; + let _ = (2048 + x - 1) / x; + + let x = 5usize; + let _ = (2048usize + x - 1) / x; + + let x = 5usize; + let _ = (2048_usize + x - 1) / x; + + let x = 2048usize; + let _ = (x + 4 - 1) / 4; + + let _ = (2048 + 4 - 1) / 4; + + let _: u32 = (2048 + 6 - 1) / 6; + let _: usize = (2048 + 6 - 1) / 6; + let _: u32 = (0x2048 + 0x6 - 1) / 0x6; + + let _ = (2048 + 6u32 - 1) / 6u32; + + let x = -2; + let _ = (-2048 + x - 1) / x; + + let _ = (1_000_000 + 6u32 - 1) / 6u32; +} diff --git a/tests/ui/manual_div_ceil_with_feature.stderr b/tests/ui/manual_div_ceil_with_feature.stderr index 361ef9bd9f42a..c5e8c1a687cd8 100644 --- a/tests/ui/manual_div_ceil_with_feature.stderr +++ b/tests/ui/manual_div_ceil_with_feature.stderr @@ -43,5 +43,71 @@ error: manually reimplementing `div_ceil` LL | let _ = (z_u + (4 - 1)) / 4; | ^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `z_u.div_ceil(4)` -error: aborting due to 7 previous errors +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:29:13 + | +LL | let _ = (2048 + x - 1) / x; + | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:32:13 + | +LL | let _ = (2048usize + x - 1) / x; + | ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048usize.div_ceil(x)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:35:13 + | +LL | let _ = (2048_usize + x - 1) / x; + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(x)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:38:13 + | +LL | let _ = (x + 4 - 1) / 4; + | ^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `x.div_ceil(4)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:40:13 + | +LL | let _ = (2048 + 4 - 1) / 4; + | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_i32.div_ceil(4)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:42:18 + | +LL | let _: u32 = (2048 + 6 - 1) / 6; + | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:43:20 + | +LL | let _: usize = (2048 + 6 - 1) / 6; + | ^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_usize.div_ceil(6)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:44:18 + | +LL | let _: u32 = (0x2048 + 0x6 - 1) / 0x6; + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `0x2048_u32.div_ceil(0x6)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:46:13 + | +LL | let _ = (2048 + 6u32 - 1) / 6u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `2048_u32.div_ceil(6u32)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:49:13 + | +LL | let _ = (-2048 + x - 1) / x; + | ^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `(-2048_i32).div_ceil(x)` + +error: manually reimplementing `div_ceil` + --> tests/ui/manual_div_ceil_with_feature.rs:51:13 + | +LL | let _ = (1_000_000 + 6u32 - 1) / 6u32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `.div_ceil()`: `1_000_000_u32.div_ceil(6u32)` + +error: aborting due to 18 previous errors