Skip to content

Commit

Permalink
Auto merge of rust-lang#10310 - c410-f3r:arith-2, r=Alexendoo
Browse files Browse the repository at this point in the history
[arithmetic_side_effects] Fix rust-lang#10209

Fix rust-lang#10209

---

changelog: Enhancement: [`arithmetic_side_effects`]: No longer lints, if safe constant values are used.
[rust-lang#10310](rust-lang/rust-clippy#10310)
<!-- changelog_checked -->
  • Loading branch information
bors committed Feb 12, 2023
2 parents ad2135e + 1ed8ed3 commit 6f353fd
Show file tree
Hide file tree
Showing 3 changed files with 146 additions and 112 deletions.
33 changes: 20 additions & 13 deletions clippy_lints/src/operators/arithmetic_side_effects.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::ARITHMETIC_SIDE_EFFECTS;
use clippy_utils::{
consts::{constant, constant_simple},
consts::{constant, constant_simple, Constant},
diagnostics::span_lint,
peel_hir_expr_refs, peel_hir_expr_unary,
is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary,
};
use rustc_ast as ast;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
Expand Down Expand Up @@ -97,17 +97,19 @@ impl ArithmeticSideEffects {
self.expr_span = Some(expr.span);
}

/// If `expr` is not a literal integer like `1`, returns `None`.
/// Returns the numeric value of a literal integer originated from `expr`, if any.
///
/// Returns the absolute value of the expression, if this is an integer literal.
fn literal_integer(expr: &hir::Expr<'_>) -> Option<u128> {
/// Literal integers can be originated from adhoc declarations like `1`, associated constants
/// like `i32::MAX` or constant references like `N` from `const N: i32 = 1;`,
fn literal_integer(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<u128> {
let actual = peel_hir_expr_unary(expr).0;
if let hir::ExprKind::Lit(ref lit) = actual.kind && let ast::LitKind::Int(n, _) = lit.node {
Some(n)
return Some(n)
}
else {
None
if let Some((Constant::Int(n), _)) = constant(cx, cx.typeck_results(), expr) {
return Some(n);
}
None
}

/// Manages when the lint should be triggered. Operations in constant environments, hard coded
Expand Down Expand Up @@ -143,7 +145,10 @@ impl ArithmeticSideEffects {
let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) {
let (actual_lhs, lhs_ref_counter) = peel_hir_expr_refs(lhs);
let (actual_rhs, rhs_ref_counter) = peel_hir_expr_refs(rhs);
match (Self::literal_integer(actual_lhs), Self::literal_integer(actual_rhs)) {
match (
Self::literal_integer(cx, actual_lhs),
Self::literal_integer(cx, actual_rhs),
) {
(None, None) => false,
(None, Some(n)) | (Some(n), None) => match (&op.node, n) {
(hir::BinOpKind::Div | hir::BinOpKind::Rem, 0) => false,
Expand Down Expand Up @@ -180,20 +185,22 @@ impl ArithmeticSideEffects {
return;
}
let actual_un_expr = peel_hir_expr_refs(un_expr).0;
if Self::literal_integer(actual_un_expr).is_some() {
if Self::literal_integer(cx, actual_un_expr).is_some() {
return;
}
self.issue_lint(cx, expr);
}

fn should_skip_expr(&mut self, expr: &hir::Expr<'_>) -> bool {
self.expr_span.is_some() || self.const_span.map_or(false, |sp| sp.contains(expr.span))
fn should_skip_expr(&mut self, cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
is_lint_allowed(cx, ARITHMETIC_SIDE_EFFECTS, expr.hir_id)
|| self.expr_span.is_some()
|| self.const_span.map_or(false, |sp| sp.contains(expr.span))
}
}

impl<'tcx> LateLintPass<'tcx> for ArithmeticSideEffects {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &hir::Expr<'tcx>) {
if self.should_skip_expr(expr) {
if self.should_skip_expr(cx, expr) {
return;
}
match &expr.kind {
Expand Down
27 changes: 27 additions & 0 deletions tests/ui/arithmetic_side_effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@

use core::num::{Saturating, Wrapping};

const ONE: i32 = 1;
const ZERO: i32 = 0;

#[derive(Clone, Copy)]
pub struct Custom;

Expand Down Expand Up @@ -182,6 +185,10 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri
_n += &0;
_n -= 0;
_n -= &0;
_n += ZERO;
_n += &ZERO;
_n -= ZERO;
_n -= &ZERO;
_n /= 99;
_n /= &99;
_n %= 99;
Expand All @@ -190,10 +197,18 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri
_n *= &0;
_n *= 1;
_n *= &1;
_n *= ZERO;
_n *= &ZERO;
_n *= ONE;
_n *= &ONE;
_n += -0;
_n += &-0;
_n -= -0;
_n -= &-0;
_n += -ZERO;
_n += &-ZERO;
_n -= -ZERO;
_n -= &-ZERO;
_n /= -99;
_n /= &-99;
_n %= -99;
Expand All @@ -208,10 +223,18 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri
_n = _n + &0;
_n = 0 + _n;
_n = &0 + _n;
_n = _n + ZERO;
_n = _n + &ZERO;
_n = ZERO + _n;
_n = &ZERO + _n;
_n = _n - 0;
_n = _n - &0;
_n = 0 - _n;
_n = &0 - _n;
_n = _n - ZERO;
_n = _n - &ZERO;
_n = ZERO - _n;
_n = &ZERO - _n;
_n = _n / 99;
_n = _n / &99;
_n = _n % 99;
Expand All @@ -222,6 +245,10 @@ pub fn non_overflowing_ops_or_ops_already_handled_by_the_compiler_should_not_tri
_n = &0 * _n;
_n = _n * 1;
_n = _n * &1;
_n = ZERO * _n;
_n = &ZERO * _n;
_n = _n * ONE;
_n = _n * &ONE;
_n = 1 * _n;
_n = &1 * _n;
_n = 23 + 85;
Expand Down
Loading

0 comments on commit 6f353fd

Please sign in to comment.