Merge pull request #1046 from oli-obk/unify_span_lint_usage
use span_lint_and_then instead of adding to the `DiagnosticWrapper`
This commit is contained in:
commit
5aea20da7f
@ -536,13 +536,14 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[P<hi
|
||||
};
|
||||
|
||||
if implements_trait(cx, arg_ty, default_trait_id, Vec::new()) {
|
||||
span_lint(cx,
|
||||
span_lint_and_then(cx,
|
||||
OR_FUN_CALL,
|
||||
span,
|
||||
&format!("use of `{}` followed by a call to `{}`", name, path))
|
||||
.span_suggestion(span,
|
||||
"try this",
|
||||
format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")));
|
||||
&format!("use of `{}` followed by a call to `{}`", name, path),
|
||||
|db| {
|
||||
db.span_suggestion(span, "try this",
|
||||
format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -590,10 +591,11 @@ fn lint_or_fun_call(cx: &LateContext, expr: &hir::Expr, name: &str, args: &[P<hi
|
||||
(false, true) => 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, "_")));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
});
|
||||
}
|
||||
}}
|
||||
}
|
||||
|
@ -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<T>(cx: &LateContext, name: Name, span: Span, pattern_span: Span, init: &Option<T>, prev_span: Span)
|
||||
where T: Deref<Target = Expr>
|
||||
{
|
||||
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"); });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<T: LintContext>(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.
|
||||
|
Loading…
Reference in New Issue
Block a user