@@ -806,7 +806,10 @@ pub struct ModuleS<'a> {
806806 parent_link : ParentLink < ' a > ,
807807 def : Option < Def > ,
808808 is_public : bool ,
809- is_extern_crate : bool ,
809+
810+ // If the module is an extern crate, `def` is root of the external crate and `extern_crate_did`
811+ // is the DefId of the local `extern crate` item (otherwise, `extern_crate_did` is None).
812+ extern_crate_did : Option < DefId > ,
810813
811814 resolutions : RefCell < HashMap < ( Name , Namespace ) , NameResolution < ' a > > > ,
812815 unresolved_imports : RefCell < Vec < ImportDirective > > ,
@@ -853,7 +856,7 @@ impl<'a> ModuleS<'a> {
853856 parent_link : parent_link,
854857 def : def,
855858 is_public : is_public,
856- is_extern_crate : false ,
859+ extern_crate_did : None ,
857860 resolutions : RefCell :: new ( HashMap :: new ( ) ) ,
858861 unresolved_imports : RefCell :: new ( Vec :: new ( ) ) ,
859862 module_children : RefCell :: new ( NodeMap ( ) ) ,
@@ -917,6 +920,16 @@ impl<'a> ModuleS<'a> {
917920 self . def . as_ref ( ) . map ( Def :: def_id)
918921 }
919922
923+ // This returns the DefId of the crate local item that controls this module's visibility.
924+ // It is only used to compute `LastPrivate` data, and it differs from `def_id` only for extern
925+ // crates, whose `def_id` is the external crate's root, not the local `extern crate` item.
926+ fn local_def_id ( & self ) -> Option < DefId > {
927+ match self . extern_crate_did {
928+ Some ( def_id) => Some ( def_id) ,
929+ None => self . def_id ( ) ,
930+ }
931+ }
932+
920933 fn is_normal ( & self ) -> bool {
921934 match self . def {
922935 Some ( Def :: Mod ( _) ) | Some ( Def :: ForeignMod ( _) ) => true ,
@@ -1027,6 +1040,14 @@ impl<'a> NameBinding<'a> {
10271040 }
10281041 }
10291042
1043+ fn local_def_id ( & self ) -> Option < DefId > {
1044+ match self . kind {
1045+ NameBindingKind :: Def ( def) => Some ( def. def_id ( ) ) ,
1046+ NameBindingKind :: Module ( ref module) => module. local_def_id ( ) ,
1047+ NameBindingKind :: Import { binding, .. } => binding. local_def_id ( ) ,
1048+ }
1049+ }
1050+
10301051 fn defined_with ( & self , modifiers : DefModifiers ) -> bool {
10311052 self . modifiers . contains ( modifiers)
10321053 }
@@ -1038,11 +1059,12 @@ impl<'a> NameBinding<'a> {
10381059 fn def_and_lp ( & self ) -> ( Def , LastPrivate ) {
10391060 let def = self . def ( ) . unwrap ( ) ;
10401061 if let Def :: Err = def { return ( def, LastMod ( AllPublic ) ) }
1041- ( def, LastMod ( if self . is_public ( ) { AllPublic } else { DependsOn ( def. def_id ( ) ) } ) )
1062+ let lp = if self . is_public ( ) { AllPublic } else { DependsOn ( self . local_def_id ( ) . unwrap ( ) ) } ;
1063+ ( def, LastMod ( lp) )
10421064 }
10431065
10441066 fn is_extern_crate ( & self ) -> bool {
1045- self . module ( ) . map ( |module| module. is_extern_crate ) . unwrap_or ( false )
1067+ self . module ( ) . and_then ( |module| module. extern_crate_did ) . is_some ( )
10461068 }
10471069
10481070 fn is_import ( & self ) -> bool {
@@ -1236,9 +1258,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
12361258 self . arenas . name_bindings . alloc ( name_binding)
12371259 }
12381260
1239- fn new_extern_crate_module ( & self , parent_link : ParentLink < ' a > , def : Def ) -> Module < ' a > {
1240- let mut module = ModuleS :: new ( parent_link, Some ( def) , false , true ) ;
1241- module. is_extern_crate = true ;
1261+ fn new_extern_crate_module ( & self ,
1262+ parent_link : ParentLink < ' a > ,
1263+ def : Def ,
1264+ is_public : bool ,
1265+ local_def : DefId )
1266+ -> Module < ' a > {
1267+ let mut module = ModuleS :: new ( parent_link, Some ( def) , false , is_public) ;
1268+ module. extern_crate_did = Some ( local_def) ;
12421269 self . arenas . modules . alloc ( module)
12431270 }
12441271
@@ -1357,7 +1384,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
13571384 // Keep track of the closest private module used
13581385 // when resolving this import chain.
13591386 if !binding. is_public ( ) {
1360- if let Some ( did) = search_module. def_id ( ) {
1387+ if let Some ( did) = search_module. local_def_id ( ) {
13611388 closest_private = LastMod ( DependsOn ( did) ) ;
13621389 }
13631390 }
@@ -1462,7 +1489,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
14621489 Success ( PrefixFound ( ref containing_module, index) ) => {
14631490 search_module = containing_module;
14641491 start_index = index;
1465- last_private = LastMod ( DependsOn ( containing_module. def_id ( )
1492+ last_private = LastMod ( DependsOn ( containing_module. local_def_id ( )
14661493 . unwrap ( ) ) ) ;
14671494 }
14681495 }
@@ -3571,7 +3598,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
35713598
35723599 if !in_module_is_extern || name_binding. is_public ( ) {
35733600 // add the module to the lookup
3574- let is_extern = in_module_is_extern || module . is_extern_crate ;
3601+ let is_extern = in_module_is_extern || name_binding . is_extern_crate ( ) ;
35753602 worklist. push ( ( module, path_segments, is_extern) ) ;
35763603 }
35773604 }
0 commit comments