|
1 | 1 | use super::ARITHMETIC_SIDE_EFFECTS;
|
2 | 2 | use clippy_utils::consts::{constant, constant_simple, Constant};
|
3 | 3 | use clippy_utils::diagnostics::span_lint;
|
4 |
| -use clippy_utils::ty::type_diagnostic_name; |
| 4 | +use clippy_utils::ty::is_type_diagnostic_item; |
5 | 5 | use clippy_utils::{expr_or_init, is_from_proc_macro, is_lint_allowed, peel_hir_expr_refs, peel_hir_expr_unary};
|
6 | 6 | use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
7 | 7 | use rustc_lint::{LateContext, LateLintPass};
|
8 |
| -use rustc_middle::ty::Ty; |
| 8 | +use rustc_middle::ty::{self, Ty}; |
9 | 9 | use rustc_session::impl_lint_pass;
|
10 | 10 | use rustc_span::source_map::Spanned;
|
11 | 11 | use rustc_span::symbol::sym;
|
@@ -88,37 +88,44 @@ impl ArithmeticSideEffects {
|
88 | 88 | }
|
89 | 89 |
|
90 | 90 | /// Verifies built-in types that have specific allowed operations
|
91 |
| - fn has_specific_allowed_type_and_operation( |
92 |
| - cx: &LateContext<'_>, |
93 |
| - lhs_ty: Ty<'_>, |
| 91 | + fn has_specific_allowed_type_and_operation<'tcx>( |
| 92 | + cx: &LateContext<'tcx>, |
| 93 | + lhs_ty: Ty<'tcx>, |
94 | 94 | op: &Spanned<hir::BinOpKind>,
|
95 |
| - rhs_ty: Ty<'_>, |
| 95 | + rhs_ty: Ty<'tcx>, |
96 | 96 | ) -> bool {
|
97 | 97 | let is_div_or_rem = matches!(op.node, hir::BinOpKind::Div | hir::BinOpKind::Rem);
|
98 |
| - let is_non_zero_u = |symbol: Option<Symbol>| { |
99 |
| - matches!( |
100 |
| - symbol, |
101 |
| - Some( |
102 |
| - sym::NonZeroU128 |
103 |
| - | sym::NonZeroU16 |
104 |
| - | sym::NonZeroU32 |
105 |
| - | sym::NonZeroU64 |
106 |
| - | sym::NonZeroU8 |
107 |
| - | sym::NonZeroUsize |
108 |
| - ) |
109 |
| - ) |
| 98 | + let is_non_zero_u = |cx: &LateContext<'tcx>, ty: Ty<'tcx>| { |
| 99 | + let tcx = cx.tcx; |
| 100 | + |
| 101 | + let ty::Adt(adt, substs) = ty.kind() else { return false }; |
| 102 | + |
| 103 | + if !tcx.is_diagnostic_item(sym::NonZero, adt.did()) { |
| 104 | + return false; |
| 105 | + }; |
| 106 | + |
| 107 | + let int_type = substs.type_at(0); |
| 108 | + let unsigned_int_types = [ |
| 109 | + tcx.types.u8, |
| 110 | + tcx.types.u16, |
| 111 | + tcx.types.u32, |
| 112 | + tcx.types.u64, |
| 113 | + tcx.types.u128, |
| 114 | + tcx.types.usize, |
| 115 | + ]; |
| 116 | + |
| 117 | + unsigned_int_types.contains(&int_type) |
110 | 118 | };
|
111 | 119 | let is_sat_or_wrap = |ty: Ty<'_>| {
|
112 |
| - let is_sat = type_diagnostic_name(cx, ty) == Some(sym::Saturating); |
113 |
| - let is_wrap = type_diagnostic_name(cx, ty) == Some(sym::Wrapping); |
114 |
| - is_sat || is_wrap |
| 120 | + is_type_diagnostic_item(cx, ty, sym::Saturating) || is_type_diagnostic_item(cx, ty, sym::Wrapping) |
115 | 121 | };
|
116 | 122 |
|
117 |
| - // If the RHS is NonZeroU*, then division or module by zero will never occur |
118 |
| - if is_non_zero_u(type_diagnostic_name(cx, rhs_ty)) && is_div_or_rem { |
| 123 | + // If the RHS is `NonZero<u*>`, then division or module by zero will never occur. |
| 124 | + if is_non_zero_u(cx, rhs_ty) && is_div_or_rem { |
119 | 125 | return true;
|
120 | 126 | }
|
121 |
| - // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module |
| 127 | + |
| 128 | + // `Saturation` and `Wrapping` can overflow if the RHS is zero in a division or module. |
122 | 129 | if is_sat_or_wrap(lhs_ty) {
|
123 | 130 | return !is_div_or_rem;
|
124 | 131 | }
|
|
0 commit comments