From b784f0d7368c08d8c84c23abce9d1e265e9fbef8 Mon Sep 17 00:00:00 2001 From: mcarton Date: Sun, 22 Jan 2017 14:51:13 +0100 Subject: [PATCH] Use `span_suggestion` in the `precedence` lint --- clippy_lints/src/precedence.rs | 53 ++++++++++++++++---------------- tests/compile-fail/precedence.rs | 36 ++++++++++++++++------ 2 files changed, 54 insertions(+), 35 deletions(-) diff --git a/clippy_lints/src/precedence.rs b/clippy_lints/src/precedence.rs index 146706646ae..0dff1495dfb 100644 --- a/clippy_lints/src/precedence.rs +++ b/clippy_lints/src/precedence.rs @@ -1,7 +1,7 @@ use rustc::lint::*; use syntax::ast::*; use syntax::codemap::Spanned; -use utils::{span_lint, snippet}; +use utils::{span_lint_and_then, snippet}; /// **What it does:** Checks for operations where precedence may be unclear /// and suggests to add parentheses. Currently it catches the following: @@ -36,41 +36,39 @@ impl LintPass for Precedence { impl EarlyLintPass for Precedence { fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) { if let ExprKind::Binary(Spanned { node: op, .. }, ref left, ref right) = expr.node { + let span_sugg = + |expr: &Expr, sugg| { + span_lint_and_then(cx, PRECEDENCE, expr.span, "operator precedence can trip the unwary", |db| { + db.span_suggestion(expr.span, "consider parenthesizing your expression", sugg); + }); + }; + if !is_bit_op(op) { return; } match (is_arith_expr(left), is_arith_expr(right)) { (true, true) => { - span_lint(cx, - PRECEDENCE, - expr.span, - &format!("operator precedence can trip the unwary. Consider parenthesizing your \ - expression:`({}) {} ({})`", + let sugg = format!("({}) {} ({})", snippet(cx, left.span, ".."), op.to_string(), - snippet(cx, right.span, ".."))); + snippet(cx, right.span, "..")); + span_sugg(expr, sugg); }, (true, false) => { - span_lint(cx, - PRECEDENCE, - expr.span, - &format!("operator precedence can trip the unwary. Consider parenthesizing your \ - expression:`({}) {} {}`", + let sugg = format!("({}) {} {}", snippet(cx, left.span, ".."), op.to_string(), - snippet(cx, right.span, ".."))); + snippet(cx, right.span, "..")); + span_sugg(expr, sugg); }, (false, true) => { - span_lint(cx, - PRECEDENCE, - expr.span, - &format!("operator precedence can trip the unwary. Consider parenthesizing your \ - expression:`{} {} ({})`", + let sugg = format!("{} {} ({})", snippet(cx, left.span, ".."), op.to_string(), - snippet(cx, right.span, ".."))); + snippet(cx, right.span, "..")); + span_sugg(expr, sugg); }, - _ => (), + (false, false) => (), } } @@ -82,12 +80,15 @@ impl EarlyLintPass for Precedence { LitKind::Int(..) | LitKind::Float(..) | LitKind::FloatUnsuffixed(..) => { - span_lint(cx, - PRECEDENCE, - expr.span, - &format!("unary minus has lower precedence than method call. Consider \ - adding parentheses to clarify your intent: -({})", - snippet(cx, rhs.span, ".."))); + span_lint_and_then(cx, + PRECEDENCE, + expr.span, + "unary minus has lower precedence than method call", + |db| { + db.span_suggestion(expr.span, + "consider adding parentheses to clarify your intent", + format!("-({})", snippet(cx, rhs.span, ".."))); + }); }, _ => (), } diff --git a/tests/compile-fail/precedence.rs b/tests/compile-fail/precedence.rs index 71dcd493008..28cc9e643c0 100644 --- a/tests/compile-fail/precedence.rs +++ b/tests/compile-fail/precedence.rs @@ -5,16 +5,34 @@ #[allow(identity_op)] #[allow(eq_op)] fn main() { - format!("{} vs. {}", 1 << 2 + 3, (1 << 2) + 3); //~ERROR operator precedence can trip - format!("{} vs. {}", 1 + 2 << 3, 1 + (2 << 3)); //~ERROR operator precedence can trip - format!("{} vs. {}", 4 >> 1 + 1, (4 >> 1) + 1); //~ERROR operator precedence can trip - format!("{} vs. {}", 1 + 3 >> 2, 1 + (3 >> 2)); //~ERROR operator precedence can trip - format!("{} vs. {}", 1 ^ 1 - 1, (1 ^ 1) - 1); //~ERROR operator precedence can trip - format!("{} vs. {}", 3 | 2 - 1, (3 | 2) - 1); //~ERROR operator precedence can trip - format!("{} vs. {}", 3 & 5 - 2, (3 & 5) - 2); //~ERROR operator precedence can trip + 1 << 2 + 3; + //~^ ERROR operator precedence can trip + //~| SUGGESTION 1 << (2 + 3) + 1 + 2 << 3; + //~^ERROR operator precedence can trip + //~| SUGGESTION (1 + 2) << 3 + 4 >> 1 + 1; + //~^ERROR operator precedence can trip + //~| SUGGESTION 4 >> (1 + 1) + 1 + 3 >> 2; + //~^ERROR operator precedence can trip + //~| SUGGESTION (1 + 3) >> 2 + 1 ^ 1 - 1; + //~^ERROR operator precedence can trip + //~| SUGGESTION 1 ^ (1 - 1) + 3 | 2 - 1; + //~^ERROR operator precedence can trip + //~| SUGGESTION 3 | (2 - 1) + 3 & 5 - 2; + //~^ERROR operator precedence can trip + //~| SUGGESTION 3 & (5 - 2) - format!("{} vs. {}", -1i32.abs(), (-1i32).abs()); //~ERROR unary minus has lower precedence - format!("{} vs. {}", -1f32.abs(), (-1f32).abs()); //~ERROR unary minus has lower precedence + -1i32.abs(); + //~^ERROR unary minus has lower precedence + //~| SUGGESTION -(1i32.abs()) + -1f32.abs(); + //~^ERROR unary minus has lower precedence + //~| SUGGESTION -(1f32.abs()) // These should not trigger an error let _ = (-1i32).abs();