Skip to content

Commit 0b9e9c9

Browse files
committed
Disable arithmetic lints in constant items
1 parent dae7abb commit 0b9e9c9

File tree

2 files changed

+79
-8
lines changed

2 files changed

+79
-8
lines changed

clippy_lints/src/arithmetic.rs

+47-8
Original file line numberDiff line numberDiff line change
@@ -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,60 @@ 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_body(&mut self, cx: &LateContext<'_, '_>, body: &hir::Body) {
124+
let body_owner = cx.tcx.hir.body_owner(body.id());
125+
126+
match cx.tcx.hir.body_owner_kind(body_owner) {
127+
hir::BodyOwnerKind::Static(_)
128+
| hir::BodyOwnerKind::Const => {
129+
let body_span = cx.tcx.hir.span(body_owner);
130+
131+
if let Some(span) = self.const_span {
132+
if span.contains(body_span) {
133+
return;
134+
}
135+
}
136+
self.const_span = Some(body_span);
137+
}
138+
hir::BodyOwnerKind::Fn => (),
139+
}
140+
}
141+
142+
fn check_body_post(&mut self, cx: &LateContext<'_, '_>, body: &hir::Body) {
143+
let body_owner = cx.tcx.hir.body_owner(body.id());
144+
let body_span = cx.tcx.hir.span(body_owner);
145+
146+
if let Some(span) = self.const_span {
147+
if span.contains(body_span) {
148+
return;
149+
}
112150
}
151+
self.const_span = None;
113152
}
114153
}

tests/ui/arithmetic.rs

+32
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,36 @@ 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+
struct Baz([i32; 1 + 1]);
46+
union Qux {
47+
field: [i32; 1 + 1],
48+
}
49+
type Alias = [i32; 1 + 1];
50+
51+
const FOO: i32 = -2;
52+
static BAR: i32 = -2;
53+
54+
let _: [i32; 1 + 1] = [0, 0];
55+
56+
let _: [i32; 1 + 1] = {
57+
let a: [i32; 1 + 1] = [0, 0];
58+
a
59+
};
60+
61+
trait Trait {
62+
const ASSOC: i32 = 1 + 1;
63+
}
64+
65+
impl Trait for Foo {
66+
const ASSOC: i32 = {
67+
let _: [i32; 1 + 1];
68+
fn foo() {}
69+
1 + 1
70+
};
71+
}
4072
}

0 commit comments

Comments
 (0)