@@ -87,7 +87,7 @@ use rustc_front::hir::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt};
87
87
use rustc_front:: hir:: { TyRptr , TyStr , TyUint , TyPath , TyPtr } ;
88
88
use rustc_front:: util:: walk_pat;
89
89
90
- use std:: collections:: { hash_map , HashMap , HashSet } ;
90
+ use std:: collections:: { HashMap , HashSet } ;
91
91
use std:: cell:: { Cell , RefCell } ;
92
92
use std:: fmt;
93
93
use std:: mem:: replace;
@@ -342,11 +342,8 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
342
342
if let Some ( sp) = resolver. ast_map . span_if_local ( did) {
343
343
err. span_note ( sp, "constant defined here" ) ;
344
344
}
345
- if let Some ( directive) = resolver. current_module
346
- . import_resolutions
347
- . borrow ( )
348
- . get ( & ( name, ValueNS ) ) {
349
- if let Some ( binding) = directive. binding {
345
+ if let Success ( binding) = resolver. current_module . resolve_name ( name, ValueNS , true ) {
346
+ if binding. is_import ( ) {
350
347
err. span_note ( binding. span . unwrap ( ) , "constant imported here" ) ;
351
348
}
352
349
}
@@ -653,10 +650,10 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
653
650
}
654
651
}
655
652
656
- type ErrorMessage = Option < ( Span , String ) > ;
653
+ pub type ErrorMessage = Option < ( Span , String ) > ;
657
654
658
655
#[ derive( Clone , PartialEq , Eq ) ]
659
- enum ResolveResult < T > {
656
+ pub enum ResolveResult < T > {
660
657
Failed ( ErrorMessage ) , // Failed to resolve the name, optional helpful error message.
661
658
Indeterminate , // Couldn't determine due to unresolved globs.
662
659
Success ( T ) , // Successfully resolved the import.
@@ -802,7 +799,7 @@ pub struct ModuleS<'a> {
802
799
is_public : bool ,
803
800
is_extern_crate : bool ,
804
801
805
- children : RefCell < HashMap < ( Name , Namespace ) , & ' a NameBinding < ' a > > > ,
802
+ children : RefCell < HashMap < ( Name , Namespace ) , NameResolution < ' a > > > ,
806
803
imports : RefCell < Vec < ImportDirective > > ,
807
804
808
805
// The anonymous children of this node. Anonymous children are pseudo-
@@ -821,9 +818,6 @@ pub struct ModuleS<'a> {
821
818
// entry block for `f`.
822
819
anonymous_children : RefCell < NodeMap < Module < ' a > > > ,
823
820
824
- // The status of resolving each import in this module.
825
- import_resolutions : RefCell < HashMap < ( Name , Namespace ) , NameResolution < ' a > > > ,
826
-
827
821
// The number of unresolved globs that this module exports.
828
822
glob_count : Cell < usize > ,
829
823
@@ -854,7 +848,6 @@ impl<'a> ModuleS<'a> {
854
848
children : RefCell :: new ( HashMap :: new ( ) ) ,
855
849
imports : RefCell :: new ( Vec :: new ( ) ) ,
856
850
anonymous_children : RefCell :: new ( NodeMap ( ) ) ,
857
- import_resolutions : RefCell :: new ( HashMap :: new ( ) ) ,
858
851
glob_count : Cell :: new ( 0 ) ,
859
852
pub_count : Cell :: new ( 0 ) ,
860
853
pub_glob_count : Cell :: new ( 0 ) ,
@@ -863,39 +856,49 @@ impl<'a> ModuleS<'a> {
863
856
}
864
857
}
865
858
866
- fn get_child ( & self , name : Name , ns : Namespace ) -> Option < & ' a NameBinding < ' a > > {
867
- self . children . borrow ( ) . get ( & ( name, ns) ) . cloned ( )
859
+ fn resolve_name ( & self , name : Name , ns : Namespace , allow_private_imports : bool )
860
+ -> ResolveResult < & ' a NameBinding < ' a > > {
861
+ let glob_count =
862
+ if allow_private_imports { self . glob_count . get ( ) } else { self . pub_glob_count . get ( ) } ;
863
+
864
+ self . children . borrow ( ) . get ( & ( name, ns) ) . cloned ( ) . unwrap_or_default ( ) . result ( glob_count)
865
+ . and_then ( |binding| {
866
+ let allowed = allow_private_imports || !binding. is_import ( ) || binding. is_public ( ) ;
867
+ if allowed { Success ( binding) } else { Failed ( None ) }
868
+ } )
868
869
}
869
870
870
- // If the name is not yet defined, define the name and return None.
871
- // Otherwise, return the existing definition.
871
+ // Define the name or return the existing binding if there is a collision.
872
872
fn try_define_child ( & self , name : Name , ns : Namespace , binding : & ' a NameBinding < ' a > )
873
873
-> Result < ( ) , & ' a NameBinding < ' a > > {
874
- match self . children . borrow_mut ( ) . entry ( ( name, ns) ) {
875
- hash_map:: Entry :: Vacant ( entry) => { entry. insert ( binding) ; Ok ( ( ) ) }
876
- hash_map:: Entry :: Occupied ( entry) => { Err ( entry. get ( ) ) } ,
877
- }
874
+ self . children . borrow_mut ( ) . entry ( ( name, ns) ) . or_insert_with ( Default :: default)
875
+ . try_define ( binding)
878
876
}
879
877
880
878
fn increment_outstanding_references_for ( & self , name : Name , ns : Namespace ) {
881
- let mut resolutions = self . import_resolutions . borrow_mut ( ) ;
882
- resolutions . entry ( ( name, ns) ) . or_insert_with ( Default :: default) . outstanding_references += 1 ;
879
+ let mut children = self . children . borrow_mut ( ) ;
880
+ children . entry ( ( name, ns) ) . or_insert_with ( Default :: default) . outstanding_references += 1 ;
883
881
}
884
882
885
883
fn decrement_outstanding_references_for ( & self , name : Name , ns : Namespace ) {
886
- match self . import_resolutions . borrow_mut ( ) . get_mut ( & ( name, ns) ) . unwrap ( )
887
- . outstanding_references {
884
+ match self . children . borrow_mut ( ) . get_mut ( & ( name, ns) ) . unwrap ( ) . outstanding_references {
888
885
0 => panic ! ( "No more outstanding references!" ) ,
889
886
ref mut outstanding_references => { * outstanding_references -= 1 ; }
890
887
}
891
888
}
892
889
890
+ fn for_each_child < F : FnMut ( Name , Namespace , & ' a NameBinding < ' a > ) > ( & self , mut f : F ) {
891
+ for ( & ( name, ns) , name_resolution) in self . children . borrow ( ) . iter ( ) {
892
+ name_resolution. binding . map ( |binding| f ( name, ns, binding) ) ;
893
+ }
894
+ }
895
+
893
896
fn for_each_local_child < F : FnMut ( Name , Namespace , & ' a NameBinding < ' a > ) > ( & self , mut f : F ) {
894
- for ( & ( name, ns) , name_binding) in self . children . borrow ( ) . iter ( ) {
895
- if !name_binding. is_extern_crate ( ) {
897
+ self . for_each_child ( | name, ns, name_binding| {
898
+ if !name_binding. is_import ( ) && !name_binding . is_extern_crate ( ) {
896
899
f ( name, ns, name_binding)
897
900
}
898
- }
901
+ } )
899
902
}
900
903
901
904
fn def_id ( & self ) -> Option < DefId > {
@@ -1240,7 +1243,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1240
1243
}
1241
1244
1242
1245
#[ inline]
1243
- fn record_import_use ( & mut self , name : Name , ns : Namespace , binding : & NameBinding < ' a > ) {
1246
+ fn record_use ( & mut self , name : Name , ns : Namespace , binding : & ' a NameBinding < ' a > ) {
1247
+ // track extern crates for unused_extern_crate lint
1248
+ if let Some ( DefId { krate, .. } ) = binding. module ( ) . and_then ( ModuleS :: def_id) {
1249
+ self . used_crates . insert ( krate) ;
1250
+ }
1251
+
1244
1252
let import_id = match binding. kind {
1245
1253
NameBindingKind :: Import { id, .. } => id,
1246
1254
_ => return ,
@@ -1278,8 +1286,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1278
1286
lp : LastPrivate )
1279
1287
-> ResolveResult < ( Module < ' a > , LastPrivate ) > {
1280
1288
fn search_parent_externals < ' a > ( needle : Name , module : Module < ' a > ) -> Option < Module < ' a > > {
1281
- match module. get_child ( needle, TypeNS ) {
1282
- Some ( binding) if binding. is_extern_crate ( ) => Some ( module) ,
1289
+ match module. resolve_name ( needle, TypeNS , false ) {
1290
+ Success ( binding) if binding. is_extern_crate ( ) => Some ( module) ,
1283
1291
_ => match module. parent_link {
1284
1292
ModuleParentLink ( ref parent, _) => {
1285
1293
search_parent_externals ( needle, parent)
@@ -1591,53 +1599,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1591
1599
/// given namespace. If successful, returns the binding corresponding to
1592
1600
/// the name.
1593
1601
fn resolve_name_in_module ( & mut self ,
1594
- module_ : Module < ' a > ,
1602
+ module : Module < ' a > ,
1595
1603
name : Name ,
1596
1604
namespace : Namespace ,
1597
1605
allow_private_imports : bool ,
1598
1606
record_used : bool )
1599
1607
-> ResolveResult < & ' a NameBinding < ' a > > {
1600
- debug ! ( "(resolving name in module) resolving `{}` in `{}`" ,
1601
- name,
1602
- module_to_string( & * module_) ) ;
1603
-
1604
- // First, check the direct children of the module.
1605
- build_reduced_graph:: populate_module_if_necessary ( self , module_) ;
1606
-
1607
- if let Some ( binding) = module_. get_child ( name, namespace) {
1608
- debug ! ( "(resolving name in module) found node as child" ) ;
1609
- if binding. is_extern_crate ( ) {
1610
- // track the extern crate as used.
1611
- if let Some ( DefId { krate, .. } ) = binding. module ( ) . unwrap ( ) . def_id ( ) {
1612
- self . used_crates . insert ( krate) ;
1613
- }
1614
- }
1615
- return Success ( binding) ;
1616
- }
1617
-
1618
- // Check the list of resolved imports.
1619
- match module_. import_resolutions . borrow ( ) . get ( & ( name, namespace) ) {
1620
- Some ( import_resolution) => {
1621
- if let Some ( binding) = import_resolution. binding {
1622
- if !allow_private_imports && binding. is_public ( ) { return Failed ( None ) }
1623
- if binding. is_public ( ) && import_resolution. outstanding_references != 0 {
1624
- debug ! ( "(resolving name in module) import unresolved; bailing out" ) ;
1625
- return Indeterminate ;
1626
- }
1608
+ debug ! ( "(resolving name in module) resolving `{}` in `{}`" , name, module_to_string( module) ) ;
1627
1609
1628
- debug ! ( "(resolving name in module) resolved to import" ) ;
1629
- if record_used {
1630
- self . record_import_use ( name, namespace, binding) ;
1631
- }
1632
- return Success ( binding) ;
1633
- }
1610
+ build_reduced_graph:: populate_module_if_necessary ( self , module) ;
1611
+ module. resolve_name ( name, namespace, allow_private_imports) . and_then ( |binding| {
1612
+ if record_used {
1613
+ self . record_use ( name, namespace, binding) ;
1634
1614
}
1635
- None => { }
1636
- }
1637
-
1638
- // We're out of luck.
1639
- debug ! ( "(resolving name in module) failed to resolve `{}`" , name) ;
1640
- return Failed ( None ) ;
1615
+ Success ( binding)
1616
+ } )
1641
1617
}
1642
1618
1643
1619
fn report_unresolved_imports ( & mut self , module_ : Module < ' a > ) {
@@ -1700,22 +1676,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1700
1676
Some ( name) => {
1701
1677
build_reduced_graph:: populate_module_if_necessary ( self , & orig_module) ;
1702
1678
1703
- match orig_module. get_child ( name, TypeNS ) {
1704
- None => {
1705
- debug ! ( "!!! (with scope) didn't find `{}` in `{}`" ,
1706
- name,
1707
- module_to_string( & * orig_module) ) ;
1708
- }
1709
- Some ( name_binding) => {
1710
- match name_binding. module ( ) {
1711
- None => {
1712
- debug ! ( "!!! (with scope) didn't find module for `{}` in `{}`" ,
1713
- name,
1714
- module_to_string( & * orig_module) ) ;
1715
- }
1716
- Some ( module_) => {
1717
- self . current_module = module_;
1718
- }
1679
+ if let Success ( name_binding) = orig_module. resolve_name ( name, TypeNS , false ) {
1680
+ match name_binding. module ( ) {
1681
+ None => {
1682
+ debug ! ( "!!! (with scope) didn't find module for `{}` in `{}`" ,
1683
+ name,
1684
+ module_to_string( orig_module) ) ;
1685
+ }
1686
+ Some ( module) => {
1687
+ self . current_module = module;
1719
1688
}
1720
1689
}
1721
1690
}
@@ -3101,7 +3070,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3101
3070
if name_path. len ( ) == 1 {
3102
3071
match this. primitive_type_table . primitive_types . get ( last_name) {
3103
3072
Some ( _) => None ,
3104
- None => this. current_module . get_child ( * last_name, TypeNS )
3073
+ None => this. current_module . resolve_name ( * last_name, TypeNS , true ) . success ( )
3105
3074
. and_then ( NameBinding :: module)
3106
3075
}
3107
3076
} else {
@@ -3161,7 +3130,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3161
3130
3162
3131
// Look for a method in the current self type's impl module.
3163
3132
if let Some ( module) = get_module ( self , path. span , & name_path) {
3164
- if let Some ( binding) = module. get_child ( name, ValueNS ) {
3133
+ if let Success ( binding) = module. resolve_name ( name, ValueNS , true ) {
3165
3134
if let Some ( Def :: Method ( did) ) = binding. def ( ) {
3166
3135
if is_static_method ( self , did) {
3167
3136
return StaticMethod ( path_names_to_string ( & path, 0 ) ) ;
@@ -3484,34 +3453,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3484
3453
// Look for trait children.
3485
3454
build_reduced_graph:: populate_module_if_necessary ( self , & search_module) ;
3486
3455
3487
- for ( & ( _, ns) , name_binding) in search_module . children . borrow ( ) . iter ( ) {
3488
- if ns != TypeNS { continue }
3456
+ search_module . for_each_child ( | _, ns, name_binding| {
3457
+ if ns != TypeNS { return }
3489
3458
let trait_def_id = match name_binding. def ( ) {
3490
3459
Some ( Def :: Trait ( trait_def_id) ) => trait_def_id,
3491
- Some ( ..) | None => continue ,
3460
+ Some ( ..) | None => return ,
3492
3461
} ;
3493
3462
if self . trait_item_map . contains_key ( & ( name, trait_def_id) ) {
3494
3463
add_trait_info ( & mut found_traits, trait_def_id, name) ;
3464
+ let trait_name = self . get_trait_name ( trait_def_id) ;
3465
+ self . record_use ( trait_name, TypeNS , name_binding) ;
3495
3466
}
3496
- }
3497
-
3498
- // Look for imports.
3499
- for ( & ( _, ns) , import) in search_module. import_resolutions . borrow ( ) . iter ( ) {
3500
- if ns != TypeNS { continue }
3501
- let binding = match import. binding {
3502
- Some ( binding) => binding,
3503
- None => continue ,
3504
- } ;
3505
- let did = match binding. def ( ) {
3506
- Some ( Def :: Trait ( trait_def_id) ) => trait_def_id,
3507
- Some ( ..) | None => continue ,
3508
- } ;
3509
- if self . trait_item_map . contains_key ( & ( name, did) ) {
3510
- add_trait_info ( & mut found_traits, did, name) ;
3511
- let trait_name = self . get_trait_name ( did) ;
3512
- self . record_import_use ( trait_name, TypeNS , binding) ;
3513
- }
3514
- }
3467
+ } ) ;
3515
3468
3516
3469
match search_module. parent_link {
3517
3470
NoParentLink | ModuleParentLink ( ..) => break ,
0 commit comments