Auto merge of #39060 - jseyfried:improve_unused, r=nrc
Improve unused `extern crate` and unused `#[macro_use]` warnings This PR - adds `unused_imports` warnings for unused `#[macro_use] extern crate` macro imports, - improves `unused_extern_crates` warnings (avoids false negatives), and - removes unused `#[macro_use]` imports and unused `extern crate`s. r? @nrc
This commit is contained in:
commit
e5b0829bb0
38 changed files with 104 additions and 127 deletions
17
src/Cargo.lock
generated
17
src/Cargo.lock
generated
|
|
@ -212,16 +212,13 @@ dependencies = [
|
|||
"proc_macro_tokens 0.0.0",
|
||||
"rustc_plugin 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
"syntax_pos 0.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc_macro_tokens"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"log 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
"syntax_pos 0.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -240,7 +237,6 @@ name = "rustc"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"arena 0.0.0",
|
||||
"flate 0.0.0",
|
||||
"fmt_macros 0.0.0",
|
||||
"graphviz 0.0.0",
|
||||
"log 0.0.0",
|
||||
|
|
@ -310,7 +306,6 @@ dependencies = [
|
|||
"rustc_data_structures 0.0.0",
|
||||
"rustc_errors 0.0.0",
|
||||
"rustc_i128 0.0.0",
|
||||
"serialize 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
"syntax_pos 0.0.0",
|
||||
]
|
||||
|
|
@ -319,7 +314,6 @@ dependencies = [
|
|||
name = "rustc_const_math"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"log 0.0.0",
|
||||
"rustc_i128 0.0.0",
|
||||
"serialize 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
|
|
@ -339,7 +333,6 @@ name = "rustc_driver"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"arena 0.0.0",
|
||||
"flate 0.0.0",
|
||||
"graphviz 0.0.0",
|
||||
"log 0.0.0",
|
||||
"proc_macro_plugin 0.0.0",
|
||||
|
|
@ -371,8 +364,6 @@ dependencies = [
|
|||
name = "rustc_errors"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"log 0.0.0",
|
||||
"serialize 0.0.0",
|
||||
"syntax_pos 0.0.0",
|
||||
]
|
||||
|
||||
|
|
@ -388,7 +379,6 @@ dependencies = [
|
|||
"log 0.0.0",
|
||||
"rustc 0.0.0",
|
||||
"rustc_data_structures 0.0.0",
|
||||
"rustc_i128 0.0.0",
|
||||
"serialize 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
"syntax_pos 0.0.0",
|
||||
|
|
@ -443,7 +433,6 @@ dependencies = [
|
|||
"graphviz 0.0.0",
|
||||
"log 0.0.0",
|
||||
"rustc 0.0.0",
|
||||
"rustc_back 0.0.0",
|
||||
"rustc_bitflags 0.0.0",
|
||||
"rustc_const_eval 0.0.0",
|
||||
"rustc_const_math 0.0.0",
|
||||
|
|
@ -474,10 +463,8 @@ version = "0.0.0"
|
|||
name = "rustc_plugin"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"log 0.0.0",
|
||||
"rustc 0.0.0",
|
||||
"rustc_back 0.0.0",
|
||||
"rustc_bitflags 0.0.0",
|
||||
"rustc_errors 0.0.0",
|
||||
"rustc_metadata 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
|
|
@ -520,9 +507,7 @@ dependencies = [
|
|||
name = "rustc_trans"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"arena 0.0.0",
|
||||
"flate 0.0.0",
|
||||
"graphviz 0.0.0",
|
||||
"log 0.0.0",
|
||||
"rustc 0.0.0",
|
||||
"rustc_back 0.0.0",
|
||||
|
|
@ -535,7 +520,6 @@ dependencies = [
|
|||
"rustc_incremental 0.0.0",
|
||||
"rustc_llvm 0.0.0",
|
||||
"rustc_platform_intrinsics 0.0.0",
|
||||
"serialize 0.0.0",
|
||||
"syntax 0.0.0",
|
||||
"syntax_pos 0.0.0",
|
||||
]
|
||||
|
|
@ -585,7 +569,6 @@ dependencies = [
|
|||
name = "serialize"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"log 0.0.0",
|
||||
"rustc_i128 0.0.0",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -11,5 +11,4 @@ crate-type = ["dylib"]
|
|||
log = { path = "../liblog" }
|
||||
rustc_plugin = { path = "../librustc_plugin" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
proc_macro_tokens = { path = "../libproc_macro_tokens" }
|
||||
|
|
|
|||
|
|
@ -88,7 +88,6 @@
|
|||
|
||||
extern crate rustc_plugin;
|
||||
extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
extern crate proc_macro_tokens;
|
||||
#[macro_use] extern crate log;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,5 +10,3 @@ crate-type = ["dylib"]
|
|||
|
||||
[dependencies]
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
log = { path = "../liblog" }
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
|
||||
use syntax::ast::Ident;
|
||||
use syntax::codemap::DUMMY_SP;
|
||||
use syntax::parse::token::{self, Token};
|
||||
|
|
|
|||
|
|
@ -58,8 +58,6 @@
|
|||
#![feature(rustc_private)]
|
||||
|
||||
extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
#[macro_use] extern crate log;
|
||||
|
||||
pub mod build;
|
||||
pub mod parse;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@
|
|||
|
||||
//! Parsing utilities for writing procedural macros.
|
||||
|
||||
extern crate syntax;
|
||||
|
||||
use syntax::parse::{ParseSess, filemap_to_tts};
|
||||
use syntax::tokenstream::TokenStream;
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ crate-type = ["dylib"]
|
|||
|
||||
[dependencies]
|
||||
arena = { path = "../libarena" }
|
||||
flate = { path = "../libflate" }
|
||||
fmt_macros = { path = "../libfmt_macros" }
|
||||
graphviz = { path = "../libgraphviz" }
|
||||
log = { path = "../liblog" }
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#![feature(associated_consts)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(conservative_impl_trait)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
|
@ -39,11 +38,9 @@
|
|||
#![feature(slice_patterns)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
|
||||
extern crate arena;
|
||||
extern crate core;
|
||||
extern crate flate;
|
||||
extern crate fmt_macros;
|
||||
extern crate getopts;
|
||||
extern crate graphviz;
|
||||
|
|
@ -52,12 +49,11 @@ extern crate rustc_llvm as llvm;
|
|||
extern crate rustc_back;
|
||||
extern crate rustc_data_structures;
|
||||
extern crate serialize;
|
||||
extern crate collections;
|
||||
extern crate rustc_const_math;
|
||||
extern crate rustc_errors as errors;
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate syntax;
|
||||
#[macro_use] extern crate syntax_pos;
|
||||
extern crate syntax_pos;
|
||||
#[macro_use] #[no_link] extern crate rustc_bitflags;
|
||||
|
||||
extern crate serialize as rustc_serialize; // used by deriving
|
||||
|
|
@ -65,9 +61,6 @@ extern crate serialize as rustc_serialize; // used by deriving
|
|||
// SNAP:
|
||||
extern crate rustc_i128;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate test;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ crate-type = ["dylib"]
|
|||
[dependencies]
|
||||
arena = { path = "../libarena" }
|
||||
log = { path = "../liblog" }
|
||||
serialize = { path = "../libserialize" }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_back = { path = "../librustc_back" }
|
||||
rustc_const_math = { path = "../librustc_const_math" }
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ extern crate rustc_data_structures;
|
|||
extern crate rustc_errors;
|
||||
extern crate graphviz;
|
||||
extern crate syntax_pos;
|
||||
extern crate serialize as rustc_serialize; // used by deriving
|
||||
|
||||
extern crate rustc_i128;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ path = "lib.rs"
|
|||
crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
log = { path = "../liblog" }
|
||||
serialize = { path = "../libserialize" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
rustc_i128 = { path = "../librustc_i128" }
|
||||
|
|
|
|||
|
|
@ -28,8 +28,7 @@
|
|||
#![feature(const_fn)]
|
||||
#![cfg_attr(not(stage0), feature(i128))]
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate syntax;
|
||||
extern crate syntax;
|
||||
|
||||
// SNAP: remove use of this crate
|
||||
extern crate rustc_i128;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ crate-type = ["dylib"]
|
|||
|
||||
[dependencies]
|
||||
arena = { path = "../libarena" }
|
||||
flate = { path = "../libflate" }
|
||||
graphviz = { path = "../libgraphviz" }
|
||||
log = { path = "../liblog" }
|
||||
proc_macro_plugin = { path = "../libproc_macro_plugin" }
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#![feature(staged_api)]
|
||||
|
||||
extern crate arena;
|
||||
extern crate flate;
|
||||
extern crate getopts;
|
||||
extern crate graphviz;
|
||||
extern crate libc;
|
||||
|
|
@ -57,7 +56,6 @@ extern crate serialize;
|
|||
extern crate rustc_llvm as llvm;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate syntax;
|
||||
extern crate syntax_ext;
|
||||
extern crate syntax_pos;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,4 @@ path = "lib.rs"
|
|||
crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
log = { path = "../liblog" }
|
||||
serialize = { path = "../libserialize" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
|
|||
|
|
@ -23,16 +23,9 @@
|
|||
#![feature(staged_api)]
|
||||
#![feature(range_contains)]
|
||||
#![feature(libc)]
|
||||
#![feature(unicode)]
|
||||
|
||||
extern crate serialize;
|
||||
extern crate term;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
#[macro_use]
|
||||
extern crate libc;
|
||||
extern crate std_unicode;
|
||||
extern crate serialize as rustc_serialize; // used by deriving
|
||||
extern crate syntax_pos;
|
||||
|
||||
pub use emitter::ColorConfig;
|
||||
|
|
|
|||
|
|
@ -16,4 +16,3 @@ serialize = { path = "../libserialize" }
|
|||
log = { path = "../liblog" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
rustc_i128 = { path = "../librustc_i128" }
|
||||
|
|
|
|||
|
|
@ -30,11 +30,9 @@ extern crate rustc_data_structures;
|
|||
extern crate serialize as rustc_serialize;
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate syntax;
|
||||
extern crate syntax;
|
||||
extern crate syntax_pos;
|
||||
|
||||
extern crate rustc_i128;
|
||||
|
||||
const ATTR_DIRTY: &'static str = "rustc_dirty";
|
||||
const ATTR_CLEAN: &'static str = "rustc_clean";
|
||||
const ATTR_DIRTY_METADATA: &'static str = "rustc_metadata_dirty";
|
||||
|
|
|
|||
|
|
@ -37,7 +37,6 @@
|
|||
#![feature(slice_patterns)]
|
||||
#![feature(staged_api)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate syntax;
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ crate-type = ["dylib"]
|
|||
graphviz = { path = "../libgraphviz" }
|
||||
log = { path = "../liblog" }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_back = { path = "../librustc_back" }
|
||||
rustc_const_eval = { path = "../librustc_const_eval" }
|
||||
rustc_const_math = { path = "../librustc_const_math" }
|
||||
rustc_data_structures = { path = "../librustc_data_structures" }
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ extern crate graphviz as dot;
|
|||
#[macro_use]
|
||||
extern crate rustc;
|
||||
extern crate rustc_data_structures;
|
||||
extern crate rustc_back;
|
||||
#[macro_use]
|
||||
#[no_link]
|
||||
extern crate rustc_bitflags;
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
#![feature(staged_api)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
extern crate core;
|
||||
#[macro_use]
|
||||
extern crate rustc;
|
||||
extern crate rustc_const_eval;
|
||||
|
|
|
|||
|
|
@ -10,10 +10,8 @@ path = "lib.rs"
|
|||
crate-type = ["dylib"]
|
||||
|
||||
[dependencies]
|
||||
log = { path = "../liblog" }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_back = { path = "../librustc_back" }
|
||||
rustc_bitflags = { path = "../librustc_bitflags" }
|
||||
rustc_metadata = { path = "../librustc_metadata" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
|
|||
|
|
@ -63,9 +63,7 @@
|
|||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(rustc_private)]
|
||||
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] extern crate syntax;
|
||||
#[macro_use] #[no_link] extern crate rustc_bitflags;
|
||||
|
||||
extern crate rustc;
|
||||
extern crate rustc_back;
|
||||
|
|
|
|||
|
|
@ -249,6 +249,8 @@ impl<'a> Resolver<'a> {
|
|||
// n.b. we don't need to look at the path option here, because cstore already did
|
||||
let crate_id = self.session.cstore.extern_mod_stmt_cnum(item.id).unwrap();
|
||||
let module = self.get_extern_crate_root(crate_id);
|
||||
self.populate_module_if_necessary(module);
|
||||
let used = self.process_legacy_macro_imports(item, module, expansion);
|
||||
let binding =
|
||||
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.arenas);
|
||||
let directive = self.arenas.alloc_import_directive(ImportDirective {
|
||||
|
|
@ -260,11 +262,11 @@ impl<'a> Resolver<'a> {
|
|||
module_path: Vec::new(),
|
||||
vis: Cell::new(vis),
|
||||
expansion: expansion,
|
||||
used: Cell::new(used),
|
||||
});
|
||||
self.potentially_unused_imports.push(directive);
|
||||
let imported_binding = self.import(binding, directive);
|
||||
self.define(parent, ident, TypeNS, imported_binding);
|
||||
self.populate_module_if_necessary(module);
|
||||
self.process_legacy_macro_imports(item, module, expansion);
|
||||
}
|
||||
|
||||
ItemKind::Mod(..) if item.ident == keywords::Invalid.ident() => {} // Crate root
|
||||
|
|
@ -522,7 +524,6 @@ impl<'a> Resolver<'a> {
|
|||
binding: &'a NameBinding<'a>,
|
||||
span: Span,
|
||||
allow_shadowing: bool) {
|
||||
self.used_crates.insert(binding.def().def_id().krate);
|
||||
self.macro_names.insert(name);
|
||||
if self.builtin_macros.insert(name, binding).is_some() && !allow_shadowing {
|
||||
let msg = format!("`{}` is already in scope", name);
|
||||
|
|
@ -532,43 +533,61 @@ impl<'a> Resolver<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expansion: Mark) {
|
||||
// This returns true if we should consider the underlying `extern crate` to be used.
|
||||
fn process_legacy_macro_imports(&mut self, item: &Item, module: Module<'a>, expansion: Mark)
|
||||
-> bool {
|
||||
let allow_shadowing = expansion == Mark::root();
|
||||
let legacy_imports = self.legacy_macro_imports(&item.attrs);
|
||||
let cnum = module.def_id().unwrap().krate;
|
||||
let mut used = legacy_imports != LegacyMacroImports::default();
|
||||
|
||||
// `#[macro_use]` and `#[macro_reexport]` are only allowed at the crate root.
|
||||
if self.current_module.parent.is_some() && legacy_imports != LegacyMacroImports::default() {
|
||||
if self.current_module.parent.is_some() && used {
|
||||
span_err!(self.session, item.span, E0468,
|
||||
"an `extern crate` loading macros must be at the crate root");
|
||||
} else if !self.use_extern_macros &&
|
||||
self.session.cstore.dep_kind(cnum).macros_only() &&
|
||||
legacy_imports == LegacyMacroImports::default() {
|
||||
} else if !self.use_extern_macros && !used &&
|
||||
self.session.cstore.dep_kind(module.def_id().unwrap().krate).macros_only() {
|
||||
let msg = "custom derive crates and `#[no_link]` crates have no effect without \
|
||||
`#[macro_use]`";
|
||||
self.session.span_warn(item.span, msg);
|
||||
self.used_crates.insert(cnum); // Avoid the normal unused extern crate warning
|
||||
used = true; // Avoid the normal unused extern crate warning
|
||||
}
|
||||
|
||||
let (graph_root, arenas) = (self.graph_root, self.arenas);
|
||||
let macro_use_directive = |span| arenas.alloc_import_directive(ImportDirective {
|
||||
id: item.id,
|
||||
parent: graph_root,
|
||||
imported_module: Cell::new(Some(module)),
|
||||
subclass: ImportDirectiveSubclass::MacroUse,
|
||||
span: span,
|
||||
module_path: Vec::new(),
|
||||
vis: Cell::new(ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX))),
|
||||
expansion: expansion,
|
||||
used: Cell::new(false),
|
||||
});
|
||||
|
||||
if let Some(span) = legacy_imports.import_all {
|
||||
let directive = macro_use_directive(span);
|
||||
self.potentially_unused_imports.push(directive);
|
||||
module.for_each_child(|ident, ns, binding| if ns == MacroNS {
|
||||
self.legacy_import_macro(ident.name, binding, span, allow_shadowing);
|
||||
let imported_binding = self.import(binding, directive);
|
||||
self.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
|
||||
});
|
||||
} else {
|
||||
for (name, span) in legacy_imports.imports {
|
||||
let ident = Ident::with_empty_ctxt(name);
|
||||
let result = self.resolve_ident_in_module(module, ident, MacroNS, false, None);
|
||||
if let Ok(binding) = result {
|
||||
self.legacy_import_macro(name, binding, span, allow_shadowing);
|
||||
let directive = macro_use_directive(span);
|
||||
self.potentially_unused_imports.push(directive);
|
||||
let imported_binding = self.import(binding, directive);
|
||||
self.legacy_import_macro(name, imported_binding, span, allow_shadowing);
|
||||
} else {
|
||||
span_err!(self.session, span, E0469, "imported macro not found");
|
||||
}
|
||||
}
|
||||
}
|
||||
for (name, span) in legacy_imports.reexports {
|
||||
let krate = module.def_id().unwrap().krate;
|
||||
self.used_crates.insert(krate);
|
||||
self.session.cstore.export_macros(krate);
|
||||
self.session.cstore.export_macros(module.def_id().unwrap().krate);
|
||||
let ident = Ident::with_empty_ctxt(name);
|
||||
let result = self.resolve_ident_in_module(module, ident, MacroNS, false, None);
|
||||
if let Ok(binding) = result {
|
||||
|
|
@ -577,6 +596,7 @@ impl<'a> Resolver<'a> {
|
|||
span_err!(self.session, span, E0470, "reexported macro not found");
|
||||
}
|
||||
}
|
||||
used
|
||||
}
|
||||
|
||||
// does this attribute list contain "macro_use"?
|
||||
|
|
|
|||
|
|
@ -22,8 +22,9 @@
|
|||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
use Resolver;
|
||||
use resolve_imports::ImportDirectiveSubclass;
|
||||
|
||||
use rustc::lint;
|
||||
use rustc::{lint, ty};
|
||||
use rustc::util::nodemap::NodeMap;
|
||||
use syntax::ast::{self, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use syntax::visit::{self, Visitor};
|
||||
|
|
@ -86,16 +87,6 @@ impl<'a, 'b> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b> {
|
|||
}
|
||||
|
||||
match item.node {
|
||||
ast::ItemKind::ExternCrate(_) => {
|
||||
if let Some(crate_num) = self.session.cstore.extern_mod_stmt_cnum(item.id) {
|
||||
if !self.used_crates.contains(&crate_num) {
|
||||
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES,
|
||||
item.id,
|
||||
item.span,
|
||||
"unused extern crate".to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::ItemKind::Use(ref p) => {
|
||||
match p.node {
|
||||
ViewPathSimple(..) => {
|
||||
|
|
@ -124,6 +115,25 @@ impl<'a, 'b> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b> {
|
|||
}
|
||||
|
||||
pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) {
|
||||
for directive in resolver.potentially_unused_imports.iter() {
|
||||
match directive.subclass {
|
||||
_ if directive.used.get() ||
|
||||
directive.vis.get() == ty::Visibility::Public ||
|
||||
directive.span.source_equal(&DUMMY_SP) => {}
|
||||
ImportDirectiveSubclass::ExternCrate => {
|
||||
let lint = lint::builtin::UNUSED_EXTERN_CRATES;
|
||||
let msg = "unused extern crate".to_string();
|
||||
resolver.session.add_lint(lint, directive.id, directive.span, msg);
|
||||
}
|
||||
ImportDirectiveSubclass::MacroUse => {
|
||||
let lint = lint::builtin::UNUSED_IMPORTS;
|
||||
let msg = "unused `#[macro_use]` import".to_string();
|
||||
resolver.session.add_lint(lint, directive.id, directive.span, msg);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
let mut visitor = UnusedImportCheckVisitor {
|
||||
resolver: resolver,
|
||||
unused_imports: NodeMap(),
|
||||
|
|
|
|||
|
|
@ -1099,7 +1099,6 @@ pub struct Resolver<'a> {
|
|||
pub glob_map: GlobMap,
|
||||
|
||||
used_imports: FxHashSet<(NodeId, Namespace)>,
|
||||
used_crates: FxHashSet<CrateNum>,
|
||||
pub maybe_unused_trait_imports: NodeSet,
|
||||
|
||||
privacy_errors: Vec<PrivacyError<'a>>,
|
||||
|
|
@ -1130,6 +1129,8 @@ pub struct Resolver<'a> {
|
|||
|
||||
// A set of procedural macros imported by `#[macro_use]` that have already been warned about
|
||||
warned_proc_macros: FxHashSet<Name>,
|
||||
|
||||
potentially_unused_imports: Vec<&'a ImportDirective<'a>>,
|
||||
}
|
||||
|
||||
pub struct ResolverArenas<'a> {
|
||||
|
|
@ -1279,7 +1280,6 @@ impl<'a> Resolver<'a> {
|
|||
glob_map: NodeMap(),
|
||||
|
||||
used_imports: FxHashSet(),
|
||||
used_crates: FxHashSet(),
|
||||
maybe_unused_trait_imports: NodeSet(),
|
||||
|
||||
privacy_errors: Vec::new(),
|
||||
|
|
@ -1309,6 +1309,7 @@ impl<'a> Resolver<'a> {
|
|||
whitelisted_legacy_custom_derives: Vec::new(),
|
||||
proc_macro_enabled: features.proc_macro,
|
||||
warned_proc_macros: FxHashSet(),
|
||||
potentially_unused_imports: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1354,15 +1355,11 @@ impl<'a> Resolver<'a> {
|
|||
|
||||
fn record_use(&mut self, ident: Ident, ns: Namespace, binding: &'a NameBinding<'a>, span: Span)
|
||||
-> bool /* true if an error was reported */ {
|
||||
// track extern crates for unused_extern_crate lint
|
||||
if let Some(DefId { krate, .. }) = binding.module().and_then(ModuleData::def_id) {
|
||||
self.used_crates.insert(krate);
|
||||
}
|
||||
|
||||
match binding.kind {
|
||||
NameBindingKind::Import { directive, binding, ref used, legacy_self_import }
|
||||
if !used.get() => {
|
||||
used.set(true);
|
||||
directive.used.set(true);
|
||||
if legacy_self_import {
|
||||
self.warn_legacy_self_import(directive);
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -341,12 +341,15 @@ impl<'a> Resolver<'a> {
|
|||
};
|
||||
}
|
||||
|
||||
let binding = match binding {
|
||||
Some(binding) => MacroBinding::Legacy(binding),
|
||||
None => match self.builtin_macros.get(&name).cloned() {
|
||||
Some(binding) => MacroBinding::Modern(binding),
|
||||
None => return None,
|
||||
},
|
||||
let binding = if let Some(binding) = binding {
|
||||
MacroBinding::Legacy(binding)
|
||||
} else if let Some(binding) = self.builtin_macros.get(&name).cloned() {
|
||||
if !self.use_extern_macros {
|
||||
self.record_use(Ident::with_empty_ctxt(name), MacroNS, binding, DUMMY_SP);
|
||||
}
|
||||
MacroBinding::Modern(binding)
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if !self.use_extern_macros {
|
||||
|
|
@ -378,6 +381,7 @@ impl<'a> Resolver<'a> {
|
|||
let (legacy_resolution, resolution) = match (legacy_resolution, resolution) {
|
||||
(Some(legacy_resolution), Ok(resolution)) => (legacy_resolution, resolution),
|
||||
(Some(MacroBinding::Modern(binding)), Err(_)) => {
|
||||
self.record_use(ident, MacroNS, binding, span);
|
||||
self.err_if_macro_use_proc_macro(ident.name, span, binding);
|
||||
continue
|
||||
},
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ pub enum ImportDirectiveSubclass<'a> {
|
|||
// n.b. `max_vis` is only used in `finalize_import` to check for reexport errors.
|
||||
},
|
||||
ExternCrate,
|
||||
MacroUse,
|
||||
}
|
||||
|
||||
/// One import directive.
|
||||
|
|
@ -62,6 +63,7 @@ pub struct ImportDirective<'a> {
|
|||
pub span: Span,
|
||||
pub vis: Cell<ty::Visibility>,
|
||||
pub expansion: Mark,
|
||||
pub used: Cell<bool>,
|
||||
}
|
||||
|
||||
impl<'a> ImportDirective<'a> {
|
||||
|
|
@ -257,6 +259,7 @@ impl<'a> Resolver<'a> {
|
|||
id: id,
|
||||
vis: Cell::new(vis),
|
||||
expansion: expansion,
|
||||
used: Cell::new(false),
|
||||
});
|
||||
|
||||
self.indeterminate_imports.push(directive);
|
||||
|
|
@ -833,5 +836,6 @@ fn import_directive_subclass_to_string(subclass: &ImportDirectiveSubclass) -> St
|
|||
SingleImport { source, .. } => source.to_string(),
|
||||
GlobImport { .. } => "*".to_string(),
|
||||
ExternCrate => "<extern crate>".to_string(),
|
||||
MacroUse => "#[macro_use]".to_string(),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,7 @@ crate-type = ["dylib"]
|
|||
test = false
|
||||
|
||||
[dependencies]
|
||||
arena = { path = "../libarena" }
|
||||
flate = { path = "../libflate" }
|
||||
graphviz = { path = "../libgraphviz" }
|
||||
log = { path = "../liblog" }
|
||||
rustc = { path = "../librustc" }
|
||||
rustc_back = { path = "../librustc_back" }
|
||||
|
|
@ -25,6 +23,5 @@ rustc_incremental = { path = "../librustc_incremental" }
|
|||
rustc_llvm = { path = "../librustc_llvm" }
|
||||
rustc_i128 = { path = "../librustc_i128" }
|
||||
rustc_platform_intrinsics = { path = "../librustc_platform_intrinsics" }
|
||||
serialize = { path = "../libserialize" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
|
|
|||
|
|
@ -40,10 +40,7 @@
|
|||
|
||||
use rustc::dep_graph::WorkProduct;
|
||||
|
||||
extern crate arena;
|
||||
extern crate flate;
|
||||
extern crate getopts;
|
||||
extern crate graphviz;
|
||||
extern crate libc;
|
||||
#[macro_use] extern crate rustc;
|
||||
extern crate rustc_back;
|
||||
|
|
@ -51,7 +48,6 @@ extern crate rustc_data_structures;
|
|||
extern crate rustc_incremental;
|
||||
pub extern crate rustc_llvm as llvm;
|
||||
extern crate rustc_platform_intrinsics as intrinsics;
|
||||
extern crate serialize;
|
||||
extern crate rustc_const_math;
|
||||
extern crate rustc_const_eval;
|
||||
#[macro_use]
|
||||
|
|
|
|||
|
|
@ -9,5 +9,4 @@ path = "lib.rs"
|
|||
crate-type = ["dylib", "rlib"]
|
||||
|
||||
[dependencies]
|
||||
log = { path = "../liblog" }
|
||||
rustc_i128 = { path = "../librustc_i128" }
|
||||
|
|
|
|||
|
|
@ -31,17 +31,10 @@ Core encoding and decoding interfaces.
|
|||
#![feature(collections)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(enumset)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(specialization)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(unicode)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
|
||||
// test harness access
|
||||
#[cfg(test)] extern crate test;
|
||||
#[macro_use] extern crate log;
|
||||
|
||||
extern crate std_unicode;
|
||||
extern crate collections;
|
||||
|
||||
extern crate rustc_i128;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
#![feature(associated_consts)]
|
||||
#![feature(const_fn)]
|
||||
#![feature(libc)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(staged_api)]
|
||||
|
|
@ -35,10 +34,7 @@
|
|||
#![feature(rustc_diagnostic_macros)]
|
||||
#![feature(specialization)]
|
||||
|
||||
extern crate core;
|
||||
extern crate serialize;
|
||||
extern crate term;
|
||||
extern crate libc;
|
||||
#[macro_use] extern crate log;
|
||||
#[macro_use] #[no_link] extern crate rustc_bitflags;
|
||||
extern crate std_unicode;
|
||||
|
|
|
|||
21
src/test/compile-fail/imports/unused-macro-use.rs
Normal file
21
src/test/compile-fail/imports/unused-macro-use.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![deny(unused)]
|
||||
|
||||
#[macro_use] //~ ERROR unused `#[macro_use]` import
|
||||
extern crate core;
|
||||
|
||||
#[macro_use(
|
||||
panic //~ ERROR unused `#[macro_use]` import
|
||||
)]
|
||||
extern crate core as core_2;
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -26,13 +26,16 @@ extern crate rand; // no error, the use marks it as used
|
|||
|
||||
extern crate lint_unused_extern_crate as other; // no error, the use * marks it as used
|
||||
|
||||
#[macro_use] extern crate core; // no error, the `#[macro_use]` marks it as used
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use rand::isaac::IsaacRng;
|
||||
|
||||
use other::*;
|
||||
|
||||
mod foo {
|
||||
// Test that this is unused even though an earler `extern crate rand` is used.
|
||||
extern crate rand; //~ ERROR unused extern crate
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: collecs::vec::Vec<usize> = Vec::new();
|
||||
let y = foo();
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const TEST_REPOS: &'static [Test] = &[
|
|||
Test {
|
||||
name: "cargo",
|
||||
repo: "https://github.com/rust-lang/cargo",
|
||||
sha: "b7be4f2ef2cf743492edc6dfb55d087ed88f2d76",
|
||||
sha: "2324c2bbaf7fc6ea9cbdd77c034ef1af769cb617",
|
||||
lock: None,
|
||||
},
|
||||
Test {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue