@@ -1340,6 +1340,12 @@ impl PrimitiveTypeTable {
1340
1340
}
1341
1341
}
1342
1342
1343
+ #[ derive( Default , Clone ) ]
1344
+ pub struct ExternPreludeEntry < ' a > {
1345
+ extern_crate_item : Option < & ' a NameBinding < ' a > > ,
1346
+ pub introduced_by_item : bool ,
1347
+ }
1348
+
1343
1349
/// The main resolver class.
1344
1350
///
1345
1351
/// This is the visitor that walks the whole crate.
@@ -1352,7 +1358,7 @@ pub struct Resolver<'a, 'b: 'a> {
1352
1358
graph_root : Module < ' a > ,
1353
1359
1354
1360
prelude : Option < Module < ' a > > ,
1355
- pub extern_prelude : FxHashSet < Name > ,
1361
+ pub extern_prelude : FxHashMap < Ident , ExternPreludeEntry < ' a > > ,
1356
1362
1357
1363
/// n.b. This is used only for better diagnostics, not name resolution itself.
1358
1364
has_self : FxHashSet < DefId > ,
@@ -1668,15 +1674,16 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
1668
1674
DefCollector :: new ( & mut definitions, Mark :: root ( ) )
1669
1675
. collect_root ( crate_name, session. local_crate_disambiguator ( ) ) ;
1670
1676
1671
- let mut extern_prelude: FxHashSet < Name > =
1672
- session. opts . externs . iter ( ) . map ( |kv| Symbol :: intern ( kv. 0 ) ) . collect ( ) ;
1677
+ let mut extern_prelude: FxHashMap < Ident , ExternPreludeEntry > =
1678
+ session. opts . externs . iter ( ) . map ( |kv| ( Ident :: from_str ( kv. 0 ) , Default :: default ( ) ) )
1679
+ . collect ( ) ;
1673
1680
1674
1681
if !attr:: contains_name ( & krate. attrs , "no_core" ) {
1675
- extern_prelude. insert ( Symbol :: intern ( "core" ) ) ;
1682
+ extern_prelude. insert ( Ident :: from_str ( "core" ) , Default :: default ( ) ) ;
1676
1683
if !attr:: contains_name ( & krate. attrs , "no_std" ) {
1677
- extern_prelude. insert ( Symbol :: intern ( "std" ) ) ;
1684
+ extern_prelude. insert ( Ident :: from_str ( "std" ) , Default :: default ( ) ) ;
1678
1685
if session. rust_2018 ( ) {
1679
- extern_prelude. insert ( Symbol :: intern ( "meta" ) ) ;
1686
+ extern_prelude. insert ( Ident :: from_str ( "meta" ) , Default :: default ( ) ) ;
1680
1687
}
1681
1688
}
1682
1689
}
@@ -1963,21 +1970,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
1963
1970
}
1964
1971
1965
1972
if !module. no_implicit_prelude {
1966
- if ns == TypeNS && self . extern_prelude . contains ( & ident. name ) {
1967
- let crate_id = if record_used {
1968
- self . crate_loader . process_path_extern ( ident. name , ident. span )
1969
- } else if let Some ( crate_id) =
1970
- self . crate_loader . maybe_process_path_extern ( ident. name , ident. span ) {
1971
- crate_id
1972
- } else {
1973
- return None ;
1974
- } ;
1975
- let crate_root = self . get_module ( DefId { krate : crate_id, index : CRATE_DEF_INDEX } ) ;
1976
- self . populate_module_if_necessary ( & crate_root) ;
1977
-
1978
- let binding = ( crate_root, ty:: Visibility :: Public ,
1979
- ident. span , Mark :: root ( ) ) . to_name_binding ( self . arenas ) ;
1980
- return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1973
+ if ns == TypeNS {
1974
+ if let Some ( binding) = self . extern_prelude_get ( ident, !record_used) {
1975
+ return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1976
+ }
1981
1977
}
1982
1978
if ns == TypeNS && is_known_tool ( ident. name ) {
1983
1979
let binding = ( Def :: ToolMod , ty:: Visibility :: Public ,
@@ -4018,7 +4014,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4018
4014
} else {
4019
4015
// Items from the prelude
4020
4016
if !module. no_implicit_prelude {
4021
- names. extend ( self . extern_prelude . iter ( ) . cloned ( ) ) ;
4017
+ names. extend ( self . extern_prelude . iter ( ) . map ( | ( ident , _ ) | ident . name ) ) ;
4022
4018
if let Some ( prelude) = self . prelude {
4023
4019
add_module_candidates ( prelude, & mut names) ;
4024
4020
}
@@ -4459,11 +4455,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4459
4455
4460
4456
if self . session . rust_2018 ( ) {
4461
4457
let extern_prelude_names = self . extern_prelude . clone ( ) ;
4462
- for & name in extern_prelude_names. iter ( ) {
4463
- let ident = Ident :: with_empty_ctxt ( name) ;
4464
- if let Some ( crate_id) = self . crate_loader . maybe_process_path_extern ( name,
4465
- ident. span )
4466
- {
4458
+ for ( ident, _) in extern_prelude_names. into_iter ( ) {
4459
+ if let Some ( crate_id) = self . crate_loader . maybe_process_path_extern ( ident. name ,
4460
+ ident. span ) {
4467
4461
let crate_root = self . get_module ( DefId {
4468
4462
krate : crate_id,
4469
4463
index : CRATE_DEF_INDEX ,
@@ -4825,6 +4819,28 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4825
4819
err. emit ( ) ;
4826
4820
self . name_already_seen . insert ( name, span) ;
4827
4821
}
4822
+
4823
+ fn extern_prelude_get ( & mut self , ident : Ident , speculative : bool )
4824
+ -> Option < & ' a NameBinding < ' a > > {
4825
+ self . extern_prelude . get ( & ident. modern ( ) ) . cloned ( ) . and_then ( |entry| {
4826
+ if let Some ( binding) = entry. extern_crate_item {
4827
+ Some ( binding)
4828
+ } else {
4829
+ let crate_id = if !speculative {
4830
+ self . crate_loader . process_path_extern ( ident. name , ident. span )
4831
+ } else if let Some ( crate_id) =
4832
+ self . crate_loader . maybe_process_path_extern ( ident. name , ident. span ) {
4833
+ crate_id
4834
+ } else {
4835
+ return None ;
4836
+ } ;
4837
+ let crate_root = self . get_module ( DefId { krate : crate_id, index : CRATE_DEF_INDEX } ) ;
4838
+ self . populate_module_if_necessary ( & crate_root) ;
4839
+ Some ( ( crate_root, ty:: Visibility :: Public , ident. span , Mark :: root ( ) )
4840
+ . to_name_binding ( self . arenas ) )
4841
+ }
4842
+ } )
4843
+ }
4828
4844
}
4829
4845
4830
4846
fn is_self_type ( path : & [ Ident ] , namespace : Namespace ) -> bool {
0 commit comments