Skip to content

Commit 2caef5f

Browse files
committed
[arithmetic_side_effects] Fix #10590
1 parent 82d71b1 commit 2caef5f

File tree

3 files changed

+212
-110
lines changed

3 files changed

+212
-110
lines changed

clippy_lints/src/operators/arithmetic_side_effects.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,35 @@ 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] = &["saturating_div", "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+
match Self::literal_integer(cx, actual_arg) {
211+
None | Some(0) => self.issue_lint(cx, arg),
212+
Some(_) => {},
213+
}
214+
}
215+
187216
fn manage_unary_ops<'tcx>(
188217
&mut self,
189218
cx: &LateContext<'tcx>,
@@ -222,6 +251,9 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
222251
hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => {
223252
self.manage_bin_ops(cx, expr, op, lhs, rhs);
224253
},
254+
hir::ExprKind::MethodCall(ps, instance, args, _) => {
255+
self.manage_method_call(args, cx, instance, ps);
256+
},
225257
hir::ExprKind::Unary(un_op, un_expr) => {
226258
self.manage_unary_ops(cx, expr, un_expr, *un_op);
227259
},

tests/ui/arithmetic_side_effects.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,17 @@ 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.saturating_div(1);
274+
_n.wrapping_div(1);
275+
_n.wrapping_rem(1);
276+
_n.wrapping_rem_euclid(1);
277+
278+
_n.checked_div(1);
279+
_n.checked_div(1);
280+
_n.checked_rem(1);
281+
_n.checked_rem_euclid(1);
282+
272283
// Unary
273284
_n = -2147483647;
274285
_n = -i32::MAX;
@@ -376,6 +387,17 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() {
376387
_custom = Custom << _custom;
377388
_custom = &Custom << _custom;
378389

390+
// Method
391+
_n.saturating_div(0);
392+
_n.wrapping_div(0);
393+
_n.wrapping_rem(0);
394+
_n.wrapping_rem_euclid(0);
395+
396+
_n.saturating_div(_n);
397+
_n.wrapping_div(_n);
398+
_n.wrapping_rem(_n);
399+
_n.wrapping_rem_euclid(_n);
400+
379401
// Unary
380402
_n = -_n;
381403
_n = -&_n;

0 commit comments

Comments
 (0)