warn on macro_use attr

cargo dev update lints

use if_chain

clean up alot, span_lint_and_sugg

find imported macros for sugg
This commit is contained in:
Devin R 2020-02-26 07:40:31 -05:00
parent ff0993c5e9
commit a4b8bb88f2
5 changed files with 80 additions and 10 deletions

View File

@ -1,10 +1,11 @@
use crate::utils::{snippet, span_lint_and_sugg};
use crate::utils::{snippet, span_lint_and_sugg, in_macro};
use if_chain::if_chain;
use rustc_ast::ast;
use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Applicability;
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::edition::Edition;
use rustc_session::{impl_lint_pass, declare_tool_lint};
use rustc_span::{edition::Edition, Span};
declare_clippy_lint! {
/// **What it does:** Checks for `#[macro_use] use...`.
@ -12,21 +13,27 @@ declare_clippy_lint! {
/// **Why is this bad?** Since the Rust 2018 edition you can import
/// macro's directly, this is considered idiomatic.
///
/// **Known problems:** This lint does not generate an auto-applicable suggestion.
/// **Known problems:** None.
///
/// **Example:**
/// ```rust
/// #[macro_use]
/// use lazy_static;
/// ```
pub MACRO_USE_IMPORTS,
pub MACRO_USE_IMPORT,
pedantic,
"#[macro_use] is no longer needed"
}
declare_lint_pass!(MacroUseImports => [MACRO_USE_IMPORTS]);
#[derive(Default)]
pub struct MacroUseImport {
collected: FxHashSet<Span>,
}
impl_lint_pass!(MacroUseImport => [MACRO_USE_IMPORT]);
impl EarlyLintPass for MacroUseImport {
impl EarlyLintPass for MacroUseImports {
fn check_item(&mut self, ecx: &EarlyContext<'_>, item: &ast::Item) {
if_chain! {
if ecx.sess.opts.edition == Edition::Edition2018;
@ -36,18 +43,59 @@ impl EarlyLintPass for MacroUseImports {
.iter()
.find(|attr| attr.ident().map(|s| s.to_string()) == Some("macro_use".to_string()));
then {
let import_path = snippet(ecx, use_tree.span, "_");
let mac_names = find_used_macros(ecx, &import_path);
let msg = "`macro_use` attributes are no longer needed in the Rust 2018 edition";
let help = format!("use {}::<macro name>", snippet(ecx, use_tree.span, "_"));
let help = format!("use {}::<macro name>", import_path);
span_lint_and_sugg(
ecx,
MACRO_USE_IMPORTS,
MACRO_USE_IMPORT,
mac_attr.span,
msg,
"remove the attribute and import the macro directly, try",
// "remove the attribute and import the macro directly, try",
"",
help,
Applicability::HasPlaceholders,
);
}
}
}
fn check_expr(&mut self, ecx: &EarlyContext<'_>, expr: &ast::Expr) {
if in_macro(expr.span) {
let name = snippet(ecx, ecx.sess.source_map().span_until_char(expr.span.source_callsite(), '!'), "_");
if let Some(callee) = expr.span.source_callee() {
if self.collected.insert(callee.def_site) {
println!("EXPR {:#?}", name);
}
}
}
}
fn check_stmt(&mut self, ecx: &EarlyContext<'_>, stmt: &ast::Stmt) {
if in_macro(stmt.span) {
let name = snippet(ecx, ecx.sess.source_map().span_until_char(stmt.span.source_callsite(), '!'), "_");
if let Some(callee) = stmt.span.source_callee() {
println!("EXPR {:#?}", name);
}
}
}
fn check_pat(&mut self, ecx: &EarlyContext<'_>, pat: &ast::Pat) {
if in_macro(pat.span) {
let name = snippet(ecx, ecx.sess.source_map().span_until_char(pat.span.source_callsite(), '!'), "_");
if let Some(callee) = pat.span.source_callee() {
println!("EXPR {:#?}", name);
}
}
}
}
fn find_used_macros(ecx: &EarlyContext<'_>, path: &str) {
for it in ecx.krate.module.items.iter() {
if in_macro(it.span) {
// println!("{:#?}", it)
}
}
for x in ecx.sess.imported_macro_spans.borrow().iter() {
// println!("{:?}", x);
}
}

BIN
macro_use_import Executable file

Binary file not shown.

View File

@ -0,0 +1,12 @@
// compile-flags: --edition 2018
#![warn(clippy::macro_use_import)]
use std::collections::HashMap;
#[macro_use]
use std::prelude;
fn main() {
let _ = HashMap::<u8, u8>::new();
serde_if_integer128!("");
println!();
}

View File

@ -0,0 +1,10 @@
error: `macro_use` attributes are no longer needed in the Rust 2018 edition
--> $DIR/macro_use_import.rs:5:1
|
LL | #[macro_use]
| ^^^^^^^^^^^^ help: remove the attribute and import the macro directly, try: `use std::prelude::<macro name>`
|
= note: `-D clippy::macro-use-import` implied by `-D warnings`
error: aborting due to previous error

View File