@@ -87,7 +87,7 @@ use rustc_front::hir::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt};
8787use rustc_front:: hir:: { TyRptr , TyStr , TyUint , TyPath , TyPtr } ;
8888use rustc_front:: util:: walk_pat;
8989
90- use std:: collections:: { hash_map , HashMap , HashSet } ;
90+ use std:: collections:: { HashMap , HashSet } ;
9191use std:: cell:: { Cell , RefCell } ;
9292use std:: fmt;
9393use std:: mem:: replace;
@@ -342,11 +342,8 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a>(resolver: &'b Resolver<'a, 'tcx>,
342342 if let Some ( sp) = resolver. ast_map . span_if_local ( did) {
343343 err. span_note ( sp, "constant defined here" ) ;
344344 }
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 ( ) {
350347 err. span_note ( binding. span . unwrap ( ) , "constant imported here" ) ;
351348 }
352349 }
@@ -653,10 +650,10 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
653650 }
654651}
655652
656- type ErrorMessage = Option < ( Span , String ) > ;
653+ pub type ErrorMessage = Option < ( Span , String ) > ;
657654
658655#[ derive( Clone , PartialEq , Eq ) ]
659- enum ResolveResult < T > {
656+ pub enum ResolveResult < T > {
660657 Failed ( ErrorMessage ) , // Failed to resolve the name, optional helpful error message.
661658 Indeterminate , // Couldn't determine due to unresolved globs.
662659 Success ( T ) , // Successfully resolved the import.
@@ -802,7 +799,7 @@ pub struct ModuleS<'a> {
802799 is_public : bool ,
803800 is_extern_crate : bool ,
804801
805- children : RefCell < HashMap < ( Name , Namespace ) , & ' a NameBinding < ' a > > > ,
802+ children : RefCell < HashMap < ( Name , Namespace ) , NameResolution < ' a > > > ,
806803 imports : RefCell < Vec < ImportDirective > > ,
807804
808805 // The anonymous children of this node. Anonymous children are pseudo-
@@ -821,9 +818,6 @@ pub struct ModuleS<'a> {
821818 // entry block for `f`.
822819 anonymous_children : RefCell < NodeMap < Module < ' a > > > ,
823820
824- // The status of resolving each import in this module.
825- import_resolutions : RefCell < HashMap < ( Name , Namespace ) , NameResolution < ' a > > > ,
826-
827821 // The number of unresolved globs that this module exports.
828822 glob_count : Cell < usize > ,
829823
@@ -854,7 +848,6 @@ impl<'a> ModuleS<'a> {
854848 children : RefCell :: new ( HashMap :: new ( ) ) ,
855849 imports : RefCell :: new ( Vec :: new ( ) ) ,
856850 anonymous_children : RefCell :: new ( NodeMap ( ) ) ,
857- import_resolutions : RefCell :: new ( HashMap :: new ( ) ) ,
858851 glob_count : Cell :: new ( 0 ) ,
859852 pub_count : Cell :: new ( 0 ) ,
860853 pub_glob_count : Cell :: new ( 0 ) ,
@@ -863,39 +856,49 @@ impl<'a> ModuleS<'a> {
863856 }
864857 }
865858
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+ } )
868869 }
869870
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.
872872 fn try_define_child ( & self , name : Name , ns : Namespace , binding : & ' a NameBinding < ' a > )
873873 -> 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)
878876 }
879877
880878 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 ;
883881 }
884882
885883 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 {
888885 0 => panic ! ( "No more outstanding references!" ) ,
889886 ref mut outstanding_references => { * outstanding_references -= 1 ; }
890887 }
891888 }
892889
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+
893896 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 ( ) {
896899 f ( name, ns, name_binding)
897900 }
898- }
901+ } )
899902 }
900903
901904 fn def_id ( & self ) -> Option < DefId > {
@@ -1240,7 +1243,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12401243 }
12411244
12421245 #[ 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+
12441252 let import_id = match binding. kind {
12451253 NameBindingKind :: Import { id, .. } => id,
12461254 _ => return ,
@@ -1278,8 +1286,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12781286 lp : LastPrivate )
12791287 -> ResolveResult < ( Module < ' a > , LastPrivate ) > {
12801288 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) ,
12831291 _ => match module. parent_link {
12841292 ModuleParentLink ( ref parent, _) => {
12851293 search_parent_externals ( needle, parent)
@@ -1591,53 +1599,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
15911599 /// given namespace. If successful, returns the binding corresponding to
15921600 /// the name.
15931601 fn resolve_name_in_module ( & mut self ,
1594- module_ : Module < ' a > ,
1602+ module : Module < ' a > ,
15951603 name : Name ,
15961604 namespace : Namespace ,
15971605 allow_private_imports : bool ,
15981606 record_used : bool )
15991607 -> 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) ) ;
16271609
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) ;
16341614 }
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+ } )
16411617 }
16421618
16431619 fn report_unresolved_imports ( & mut self , module_ : Module < ' a > ) {
@@ -1700,22 +1676,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
17001676 Some ( name) => {
17011677 build_reduced_graph:: populate_module_if_necessary ( self , & orig_module) ;
17021678
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;
17191688 }
17201689 }
17211690 }
@@ -3101,7 +3070,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
31013070 if name_path. len ( ) == 1 {
31023071 match this. primitive_type_table . primitive_types . get ( last_name) {
31033072 Some ( _) => None ,
3104- None => this. current_module . get_child ( * last_name, TypeNS )
3073+ None => this. current_module . resolve_name ( * last_name, TypeNS , true ) . success ( )
31053074 . and_then ( NameBinding :: module)
31063075 }
31073076 } else {
@@ -3161,7 +3130,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
31613130
31623131 // Look for a method in the current self type's impl module.
31633132 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 ) {
31653134 if let Some ( Def :: Method ( did) ) = binding. def ( ) {
31663135 if is_static_method ( self , did) {
31673136 return StaticMethod ( path_names_to_string ( & path, 0 ) ) ;
@@ -3484,34 +3453,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
34843453 // Look for trait children.
34853454 build_reduced_graph:: populate_module_if_necessary ( self , & search_module) ;
34863455
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 }
34893458 let trait_def_id = match name_binding. def ( ) {
34903459 Some ( Def :: Trait ( trait_def_id) ) => trait_def_id,
3491- Some ( ..) | None => continue ,
3460+ Some ( ..) | None => return ,
34923461 } ;
34933462 if self . trait_item_map . contains_key ( & ( name, trait_def_id) ) {
34943463 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) ;
34953466 }
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+ } ) ;
35153468
35163469 match search_module. parent_link {
35173470 NoParentLink | ModuleParentLink ( ..) => break ,
0 commit comments