Skip to content

Commit 4235e44

Browse files
committed
[arithmetic_side_effects] Fix #10590
1 parent 82d71b1 commit 4235e44

File tree

3 files changed

+169
-110
lines changed

3 files changed

+169
-110
lines changed

clippy_lints/src/operators/arithmetic_side_effects.rs

+31
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,34 @@ impl ArithmeticSideEffects {
184184
}
185185
}
186186

187+
/// There are some integer methods like `wrapping_div` that will panic depending on the
188+
/// provided input.
189+
fn manage_method_call<'tcx>(
190+
&mut self,
191+
args: &[hir::Expr<'tcx>],
192+
cx: &LateContext<'tcx>,
193+
instance: &hir::Expr<'tcx>,
194+
ps: &hir::PathSegment<'tcx>,
195+
) {
196+
const METHODS: &[&str] = &["wrapping_div", "wrapping_rem", "wrapping_rem_euclid"];
197+
let Some(arg) = args.first() else { return; };
198+
if constant_simple(cx, cx.typeck_results(), instance).is_some() {
199+
return;
200+
}
201+
let instance_ty = cx.typeck_results().expr_ty(instance);
202+
if !Self::is_integral(instance_ty) {
203+
return;
204+
}
205+
let has_method = METHODS.iter().copied().any(|method| method == ps.ident.as_str());
206+
if !has_method {
207+
return;
208+
}
209+
let (actual_arg, _) = peel_hir_expr_refs(arg);
210+
if let Some(n) = Self::literal_integer(cx, actual_arg) && n == 0 {
211+
self.issue_lint(cx, arg);
212+
}
213+
}
214+
187215
fn manage_unary_ops<'tcx>(
188216
&mut self,
189217
cx: &LateContext<'tcx>,
@@ -222,6 +250,9 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
222250
hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => {
223251
self.manage_bin_ops(cx, expr, op, lhs, rhs);
224252
},
253+
hir::ExprKind::MethodCall(ps, instance, args, _) => {
254+
self.manage_method_call(args, cx, instance, ps);
255+
},
225256
hir::ExprKind::Unary(un_op, un_expr) => {
226257
self.manage_unary_ops(cx, expr, un_expr, *un_op);
227258
},

tests/ui/arithmetic_side_effects.rs

+10
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,11 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri
269269
_n = &1 * _n;
270270
_n = 23 + 85;
271271

272+
// Method
273+
_n.wrapping_div(1);
274+
_n.wrapping_rem(1);
275+
_n.wrapping_rem_euclid(1);
276+
272277
// Unary
273278
_n = -2147483647;
274279
_n = -i32::MAX;
@@ -376,6 +381,11 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() {
376381
_custom = Custom << _custom;
377382
_custom = &Custom << _custom;
378383

384+
// Method
385+
_n.wrapping_div(0);
386+
_n.wrapping_rem(0);
387+
_n.wrapping_rem_euclid(0);
388+
379389
// Unary
380390
_n = -_n;
381391
_n = -&_n;

0 commit comments

Comments
 (0)