@@ -21,7 +21,7 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace};
2121use middle:: ty:: { ExplicitSelfCategory , StaticExplicitSelfCategory } ;
2222use util:: nodemap:: { NodeMap , DefIdSet , FnvHashMap } ;
2323
24- use syntax:: ast:: { Arm , BindByRef , BindByValue , BindingMode , Block , Crate } ;
24+ use syntax:: ast:: { Arm , BindByRef , BindByValue , BindingMode , Block , Crate , CrateNum } ;
2525use syntax:: ast:: { DeclItem , DefId , Expr , ExprAgain , ExprBreak , ExprField } ;
2626use syntax:: ast:: { ExprFnBlock , ExprForLoop , ExprLoop , ExprWhile , ExprMethodCall } ;
2727use syntax:: ast:: { ExprPath , ExprProc , ExprStruct , ExprUnboxedFn , FnDecl } ;
@@ -899,6 +899,7 @@ struct Resolver<'a> {
899899 emit_errors : bool ,
900900
901901 used_imports : HashSet < ( NodeId , Namespace ) > ,
902+ used_crates : HashSet < CrateNum > ,
902903}
903904
904905struct BuildReducedGraphVisitor < ' a , ' b : ' a > {
@@ -995,6 +996,7 @@ impl<'a> Resolver<'a> {
995996 export_map2 : RefCell :: new ( NodeMap :: new ( ) ) ,
996997 trait_map : NodeMap :: new ( ) ,
997998 used_imports : HashSet :: new ( ) ,
999+ used_crates : HashSet :: new ( ) ,
9981000 external_exports : DefIdSet :: new ( ) ,
9991001 last_private : NodeMap :: new ( ) ,
10001002
@@ -2462,7 +2464,14 @@ impl<'a> Resolver<'a> {
24622464 debug ! ( "(resolving single import) found \
24632465 import in ns {:?}", namespace) ;
24642466 let id = import_resolution. id ( namespace) ;
2467+ // track used imports and extern crates as well
24652468 this. used_imports . insert ( ( id, namespace) ) ;
2469+ match target_module. def_id . get ( ) {
2470+ Some ( DefId { krate : kid, ..} ) => {
2471+ this. used_crates . insert ( kid) ;
2472+ } ,
2473+ _ => { }
2474+ }
24662475 return BoundResult ( target_module, bindings) ;
24672476 }
24682477 }
@@ -2505,6 +2514,11 @@ impl<'a> Resolver<'a> {
25052514 Some ( module) => {
25062515 debug ! ( "(resolving single import) found external \
25072516 module") ;
2517+ // track the module as used.
2518+ match module. def_id . get ( ) {
2519+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
2520+ _ => { }
2521+ }
25082522 let name_bindings =
25092523 Rc :: new ( Resolver :: create_name_bindings_from_module (
25102524 module) ) ;
@@ -3039,6 +3053,14 @@ impl<'a> Resolver<'a> {
30393053 ( _, _) => {
30403054 search_module = module_def. clone ( ) ;
30413055
3056+ // track extern crates for unused_extern_crate lint
3057+ match module_def. def_id . get ( ) {
3058+ Some ( did) => {
3059+ self . used_crates . insert ( did. krate ) ;
3060+ }
3061+ _ => { }
3062+ }
3063+
30423064 // Keep track of the closest
30433065 // private module used when
30443066 // resolving this import chain.
@@ -3222,7 +3244,12 @@ impl<'a> Resolver<'a> {
32223244 Some ( target) => {
32233245 debug ! ( "(resolving item in lexical scope) using \
32243246 import resolution") ;
3247+ // track used imports and extern crates as well
32253248 self . used_imports . insert ( ( import_resolution. id ( namespace) , namespace) ) ;
3249+ match target. target_module . def_id . get ( ) {
3250+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
3251+ _ => { }
3252+ }
32263253 return Success ( ( target, false ) ) ;
32273254 }
32283255 }
@@ -3501,7 +3528,12 @@ impl<'a> Resolver<'a> {
35013528 Some ( target) => {
35023529 debug ! ( "(resolving name in module) resolved to \
35033530 import") ;
3531+ // track used imports and extern crates as well
35043532 self . used_imports . insert ( ( import_resolution. id ( namespace) , namespace) ) ;
3533+ match target. target_module . def_id . get ( ) {
3534+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
3535+ _ => { }
3536+ }
35053537 return Success ( ( target, true ) ) ;
35063538 }
35073539 }
@@ -5068,7 +5100,14 @@ impl<'a> Resolver<'a> {
50685100 Some ( def) => {
50695101 // Found it.
50705102 let id = import_resolution. id ( namespace) ;
5103+ // track imports and extern crates as well
50715104 self . used_imports . insert ( ( id, namespace) ) ;
5105+ match target. target_module . def_id . get ( ) {
5106+ Some ( DefId { krate : kid, ..} ) => {
5107+ self . used_crates . insert ( kid) ;
5108+ } ,
5109+ _ => { }
5110+ }
50725111 return ImportNameDefinition ( def, LastMod ( AllPublic ) ) ;
50735112 }
50745113 None => {
@@ -5092,6 +5131,8 @@ impl<'a> Resolver<'a> {
50925131 match module. def_id . get ( ) {
50935132 None => { } // Continue.
50945133 Some ( def_id) => {
5134+ // track used crates
5135+ self . used_crates . insert ( def_id. krate ) ;
50955136 let lp = if module. is_public { LastMod ( AllPublic ) } else {
50965137 LastMod ( DependsOn ( def_id) )
50975138 } ;
@@ -5175,6 +5216,10 @@ impl<'a> Resolver<'a> {
51755216 } ,
51765217 _ => ( ) ,
51775218 }
5219+ match containing_module. def_id . get ( ) {
5220+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
5221+ _ => { }
5222+ }
51785223 return Some ( def) ;
51795224 }
51805225
@@ -5794,6 +5839,10 @@ impl<'a> Resolver<'a> {
57945839 if self . trait_item_map . borrow ( ) . contains_key ( & ( name, did) ) {
57955840 add_trait_info ( & mut found_traits, did, name) ;
57965841 self . used_imports . insert ( ( import. type_id , TypeNS ) ) ;
5842+ match target. target_module . def_id . get ( ) {
5843+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
5844+ _ => { }
5845+ }
57975846 }
57985847 }
57995848
@@ -5866,10 +5915,22 @@ impl<'a> Resolver<'a> {
58665915 if vi. span == DUMMY_SP { return }
58675916
58685917 match vi. node {
5869- ViewItemExternCrate ( ..) => { } // ignore
5918+ ViewItemExternCrate ( _, _, id) => {
5919+ match self . session . cstore . find_extern_mod_stmt_cnum ( id)
5920+ {
5921+ Some ( crate_num) => if !self . used_crates . contains ( & crate_num) {
5922+ self . session . add_lint ( lint:: builtin:: UNUSED_EXTERN_CRATE ,
5923+ id,
5924+ vi. span ,
5925+ "unused extern crate" . to_string ( ) ) ;
5926+ } ,
5927+ _ => { }
5928+ }
5929+ } ,
58705930 ViewItemUse ( ref p) => {
58715931 match p. node {
58725932 ViewPathSimple ( _, _, id) => self . finalize_import ( id, p. span ) ,
5933+
58735934 ViewPathList ( _, ref list, _) => {
58745935 for i in list. iter ( ) {
58755936 self . finalize_import ( i. node . id ( ) , i. span ) ;
0 commit comments