Skip to content

Commit bc497a6

Browse files
authored
Merge pull request #1465 from Manishearth/1464
Use `span_suggestion` in the `precedence` lint
2 parents 276ad24 + b784f0d commit bc497a6

File tree

2 files changed

+54
-35
lines changed

2 files changed

+54
-35
lines changed

clippy_lints/src/precedence.rs

+27-26
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use rustc::lint::*;
22
use syntax::ast::*;
33
use syntax::codemap::Spanned;
4-
use utils::{span_lint, snippet};
4+
use utils::{span_lint_and_then, snippet};
55

66
/// **What it does:** Checks for operations where precedence may be unclear
77
/// and suggests to add parentheses. Currently it catches the following:
@@ -36,41 +36,39 @@ impl LintPass for Precedence {
3636
impl EarlyLintPass for Precedence {
3737
fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
3838
if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node {
39+
let span_sugg =
40+
|expr: &Expr, sugg| {
41+
span_lint_and_then(cx, PRECEDENCE, expr.span, "operator precedence can trip the unwary", |db| {
42+
db.span_suggestion(expr.span, "consider parenthesizing your expression", sugg);
43+
});
44+
};
45+
3946
if !is_bit_op(op) {
4047
return;
4148
}
4249
match (is_arith_expr(left), is_arith_expr(right)) {
4350
(true, true) => {
44-
span_lint(cx,
45-
PRECEDENCE,
46-
expr.span,
47-
&format!("operator precedence can trip the unwary. Consider parenthesizing your \
48-
expression:`({}) {} ({})`",
51+
let sugg = format!("({}) {} ({})",
4952
snippet(cx, left.span, ".."),
5053
op.to_string(),
51-
snippet(cx, right.span, "..")));
54+
snippet(cx, right.span, ".."));
55+
span_sugg(expr, sugg);
5256
},
5357
(true, false) => {
54-
span_lint(cx,
55-
PRECEDENCE,
56-
expr.span,
57-
&format!("operator precedence can trip the unwary. Consider parenthesizing your \
58-
expression:`({}) {} {}`",
58+
let sugg = format!("({}) {} {}",
5959
snippet(cx, left.span, ".."),
6060
op.to_string(),
61-
snippet(cx, right.span, "..")));
61+
snippet(cx, right.span, ".."));
62+
span_sugg(expr, sugg);
6263
},
6364
(false, true) => {
64-
span_lint(cx,
65-
PRECEDENCE,
66-
expr.span,
67-
&format!("operator precedence can trip the unwary. Consider parenthesizing your \
68-
expression:`{} {} ({})`",
65+
let sugg = format!("{} {} ({})",
6966
snippet(cx, left.span, ".."),
7067
op.to_string(),
71-
snippet(cx, right.span, "..")));
68+
snippet(cx, right.span, ".."));
69+
span_sugg(expr, sugg);
7270
},
73-
_ => (),
71+
(false, false) => (),
7472
}
7573
}
7674

@@ -82,12 +80,15 @@ impl EarlyLintPass for Precedence {
8280
LitKind::Int(..) |
8381
LitKind::Float(..) |
8482
LitKind::FloatUnsuffixed(..) => {
85-
span_lint(cx,
86-
PRECEDENCE,
87-
expr.span,
88-
&format!("unary minus has lower precedence than method call. Consider \
89-
adding parentheses to clarify your intent: -({})",
90-
snippet(cx, rhs.span, "..")));
83+
span_lint_and_then(cx,
84+
PRECEDENCE,
85+
expr.span,
86+
"unary minus has lower precedence than method call",
87+
|db| {
88+
db.span_suggestion(expr.span,
89+
"consider adding parentheses to clarify your intent",
90+
format!("-({})", snippet(cx, rhs.span, "..")));
91+
});
9192
},
9293
_ => (),
9394
}

tests/compile-fail/precedence.rs

+27-9
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,34 @@
55
#[allow(identity_op)]
66
#[allow(eq_op)]
77
fn main() {
8-
format!("{} vs. {}", 1 << 2 + 3, (1 << 2) + 3); //~ERROR operator precedence can trip
9-
format!("{} vs. {}", 1 + 2 << 3, 1 + (2 << 3)); //~ERROR operator precedence can trip
10-
format!("{} vs. {}", 4 >> 1 + 1, (4 >> 1) + 1); //~ERROR operator precedence can trip
11-
format!("{} vs. {}", 1 + 3 >> 2, 1 + (3 >> 2)); //~ERROR operator precedence can trip
12-
format!("{} vs. {}", 1 ^ 1 - 1, (1 ^ 1) - 1); //~ERROR operator precedence can trip
13-
format!("{} vs. {}", 3 | 2 - 1, (3 | 2) - 1); //~ERROR operator precedence can trip
14-
format!("{} vs. {}", 3 & 5 - 2, (3 & 5) - 2); //~ERROR operator precedence can trip
8+
1 << 2 + 3;
9+
//~^ ERROR operator precedence can trip
10+
//~| SUGGESTION 1 << (2 + 3)
11+
1 + 2 << 3;
12+
//~^ERROR operator precedence can trip
13+
//~| SUGGESTION (1 + 2) << 3
14+
4 >> 1 + 1;
15+
//~^ERROR operator precedence can trip
16+
//~| SUGGESTION 4 >> (1 + 1)
17+
1 + 3 >> 2;
18+
//~^ERROR operator precedence can trip
19+
//~| SUGGESTION (1 + 3) >> 2
20+
1 ^ 1 - 1;
21+
//~^ERROR operator precedence can trip
22+
//~| SUGGESTION 1 ^ (1 - 1)
23+
3 | 2 - 1;
24+
//~^ERROR operator precedence can trip
25+
//~| SUGGESTION 3 | (2 - 1)
26+
3 & 5 - 2;
27+
//~^ERROR operator precedence can trip
28+
//~| SUGGESTION 3 & (5 - 2)
1529

16-
format!("{} vs. {}", -1i32.abs(), (-1i32).abs()); //~ERROR unary minus has lower precedence
17-
format!("{} vs. {}", -1f32.abs(), (-1f32).abs()); //~ERROR unary minus has lower precedence
30+
-1i32.abs();
31+
//~^ERROR unary minus has lower precedence
32+
//~| SUGGESTION -(1i32.abs())
33+
-1f32.abs();
34+
//~^ERROR unary minus has lower precedence
35+
//~| SUGGESTION -(1f32.abs())
1836

1937
// These should not trigger an error
2038
let _ = (-1i32).abs();

0 commit comments

Comments
 (0)