Skip to content

Commit 7dea4dc

Browse files
committed
Disable arithmetic lints in constant items
1 parent dae7abb commit 7dea4dc

File tree

2 files changed

+43
-9
lines changed

2 files changed

+43
-9
lines changed

clippy_lints/src/arithmetic.rs

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010

1111
use crate::utils::span_lint;
12-
use crate::rustc::hir;
12+
use crate::rustc::hir::{self, Item, ItemKind};
1313
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
1414
use crate::rustc::{declare_tool_lint, lint_array};
1515
use crate::syntax::source_map::Span;
@@ -51,7 +51,9 @@ declare_clippy_lint! {
5151

5252
#[derive(Copy, Clone, Default)]
5353
pub struct Arithmetic {
54-
span: Option<Span>,
54+
expr_span: Option<Span>,
55+
/// This field is used to check whether expressions are constants, such as in enum discriminants and consts
56+
const_span: Option<Span>,
5557
}
5658

5759
impl LintPass for Arithmetic {
@@ -62,9 +64,15 @@ impl LintPass for Arithmetic {
6264

6365
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
6466
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
65-
if self.span.is_some() {
67+
if self.expr_span.is_some() {
6668
return;
6769
}
70+
71+
if let Some(span) = self.const_span {
72+
if span.contains(expr.span) {
73+
return;
74+
}
75+
}
6876
match expr.node {
6977
hir::ExprKind::Binary(ref op, ref l, ref r) => {
7078
match op.node {
@@ -86,29 +94,47 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
8694
let (l_ty, r_ty) = (cx.tables.expr_ty(l), cx.tables.expr_ty(r));
8795
if l_ty.is_integral() && r_ty.is_integral() {
8896
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
89-
self.span = Some(expr.span);
97+
self.expr_span = Some(expr.span);
9098
} else if l_ty.is_floating_point() && r_ty.is_floating_point() {
9199
span_lint(cx, FLOAT_ARITHMETIC, expr.span, "floating-point arithmetic detected");
92-
self.span = Some(expr.span);
100+
self.expr_span = Some(expr.span);
93101
}
94102
},
95103
hir::ExprKind::Unary(hir::UnOp::UnNeg, ref arg) => {
96104
let ty = cx.tables.expr_ty(arg);
97105
if ty.is_integral() {
98106
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
99-
self.span = Some(expr.span);
107+
self.expr_span = Some(expr.span);
100108
} else if ty.is_floating_point() {
101109
span_lint(cx, FLOAT_ARITHMETIC, expr.span, "floating-point arithmetic detected");
102-
self.span = Some(expr.span);
110+
self.expr_span = Some(expr.span);
103111
}
104112
},
105113
_ => (),
106114
}
107115
}
108116

109117
fn check_expr_post(&mut self, _: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
110-
if Some(expr.span) == self.span {
111-
self.span = None;
118+
if Some(expr.span) == self.expr_span {
119+
self.expr_span = None;
120+
}
121+
}
122+
123+
fn check_item(&mut self, _: &LateContext<'_, '_>, item: &Item) {
124+
match item.node {
125+
ItemKind::Enum(..)
126+
| ItemKind::Const(..)
127+
| ItemKind::Static(..) => self.const_span = Some(item.span),
128+
_ => (),
129+
}
130+
}
131+
132+
fn check_item_post(&mut self, _: &LateContext<'_, '_>, item: &Item) {
133+
match item.node {
134+
ItemKind::Enum(..)
135+
| ItemKind::Const(..)
136+
| ItemKind::Static(..) => self.const_span = None,
137+
_ => (),
112138
}
113139
}
114140
}

tests/ui/arithmetic.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,12 @@ fn main() {
3737
f / 2.0;
3838
f - 2.0 * 4.2;
3939
-f;
40+
41+
// No errors for the following items because they are constant expressions
42+
enum Foo {
43+
Bar = -2,
44+
}
45+
46+
const FOO: i32 = -2;
47+
static BAR: i32 = -2;
4048
}

0 commit comments

Comments
 (0)