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:
bors 2017-01-22 03:42:24 +00:00
commit e5b0829bb0
38 changed files with 104 additions and 127 deletions

17
src/Cargo.lock generated
View file

@ -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",
]

View file

@ -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" }

View file

@ -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;

View file

@ -10,5 +10,3 @@ crate-type = ["dylib"]
[dependencies]
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
log = { path = "../liblog" }

View file

@ -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};

View file

@ -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;

View file

@ -10,8 +10,6 @@
//! Parsing utilities for writing procedural macros.
extern crate syntax;
use syntax::parse::{ParseSess, filemap_to_tts};
use syntax::tokenstream::TokenStream;

View file

@ -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" }

View file

@ -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;

View file

@ -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" }

View file

@ -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;

View file

@ -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" }

View file

@ -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;

View file

@ -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" }

View file

@ -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;

View file

@ -9,6 +9,4 @@ path = "lib.rs"
crate-type = ["dylib"]
[dependencies]
log = { path = "../liblog" }
serialize = { path = "../libserialize" }
syntax_pos = { path = "../libsyntax_pos" }

View file

@ -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;

View file

@ -16,4 +16,3 @@ serialize = { path = "../libserialize" }
log = { path = "../liblog" }
syntax = { path = "../libsyntax" }
syntax_pos = { path = "../libsyntax_pos" }
rustc_i128 = { path = "../librustc_i128" }

View file

@ -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";

View file

@ -37,7 +37,6 @@
#![feature(slice_patterns)]
#![feature(staged_api)]
#[macro_use]
extern crate syntax;
#[macro_use]
extern crate rustc;

View file

@ -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" }

View file

@ -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;

View file

@ -27,7 +27,6 @@
#![feature(staged_api)]
#![feature(rustc_private)]
extern crate core;
#[macro_use]
extern crate rustc;
extern crate rustc_const_eval;

View file

@ -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" }

View file

@ -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;

View file

@ -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"?

View file

@ -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(),

View file

@ -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;

View file

@ -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
},

View file

@ -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(),
}
}

View file

@ -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" }

View file

@ -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]

View file

@ -9,5 +9,4 @@ path = "lib.rs"
crate-type = ["dylib", "rlib"]
[dependencies]
log = { path = "../liblog" }
rustc_i128 = { path = "../librustc_i128" }

View file

@ -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;

View file

@ -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;

View 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() {}

View file

@ -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();

View file

@ -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 {