diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 1f9b2512d..aaf2ef573 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -434,6 +434,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { methods::WRONG_PUB_SELF_CONVENTION, misc::FLOAT_CMP_CONST, missing_doc::MISSING_DOCS_IN_PRIVATE_ITEMS, + panic_unimplemented::UNIMPLEMENTED, shadow::SHADOW_REUSE, shadow::SHADOW_SAME, shadow::SHADOW_UNRELATED, @@ -627,7 +628,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { open_options::NONSENSICAL_OPEN_OPTIONS, overflow_check_conditional::OVERFLOW_CHECK_CONDITIONAL, panic_unimplemented::PANIC_PARAMS, - panic_unimplemented::UNIMPLEMENTED, partialeq_ne_impl::PARTIALEQ_NE_IMPL, precedence::PRECEDENCE, ptr::CMP_NULL, @@ -750,7 +750,6 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry) { non_expressive_names::MANY_SINGLE_CHAR_NAMES, ok_if_let::IF_LET_SOME_RESULT, panic_unimplemented::PANIC_PARAMS, - panic_unimplemented::UNIMPLEMENTED, ptr::CMP_NULL, ptr::PTR_ARG, question_mark::QUESTION_MARK, diff --git a/clippy_lints/src/panic_unimplemented.rs b/clippy_lints/src/panic_unimplemented.rs index 7f1b6775b..b257f5b3b 100644 --- a/clippy_lints/src/panic_unimplemented.rs +++ b/clippy_lints/src/panic_unimplemented.rs @@ -2,6 +2,7 @@ use rustc::hir::*; use rustc::lint::*; use syntax::ast::LitKind; use syntax::ptr::P; +use syntax::ext::quote::rt::Span; use utils::{is_direct_expn_of, is_expn_of, match_def_path, opt_def_id, paths, resolve_node, span_lint}; /// **What it does:** Checks for missing parameters in `panic!`. @@ -35,7 +36,7 @@ declare_clippy_lint! { /// ``` declare_clippy_lint! { pub UNIMPLEMENTED, - style, + restriction, "`unimplemented!` should not be present in production code" } @@ -60,7 +61,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { if params.len() == 2; then { if is_expn_of(expr.span, "unimplemented").is_some() { - span_lint(cx, UNIMPLEMENTED, expr.span, + let span = get_outer_span(expr); + span_lint(cx, UNIMPLEMENTED, span, "`unimplemented` should not be present in production code"); } else { match_panic(params, expr, cx); @@ -70,6 +72,18 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { } } +fn get_outer_span(expr: &Expr) -> Span { + if_chain! { + if let Some(first) = expr.span.ctxt().outer().expn_info(); + if let Some(second) = first.call_site.ctxt().outer().expn_info(); + then { + second.call_site + } else { + expr.span + } + } +} + fn match_panic(params: &P<[Expr]>, expr: &Expr, cx: &LateContext) { if_chain! { if let ExprLit(ref lit) = params[0].node; diff --git a/tests/run-pass/ice_exacte_size.rs b/tests/run-pass/ice_exacte_size.rs index d99734810..914153c64 100644 --- a/tests/run-pass/ice_exacte_size.rs +++ b/tests/run-pass/ice_exacte_size.rs @@ -6,7 +6,6 @@ struct Foo; impl Iterator for Foo { type Item = (); - #[allow(unimplemented)] fn next(&mut self) -> Option<()> { let _ = self.len() == 0; unimplemented!() diff --git a/tests/ui/panic_unimplemented.rs b/tests/ui/panic_unimplemented.rs index 56d06f239..33050633f 100644 --- a/tests/ui/panic_unimplemented.rs +++ b/tests/ui/panic_unimplemented.rs @@ -54,7 +54,9 @@ fn ok_escaped() { } fn unimplemented() { + let a = 2; unimplemented!(); + let b = a + 2; } fn main() { diff --git a/tests/ui/panic_unimplemented.stderr b/tests/ui/panic_unimplemented.stderr index 534bfbae8..3bf5589c4 100644 --- a/tests/ui/panic_unimplemented.stderr +++ b/tests/ui/panic_unimplemented.stderr @@ -25,13 +25,12 @@ error: you probably are missing some parameter in your format string | ^^^^^^^^^^^^ error: `unimplemented` should not be present in production code - --> $DIR/panic_unimplemented.rs:57:5 + --> $DIR/panic_unimplemented.rs:58:5 | -57 | unimplemented!(); +58 | unimplemented!(); | ^^^^^^^^^^^^^^^^^ | = note: `-D unimplemented` implied by `-D warnings` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) error: aborting due to 5 previous errors