Skip to content

Commit e004b94

Browse files
committed
Auto merge of rust-lang#5329 - matthiaskrgr:int_arith_on_ref_5328, r=flip1995
integer_arithmetic: detect integer arithmetic on references. changelog: integer_arithmetic fix false negatives with references on integers Fixes rust-lang#5328
2 parents 08fc398 + ec1dcde commit e004b94

11 files changed

+355
-184
lines changed

clippy_dev/src/stderr_length_check.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use std::path::{Path, PathBuf};
44

55
use walkdir::WalkDir;
66

7+
use clippy_dev::clippy_project_root;
8+
79
// The maximum length allowed for stderr files.
810
//
911
// We limit this because small files are easier to deal with than bigger files.
@@ -14,22 +16,24 @@ pub fn check() {
1416

1517
if !exceeding_files.is_empty() {
1618
eprintln!("Error: stderr files exceeding limit of {} lines:", LENGTH_LIMIT);
17-
for path in exceeding_files {
18-
println!("{}", path.display());
19+
for (path, count) in exceeding_files {
20+
println!("{}: {}", path.display(), count);
1921
}
2022
std::process::exit(1);
2123
}
2224
}
2325

24-
fn exceeding_stderr_files() -> Vec<PathBuf> {
26+
fn exceeding_stderr_files() -> Vec<(PathBuf, usize)> {
2527
// We use `WalkDir` instead of `fs::read_dir` here in order to recurse into subdirectories.
26-
WalkDir::new("../tests/ui")
28+
WalkDir::new(clippy_project_root().join("tests/ui"))
2729
.into_iter()
2830
.filter_map(Result::ok)
31+
.filter(|f| !f.file_type().is_dir())
2932
.filter_map(|e| {
3033
let p = e.into_path();
31-
if p.extension() == Some(OsStr::new("stderr")) && count_linenumbers(&p) > LENGTH_LIMIT {
32-
Some(p)
34+
let count = count_linenumbers(&p);
35+
if p.extension() == Some(OsStr::new("stderr")) && count > LENGTH_LIMIT {
36+
Some((p, count))
3337
} else {
3438
None
3539
}

clippy_lints/src/arithmetic.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Arithmetic {
8181
| hir::BinOpKind::Gt => return,
8282
_ => (),
8383
}
84+
8485
let (l_ty, r_ty) = (cx.tables.expr_ty(l), cx.tables.expr_ty(r));
85-
if l_ty.is_integral() && r_ty.is_integral() {
86+
if l_ty.peel_refs().is_integral() && r_ty.peel_refs().is_integral() {
8687
span_lint(cx, INTEGER_ARITHMETIC, expr.span, "integer arithmetic detected");
8788
self.expr_span = Some(expr.span);
88-
} else if l_ty.is_floating_point() && r_ty.is_floating_point() {
89+
} else if l_ty.peel_refs().is_floating_point() && r_ty.peel_refs().is_floating_point() {
8990
span_lint(cx, FLOAT_ARITHMETIC, expr.span, "floating-point arithmetic detected");
9091
self.expr_span = Some(expr.span);
9192
}

tests/ui/arithmetic.stderr

-127
This file was deleted.

tests/ui/checked_unwrap/complex_conditionals.rs

-11
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,4 @@ fn test_complex_conditions() {
5151
}
5252
}
5353

54-
fn test_nested() {
55-
fn nested() {
56-
let x = Some(());
57-
if x.is_some() {
58-
x.unwrap(); // unnecessary
59-
} else {
60-
x.unwrap(); // will panic
61-
}
62-
}
63-
}
64-
6554
fn main() {}

tests/ui/checked_unwrap/complex_conditionals.stderr

+1-18
Original file line numberDiff line numberDiff line change
@@ -188,22 +188,5 @@ LL | if x.is_ok() || !(y.is_ok() && z.is_err()) {
188188
LL | z.unwrap_err(); // unnecessary
189189
| ^^^^^^^^^^^^^^
190190

191-
error: You checked before that `unwrap()` cannot fail. Instead of checking and unwrapping, it's better to use `if let` or `match`.
192-
--> $DIR/complex_conditionals.rs:58:13
193-
|
194-
LL | if x.is_some() {
195-
| ----------- the check is happening here
196-
LL | x.unwrap(); // unnecessary
197-
| ^^^^^^^^^^
198-
199-
error: This call to `unwrap()` will always panic.
200-
--> $DIR/complex_conditionals.rs:60:13
201-
|
202-
LL | if x.is_some() {
203-
| ----------- because of this check
204-
...
205-
LL | x.unwrap(); // will panic
206-
| ^^^^^^^^^^
207-
208-
error: aborting due to 22 previous errors
191+
error: aborting due to 20 previous errors
209192

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
2+
#![allow(clippy::if_same_then_else)]
3+
4+
fn test_nested() {
5+
fn nested() {
6+
let x = Some(());
7+
if x.is_some() {
8+
x.unwrap(); // unnecessary
9+
} else {
10+
x.unwrap(); // will panic
11+
}
12+
}
13+
}
14+
15+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
error: You checked before that `unwrap()` cannot fail. Instead of checking and unwrapping, it's better to use `if let` or `match`.
2+
--> $DIR/complex_conditionals_nested.rs:8:13
3+
|
4+
LL | if x.is_some() {
5+
| ----------- the check is happening here
6+
LL | x.unwrap(); // unnecessary
7+
| ^^^^^^^^^^
8+
|
9+
note: the lint level is defined here
10+
--> $DIR/complex_conditionals_nested.rs:1:35
11+
|
12+
LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
14+
15+
error: This call to `unwrap()` will always panic.
16+
--> $DIR/complex_conditionals_nested.rs:10:13
17+
|
18+
LL | if x.is_some() {
19+
| ----------- because of this check
20+
...
21+
LL | x.unwrap(); // will panic
22+
| ^^^^^^^^^^
23+
|
24+
note: the lint level is defined here
25+
--> $DIR/complex_conditionals_nested.rs:1:9
26+
|
27+
LL | #![deny(clippy::panicking_unwrap, clippy::unnecessary_unwrap)]
28+
| ^^^^^^^^^^^^^^^^^^^^^^^^
29+
30+
error: aborting due to 2 previous errors
31+

tests/ui/float_arithmetic.rs

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#![warn(clippy::integer_arithmetic, clippy::float_arithmetic)]
2+
#![allow(
3+
unused,
4+
clippy::shadow_reuse,
5+
clippy::shadow_unrelated,
6+
clippy::no_effect,
7+
clippy::unnecessary_operation,
8+
clippy::op_ref,
9+
clippy::trivially_copy_pass_by_ref
10+
)]
11+
12+
#[rustfmt::skip]
13+
fn main() {
14+
let mut f = 1.0f32;
15+
16+
f * 2.0;
17+
18+
1.0 + f;
19+
f * 2.0;
20+
f / 2.0;
21+
f - 2.0 * 4.2;
22+
-f;
23+
24+
f += 1.0;
25+
f -= 1.0;
26+
f *= 2.0;
27+
f /= 2.0;
28+
}
29+
30+
// also warn about floating point arith with references involved
31+
32+
pub fn float_arith_ref() {
33+
3.1_f32 + &1.2_f32;
34+
&3.4_f32 + 1.5_f32;
35+
&3.5_f32 + &1.3_f32;
36+
}
37+
38+
pub fn float_foo(f: &f32) -> f32 {
39+
let a = 5.1;
40+
a + f
41+
}
42+
43+
pub fn float_bar(f1: &f32, f2: &f32) -> f32 {
44+
f1 + f2
45+
}
46+
47+
pub fn float_baz(f1: f32, f2: &f32) -> f32 {
48+
f1 + f2
49+
}
50+
51+
pub fn float_qux(f1: f32, f2: f32) -> f32 {
52+
(&f1 + &f2)
53+
}

0 commit comments

Comments
 (0)