From b2f1940f6f76c78771a2793b97e0cf2c5b459d1f Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Tue, 13 Oct 2015 13:48:48 +0200 Subject: [PATCH] improved precedence messages (fixes #389) --- src/precedence.rs | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/precedence.rs b/src/precedence.rs index ce06278b782..b7dbe268557 100644 --- a/src/precedence.rs +++ b/src/precedence.rs @@ -1,7 +1,9 @@ use rustc::lint::*; use syntax::codemap::Spanned; use syntax::ast::*; -use utils::span_lint; +use syntax::ast_util::binop_to_string; + +use utils::{span_lint, snippet}; declare_lint!(pub PRECEDENCE, Warn, "catches operations where precedence may be unclear. See the wiki for a \ @@ -19,10 +21,24 @@ impl LintPass for Precedence { impl EarlyLintPass for Precedence { fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) { if let ExprBinary(Spanned { node: op, ..}, ref left, ref right) = expr.node { - if is_bit_op(op) && (is_arith_expr(left) || is_arith_expr(right)) { - span_lint(cx, PRECEDENCE, expr.span, - "operator precedence can trip the unwary. Consider adding parentheses \ - to the subexpression"); + 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:\ + `({}) {} ({})`", snippet(cx, left.span, ".."), + binop_to_string(op), snippet(cx, right.span, ".."))), + (true, false) => span_lint(cx, PRECEDENCE, expr.span, + &format!("operator precedence can trip the unwary. \ + Consider parenthesizing your expression:\ + `({}) {} {}`", snippet(cx, left.span, ".."), + binop_to_string(op), snippet(cx, right.span, ".."))), + (false, true) => span_lint(cx, PRECEDENCE, expr.span, + &format!("operator precedence can trip the unwary. \ + Consider parenthesizing your expression:\ + `{} {} ({})`", snippet(cx, left.span, ".."), + binop_to_string(op), snippet(cx, right.span, ".."))), + _ => (), } } @@ -32,9 +48,11 @@ impl EarlyLintPass for Precedence { if let ExprLit(ref lit) = slf.node { match lit.node { LitInt(..) | LitFloat(..) | LitFloatUnsuffixed(..) => - span_lint(cx, PRECEDENCE, expr.span, - "unary minus has lower precedence than method call. Consider \ - adding parentheses to clarify your intent"), + 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, ".."))), _ => () } }