From 1605ef6ed48fded84b7b8556c9b65809c5aba1ad Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 1 Jan 2016 02:09:03 +0530 Subject: [PATCH] Rustup to syntax::errors changes --- Cargo.toml | 2 +- src/cyclomatic_complexity.rs | 13 +-- src/eta_reduction.rs | 4 +- src/len_zero.rs | 2 +- src/minmax.rs | 2 +- src/mut_mut.rs | 8 +- src/mutex_atomic.rs | 2 +- src/precedence.rs | 23 ++++-- src/returns.rs | 8 +- src/shadow.rs | 22 +++--- src/strings.rs | 4 +- src/utils.rs | 88 ++++++++++++++------- tests/compile-fail/cyclomatic_complexity.rs | 3 +- 13 files changed, 110 insertions(+), 71 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4bae9f5aa22..3ab2c9ef6e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "clippy" -version = "0.0.33" +version = "0.0.34" authors = [ "Manish Goregaokar ", "Andre Bogus ", diff --git a/src/cyclomatic_complexity.rs b/src/cyclomatic_complexity.rs index c2cc6a8c4ab..7beb3296aac 100644 --- a/src/cyclomatic_complexity.rs +++ b/src/cyclomatic_complexity.rs @@ -9,7 +9,7 @@ use syntax::attr::*; use syntax::ast::Attribute; use rustc_front::intravisit::{Visitor, walk_expr}; -use utils::{in_macro, LimitStack}; +use utils::{in_macro, LimitStack, span_help_and_lint}; /// **What it does:** It `Warn`s on methods with high cyclomatic complexity /// @@ -59,8 +59,8 @@ impl CyclomaticComplexity { } else { let rust_cc = cc + divergence - narms; if rust_cc > self.limit.limit() { - cx.span_lint_help(CYCLOMATIC_COMPLEXITY, span, - &format!("The function has a cyclomatic complexity of {}.", rust_cc), + span_help_and_lint(cx, CYCLOMATIC_COMPLEXITY, span, + &format!("The function has a cyclomatic complexity of {}", rust_cc), "You could split it up into multiple smaller functions"); } } @@ -140,8 +140,9 @@ fn report_cc_bug(cx: &LateContext, cc: u64, narms: u64, div: u64, span: Span) { #[cfg(not(feature="debugging"))] fn report_cc_bug(cx: &LateContext, cc: u64, narms: u64, div: u64, span: Span) { if cx.current_level(CYCLOMATIC_COMPLEXITY) != Level::Allow { - cx.sess().span_note(span, &format!("Clippy encountered a bug calculating cyclomatic complexity \ - (hide this message with `#[allow(cyclomatic_complexity)]`): \ - cc = {}, arms = {}, div = {}. Please file a bug report.", cc, narms, div)); + cx.sess().span_note_without_error(span, + &format!("Clippy encountered a bug calculating cyclomatic complexity \ + (hide this message with `#[allow(cyclomatic_complexity)]`): \ + cc = {}, arms = {}, div = {}. Please file a bug report.", cc, narms, div)); } } diff --git a/src/eta_reduction.rs b/src/eta_reduction.rs index c25228793e6..6b561ff7a05 100644 --- a/src/eta_reduction.rs +++ b/src/eta_reduction.rs @@ -84,9 +84,9 @@ fn check_closure(cx: &LateContext, expr: &Expr) { } span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found", - || { + |db| { if let Some(snippet) = snippet_opt(cx, caller.span) { - cx.sess().span_suggestion(expr.span, + db.span_suggestion(expr.span, "remove closure as shown:", snippet); } diff --git a/src/len_zero.rs b/src/len_zero.rs index 589b4f6ebb1..d574fa2c336 100644 --- a/src/len_zero.rs +++ b/src/len_zero.rs @@ -135,7 +135,7 @@ fn check_len_zero(cx: &LateContext, span: Span, name: &Name, has_is_empty(cx, &args[0]) { span_lint(cx, LEN_ZERO, span, &format!( "consider replacing the len comparison with `{}{}.is_empty()`", - op, snippet(cx, args[0].span, "_"))) + op, snippet(cx, args[0].span, "_"))); } } } diff --git a/src/minmax.rs b/src/minmax.rs index b63e839612c..2a8e064f9f4 100644 --- a/src/minmax.rs +++ b/src/minmax.rs @@ -37,7 +37,7 @@ impl LateLintPass for MinMaxPass { (_, None) | (Max, Some(Less)) | (Min, Some(Greater)) => (), _ => { span_lint(cx, MIN_MAX, expr.span, - "this min/max combination leads to constant result") + "this min/max combination leads to constant result"); } } } diff --git a/src/mut_mut.rs b/src/mut_mut.rs index ade688d377f..db6f0e0320b 100644 --- a/src/mut_mut.rs +++ b/src/mut_mut.rs @@ -30,8 +30,8 @@ impl LateLintPass for MutMut { } fn check_ty(&mut self, cx: &LateContext, ty: &Ty) { - unwrap_mut(ty).and_then(unwrap_mut).map_or((), |_| span_lint(cx, MUT_MUT, - ty.span, "generally you want to avoid `&mut &mut _` if possible")) + unwrap_mut(ty).and_then(unwrap_mut).map_or((), |_| { span_lint(cx, MUT_MUT, + ty.span, "generally you want to avoid `&mut &mut _` if possible"); }); } } @@ -52,12 +52,12 @@ fn check_expr_mut(cx: &LateContext, expr: &Expr) { cx.tcx.expr_ty(e).sty { span_lint(cx, MUT_MUT, expr.span, "this expression mutably borrows a mutable reference. \ - Consider reborrowing") + Consider reborrowing"); } }, |_| { span_lint(cx, MUT_MUT, expr.span, - "generally you want to avoid `&mut &mut _` if possible") + "generally you want to avoid `&mut &mut _` if possible"); } ) }) diff --git a/src/mutex_atomic.rs b/src/mutex_atomic.rs index 40f7d21f43c..8899eb56d42 100644 --- a/src/mutex_atomic.rs +++ b/src/mutex_atomic.rs @@ -63,7 +63,7 @@ impl LateLintPass for MutexAtomic { ty::TyInt(t) if t != ast::TyIs => span_lint(cx, MUTEX_INTEGER, expr.span, &msg), _ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg) - } + }; } } } diff --git a/src/precedence.rs b/src/precedence.rs index 3aae9fd0d6c..91ff0680b3e 100644 --- a/src/precedence.rs +++ b/src/precedence.rs @@ -33,21 +33,27 @@ impl EarlyLintPass for Precedence { if let ExprBinary(Spanned { node: op, ..}, ref left, ref right) = expr.node { if !is_bit_op(op) { return; } match (is_arith_expr(left), is_arith_expr(right)) { - (true, true) => span_lint(cx, PRECEDENCE, expr.span, + (true, true) => { + span_lint(cx, PRECEDENCE, expr.span, &format!("operator precedence can trip the unwary. \ Consider parenthesizing your expression:\ `({}) {} ({})`", snippet(cx, left.span, ".."), - op.to_string(), snippet(cx, right.span, ".."))), - (true, false) => span_lint(cx, PRECEDENCE, expr.span, + op.to_string(), 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, ".."), - op.to_string(), snippet(cx, right.span, ".."))), - (false, true) => span_lint(cx, PRECEDENCE, expr.span, + op.to_string(), 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, ".."), - op.to_string(), snippet(cx, right.span, ".."))), + op.to_string(), snippet(cx, right.span, ".."))); + }, _ => (), } } @@ -57,12 +63,13 @@ impl EarlyLintPass for Precedence { if let Some(slf) = args.first() { if let ExprLit(ref lit) = slf.node { match lit.node { - LitInt(..) | LitFloat(..) | LitFloatUnsuffixed(..) => + LitInt(..) | LitFloat(..) | LitFloatUnsuffixed(..) => { 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, ".."))), + snippet(cx, rhs.span, ".."))); + } _ => () } } diff --git a/src/returns.rs b/src/returns.rs index 3ef94a4c926..15f9bb80d95 100644 --- a/src/returns.rs +++ b/src/returns.rs @@ -75,9 +75,9 @@ impl ReturnPass { if in_external_macro(cx, spans.1) {return;} span_lint_and_then(cx, NEEDLESS_RETURN, spans.0, "unneeded return statement", - || { + |db| { if let Some(snippet) = snippet_opt(cx, spans.1) { - cx.sess().span_suggestion(spans.0, + db.span_suggestion(spans.0, "remove `return` as shown:", snippet); } @@ -105,11 +105,11 @@ impl ReturnPass { fn emit_let_lint(&mut self, cx: &EarlyContext, lint_span: Span, note_span: Span) { if in_external_macro(cx, note_span) {return;} - span_lint(cx, LET_AND_RETURN, lint_span, + let mut db = span_lint(cx, LET_AND_RETURN, lint_span, "returning the result of a let binding from a block. \ Consider returning the expression directly."); if cx.current_level(LET_AND_RETURN) != Level::Allow { - cx.sess().span_note(note_span, + db.span_note(note_span, "this expression can be directly returned"); } } diff --git a/src/shadow.rs b/src/shadow.rs index 27bed50c263..1210590bbcb 100644 --- a/src/shadow.rs +++ b/src/shadow.rs @@ -7,7 +7,7 @@ use rustc_front::intravisit::{Visitor, FnKind}; use rustc::lint::*; use rustc::middle::def::Def::{DefVariant, DefStruct}; -use utils::{is_from_for_desugar, in_external_macro, snippet, span_lint, span_note_and_lint}; +use utils::{is_from_for_desugar, in_external_macro, snippet, span_lint, span_note_and_lint, DiagnosticWrapper}; /// **What it does:** This lint checks for bindings that shadow other bindings already in scope, while just changing reference level or mutability. It is `Allow` by default. /// @@ -180,39 +180,39 @@ fn check_pat(cx: &LateContext, pat: &Pat, init: &Option<&Expr>, span: Span, fn lint_shadow(cx: &LateContext, name: Name, span: Span, lspan: Span, init: &Option, prev_span: Span) where T: Deref { - fn note_orig(cx: &LateContext, lint: &'static Lint, span: Span) { + fn note_orig(cx: &LateContext, mut db: DiagnosticWrapper, lint: &'static Lint, span: Span) { if cx.current_level(lint) != Level::Allow { - cx.sess().span_note(span, "previous binding is here"); + db.span_note(span, "previous binding is here"); } } if let Some(ref expr) = *init { if is_self_shadow(name, expr) { - span_lint(cx, SHADOW_SAME, span, &format!( + let db = span_lint(cx, SHADOW_SAME, span, &format!( "{} is shadowed by itself in {}", snippet(cx, lspan, "_"), snippet(cx, expr.span, ".."))); - note_orig(cx, SHADOW_SAME, prev_span); + note_orig(cx, db, SHADOW_SAME, prev_span); } else { if contains_self(name, expr) { - span_note_and_lint(cx, SHADOW_REUSE, lspan, &format!( + let db = span_note_and_lint(cx, SHADOW_REUSE, lspan, &format!( "{} is shadowed by {} which reuses the original value", snippet(cx, lspan, "_"), snippet(cx, expr.span, "..")), expr.span, "initialization happens here"); - note_orig(cx, SHADOW_REUSE, prev_span); + note_orig(cx, db, SHADOW_REUSE, prev_span); } else { - span_note_and_lint(cx, SHADOW_UNRELATED, lspan, &format!( + let db = span_note_and_lint(cx, SHADOW_UNRELATED, lspan, &format!( "{} is shadowed by {}", snippet(cx, lspan, "_"), snippet(cx, expr.span, "..")), expr.span, "initialization happens here"); - note_orig(cx, SHADOW_UNRELATED, prev_span); + note_orig(cx, db, SHADOW_UNRELATED, prev_span); } } } else { - span_lint(cx, SHADOW_UNRELATED, span, &format!( + let db = span_lint(cx, SHADOW_UNRELATED, span, &format!( "{} shadows a previous declaration", snippet(cx, lspan, "_"))); - note_orig(cx, SHADOW_UNRELATED, prev_span); + note_orig(cx, db, SHADOW_UNRELATED, prev_span); } } diff --git a/src/strings.rs b/src/strings.rs index d60a045aa75..861ae0bb012 100644 --- a/src/strings.rs +++ b/src/strings.rs @@ -75,13 +75,13 @@ impl LateLintPass for StringAdd { } span_lint(cx, STRING_ADD, e.span, "you added something to a string. \ - Consider using `String::push_str()` instead") + Consider using `String::push_str()` instead"); } } else if let ExprAssign(ref target, ref src) = e.node { if is_string(cx, target) && is_add(cx, src, target) { span_lint(cx, STRING_ADD_ASSIGN, e.span, "you assigned the result of adding something to this string. \ - Consider using `String::push_str()` instead") + Consider using `String::push_str()` instead"); } } } diff --git a/src/utils.rs b/src/utils.rs index 2ff498b5646..7c0ee09b3cd 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -8,10 +8,12 @@ use rustc::middle::ty; use std::borrow::Cow; use syntax::ast::Lit_::*; use syntax::ast; +use syntax::errors::DiagnosticBuilder; use syntax::ptr::P; use rustc::session::Session; use std::str::FromStr; +use std::ops::{Deref, DerefMut}; pub type MethodArgs = HirVec>; @@ -307,63 +309,91 @@ pub fn get_enclosing_block<'c>(cx: &'c LateContext, node: NodeId) -> Option<&'c } else { None } } -#[cfg(not(feature="structured_logging"))] -pub fn span_lint(cx: &T, lint: &'static Lint, sp: Span, msg: &str) { - cx.span_lint(lint, sp, msg); - if cx.current_level(lint) != Level::Allow { - cx.sess().fileline_help(sp, &format!("for further information visit \ - https://github.com/Manishearth/rust-clippy/wiki#{}", - lint.name_lower())) +pub struct DiagnosticWrapper<'a>(pub DiagnosticBuilder<'a>); + +impl<'a> Drop for DiagnosticWrapper<'a> { + fn drop(&mut self) { + self.0.emit(); } } +impl<'a> DerefMut for DiagnosticWrapper<'a> { + fn deref_mut(&mut self) -> &mut DiagnosticBuilder<'a> { + &mut self.0 + } +} + +impl<'a> Deref for DiagnosticWrapper<'a> { + type Target = DiagnosticBuilder<'a>; + fn deref(&self) -> &DiagnosticBuilder<'a> { + &self.0 + } +} + +#[cfg(not(feature="structured_logging"))] +pub fn span_lint<'a, T: LintContext>(cx: &'a T, lint: &'static Lint, + sp: Span, msg: &str) -> DiagnosticWrapper<'a> { + let mut db = cx.struct_span_lint(lint, sp, msg); + if cx.current_level(lint) != Level::Allow { + db.fileline_help(sp, &format!("for further information visit \ + https://github.com/Manishearth/rust-clippy/wiki#{}", + lint.name_lower())); + } + DiagnosticWrapper(db) +} + #[cfg(feature="structured_logging")] -pub fn span_lint(cx: &T, lint: &'static Lint, sp: Span, msg: &str) { +pub fn span_lint<'a, T: LintContext>(cx: &'a T, lint: &'static Lint, + sp: Span, msg: &str) -> DiagnosticWrapper<'a> { // lint.name / lint.desc is can give details of the lint // cx.sess().codemap() has all these nice functions for line/column/snippet details // http://doc.rust-lang.org/syntax/codemap/struct.CodeMap.html#method.span_to_string - cx.span_lint(lint, sp, msg); + let mut db = cx.struct_span_lint(lint, sp, msg); if cx.current_level(lint) != Level::Allow { - cx.sess().fileline_help(sp, &format!("for further information visit \ + db.fileline_help(sp, &format!("for further information visit \ https://github.com/Manishearth/rust-clippy/wiki#{}", - lint.name_lower())) + lint.name_lower())); } + DiagnosticWrapper(db) } -pub fn span_help_and_lint(cx: &T, lint: &'static Lint, span: Span, - msg: &str, help: &str) { - cx.span_lint(lint, span, msg); +pub fn span_help_and_lint<'a, T: LintContext>(cx: &'a T, lint: &'static Lint, span: Span, + msg: &str, help: &str) -> DiagnosticWrapper<'a> { + let mut db = cx.struct_span_lint(lint, span, msg); if cx.current_level(lint) != Level::Allow { - cx.sess().fileline_help(span, &format!("{}\nfor further information \ + db.fileline_help(span, &format!("{}\nfor further information \ visit https://github.com/Manishearth/rust-clippy/wiki#{}", - help, lint.name_lower())) + help, lint.name_lower())); } + DiagnosticWrapper(db) } -pub fn span_note_and_lint(cx: &T, lint: &'static Lint, span: Span, - msg: &str, note_span: Span, note: &str) { - cx.span_lint(lint, span, msg); +pub fn span_note_and_lint<'a, T: LintContext>(cx: &'a T, lint: &'static Lint, span: Span, + msg: &str, note_span: Span, note: &str) -> DiagnosticWrapper<'a> { + let mut db = cx.struct_span_lint(lint, span, msg); if cx.current_level(lint) != Level::Allow { if note_span == span { - cx.sess().fileline_note(note_span, note) + db.fileline_note(note_span, note); } else { - cx.sess().span_note(note_span, note) + db.span_note(note_span, note); } - cx.sess().fileline_help(span, &format!("for further information visit \ + db.fileline_help(span, &format!("for further information visit \ https://github.com/Manishearth/rust-clippy/wiki#{}", - lint.name_lower())) + lint.name_lower())); } + DiagnosticWrapper(db) } -pub fn span_lint_and_then(cx: &T, lint: &'static Lint, sp: Span, - msg: &str, f: F) where F: Fn() { - cx.span_lint(lint, sp, msg); +pub fn span_lint_and_then<'a, T: LintContext, F>(cx: &'a T, lint: &'static Lint, sp: Span, + msg: &str, f: F) -> DiagnosticWrapper<'a> where F: Fn(&mut DiagnosticWrapper) { + let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg)); if cx.current_level(lint) != Level::Allow { - f(); - cx.sess().fileline_help(sp, &format!("for further information visit \ + f(&mut db); + db.fileline_help(sp, &format!("for further information visit \ https://github.com/Manishearth/rust-clippy/wiki#{}", - lint.name_lower())) + lint.name_lower())); } + db } /// return the base type for references and raw pointers diff --git a/tests/compile-fail/cyclomatic_complexity.rs b/tests/compile-fail/cyclomatic_complexity.rs index 1a6dfd28728..f79440af121 100644 --- a/tests/compile-fail/cyclomatic_complexity.rs +++ b/tests/compile-fail/cyclomatic_complexity.rs @@ -4,7 +4,8 @@ #![deny(cyclomatic_complexity)] #![allow(unused)] -fn main() { //~ ERROR: The function has a cyclomatic complexity of 28. + +fn main() { //~ERROR The function has a cyclomatic complexity of 28 if true { println!("a"); }