diff --git a/clippy_lints/src/macro_use.rs b/clippy_lints/src/macro_use.rs index b7a3c1e560e9..35dcb8e13c84 100644 --- a/clippy_lints/src/macro_use.rs +++ b/clippy_lints/src/macro_use.rs @@ -13,6 +13,25 @@ const PRELUDE: &[&str] = &[ "macros" ]; const BRACKETS: &[char] = &['<', '>']; + +declare_clippy_lint! { + /// **What it does:** Checks for `#[macro_use] use...`. + /// + /// **Why is this bad?** Since the Rust 2018 edition you can import + /// macro's directly, this is considered idiomatic. + /// + /// **Known problems:** None. + /// + /// **Example:** + /// ```rust + /// #[macro_use] + /// use lazy_static; + /// ``` + pub MACRO_USE_IMPORTS, + pedantic, + "#[macro_use] is no longer needed" +} + /// MacroRefData includes the name of the macro /// and the path from `SourceMap::span_to_filename`. pub struct MacroRefData { @@ -32,29 +51,10 @@ impl MacroRefData { if path.contains(' ') { path = path.split(' ').next().unwrap().to_string(); } - println!("NEW {} {}", name, path); Self { name: name.to_string(), path, } } } -declare_clippy_lint! { - /// **What it does:** Checks for `#[macro_use] use...`. - /// - /// **Why is this bad?** Since the Rust 2018 edition you can import - /// macro's directly, this is considered idiomatic. - /// - /// **Known problems:** None. - /// - /// **Example:** - /// ```rust - /// #[macro_use] - /// use lazy_static; - /// ``` - pub MACRO_USE_IMPORTS, - pedantic, - "#[macro_use] is no longer needed" -} - #[derive(Default)] pub struct MacroUseImports { /// the actual import path used and its span. @@ -66,8 +66,6 @@ pub struct MacroUseImports { impl MacroUseImports { fn import_path_mac(&self, use_path: &str) -> String { - println!("END {:?}", use_path); - for mac in self.collected.values() { if paths_match(mac, use_path) { return make_path(mac, use_path) @@ -82,8 +80,6 @@ fn paths_match(mac: &MacroRefData, use_path: &str) -> bool { .filter(|s| *s != "") .collect::>(); - println!("{:?}", segs); - if segs.starts_with(&["std"]) { return PRELUDE.iter().any(|m| segs.contains(m)) } @@ -92,14 +88,19 @@ fn paths_match(mac: &MacroRefData, use_path: &str) -> bool { } fn make_path(mac: &MacroRefData, use_path: &str) -> String { - let mut res = String::default(); - + if use_path.split("::").count() == 1 { + return format!("{}::{}", use_path, mac.name); + } + let segs = mac.path.split("::") - .filter(|s| *s == "") + .filter(|s| *s != "") .collect::>(); + if segs.starts_with(&["std"]) && PRELUDE.iter().any(|m| segs.contains(m)) { + return format!("std::prelude::{}", mac.name); + } - res + mac.path.clone() } impl_lint_pass!(MacroUseImports => [MACRO_USE_IMPORTS]); @@ -128,7 +129,6 @@ impl EarlyLintPass for MacroUseImports { if let Some(callee) = expr.span.source_callee() { self.collected.entry(call_site) .or_insert_with(|| { - println!("EXPR {:?}", name); MacroRefData::new(name.to_string(), callee.def_site, ecx) }); } @@ -141,7 +141,6 @@ impl EarlyLintPass for MacroUseImports { if let Some(callee) = stmt.span.source_callee() { self.collected.entry(call_site) .or_insert_with(|| { - println!("STMT {:?}", name); MacroRefData::new(name.to_string(), callee.def_site, ecx) }); } @@ -154,25 +153,25 @@ impl EarlyLintPass for MacroUseImports { if let Some(callee) = pat.span.source_callee() { self.collected.entry(call_site) .or_insert_with(|| { - println!("PAT {:?}", name); MacroRefData::new(name.to_string(), callee.def_site, ecx) }); } } } - fn check_mac(&mut self, ecx: &EarlyContext<'_>, mac: &ast::Mac) { - let call_site = mac.span().source_callsite(); - let name = snippet(ecx, ecx.sess.source_map().span_until_char(call_site, '!'), "_"); - if let Some(callee) = mac.span().source_callee() { - self.collected.entry(call_site) - .or_insert_with(|| { - println!("MAC {:?}", name); - MacroRefData::new(name.to_string(), callee.def_site, ecx) - }); + fn check_ty(&mut self, ecx: &EarlyContext<'_>, ty: &ast::Ty) { + if in_macro(ty.span) { + let call_site = ty.span.source_callsite(); + let name = snippet(ecx, ecx.sess.source_map().span_until_char(call_site, '!'), "_"); + if let Some(callee) = ty.span.source_callee() { + self.collected.entry(call_site) + .or_insert_with(|| { + MacroRefData::new(name.to_string(), callee.def_site, ecx) + }); + } } } - fn check_crate_post(&mut self, ecx: &EarlyContext<'_>, krate: &ast::Crate) { + fn check_crate_post(&mut self, ecx: &EarlyContext<'_>, _krate: &ast::Crate) { for (name, span) in self.imports.iter() { let import_path = self.import_path_mac(&name); let msg = "`macro_use` attributes are no longer needed in the Rust 2018 edition"; @@ -182,8 +181,7 @@ impl EarlyLintPass for MacroUseImports { MACRO_USE_IMPORTS, *span, msg, - // "remove the attribute and import the macro directly, try", - "", + "remove the attribute and import the macro directly, try", help, Applicability::HasPlaceholders, )