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()) {
|
if implements_trait(cx, arg_ty, default_trait_id, Vec::new()) {
|
||||||
span_lint(cx,
|
span_lint_and_then(cx,
|
||||||
OR_FUN_CALL,
|
OR_FUN_CALL,
|
||||||
span,
|
span,
|
||||||
&format!("use of `{}` followed by a call to `{}`", name, path))
|
&format!("use of `{}` followed by a call to `{}`", name, path),
|
||||||
.span_suggestion(span,
|
|db| {
|
||||||
"try this",
|
db.span_suggestion(span, "try this",
|
||||||
format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")));
|
format!("{}.unwrap_or_default()", snippet(cx, self_expr.span, "_")));
|
||||||
|
});
|
||||||
return true;
|
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, ".."),
|
(false, true) => snippet(cx, fun.span, ".."),
|
||||||
};
|
};
|
||||||
|
|
||||||
span_lint(cx, OR_FUN_CALL, span, &format!("use of `{}` followed by a function call", name))
|
span_lint_and_then(cx, OR_FUN_CALL, span, &format!("use of `{}` followed by a function call", name), |db| {
|
||||||
.span_suggestion(span,
|
db.span_suggestion(span,
|
||||||
"try this",
|
"try this",
|
||||||
format!("{}.{}_{}({})", snippet(cx, self_expr.span, "_"), name, suffix, sugg));
|
format!("{}.{}_{}({})", snippet(cx, self_expr.span, "_"), name, suffix, sugg));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.len() == 2 {
|
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) {
|
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(_, ty::TypeAndMut { ty: ref inner, .. }) = ty.sty {
|
||||||
if let ty::TyRef(..) = inner.sty {
|
if let ty::TyRef(..) = inner.sty {
|
||||||
let mut db = span_lint(cx,
|
span_lint_and_then(cx,
|
||||||
CLONE_DOUBLE_REF,
|
CLONE_DOUBLE_REF,
|
||||||
expr.span,
|
expr.span,
|
||||||
"using `clone` on a double-reference; \
|
"using `clone` on a double-reference; \
|
||||||
this will copy the reference instead of cloning \
|
this will copy the reference instead of cloning the inner type",
|
||||||
the inner type");
|
|db| if let Some(snip) = snippet_opt(cx, arg.span) {
|
||||||
if let Some(snip) = snippet_opt(cx, arg.span) {
|
db.span_suggestion(expr.span, "try dereferencing it", format!("(*{}).clone()", snip));
|
||||||
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]);
|
let arg_ty = cx.tcx.expr_ty(&args[1]);
|
||||||
if let Some((span, r)) = derefs_to_slice(cx, &args[1], &arg_ty) {
|
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_lint_and_then(cx, EXTEND_FROM_SLICE, expr.span, "use of `extend` to extend a Vec by a slice", |db| {
|
||||||
.span_suggestion(expr.span,
|
db.span_suggestion(expr.span,
|
||||||
"try this",
|
"try this",
|
||||||
format!("{}.extend_from_slice({}{})",
|
format!("{}.extend_from_slice({}{})",
|
||||||
snippet(cx, args[0].span, "_"),
|
snippet(cx, args[0].span, "_"),
|
||||||
r,
|
r,
|
||||||
snippet(cx, span, "_")));
|
snippet(cx, span, "_")));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ use rustc::ty;
|
|||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax::codemap::Span;
|
use syntax::codemap::Span;
|
||||||
use utils::paths;
|
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
|
/// **What it does:** This lints about type with a `fn new() -> Self` method
|
||||||
/// and no implementation of
|
/// and no implementation of
|
||||||
@ -112,24 +112,26 @@ impl LateLintPass for NewWithoutDefault {
|
|||||||
!implements_trait(cx, self_ty, default_trait_id, Vec::new())
|
!implements_trait(cx, self_ty, default_trait_id, Vec::new())
|
||||||
], {
|
], {
|
||||||
if can_derive_default(self_ty, cx, default_trait_id) {
|
if can_derive_default(self_ty, cx, default_trait_id) {
|
||||||
span_lint(cx,
|
span_lint_and_then(cx,
|
||||||
NEW_WITHOUT_DEFAULT_DERIVE, span,
|
NEW_WITHOUT_DEFAULT_DERIVE, span,
|
||||||
&format!("you should consider deriving a \
|
&format!("you should consider deriving a \
|
||||||
`Default` implementation for `{}`",
|
`Default` implementation for `{}`",
|
||||||
self_ty)).
|
self_ty),
|
||||||
span_suggestion(span,
|
|db| {
|
||||||
"try this",
|
db.span_suggestion(span, "try this", "#[derive(Default)]".into());
|
||||||
"#[derive(Default)]".into());
|
});
|
||||||
} else {
|
} else {
|
||||||
span_lint(cx,
|
span_lint_and_then(cx,
|
||||||
NEW_WITHOUT_DEFAULT, span,
|
NEW_WITHOUT_DEFAULT, span,
|
||||||
&format!("you should consider adding a \
|
&format!("you should consider adding a \
|
||||||
`Default` implementation for `{}`",
|
`Default` implementation for `{}`",
|
||||||
self_ty)).
|
self_ty),
|
||||||
span_suggestion(span,
|
|db| {
|
||||||
"try this",
|
db.span_suggestion(span,
|
||||||
format!("impl Default for {} {{ fn default() -> \
|
"try this",
|
||||||
Self {{ {}::new() }} }}", self_ty, self_ty));
|
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 rustc::hir::intravisit::{Visitor, FnKind};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use syntax::codemap::Span;
|
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.
|
/// **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)
|
fn lint_shadow<T>(cx: &LateContext, name: Name, span: Span, pattern_span: Span, init: &Option<T>, prev_span: Span)
|
||||||
where T: Deref<Target = Expr>
|
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 let Some(ref expr) = *init {
|
||||||
if is_self_shadow(name, expr) {
|
if is_self_shadow(name, expr) {
|
||||||
let db = span_lint(cx,
|
span_lint_and_then(cx,
|
||||||
SHADOW_SAME,
|
SHADOW_SAME,
|
||||||
span,
|
span,
|
||||||
&format!("`{}` is shadowed by itself in `{}`",
|
&format!("`{}` is shadowed by itself in `{}`",
|
||||||
snippet(cx, pattern_span, "_"),
|
snippet(cx, pattern_span, "_"),
|
||||||
snippet(cx, expr.span, "..")));
|
snippet(cx, expr.span, "..")),
|
||||||
|
|db| { db.span_note(prev_span, "previous binding is here"); },
|
||||||
note_orig(cx, db, SHADOW_SAME, prev_span);
|
);
|
||||||
} else if contains_self(name, expr) {
|
} else if contains_self(name, expr) {
|
||||||
let db = span_note_and_lint(cx,
|
span_lint_and_then(cx,
|
||||||
SHADOW_REUSE,
|
SHADOW_REUSE,
|
||||||
pattern_span,
|
pattern_span,
|
||||||
&format!("`{}` is shadowed by `{}` which reuses the original value",
|
&format!("`{}` is shadowed by `{}` which reuses the original value",
|
||||||
snippet(cx, pattern_span, "_"),
|
snippet(cx, pattern_span, "_"),
|
||||||
snippet(cx, expr.span, "..")),
|
snippet(cx, expr.span, "..")),
|
||||||
expr.span,
|
|db| {
|
||||||
"initialization happens here");
|
db.span_note(expr.span, "initialization happens here");
|
||||||
note_orig(cx, db, SHADOW_REUSE, prev_span);
|
db.span_note(prev_span, "previous binding is here");
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
let db = span_note_and_lint(cx,
|
span_lint_and_then(cx,
|
||||||
SHADOW_UNRELATED,
|
SHADOW_UNRELATED,
|
||||||
pattern_span,
|
pattern_span,
|
||||||
&format!("`{}` is shadowed by `{}`",
|
&format!("`{}` is shadowed by `{}`",
|
||||||
snippet(cx, pattern_span, "_"),
|
snippet(cx, pattern_span, "_"),
|
||||||
snippet(cx, expr.span, "..")),
|
snippet(cx, expr.span, "..")),
|
||||||
expr.span,
|
|db| {
|
||||||
"initialization happens here");
|
db.span_note(expr.span, "initialization happens here");
|
||||||
note_orig(cx, db, SHADOW_UNRELATED, prev_span);
|
db.span_note(prev_span, "previous binding is here");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
let db = span_lint(cx,
|
span_lint_and_then(cx,
|
||||||
SHADOW_UNRELATED,
|
SHADOW_UNRELATED,
|
||||||
span,
|
span,
|
||||||
&format!("{} shadows a previous declaration", snippet(cx, pattern_span, "_")));
|
&format!("{} shadows a previous declaration", snippet(cx, pattern_span, "_")),
|
||||||
note_orig(cx, db, SHADOW_UNRELATED, prev_span);
|
|db| { db.span_note(prev_span, "previous binding is here"); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ use rustc::ty;
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::{Deref, DerefMut};
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use syntax::ast::{self, LitKind, RangeLimits};
|
use syntax::ast::{self, LitKind, RangeLimits};
|
||||||
use syntax::codemap::{ExpnInfo, Span, ExpnFormat};
|
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> {
|
impl<'a> DiagnosticWrapper<'a> {
|
||||||
fn wiki_link(&mut self, lint: &'static Lint) {
|
fn wiki_link(&mut self, lint: &'static Lint) {
|
||||||
if env::var("CLIPPY_DISABLE_WIKI_LINKS").is_err() {
|
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()));
|
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));
|
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg));
|
||||||
if cx.current_level(lint) != Level::Allow {
|
if cx.current_level(lint) != Level::Allow {
|
||||||
db.wiki_link(lint);
|
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)
|
// FIXME: needless lifetime doesn't trigger here
|
||||||
-> DiagnosticWrapper<'a> {
|
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));
|
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg));
|
||||||
if cx.current_level(lint) != Level::Allow {
|
if cx.current_level(lint) != Level::Allow {
|
||||||
db.help(help);
|
db.0.help(help);
|
||||||
db.wiki_link(lint);
|
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,
|
pub fn span_note_and_lint<'a, T: LintContext>(cx: &'a T, lint: &'static Lint, span: Span, msg: &str, note_span: Span,
|
||||||
note: &str)
|
note: &str) {
|
||||||
-> DiagnosticWrapper<'a> {
|
|
||||||
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg));
|
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, span, msg));
|
||||||
if cx.current_level(lint) != Level::Allow {
|
if cx.current_level(lint) != Level::Allow {
|
||||||
if note_span == span {
|
if note_span == span {
|
||||||
db.note(note);
|
db.0.note(note);
|
||||||
} else {
|
} else {
|
||||||
db.span_note(note_span, note);
|
db.0.span_note(note_span, note);
|
||||||
}
|
}
|
||||||
db.wiki_link(lint);
|
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)
|
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 DiagnosticBuilder<'a>)
|
||||||
where F: FnOnce(&mut DiagnosticWrapper)
|
|
||||||
{
|
{
|
||||||
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg));
|
let mut db = DiagnosticWrapper(cx.struct_span_lint(lint, sp, msg));
|
||||||
if cx.current_level(lint) != Level::Allow {
|
if cx.current_level(lint) != Level::Allow {
|
||||||
f(&mut db);
|
f(&mut db.0);
|
||||||
db.wiki_link(lint);
|
db.wiki_link(lint);
|
||||||
}
|
}
|
||||||
db
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the base type for references and raw pointers.
|
/// Return the base type for references and raw pointers.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user