reporting improvements

This commit is contained in:
llogiq 2015-09-02 08:19:47 +02:00
parent bc1eb84810
commit 0fb7d1d2d9
4 changed files with 40 additions and 21 deletions

View file

@ -6,7 +6,7 @@ use syntax::visit::FnKind;
use rustc::lint::{Context, LintArray, LintPass}; use rustc::lint::{Context, LintArray, LintPass};
use rustc::middle::def::Def::{DefVariant, DefStruct}; use rustc::middle::def::Def::{DefVariant, DefStruct};
use utils::{in_external_macro, snippet, span_lint}; use utils::{in_external_macro, snippet, span_lint, span_note_and_lint};
declare_lint!(pub SHADOW_SAME, Allow, declare_lint!(pub SHADOW_SAME, Allow,
"rebinding a name to itself, e.g. `let mut x = &mut x`"); "rebinding a name to itself, e.g. `let mut x = &mut x`");
@ -131,9 +131,9 @@ fn check_pat(cx: &Context, pat: &Pat, init: &Option<&Expr>, span: Span,
PatBox(ref inner) => { PatBox(ref inner) => {
if let Some(ref initp) = *init { if let Some(ref initp) = *init {
if let ExprBox(_, ref inner_init) = initp.node { if let ExprBox(_, ref inner_init) = initp.node {
check_pat(cx, inner, &Some(&**inner_init), span, bindings), check_pat(cx, inner, &Some(&**inner_init), span, bindings);
} else { } else {
check_pat(cx, inner, init, span, bindings), check_pat(cx, inner, init, span, bindings);
} }
} else { } else {
check_pat(cx, inner, init, span, bindings); check_pat(cx, inner, init, span, bindings);
@ -149,7 +149,7 @@ fn check_pat(cx: &Context, pat: &Pat, init: &Option<&Expr>, span: Span,
fn lint_shadow<T>(cx: &Context, name: Name, span: Span, lspan: Span, init: fn lint_shadow<T>(cx: &Context, name: Name, span: Span, lspan: Span, init:
&Option<T>) where T: Deref<Target=Expr> { &Option<T>) where T: Deref<Target=Expr> {
if let &Some(ref expr) = init { if let Some(ref expr) = *init {
if is_self_shadow(name, expr) { if is_self_shadow(name, expr) {
span_lint(cx, SHADOW_SAME, span, &format!( span_lint(cx, SHADOW_SAME, span, &format!(
"{} is shadowed by itself in {}", "{} is shadowed by itself in {}",
@ -157,20 +157,22 @@ fn lint_shadow<T>(cx: &Context, name: Name, span: Span, lspan: Span, init:
snippet(cx, expr.span, ".."))); snippet(cx, expr.span, "..")));
} else { } else {
if contains_self(name, expr) { if contains_self(name, expr) {
span_lint(cx, SHADOW_REUSE, span, &format!( span_note_and_lint(cx, SHADOW_REUSE, lspan, &format!(
"{} is shadowed by {} which reuses the original value", "{} is shadowed by {} which reuses the original value",
snippet(cx, lspan, "_"), snippet(cx, lspan, "_"),
snippet(cx, expr.span, ".."))); snippet(cx, expr.span, "..")),
expr.span, "initialization happens here");
} else { } else {
span_lint(cx, SHADOW_UNRELATED, span, &format!( span_note_and_lint(cx, SHADOW_UNRELATED, lspan, &format!(
"{} is shadowed by {} in this declaration", "{} is shadowed by {}",
snippet(cx, lspan, "_"), snippet(cx, lspan, "_"),
snippet(cx, expr.span, ".."))); snippet(cx, expr.span, "..")),
expr.span, "initialization happens here");
} }
} }
} else { } else {
span_lint(cx, SHADOW_UNRELATED, span, &format!( span_lint(cx, SHADOW_UNRELATED, span, &format!(
"{} is shadowed in this declaration", snippet(cx, lspan, "_"))); "{} shadows a previous declaration", snippet(cx, lspan, "_")));
} }
} }

View file

@ -23,7 +23,7 @@ pub fn in_macro(cx: &Context, opt_info: Option<&ExpnInfo>) -> bool {
if info.callee.name() == "closure expansion" { if info.callee.name() == "closure expansion" {
return false; return false;
} }
}, },
ExpnFormat::MacroAttribute(..) => { ExpnFormat::MacroAttribute(..) => {
// these are all plugins // these are all plugins
return true; return true;
@ -177,7 +177,7 @@ pub fn span_lint(cx: &Context, lint: &'static Lint, sp: Span, msg: &str) {
pub fn span_help_and_lint(cx: &Context, lint: &'static Lint, span: Span, pub fn span_help_and_lint(cx: &Context, lint: &'static Lint, span: Span,
msg: &str, help: &str) { msg: &str, help: &str) {
span_lint(cx, lint, span, msg); cx.span_lint(lint, span, msg);
if cx.current_level(lint) != Level::Allow { if cx.current_level(lint) != Level::Allow {
cx.sess().fileline_help(span, &format!("{}\nfor further information \ cx.sess().fileline_help(span, &format!("{}\nfor further information \
visit https://github.com/Manishearth/rust-clippy/wiki#{}", visit https://github.com/Manishearth/rust-clippy/wiki#{}",
@ -185,6 +185,21 @@ pub fn span_help_and_lint(cx: &Context, lint: &'static Lint, span: Span,
} }
} }
pub fn span_note_and_lint(cx: &Context, lint: &'static Lint, span: Span,
msg: &str, note_span: Span, note: &str) {
cx.span_lint(lint, span, msg);
if cx.current_level(lint) != Level::Allow {
if note_span == span {
cx.sess().fileline_note(note_span, note)
} else {
cx.sess().span_note(note_span, note)
}
cx.sess().fileline_help(span, &format!("for further information visit \
https://github.com/Manishearth/rust-clippy/wiki#{}",
lint.name_lower()))
}
}
/// return the base type for references and raw pointers /// return the base type for references and raw pointers
pub fn walk_ptrs_ty(ty: ty::Ty) -> ty::Ty { pub fn walk_ptrs_ty(ty: ty::Ty) -> ty::Ty {
match ty.sty { match ty.sty {

View file

@ -39,14 +39,16 @@ fn single_match(){
} }
fn ref_pats() { fn ref_pats() {
let ref v = Some(0); {
match v { //~ERROR instead of prefixing all patterns with `&` let ref v = Some(0);
&Some(v) => println!("{:?}", v), match v { //~ERROR instead of prefixing all patterns with `&`
&None => println!("none"), &Some(v) => println!("{:?}", v),
} &None => println!("none"),
match v { // this doesn't trigger, we have a different pattern }
&Some(v) => println!("some"), match v { // this doesn't trigger, we have a different pattern
other => println!("other"), &Some(v) => println!("some"),
other => println!("other"),
}
} }
let ref tup = (1, 2); let ref tup = (1, 2);
match tup { //~ERROR instead of prefixing all patterns with `&` match tup { //~ERROR instead of prefixing all patterns with `&`

View file

@ -18,7 +18,7 @@ fn main() {
let x = (1, x); //~ERROR: x is shadowed by (1, x) which reuses let x = (1, x); //~ERROR: x is shadowed by (1, x) which reuses
let x = first(x); //~ERROR: x is shadowed by first(x) which reuses let x = first(x); //~ERROR: x is shadowed by first(x) which reuses
let y = 1; let y = 1;
let x = y; //~ERROR: x is shadowed by y in this declaration let x = y; //~ERROR: x is shadowed by y
let o = Some(1u8); let o = Some(1u8);