@@ -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 > {
@@ -987,6 +988,7 @@ impl<'a> Resolver<'a> {
987
988
export_map2 : RefCell :: new ( NodeMap :: new ( ) ) ,
988
989
trait_map : NodeMap :: new ( ) ,
989
990
used_imports : HashSet :: new ( ) ,
991
+ used_crates : HashSet :: new ( ) ,
990
992
external_exports : DefIdSet :: new ( ) ,
991
993
last_private : NodeMap :: new ( ) ,
992
994
@@ -2453,7 +2455,14 @@ impl<'a> Resolver<'a> {
2453
2455
debug ! ( "(resolving single import) found \
2454
2456
import in ns {:?}", namespace) ;
2455
2457
let id = import_resolution. id ( namespace) ;
2458
+ // track used imports and extern crates as well
2456
2459
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
+ }
2457
2466
return BoundResult ( target_module, bindings) ;
2458
2467
}
2459
2468
}
@@ -2496,6 +2505,11 @@ impl<'a> Resolver<'a> {
2496
2505
Some ( module) => {
2497
2506
debug ! ( "(resolving single import) found external \
2498
2507
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
+ }
2499
2513
let name_bindings =
2500
2514
Rc :: new ( Resolver :: create_name_bindings_from_module (
2501
2515
module) ) ;
@@ -3030,6 +3044,14 @@ impl<'a> Resolver<'a> {
3030
3044
( _, _) => {
3031
3045
search_module = module_def. clone ( ) ;
3032
3046
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
+
3033
3055
// Keep track of the closest
3034
3056
// private module used when
3035
3057
// resolving this import chain.
@@ -3213,7 +3235,12 @@ impl<'a> Resolver<'a> {
3213
3235
Some ( target) => {
3214
3236
debug ! ( "(resolving item in lexical scope) using \
3215
3237
import resolution") ;
3238
+ // track used imports and extern crates as well
3216
3239
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
+ }
3217
3244
return Success ( ( target, false ) ) ;
3218
3245
}
3219
3246
}
@@ -3492,7 +3519,12 @@ impl<'a> Resolver<'a> {
3492
3519
Some ( target) => {
3493
3520
debug ! ( "(resolving name in module) resolved to \
3494
3521
import") ;
3522
+ // track used imports and extern crates as well
3495
3523
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
+ }
3496
3528
return Success ( ( target, true ) ) ;
3497
3529
}
3498
3530
}
@@ -5061,7 +5093,14 @@ impl<'a> Resolver<'a> {
5061
5093
Some ( def) => {
5062
5094
// Found it.
5063
5095
let id = import_resolution. id ( namespace) ;
5096
+ // track imports and extern crates as well
5064
5097
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
+ }
5065
5104
return ImportNameDefinition ( def, LastMod ( AllPublic ) ) ;
5066
5105
}
5067
5106
None => {
@@ -5085,6 +5124,8 @@ impl<'a> Resolver<'a> {
5085
5124
match module. def_id . get ( ) {
5086
5125
None => { } // Continue.
5087
5126
Some ( def_id) => {
5127
+ // track used crates
5128
+ self . used_crates . insert ( def_id. krate ) ;
5088
5129
let lp = if module. is_public { LastMod ( AllPublic ) } else {
5089
5130
LastMod ( DependsOn ( def_id) )
5090
5131
} ;
@@ -5168,6 +5209,10 @@ impl<'a> Resolver<'a> {
5168
5209
} ,
5169
5210
_ => ( ) ,
5170
5211
}
5212
+ match containing_module. def_id . get ( ) {
5213
+ Some ( DefId { krate : kid, ..} ) => { self . used_crates . insert ( kid) ; } ,
5214
+ _ => { }
5215
+ }
5171
5216
return Some ( def) ;
5172
5217
}
5173
5218
@@ -5787,6 +5832,10 @@ impl<'a> Resolver<'a> {
5787
5832
if self . trait_item_map . borrow ( ) . contains_key ( & ( name, did) ) {
5788
5833
add_trait_info ( & mut found_traits, did, name) ;
5789
5834
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
+ }
5790
5839
}
5791
5840
}
5792
5841
@@ -5859,10 +5908,22 @@ impl<'a> Resolver<'a> {
5859
5908
if vi. span == DUMMY_SP { return }
5860
5909
5861
5910
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
+ } ,
5863
5923
ViewItemUse ( ref p) => {
5864
5924
match p. node {
5865
5925
ViewPathSimple ( _, _, id) => self . finalize_import ( id, p. span ) ,
5926
+
5866
5927
ViewPathList ( _, ref list, _) => {
5867
5928
for i in list. iter ( ) {
5868
5929
self . finalize_import ( i. node . id ( ) , i. span ) ;
0 commit comments