diff options
| author | Caio <c410.f3r@gmail.com> | 2023-08-31 15:10:51 -0300 |
|---|---|---|
| committer | Philipp Krones <hello@philkrones.com> | 2023-09-01 10:28:55 +0200 |
| commit | 0164f7e8b20d749d38902e9d63f873fe0a74b1fd (patch) | |
| tree | 1308564bfe4fee5590951d3296e0fa30f0b1e0e5 /src/tools/clippy/clippy_lints | |
| parent | dc348dbd90cf9f4c0bd1485b4c68aed60b32c433 (diff) | |
| download | rust-0164f7e8b20d749d38902e9d63f873fe0a74b1fd.tar.gz rust-0164f7e8b20d749d38902e9d63f873fe0a74b1fd.zip | |
[`clippy`] Use symbols intended for `arithmetic_side_effects`
Diffstat (limited to 'src/tools/clippy/clippy_lints')
| -rw-r--r-- | src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs index f9108145cdb..a687c7d29b5 100644 --- a/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs +++ b/src/tools/clippy/clippy_lints/src/operators/arithmetic_side_effects.rs @@ -1,24 +1,20 @@ use super::ARITHMETIC_SIDE_EFFECTS; use clippy_utils::consts::{constant, constant_simple, Constant}; use clippy_utils::diagnostics::span_lint; +use clippy_utils::ty::type_diagnostic_name; use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::Ty; use rustc_session::impl_lint_pass; use rustc_span::source_map::{Span, Spanned}; +use rustc_span::symbol::sym; use rustc_span::Symbol; use {rustc_ast as ast, rustc_hir as hir}; -const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[ - ["f32", "f32"], - ["f64", "f64"], - ["std::num::Saturating", "*"], - ["std::num::Wrapping", "*"], - ["std::string::String", "str"], -]; +const HARD_CODED_ALLOWED_BINARY: &[[&str; 2]] = &[["f32", "f32"], ["f64", "f64"], ["std::string::String", "str"]]; const HARD_CODED_ALLOWED_UNARY: &[&str] = &["f32", "f64", "std::num::Saturating", "std::num::Wrapping"]; -const INTEGER_METHODS: &[&str] = &["saturating_div", "wrapping_div", "wrapping_rem", "wrapping_rem_euclid"]; +const INTEGER_METHODS: &[Symbol] = &[sym::saturating_div, sym::wrapping_div, sym::wrapping_rem, sym::wrapping_rem_euclid]; #[derive(Debug)] pub struct ArithmeticSideEffects { @@ -53,7 +49,7 @@ impl ArithmeticSideEffects { allowed_unary, const_span: None, expr_span: None, - integer_methods: INTEGER_METHODS.iter().map(|el| Symbol::intern(el)).collect(), + integer_methods: INTEGER_METHODS.iter().copied().collect(), } } @@ -86,6 +82,38 @@ impl ArithmeticSideEffects { self.allowed_unary.contains(ty_string_elem) } + /// Verifies built-in types that have specific allowed operations + fn has_specific_allowed_type_and_operation( + cx: &LateContext<'_>, + lhs_ty: Ty<'_>, + op: &Spanned<hir::BinOpKind>, + rhs_ty: Ty<'_>, + ) -> bool { + let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem); + let is_non_zero_u = |symbol: Option<Symbol>| { + matches!( + symbol, + Some(sym::NonZeroU128 | sym::NonZeroU16 | sym::NonZeroU32 | sym::NonZeroU64 | sym::NonZeroU8 | sym::NonZeroUsize) + ) + }; + let is_sat_or_wrap = |ty: Ty<'_>| { + let is_sat = type_diagnostic_name(cx, ty) == Some(sym::Saturating); + let is_wrap = type_diagnostic_name(cx, ty) == Some(sym::Wrapping); + is_sat || is_wrap + }; + + // If the RHS is NonZeroU*, then division or module by zero will never occur + if is_non_zero_u(type_diagnostic_name(cx, rhs_ty)) && is_div_or_rem { + return true; + } + // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module + if is_sat_or_wrap(lhs_ty) { + return !is_div_or_rem; + } + + false + } + // For example, 8i32 or &i64::MAX. fn is_integral(ty: Ty<'_>) -> bool { ty.peel_refs().is_integral() @@ -147,6 +175,9 @@ impl ArithmeticSideEffects { if self.has_allowed_binary(lhs_ty, rhs_ty) { return; } + if Self::has_specific_allowed_type_and_operation(cx, lhs_ty, op, rhs_ty) { + return; + } let has_valid_op = if Self::is_integral(lhs_ty) && Self::is_integral(rhs_ty) { if let hir::BinOpKind::Shl | hir::BinOpKind::Shr = op.node { // At least for integers, shifts are already handled by the CTFE |
