@@ -806,7 +806,10 @@ pub struct ModuleS<'a> {
806
806
parent_link : ParentLink < ' a > ,
807
807
def : Option < Def > ,
808
808
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 > ,
810
813
811
814
resolutions : RefCell < HashMap < ( Name , Namespace ) , NameResolution < ' a > > > ,
812
815
unresolved_imports : RefCell < Vec < ImportDirective > > ,
@@ -853,7 +856,7 @@ impl<'a> ModuleS<'a> {
853
856
parent_link : parent_link,
854
857
def : def,
855
858
is_public : is_public,
856
- is_extern_crate : false ,
859
+ extern_crate_did : None ,
857
860
resolutions : RefCell :: new ( HashMap :: new ( ) ) ,
858
861
unresolved_imports : RefCell :: new ( Vec :: new ( ) ) ,
859
862
module_children : RefCell :: new ( NodeMap ( ) ) ,
@@ -917,6 +920,16 @@ impl<'a> ModuleS<'a> {
917
920
self . def . as_ref ( ) . map ( Def :: def_id)
918
921
}
919
922
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
+
920
933
fn is_normal ( & self ) -> bool {
921
934
match self . def {
922
935
Some ( Def :: Mod ( _) ) | Some ( Def :: ForeignMod ( _) ) => true ,
@@ -1027,6 +1040,14 @@ impl<'a> NameBinding<'a> {
1027
1040
}
1028
1041
}
1029
1042
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
+
1030
1051
fn defined_with ( & self , modifiers : DefModifiers ) -> bool {
1031
1052
self . modifiers . contains ( modifiers)
1032
1053
}
@@ -1038,11 +1059,12 @@ impl<'a> NameBinding<'a> {
1038
1059
fn def_and_lp ( & self ) -> ( Def , LastPrivate ) {
1039
1060
let def = self . def ( ) . unwrap ( ) ;
1040
1061
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) )
1042
1064
}
1043
1065
1044
1066
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 ( )
1046
1068
}
1047
1069
1048
1070
fn is_import ( & self ) -> bool {
@@ -1236,9 +1258,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1236
1258
self . arenas . name_bindings . alloc ( name_binding)
1237
1259
}
1238
1260
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) ;
1242
1269
self . arenas . modules . alloc ( module)
1243
1270
}
1244
1271
@@ -1357,7 +1384,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1357
1384
// Keep track of the closest private module used
1358
1385
// when resolving this import chain.
1359
1386
if !binding. is_public ( ) {
1360
- if let Some ( did) = search_module. def_id ( ) {
1387
+ if let Some ( did) = search_module. local_def_id ( ) {
1361
1388
closest_private = LastMod ( DependsOn ( did) ) ;
1362
1389
}
1363
1390
}
@@ -1462,7 +1489,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1462
1489
Success ( PrefixFound ( ref containing_module, index) ) => {
1463
1490
search_module = containing_module;
1464
1491
start_index = index;
1465
- last_private = LastMod ( DependsOn ( containing_module. def_id ( )
1492
+ last_private = LastMod ( DependsOn ( containing_module. local_def_id ( )
1466
1493
. unwrap ( ) ) ) ;
1467
1494
}
1468
1495
}
@@ -3571,7 +3598,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3571
3598
3572
3599
if !in_module_is_extern || name_binding. is_public ( ) {
3573
3600
// 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 ( ) ;
3575
3602
worklist. push ( ( module, path_segments, is_extern) ) ;
3576
3603
}
3577
3604
}
0 commit comments