diff --git a/clippy_lints/src/methods.rs b/clippy_lints/src/methods.rs index 950a03159b2..a959dbe1d6a 100644 --- a/clippy_lints/src/methods.rs +++ b/clippy_lints/src/methods.rs @@ -536,13 +536,14 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[P snippet(cx, fun.span, ".."), }; - span_lint(cx, OR_FUN_CALL, span, &format!("use of `{}` followed by a function call", name)) - .span_suggestion(span, - "try this", - format!("{}.{}_{}({})", snippet(cx, self_expr.span, "_"), name, suffix, sugg)); + span_lint_and_then(cx, OR_FUN_CALL, span, &format!("use of `{}` followed by a function call", name), |db| { + db.span_suggestion(span, + "try this", + format!("{}.{}_{}({})", snippet(cx, self_expr.span, "_"), name, suffix, sugg)); + }); } if args.len() == 2 { @@ -621,15 +623,14 @@ fn lint_clone_on_copy(cx: &LateContext, expr: &hir::Expr) { fn lint_clone_double_ref(cx: &LateContext, expr: &hir::Expr, arg: &hir::Expr, ty: ty::Ty) { if let ty::TyRef(_, ty::TypeAndMut { ty: ref inner, .. }) = ty.sty { if let ty::TyRef(..) = inner.sty { - let mut db = span_lint(cx, - CLONE_DOUBLE_REF, - expr.span, - "using `clone` on a double-reference; \ - this will copy the reference instead of cloning \ - the inner type"); - if let Some(snip) = snippet_opt(cx, arg.span) { - db.span_suggestion(expr.span, "try dereferencing it", format!("(*{}).clone()", snip)); - } + span_lint_and_then(cx, + CLONE_DOUBLE_REF, + expr.span, + "using `clone` on a double-reference; \ + this will copy the reference instead of cloning the inner type", + |db| if let Some(snip) = snippet_opt(cx, arg.span) { + db.span_suggestion(expr.span, "try dereferencing it", format!("(*{}).clone()", snip)); + }); } } } @@ -641,13 +642,14 @@ fn lint_extend(cx: &LateContext, expr: &hir::Expr, args: &MethodArgs) { } let arg_ty = cx.tcx.expr_ty(&args[1]); if let Some((span, r)) = derefs_to_slice(cx, &args[1], &arg_ty) { - span_lint(cx, EXTEND_FROM_SLICE, expr.span, "use of `extend` to extend a Vec by a slice") - .span_suggestion(expr.span, - "try this", - format!("{}.extend_from_slice({}{})", - snippet(cx, args[0].span, "_"), - r, - snippet(cx, span, "_"))); + span_lint_and_then(cx, EXTEND_FROM_SLICE, expr.span, "use of `extend` to extend a Vec by a slice", |db| { + db.span_suggestion(expr.span, + "try this", + format!("{}.extend_from_slice({}{})", + snippet(cx, args[0].span, "_"), + r, + snippet(cx, span, "_"))); + }); } } diff --git a/clippy_lints/src/new_without_default.rs b/clippy_lints/src/new_without_default.rs index f400f1b6643..20c0d282bd8 100644 --- a/clippy_lints/src/new_without_default.rs +++ b/clippy_lints/src/new_without_default.rs @@ -6,7 +6,7 @@ use rustc::ty; use syntax::ast; use syntax::codemap::Span; use utils::paths; -use utils::{get_trait_def_id, implements_trait, in_external_macro, return_ty, same_tys, span_lint}; +use utils::{get_trait_def_id, implements_trait, in_external_macro, return_ty, same_tys, span_lint_and_then}; /// **What it does:** This lints about type with a `fn new() -> Self` method /// and no implementation of @@ -112,24 +112,26 @@ impl LateLintPass for NewWithoutDefault { !implements_trait(cx, self_ty, default_trait_id, Vec::new()) ], { if can_derive_default(self_ty, cx, default_trait_id) { - span_lint(cx, - NEW_WITHOUT_DEFAULT_DERIVE, span, - &format!("you should consider deriving a \ - `Default` implementation for `{}`", - self_ty)). - span_suggestion(span, - "try this", - "#[derive(Default)]".into()); + span_lint_and_then(cx, + NEW_WITHOUT_DEFAULT_DERIVE, span, + &format!("you should consider deriving a \ + `Default` implementation for `{}`", + self_ty), + |db| { + db.span_suggestion(span, "try this", "#[derive(Default)]".into()); + }); } else { - span_lint(cx, - NEW_WITHOUT_DEFAULT, span, - &format!("you should consider adding a \ - `Default` implementation for `{}`", - self_ty)). - span_suggestion(span, - "try this", - format!("impl Default for {} {{ fn default() -> \ - Self {{ {}::new() }} }}", self_ty, self_ty)); + span_lint_and_then(cx, + NEW_WITHOUT_DEFAULT, span, + &format!("you should consider adding a \ + `Default` implementation for `{}`", + self_ty), + |db| { + db.span_suggestion(span, + "try this", + format!("impl Default for {} {{ fn default() -> \ + Self {{ {}::new() }} }}", self_ty, self_ty)); + }); } }} } diff --git a/clippy_lints/src/shadow.rs b/clippy_lints/src/shadow.rs index 5bb3e006862..b12e68185c2 100644 --- a/clippy_lints/src/shadow.rs +++ b/clippy_lints/src/shadow.rs @@ -5,7 +5,7 @@ use rustc::hir::*; use rustc::hir::intravisit::{Visitor, FnKind}; use std::ops::Deref; use syntax::codemap::Span; -use utils::{is_from_for_desugar, in_external_macro, snippet, span_lint, span_note_and_lint, DiagnosticWrapper}; +use utils::{is_from_for_desugar, in_external_macro, snippet, span_lint_and_then}; /// **What it does:** This lint checks for bindings that shadow other bindings already in scope, while just changing reference level or mutability. /// @@ -197,49 +197,46 @@ fn check_pat(cx: &LateContext, pat: &Pat, init: &Option<&Expr>, span: Span, bind fn lint_shadow(cx: &LateContext, name: Name, span: Span, pattern_span: Span, init: &Option, prev_span: Span) where T: Deref { - fn note_orig(cx: &LateContext, mut db: DiagnosticWrapper, lint: &'static Lint, span: Span) { - if cx.current_level(lint) != Level::Allow { - db.span_note(span, "previous binding is here"); - } - } if let Some(ref expr) = *init { if is_self_shadow(name, expr) { - let db = span_lint(cx, + span_lint_and_then(cx, SHADOW_SAME, span, &format!("`{}` is shadowed by itself in `{}`", snippet(cx, pattern_span, "_"), - snippet(cx, expr.span, ".."))); - - note_orig(cx, db, SHADOW_SAME, prev_span); + snippet(cx, expr.span, "..")), + |db| { db.span_note(prev_span, "previous binding is here"); }, + ); } else if contains_self(name, expr) { - let db = span_note_and_lint(cx, - SHADOW_REUSE, - pattern_span, - &format!("`{}` is shadowed by `{}` which reuses the original value", - snippet(cx, pattern_span, "_"), - snippet(cx, expr.span, "..")), - expr.span, - "initialization happens here"); - note_orig(cx, db, SHADOW_REUSE, prev_span); + span_lint_and_then(cx, + SHADOW_REUSE, + pattern_span, + &format!("`{}` is shadowed by `{}` which reuses the original value", + snippet(cx, pattern_span, "_"), + snippet(cx, expr.span, "..")), + |db| { + db.span_note(expr.span, "initialization happens here"); + db.span_note(prev_span, "previous binding is here"); + }); } else { - let db = span_note_and_lint(cx, - SHADOW_UNRELATED, - pattern_span, - &format!("`{}` is shadowed by `{}`", - snippet(cx, pattern_span, "_"), - snippet(cx, expr.span, "..")), - expr.span, - "initialization happens here"); - note_orig(cx, db, SHADOW_UNRELATED, prev_span); + span_lint_and_then(cx, + SHADOW_UNRELATED, + pattern_span, + &format!("`{}` is shadowed by `{}`", + snippet(cx, pattern_span, "_"), + snippet(cx, expr.span, "..")), + |db| { + db.span_note(expr.span, "initialization happens here"); + db.span_note(prev_span, "previous binding is here"); + }); } } else { - let db = span_lint(cx, + span_lint_and_then(cx, SHADOW_UNRELATED, span, - &format!("{} shadows a previous declaration", snippet(cx, pattern_span, "_"))); - note_orig(cx, db, SHADOW_UNRELATED, prev_span); + &format!("{} shadows a previous declaration", snippet(cx, pattern_span, "_")), + |db| { db.span_note(prev_span, "previous binding is here"); }); } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index e35b1bbac6b..9eb54c2a013 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -12,7 +12,6 @@ use rustc::ty; use std::borrow::Cow; use std::env; use std::mem; -use std::ops::{Deref, DerefMut}; use std::str::FromStr; use syntax::ast::{self, LitKind, RangeLimits}; use syntax::codemap::{ExpnInfo, Span, ExpnFormat}; @@ -453,71 +452,52 @@ impl<'a> Drop for DiagnosticWrapper<'a> { } } -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 - } -} - impl<'a> DiagnosticWrapper<'a> { fn wiki_link(&mut self, lint: &'static Lint) { if env::var("CLIPPY_DISABLE_WIKI_LINKS").is_err() { - self.help(&format!("for further information visit https://github.com/Manishearth/rust-clippy/wiki#{}", + self.0.help(&format!("for further information visit https://github.com/Manishearth/rust-clippy/wiki#{}", lint.name_lower())); } } } -pub fn span_lint<'a, T: LintContext>(cx: &'a T, lint: &'static Lint, sp: Span, msg: &str) -> DiagnosticWrapper<'a> { +pub fn span_lint(cx: &T, lint: &'static Lint, sp: Span, msg: &str) { let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg)); if cx.current_level(lint) != Level::Allow { db.wiki_link(lint); } - db } -pub fn span_help_and_lint<'a, T: LintContext>(cx: &'a T, lint: &'static Lint, span: Span, msg: &str, help: &str) - -> DiagnosticWrapper<'a> { +// FIXME: needless lifetime doesn't trigger here +pub fn span_help_and_lint<'a, T: LintContext>(cx: &'a T, lint: &'static Lint, span: Span, msg: &str, help: &str) { let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg)); if cx.current_level(lint) != Level::Allow { - db.help(help); + db.0.help(help); db.wiki_link(lint); } - db } 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> { + note: &str) { let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg)); if cx.current_level(lint) != Level::Allow { if note_span == span { - db.note(note); + db.0.note(note); } else { - db.span_note(note_span, note); + db.0.span_note(note_span, note); } db.wiki_link(lint); } - db } 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: FnOnce(&mut DiagnosticWrapper) + where F: FnOnce(&mut DiagnosticBuilder<'a>) { let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg)); if cx.current_level(lint) != Level::Allow { - f(&mut db); + f(&mut db.0); db.wiki_link(lint); } - db } /// Return the base type for references and raw pointers.