@@ -53,8 +53,8 @@ use rustc::hir::def_id::DefId;
53
53
use rustc:: hir:: pat_util:: pat_bindings;
54
54
use rustc:: ty;
55
55
use rustc:: ty:: subst:: { ParamSpace , FnSpace , TypeSpace } ;
56
- use rustc:: hir:: { Freevar , FreevarMap , TraitMap , GlobMap } ;
57
- use rustc:: util:: nodemap:: { NodeMap , FnvHashMap , FnvHashSet } ;
56
+ use rustc:: hir:: { Freevar , FreevarMap , TraitCandidate , TraitMap , GlobMap } ;
57
+ use rustc:: util:: nodemap:: { NodeMap , NodeSet , FnvHashMap , FnvHashSet } ;
58
58
59
59
use syntax:: ast:: { self , FloatTy } ;
60
60
use syntax:: ast:: { CRATE_NODE_ID , Name , NodeId , CrateNum , IntTy , UintTy } ;
@@ -1091,6 +1091,7 @@ pub struct Resolver<'a, 'tcx: 'a> {
1091
1091
1092
1092
used_imports : HashSet < ( NodeId , Namespace ) > ,
1093
1093
used_crates : HashSet < CrateNum > ,
1094
+ maybe_unused_trait_imports : NodeSet ,
1094
1095
1095
1096
// Callback function for intercepting walks
1096
1097
callback : Option < Box < Fn ( hir_map:: Node , & mut bool ) -> bool > > ,
@@ -1181,13 +1182,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1181
1182
export_map : NodeMap ( ) ,
1182
1183
trait_map : NodeMap ( ) ,
1183
1184
module_map : NodeMap ( ) ,
1184
- used_imports : HashSet :: new ( ) ,
1185
- used_crates : HashSet :: new ( ) ,
1186
1185
1187
1186
emit_errors : true ,
1188
1187
make_glob_map : make_glob_map == MakeGlobMap :: Yes ,
1189
1188
glob_map : NodeMap ( ) ,
1190
1189
1190
+ used_imports : HashSet :: new ( ) ,
1191
+ used_crates : HashSet :: new ( ) ,
1192
+ maybe_unused_trait_imports : NodeSet ( ) ,
1193
+
1191
1194
callback : None ,
1192
1195
resolved : false ,
1193
1196
privacy_errors : Vec :: new ( ) ,
@@ -1230,7 +1233,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1230
1233
}
1231
1234
1232
1235
#[ inline]
1233
- fn record_use ( & mut self , name : Name , ns : Namespace , binding : & ' a NameBinding < ' a > ) {
1236
+ fn record_use ( & mut self , name : Name , binding : & ' a NameBinding < ' a > ) {
1234
1237
// track extern crates for unused_extern_crate lint
1235
1238
if let Some ( DefId { krate, .. } ) = binding. module ( ) . and_then ( ModuleS :: def_id) {
1236
1239
self . used_crates . insert ( krate) ;
@@ -1242,7 +1245,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1242
1245
_ => return ,
1243
1246
} ;
1244
1247
1245
- self . used_imports . insert ( ( directive. id , ns) ) ;
1246
1248
if let Some ( error) = privacy_error. as_ref ( ) {
1247
1249
self . privacy_errors . push ( ( * * error) . clone ( ) ) ;
1248
1250
}
@@ -1553,7 +1555,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1553
1555
false => module. resolve_name ( name, namespace, false ) ,
1554
1556
} . and_then ( |binding| {
1555
1557
if record_used {
1556
- self . record_use ( name, namespace, binding) ;
1558
+ if let NameBindingKind :: Import { directive, .. } = binding. kind {
1559
+ self . used_imports . insert ( ( directive. id , namespace) ) ;
1560
+ }
1561
+ self . record_use ( name, binding) ;
1557
1562
}
1558
1563
Success ( binding)
1559
1564
} )
@@ -3215,21 +3220,27 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3215
3220
}
3216
3221
}
3217
3222
3218
- fn get_traits_containing_item ( & mut self , name : Name ) -> Vec < DefId > {
3223
+ fn get_traits_containing_item ( & mut self , name : Name ) -> Vec < TraitCandidate > {
3219
3224
debug ! ( "(getting traits containing item) looking for '{}'" , name) ;
3220
3225
3221
- fn add_trait_info ( found_traits : & mut Vec < DefId > , trait_def_id : DefId , name : Name ) {
3226
+ fn add_trait_info ( found_traits : & mut Vec < TraitCandidate > ,
3227
+ trait_def_id : DefId ,
3228
+ import_id : Option < NodeId > ,
3229
+ name : Name ) {
3222
3230
debug ! ( "(adding trait info) found trait {:?} for method '{}'" ,
3223
3231
trait_def_id,
3224
3232
name) ;
3225
- found_traits. push ( trait_def_id) ;
3233
+ found_traits. push ( TraitCandidate {
3234
+ def_id : trait_def_id,
3235
+ import_id : import_id,
3236
+ } ) ;
3226
3237
}
3227
3238
3228
3239
let mut found_traits = Vec :: new ( ) ;
3229
3240
// Look for the current trait.
3230
3241
if let Some ( ( trait_def_id, _) ) = self . current_trait_ref {
3231
3242
if self . trait_item_map . contains_key ( & ( name, trait_def_id) ) {
3232
- add_trait_info ( & mut found_traits, trait_def_id, name) ;
3243
+ add_trait_info ( & mut found_traits, trait_def_id, None , name) ;
3233
3244
}
3234
3245
}
3235
3246
@@ -3252,9 +3263,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3252
3263
for binding in traits. as_ref ( ) . unwrap ( ) . iter ( ) {
3253
3264
let trait_def_id = binding. def ( ) . unwrap ( ) . def_id ( ) ;
3254
3265
if self . trait_item_map . contains_key ( & ( name, trait_def_id) ) {
3255
- add_trait_info ( & mut found_traits, trait_def_id, name) ;
3266
+ let mut import_id = None ;
3267
+ if let NameBindingKind :: Import { directive, .. } = binding. kind {
3268
+ let id = directive. id ;
3269
+ self . maybe_unused_trait_imports . insert ( id) ;
3270
+ import_id = Some ( id) ;
3271
+ }
3272
+ add_trait_info ( & mut found_traits, trait_def_id, import_id, name) ;
3256
3273
let trait_name = self . get_trait_name ( trait_def_id) ;
3257
- self . record_use ( trait_name, TypeNS , binding) ;
3274
+ self . record_use ( trait_name, binding) ;
3258
3275
}
3259
3276
}
3260
3277
} ;
@@ -3634,6 +3651,7 @@ fn err_path_resolution() -> PathResolution {
3634
3651
pub struct CrateMap {
3635
3652
pub def_map : RefCell < DefMap > ,
3636
3653
pub freevars : FreevarMap ,
3654
+ pub maybe_unused_trait_imports : NodeSet ,
3637
3655
pub export_map : ExportMap ,
3638
3656
pub trait_map : TraitMap ,
3639
3657
pub glob_map : Option < GlobMap > ,
@@ -3671,6 +3689,7 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
3671
3689
CrateMap {
3672
3690
def_map : resolver. def_map ,
3673
3691
freevars : resolver. freevars ,
3692
+ maybe_unused_trait_imports : resolver. maybe_unused_trait_imports ,
3674
3693
export_map : resolver. export_map ,
3675
3694
trait_map : resolver. trait_map ,
3676
3695
glob_map : if resolver. make_glob_map {
0 commit comments