diff --git a/clippy_lints/src/operators/integer_division_remainder_used.rs b/clippy_lints/src/operators/integer_division_remainder_used.rs index 976b2d8b0c63..3be1a291db2b 100644 --- a/clippy_lints/src/operators/integer_division_remainder_used.rs +++ b/clippy_lints/src/operators/integer_division_remainder_used.rs @@ -22,3 +22,40 @@ pub(super) fn check(cx: &LateContext<'_>, op: BinOpKind, lhs: &Expr<'_>, rhs: &E ); } } +// check method call is present in specific list if yes also lint it +pub(super) fn check_method_call(cx: &LateContext<'_>, method_name: &str, receiver: &Expr<'_>, span: Span) { + let instance_ty = cx.typeck_results().expr_ty(receiver); + if matches!( + method_name, + "checked_div" + | "checked_div_euclid" + | "checked_div_exact" + | "checked_rem" + | "checked_rem_euclid" + | "div_ceil" + | "div_euclid" + | "div_exact" + | "overflowing_div" + | "overflowing_div_euclid" + | "overflowing_rem" + | "overflowing_rem_euclid" + | "rem_euclid" + | "strict_div" + | "strict_div_euclid" + | "saturating_div" + | "strict_rem" + | "strict_rem_euclid" + | "wrapping_div" + | "wrapping_div_euclid" + | "wrapping_rem" + | "wrapping_rem_euclid" + ) && matches!(instance_ty.peel_refs().kind(), ty::Int(_) | ty::Uint(_)) + { + span_lint( + cx, + INTEGER_DIVISION_REMAINDER_USED, + span.source_callsite(), + format!("use of `{method_name}` has been disallowed in this context"), + ); + } +} diff --git a/clippy_lints/src/operators/mod.rs b/clippy_lints/src/operators/mod.rs index 47938c7da392..e4022f6d4079 100644 --- a/clippy_lints/src/operators/mod.rs +++ b/clippy_lints/src/operators/mod.rs @@ -1088,6 +1088,9 @@ impl<'tcx> LateLintPass<'tcx> for Operators { ); manual_div_ceil::check(cx, e, op.node, lhs, rhs, self.msrv); }, + ExprKind::MethodCall(path, receiver, _args, span) => { + integer_division_remainder_used::check_method_call(cx, path.ident.name.as_str(), receiver, span); + }, ExprKind::AssignOp(op, lhs, rhs) => { let bin_op = op.node.into(); if !e.span.from_expansion() { diff --git a/tests/ui/integer_division_remainder_used.rs b/tests/ui/integer_division_remainder_used.rs index f8d303b04bfc..30d3f05efae2 100644 --- a/tests/ui/integer_division_remainder_used.rs +++ b/tests/ui/integer_division_remainder_used.rs @@ -19,6 +19,21 @@ impl std::ops::Rem for CustomOps { } } +fn issue17603() { + let x: u16 = 7; + let _ = x.div_ceil(3); + //~^ integer_division_remainder_used + + let _ = x.wrapping_div(3); + //~^ integer_division_remainder_used + + let _ = x.checked_rem(3); + //~^ integer_division_remainder_used + + let f: f64 = 7.0; + let _ = f.div_euclid(3.0); +} + fn main() { // should trigger let a = 10; diff --git a/tests/ui/integer_division_remainder_used.stderr b/tests/ui/integer_division_remainder_used.stderr index 84fa20020adc..cf02a7c5f799 100644 --- a/tests/ui/integer_division_remainder_used.stderr +++ b/tests/ui/integer_division_remainder_used.stderr @@ -13,59 +13,77 @@ error: use of `%` has been disallowed in this context LL | Self(self.0 % rhs.0) | ^^^^^^^^^^^^^^ +error: use of `div_ceil` has been disallowed in this context + --> tests/ui/integer_division_remainder_used.rs:24:15 + | +LL | let _ = x.div_ceil(3); + | ^^^^^^^^^^^ + +error: use of `wrapping_div` has been disallowed in this context + --> tests/ui/integer_division_remainder_used.rs:27:15 + | +LL | let _ = x.wrapping_div(3); + | ^^^^^^^^^^^^^^^ + +error: use of `checked_rem` has been disallowed in this context + --> tests/ui/integer_division_remainder_used.rs:30:15 + | +LL | let _ = x.checked_rem(3); + | ^^^^^^^^^^^^^^ + error: use of `/` has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:26:13 + --> tests/ui/integer_division_remainder_used.rs:41:13 | LL | let c = a / b; | ^^^^^ error: use of `%` has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:28:13 + --> tests/ui/integer_division_remainder_used.rs:43:13 | LL | let d = a % b; | ^^^^^ error: use of `/` has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:30:13 + --> tests/ui/integer_division_remainder_used.rs:45:13 | LL | let e = &a / b; | ^^^^^^ error: use of `%` has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:32:13 + --> tests/ui/integer_division_remainder_used.rs:47:13 | LL | let f = a % &b; | ^^^^^^ error: use of `/` has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:34:13 + --> tests/ui/integer_division_remainder_used.rs:49:13 | LL | let g = &a / &b; | ^^^^^^^ error: use of `%` has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:36:13 + --> tests/ui/integer_division_remainder_used.rs:51:13 | LL | let h = &10 % b; | ^^^^^^^ error: use of `/` has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:38:13 + --> tests/ui/integer_division_remainder_used.rs:53:13 | LL | let i = a / &4; | ^^^^^^ error: use of `/` has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:43:5 + --> tests/ui/integer_division_remainder_used.rs:58:5 | LL | j /= 2; | ^^^^^^ error: use of `%` has been disallowed in this context - --> tests/ui/integer_division_remainder_used.rs:45:5 + --> tests/ui/integer_division_remainder_used.rs:60:5 | LL | j %= 3; | ^^^^^^ -error: aborting due to 11 previous errors +error: aborting due to 14 previous errors