diff --git a/src/eta_reduction.rs b/src/eta_reduction.rs index c4c0912464c..5ade158200c 100644 --- a/src/eta_reduction.rs +++ b/src/eta_reduction.rs @@ -2,7 +2,7 @@ use rustc::lint::*; use rustc_front::hir::*; use rustc::middle::ty; -use utils::{snippet, span_lint, is_adjusted}; +use utils::{snippet_opt, span_lint, is_adjusted}; #[allow(missing_copy_implementations)] @@ -75,9 +75,12 @@ fn check_closure(cx: &LateContext, expr: &Expr) { return } } - span_lint(cx, REDUNDANT_CLOSURE, expr.span, &format!( - "redundant closure found. Consider using `{}` in its place", - snippet(cx, caller.span, ".."))); + span_lint(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure found"); + if let Some(snippet) = snippet_opt(cx, caller.span) { + cx.sess().span_suggestion(expr.span, + "remove closure as shown:", + snippet); + } } } } diff --git a/src/utils.rs b/src/utils.rs index 2b38403b63a..21d1f9d16ec 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -195,6 +195,11 @@ pub fn snippet<'a, T: LintContext>(cx: &T, span: Span, default: &'a str) -> Cow< cx.sess().codemap().span_to_snippet(span).map(From::from).unwrap_or(Cow::Borrowed(default)) } +/// Converts a span to a code snippet. Returns None if not available. +pub fn snippet_opt(cx: &T, span: Span) -> Option { + cx.sess().codemap().span_to_snippet(span).ok() +} + /// convert a span (from a block) to a code snippet if available, otherwise use default, e.g. /// `snippet(cx, expr.span, "..")` /// This trims the code of indentation, except for the first line diff --git a/tests/compile-fail/eta.rs b/tests/compile-fail/eta.rs index d53ea4e97d7..a51d116d9cc 100644 --- a/tests/compile-fail/eta.rs +++ b/tests/compile-fail/eta.rs @@ -5,11 +5,17 @@ fn main() { let a = Some(1u8).map(|a| foo(a)); - //~^ ERROR redundant closure found. Consider using `foo` in its place + //~^ ERROR redundant closure found + //~| HELP remove closure as shown + //~| SUGGESTION let a = Some(1u8).map(foo); meta(|a| foo(a)); - //~^ ERROR redundant closure found. Consider using `foo` in its place + //~^ ERROR redundant closure found + //~| HELP remove closure as shown + //~| SUGGESTION meta(foo); let c = Some(1u8).map(|a| {1+2; foo}(a)); - //~^ ERROR redundant closure found. Consider using `{1+2; foo}` in its place + //~^ ERROR redundant closure found + //~| HELP remove closure as shown + //~| SUGGESTION let c = Some(1u8).map({1+2; foo}); let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted? all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted unsafe {