@@ -21,7 +21,7 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace};
21
21
use middle:: ty:: { ExplicitSelfCategory , StaticExplicitSelfCategory } ;
22
22
use util:: nodemap:: { NodeMap , DefIdSet , FnvHashMap } ;
23
23
24
- use syntax:: ast:: { Arm , BindByRef , BindByValue , BindingMode , Block , Crate } ;
24
+ use syntax:: ast:: { Arm , BindByRef , BindByValue , BindingMode , Block , Crate , CrateNum } ;
25
25
use syntax:: ast:: { DeclItem , DefId , Expr , ExprAgain , ExprBreak , ExprField } ;
26
26
use syntax:: ast:: { ExprFnBlock , ExprForLoop , ExprLoop , ExprWhile , ExprMethodCall } ;
27
27
use syntax:: ast:: { ExprPath , ExprProc , ExprStruct , ExprUnboxedFn , FnDecl } ;
@@ -899,6 +899,7 @@ struct Resolver<'a> {
899
899
emit_errors : bool ,
900
900
901
901
used_imports : HashSet < ( NodeId , Namespace ) > ,
902
+ used_crates : HashSet < CrateNum > ,
902
903
}
903
904
904
905
struct BuildReducedGraphVisitor < ' a , ' b : ' a > {
@@ -995,6 +996,7 @@ impl<'a> Resolver<'a> {
995
996
export_map2 : RefCell :: new ( NodeMap :: new ( ) ) ,
996
997
trait_map : NodeMap :: new ( ) ,
997
998
used_imports : HashSet :: new ( ) ,
999
+ used_crates : HashSet :: new ( ) ,
998
1000
external_exports : DefIdSet :: new ( ) ,
999
1001
last_private : NodeMap :: new ( ) ,
1000
1002
@@ -2462,7 +2464,14 @@ impl<'a> Resolver<'a> {
2462
2464
debug ! ( "(resolving single import) found \
2463
2465
import in ns {:?}", namespace) ;
2464
2466
let id = import_resolution. id ( namespace) ;
2467
+ // track used imports and extern crates as well
2465
2468
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
+ }
2466
2475
return BoundResult ( target_module, bindings) ;
2467
2476
}
2468
2477
}
@@ -2505,6 +2514,11 @@ impl<'a> Resolver<'a> {
2505
2514
Some ( module) => {
2506
2515
debug ! ( "(resolving single import) found external \
2507
2516
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
+ }
2508
2522
let name_bindings =
2509
2523
Rc :: new ( Resolver :: create_name_bindings_from_module (
2510
2524
module) ) ;
@@ -3039,6 +3053,14 @@ impl<'a> Resolver<'a> {
3039
3053
( _, _) => {
3040
3054
search_module = module_def. clone ( ) ;
3041
3055
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
+
3042
3064
// Keep track of the closest
3043
3065
// private module used when
3044
3066
// resolving this import chain.
@@ -3222,7 +3244,12 @@ impl<'a> Resolver<'a> {
3222
3244
Some ( target) => {
3223
3245
debug ! ( "(resolving item in lexical scope) using \
3224
3246
import resolution") ;
3247
+ // track used imports and extern crates as well
3225
3248
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
+ }
3226
3253
return Success ( ( target, false ) ) ;
3227
3254
}
3228
3255
}
@@ -3501,7 +3528,12 @@ impl<'a> Resolver<'a> {
3501
3528
Some ( target) => {
3502
3529
debug ! ( "(resolving name in module) resolved to \
3503
3530
import") ;
3531
+ // track used imports and extern crates as well
3504
3532
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
+ }
3505
3537
return Success ( ( target, true ) ) ;
3506
3538
}
3507
3539
}
@@ -5068,7 +5100,14 @@ impl<'a> Resolver<'a> {
5068
5100
Some ( def) => {
5069
5101
// Found it.
5070
5102
let id = import_resolution. id ( namespace) ;
5103
+ // track imports and extern crates as well
5071
5104
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
+ }
5072
5111
return ImportNameDefinition ( def, LastMod ( AllPublic ) ) ;
5073
5112
}
5074
5113
None => {
@@ -5092,6 +5131,8 @@ impl<'a> Resolver<'a> {
5092
5131
match module. def_id . get ( ) {
5093
5132
None => { } // Continue.
5094
5133
Some ( def_id) => {
5134
+ // track used crates
5135
+ self . used_crates . insert ( def_id. krate ) ;
5095
5136
let lp = if module. is_public { LastMod ( AllPublic ) } else {
5096
5137
LastMod ( DependsOn ( def_id) )
5097
5138
} ;
@@ -5175,6 +5216,10 @@ impl<'a> Resolver<'a> {
5175
5216
} ,
5176
5217
_ => ( ) ,
5177
5218
}
5219
+ match containing_module. def_id . get ( ) {
5220
+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
5221
+ _ => { }
5222
+ }
5178
5223
return Some ( def) ;
5179
5224
}
5180
5225
@@ -5794,6 +5839,10 @@ impl<'a> Resolver<'a> {
5794
5839
if self . trait_item_map . borrow ( ) . contains_key ( & ( name, did) ) {
5795
5840
add_trait_info ( & mut found_traits, did, name) ;
5796
5841
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
+ }
5797
5846
}
5798
5847
}
5799
5848
@@ -5866,10 +5915,22 @@ impl<'a> Resolver<'a> {
5866
5915
if vi. span == DUMMY_SP { return }
5867
5916
5868
5917
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
+ } ,
5870
5930
ViewItemUse ( ref p) => {
5871
5931
match p. node {
5872
5932
ViewPathSimple ( _, _, id) => self . finalize_import ( id, p. span ) ,
5933
+
5873
5934
ViewPathList ( _, ref list, _) => {
5874
5935
for i in list. iter ( ) {
5875
5936
self . finalize_import ( i. node . id ( ) , i. span ) ;
0 commit comments