Skip to content

Commit 3db7352

Browse files
committed
[arithmetic_side_effects] Fix #10590
1 parent f1a552c commit 3db7352

File tree

3 files changed

+211
-110
lines changed

3 files changed

+211
-110
lines changed

clippy_lints/src/operators/arithmetic_side_effects.rs

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

188+
/// There are some integer methods like `wrapping_div` that will panic depending on the
189+
/// provided input.
190+
fn manage_method_call<'tcx>(
191+
&mut self,
192+
args: &[hir::Expr<'tcx>],
193+
cx: &LateContext<'tcx>,
194+
ps: &hir::PathSegment<'tcx>,
195+
receiver: &hir::Expr<'tcx>,
196+
) {
197+
const METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"];
198+
let Some(arg) = args.first() else { return; };
199+
if constant_simple(cx, cx.typeck_results(), receiver).is_some() {
200+
return;
201+
}
202+
let instance_ty = cx.typeck_results().expr_ty(receiver);
203+
if !Self::is_integral(instance_ty) {
204+
return;
205+
}
206+
if METHODS.iter().copied().all(|method| method != ps.ident.as_str()) {
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+
188216
fn manage_unary_ops<'tcx>(
189217
&mut self,
190218
cx: &LateContext<'tcx>,
@@ -224,6 +252,9 @@ impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
224252
hir::ExprKind::AssignOp(op, lhs, rhs) | hir::ExprKind::Binary(op, lhs, rhs) => {
225253
self.manage_bin_ops(cx, expr, op, lhs, rhs);
226254
},
255+
hir::ExprKind::MethodCall(ps, receiver, args, _) => {
256+
self.manage_method_call(args, cx, ps, receiver);
257+
},
227258
hir::ExprKind::Unary(un_op, un_expr) => {
228259
self.manage_unary_ops(cx, expr, un_expr, *un_op);
229260
},

tests/ui/arithmetic_side_effects.rs

+22
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,17 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri
276276
_n = &1 * _n;
277277
_n = 23 + 85;
278278

279+
// Method
280+
_n.saturating_div(1);
281+
_n.wrapping_div(1);
282+
_n.wrapping_rem(1);
283+
_n.wrapping_rem_euclid(1);
284+
285+
_n.saturating_div(1);
286+
_n.checked_div(1);
287+
_n.checked_rem(1);
288+
_n.checked_rem_euclid(1);
289+
279290
// Unary
280291
_n = -2147483647;
281292
_n = -i32::MAX;
@@ -383,6 +394,17 @@ pub fn unknown_ops_or_runtime_ops_that_can_overflow() {
383394
_custom = Custom << _custom;
384395
_custom = &Custom << _custom;
385396

397+
// Method
398+
_n.saturating_div(0);
399+
_n.wrapping_div(0);
400+
_n.wrapping_rem(0);
401+
_n.wrapping_rem_euclid(0);
402+
403+
_n.saturating_div(_n);
404+
_n.wrapping_div(_n);
405+
_n.wrapping_rem(_n);
406+
_n.wrapping_rem_euclid(_n);
407+
386408
// Unary
387409
_n = -_n;
388410
_n = -&_n;

0 commit comments

Comments
 (0)