@@ -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 > {
@@ -987,6 +988,7 @@ impl<'a> Resolver<'a> {
987988 export_map2 : RefCell :: new ( NodeMap :: new ( ) ) ,
988989 trait_map : NodeMap :: new ( ) ,
989990 used_imports : HashSet :: new ( ) ,
991+ used_crates : HashSet :: new ( ) ,
990992 external_exports : DefIdSet :: new ( ) ,
991993 last_private : NodeMap :: new ( ) ,
992994
@@ -2453,7 +2455,14 @@ impl<'a> Resolver<'a> {
24532455 debug ! ( "(resolving single import) found \
24542456 import in ns {:?}", namespace) ;
24552457 let id = import_resolution. id ( namespace) ;
2458+ // track used imports and extern crates as well
24562459 this. used_imports . insert ( ( id, namespace) ) ;
2460+ match target_module. def_id . get ( ) {
2461+ Some ( DefId { krate : kid, ..} ) => {
2462+ this. used_crates . insert ( kid) ;
2463+ } ,
2464+ _ => { }
2465+ }
24572466 return BoundResult ( target_module, bindings) ;
24582467 }
24592468 }
@@ -2496,6 +2505,11 @@ impl<'a> Resolver<'a> {
24962505 Some ( module) => {
24972506 debug ! ( "(resolving single import) found external \
24982507 module") ;
2508+ // track the module as used.
2509+ match module. def_id . get ( ) {
2510+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
2511+ _ => { }
2512+ }
24992513 let name_bindings =
25002514 Rc :: new ( Resolver :: create_name_bindings_from_module (
25012515 module) ) ;
@@ -3030,6 +3044,14 @@ impl<'a> Resolver<'a> {
30303044 ( _, _) => {
30313045 search_module = module_def. clone ( ) ;
30323046
3047+ // track extern crates for unused_extern_crate lint
3048+ match module_def. def_id . get ( ) {
3049+ Some ( did) => {
3050+ self . used_crates . insert ( did. krate ) ;
3051+ }
3052+ _ => { }
3053+ }
3054+
30333055 // Keep track of the closest
30343056 // private module used when
30353057 // resolving this import chain.
@@ -3213,7 +3235,12 @@ impl<'a> Resolver<'a> {
32133235 Some ( target) => {
32143236 debug ! ( "(resolving item in lexical scope) using \
32153237 import resolution") ;
3238+ // track used imports and extern crates as well
32163239 self . used_imports . insert ( ( import_resolution. id ( namespace) , namespace) ) ;
3240+ match target. target_module . def_id . get ( ) {
3241+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
3242+ _ => { }
3243+ }
32173244 return Success ( ( target, false ) ) ;
32183245 }
32193246 }
@@ -3492,7 +3519,12 @@ impl<'a> Resolver<'a> {
34923519 Some ( target) => {
34933520 debug ! ( "(resolving name in module) resolved to \
34943521 import") ;
3522+ // track used imports and extern crates as well
34953523 self . used_imports . insert ( ( import_resolution. id ( namespace) , namespace) ) ;
3524+ match target. target_module . def_id . get ( ) {
3525+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
3526+ _ => { }
3527+ }
34963528 return Success ( ( target, true ) ) ;
34973529 }
34983530 }
@@ -5061,7 +5093,14 @@ impl<'a> Resolver<'a> {
50615093 Some ( def) => {
50625094 // Found it.
50635095 let id = import_resolution. id ( namespace) ;
5096+ // track imports and extern crates as well
50645097 self . used_imports . insert ( ( id, namespace) ) ;
5098+ match target. target_module . def_id . get ( ) {
5099+ Some ( DefId { krate : kid, ..} ) => {
5100+ self . used_crates . insert ( kid) ;
5101+ } ,
5102+ _ => { }
5103+ }
50655104 return ImportNameDefinition ( def, LastMod ( AllPublic ) ) ;
50665105 }
50675106 None => {
@@ -5085,6 +5124,8 @@ impl<'a> Resolver<'a> {
50855124 match module. def_id . get ( ) {
50865125 None => { } // Continue.
50875126 Some ( def_id) => {
5127+ // track used crates
5128+ self . used_crates . insert ( def_id. krate ) ;
50885129 let lp = if module. is_public { LastMod ( AllPublic ) } else {
50895130 LastMod ( DependsOn ( def_id) )
50905131 } ;
@@ -5168,6 +5209,10 @@ impl<'a> Resolver<'a> {
51685209 } ,
51695210 _ => ( ) ,
51705211 }
5212+ match containing_module. def_id . get ( ) {
5213+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
5214+ _ => { }
5215+ }
51715216 return Some ( def) ;
51725217 }
51735218
@@ -5787,6 +5832,10 @@ impl<'a> Resolver<'a> {
57875832 if self . trait_item_map . borrow ( ) . contains_key ( & ( name, did) ) {
57885833 add_trait_info ( & mut found_traits, did, name) ;
57895834 self . used_imports . insert ( ( import. type_id , TypeNS ) ) ;
5835+ match target. target_module . def_id . get ( ) {
5836+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
5837+ _ => { }
5838+ }
57905839 }
57915840 }
57925841
@@ -5859,10 +5908,22 @@ impl<'a> Resolver<'a> {
58595908 if vi. span == DUMMY_SP { return }
58605909
58615910 match vi. node {
5862- ViewItemExternCrate ( ..) => { } // ignore
5911+ ViewItemExternCrate ( _, _, id) => {
5912+ match self . session . cstore . find_extern_mod_stmt_cnum ( id)
5913+ {
5914+ Some ( crate_num) => if !self . used_crates . contains ( & crate_num) {
5915+ self . session . add_lint ( lint:: builtin:: UNUSED_EXTERN_CRATE ,
5916+ id,
5917+ vi. span ,
5918+ "unused extern crate" . to_string ( ) ) ;
5919+ } ,
5920+ _ => { }
5921+ }
5922+ } ,
58635923 ViewItemUse ( ref p) => {
58645924 match p. node {
58655925 ViewPathSimple ( _, _, id) => self . finalize_import ( id, p. span ) ,
5926+
58665927 ViewPathList ( _, ref list, _) => {
58675928 for i in list. iter ( ) {
58685929 self . finalize_import ( i. node . id ( ) , i. span ) ;
0 commit comments