New lint : unused_extern_crate. #10385
This commit is contained in:
parent
805cf81b77
commit
9f8ec427e5
@ -1525,6 +1525,9 @@ impl LintPass for Stability {
|
||||
declare_lint!(pub UNUSED_IMPORTS, Warn,
|
||||
"imports that are never used")
|
||||
|
||||
declare_lint!(pub UNUSED_EXTERN_CRATE, Allow,
|
||||
"extern crates that are never used")
|
||||
|
||||
declare_lint!(pub UNNECESSARY_QUALIFICATION, Allow,
|
||||
"detects unnecessarily qualified names")
|
||||
|
||||
@ -1569,6 +1572,7 @@ impl LintPass for HardwiredLints {
|
||||
fn get_lints(&self) -> LintArray {
|
||||
lint_array!(
|
||||
UNUSED_IMPORTS,
|
||||
UNUSED_EXTERN_CRATE,
|
||||
UNNECESSARY_QUALIFICATION,
|
||||
UNRECOGNIZED_LINT,
|
||||
UNUSED_VARIABLE,
|
||||
|
@ -201,7 +201,7 @@ impl LintStore {
|
||||
|
||||
add_lint_group!(sess, "unused",
|
||||
UNUSED_IMPORTS, UNUSED_VARIABLE, DEAD_ASSIGNMENT, DEAD_CODE,
|
||||
UNUSED_MUT, UNREACHABLE_CODE)
|
||||
UNUSED_MUT, UNREACHABLE_CODE, UNUSED_EXTERN_CRATE)
|
||||
|
||||
// We have one lint pass defined in this module.
|
||||
self.register_pass(sess, false, box GatherNodeLevels as LintPassObject);
|
||||
|
@ -21,7 +21,7 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace};
|
||||
use middle::ty::{ExplicitSelfCategory, StaticExplicitSelfCategory};
|
||||
use util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
|
||||
|
||||
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate};
|
||||
use syntax::ast::{Arm, BindByRef, BindByValue, BindingMode, Block, Crate, CrateNum};
|
||||
use syntax::ast::{DeclItem, DefId, Expr, ExprAgain, ExprBreak, ExprField};
|
||||
use syntax::ast::{ExprFnBlock, ExprForLoop, ExprLoop, ExprWhile, ExprMethodCall};
|
||||
use syntax::ast::{ExprPath, ExprProc, ExprStruct, ExprUnboxedFn, FnDecl};
|
||||
@ -899,6 +899,7 @@ struct Resolver<'a> {
|
||||
emit_errors: bool,
|
||||
|
||||
used_imports: HashSet<(NodeId, Namespace)>,
|
||||
used_crates: HashSet<CrateNum>,
|
||||
}
|
||||
|
||||
struct BuildReducedGraphVisitor<'a, 'b:'a> {
|
||||
@ -987,6 +988,7 @@ impl<'a> Resolver<'a> {
|
||||
export_map2: RefCell::new(NodeMap::new()),
|
||||
trait_map: NodeMap::new(),
|
||||
used_imports: HashSet::new(),
|
||||
used_crates: HashSet::new(),
|
||||
external_exports: DefIdSet::new(),
|
||||
last_private: NodeMap::new(),
|
||||
|
||||
@ -2453,7 +2455,14 @@ impl<'a> Resolver<'a> {
|
||||
debug!("(resolving single import) found \
|
||||
import in ns {:?}", namespace);
|
||||
let id = import_resolution.id(namespace);
|
||||
// track used imports and extern crates as well
|
||||
this.used_imports.insert((id, namespace));
|
||||
match target_module.def_id.get() {
|
||||
Some(DefId{krate: kid, ..}) => {
|
||||
this.used_crates.insert(kid);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
return BoundResult(target_module, bindings);
|
||||
}
|
||||
}
|
||||
@ -2496,6 +2505,11 @@ impl<'a> Resolver<'a> {
|
||||
Some(module) => {
|
||||
debug!("(resolving single import) found external \
|
||||
module");
|
||||
// track the module as used.
|
||||
match module.def_id.get() {
|
||||
Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
|
||||
_ => {}
|
||||
}
|
||||
let name_bindings =
|
||||
Rc::new(Resolver::create_name_bindings_from_module(
|
||||
module));
|
||||
@ -3030,6 +3044,14 @@ impl<'a> Resolver<'a> {
|
||||
(_, _) => {
|
||||
search_module = module_def.clone();
|
||||
|
||||
// track extern crates for unused_extern_crate lint
|
||||
match module_def.def_id.get() {
|
||||
Some(did) => {
|
||||
self.used_crates.insert(did.krate);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// Keep track of the closest
|
||||
// private module used when
|
||||
// resolving this import chain.
|
||||
@ -3213,7 +3235,12 @@ impl<'a> Resolver<'a> {
|
||||
Some(target) => {
|
||||
debug!("(resolving item in lexical scope) using \
|
||||
import resolution");
|
||||
// track used imports and extern crates as well
|
||||
self.used_imports.insert((import_resolution.id(namespace), namespace));
|
||||
match target.target_module.def_id.get() {
|
||||
Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
|
||||
_ => {}
|
||||
}
|
||||
return Success((target, false));
|
||||
}
|
||||
}
|
||||
@ -3492,7 +3519,12 @@ impl<'a> Resolver<'a> {
|
||||
Some(target) => {
|
||||
debug!("(resolving name in module) resolved to \
|
||||
import");
|
||||
// track used imports and extern crates as well
|
||||
self.used_imports.insert((import_resolution.id(namespace), namespace));
|
||||
match target.target_module.def_id.get() {
|
||||
Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
|
||||
_ => {}
|
||||
}
|
||||
return Success((target, true));
|
||||
}
|
||||
}
|
||||
@ -5061,7 +5093,14 @@ impl<'a> Resolver<'a> {
|
||||
Some(def) => {
|
||||
// Found it.
|
||||
let id = import_resolution.id(namespace);
|
||||
// track imports and extern crates as well
|
||||
self.used_imports.insert((id, namespace));
|
||||
match target.target_module.def_id.get() {
|
||||
Some(DefId{krate: kid, ..}) => {
|
||||
self.used_crates.insert(kid);
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
return ImportNameDefinition(def, LastMod(AllPublic));
|
||||
}
|
||||
None => {
|
||||
@ -5085,6 +5124,8 @@ impl<'a> Resolver<'a> {
|
||||
match module.def_id.get() {
|
||||
None => {} // Continue.
|
||||
Some(def_id) => {
|
||||
// track used crates
|
||||
self.used_crates.insert(def_id.krate);
|
||||
let lp = if module.is_public {LastMod(AllPublic)} else {
|
||||
LastMod(DependsOn(def_id))
|
||||
};
|
||||
@ -5168,6 +5209,10 @@ impl<'a> Resolver<'a> {
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
match containing_module.def_id.get() {
|
||||
Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
|
||||
_ => {}
|
||||
}
|
||||
return Some(def);
|
||||
}
|
||||
|
||||
@ -5787,6 +5832,10 @@ impl<'a> Resolver<'a> {
|
||||
if self.trait_item_map.borrow().contains_key(&(name, did)) {
|
||||
add_trait_info(&mut found_traits, did, name);
|
||||
self.used_imports.insert((import.type_id, TypeNS));
|
||||
match target.target_module.def_id.get() {
|
||||
Some(DefId{krate: kid, ..}) => { self.used_crates.insert(kid); },
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5859,10 +5908,22 @@ impl<'a> Resolver<'a> {
|
||||
if vi.span == DUMMY_SP { return }
|
||||
|
||||
match vi.node {
|
||||
ViewItemExternCrate(..) => {} // ignore
|
||||
ViewItemExternCrate(_, _, id) => {
|
||||
match self.session.cstore.find_extern_mod_stmt_cnum(id)
|
||||
{
|
||||
Some(crate_num) => if !self.used_crates.contains(&crate_num) {
|
||||
self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATE,
|
||||
id,
|
||||
vi.span,
|
||||
"unused extern crate".to_string());
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
ViewItemUse(ref p) => {
|
||||
match p.node {
|
||||
ViewPathSimple(_, _, id) => self.finalize_import(id, p.span),
|
||||
|
||||
ViewPathList(_, ref list, _) => {
|
||||
for i in list.iter() {
|
||||
self.finalize_import(i.node.id(), i.span);
|
||||
|
32
src/test/compile-fail/lint-unused-extern-crate.rs
Normal file
32
src/test/compile-fail/lint-unused-extern-crate.rs
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright 2014 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.
|
||||
|
||||
#![feature(globs)]
|
||||
#![deny(unused_extern_crate)]
|
||||
#![allow(unused_variable)]
|
||||
|
||||
extern crate libc; //~ ERROR: unused extern crate
|
||||
|
||||
extern crate "collections" as collecs; // no error, it is used
|
||||
|
||||
extern crate rand; // no error, the use marks it as used
|
||||
// even if imported objects aren't used
|
||||
|
||||
extern crate time; // no error, the use * marks it as used
|
||||
|
||||
#[allow(unused_imports)]
|
||||
use rand::isaac::IsaacRng;
|
||||
|
||||
use time::*;
|
||||
|
||||
fn main() {
|
||||
let x: collecs::vec::Vec<uint> = Vec::new();
|
||||
let y = now();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user