@@ -1340,6 +1340,12 @@ impl PrimitiveTypeTable {
13401340 }
13411341}
13421342
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+
13431349/// The main resolver class.
13441350///
13451351/// This is the visitor that walks the whole crate.
@@ -1352,7 +1358,7 @@ pub struct Resolver<'a, 'b: 'a> {
13521358 graph_root : Module < ' a > ,
13531359
13541360 prelude : Option < Module < ' a > > ,
1355- pub extern_prelude : FxHashSet < Name > ,
1361+ pub extern_prelude : FxHashMap < Ident , ExternPreludeEntry < ' a > > ,
13561362
13571363 /// n.b. This is used only for better diagnostics, not name resolution itself.
13581364 has_self : FxHashSet < DefId > ,
@@ -1668,15 +1674,16 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
16681674 DefCollector :: new ( & mut definitions, Mark :: root ( ) )
16691675 . collect_root ( crate_name, session. local_crate_disambiguator ( ) ) ;
16701676
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 ( ) ;
16731680
16741681 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 ( ) ) ;
16761683 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 ( ) ) ;
16781685 if session. rust_2018 ( ) {
1679- extern_prelude. insert ( Symbol :: intern ( "meta" ) ) ;
1686+ extern_prelude. insert ( Ident :: from_str ( "meta" ) , Default :: default ( ) ) ;
16801687 }
16811688 }
16821689 }
@@ -1963,21 +1970,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
19631970 }
19641971
19651972 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+ }
19811977 }
19821978 if ns == TypeNS && is_known_tool ( ident. name ) {
19831979 let binding = ( Def :: ToolMod , ty:: Visibility :: Public ,
@@ -4018,7 +4014,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
40184014 } else {
40194015 // Items from the prelude
40204016 if !module. no_implicit_prelude {
4021- names. extend ( self . extern_prelude . iter ( ) . cloned ( ) ) ;
4017+ names. extend ( self . extern_prelude . iter ( ) . map ( | ( ident , _ ) | ident . name ) ) ;
40224018 if let Some ( prelude) = self . prelude {
40234019 add_module_candidates ( prelude, & mut names) ;
40244020 }
@@ -4459,11 +4455,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
44594455
44604456 if self . session . rust_2018 ( ) {
44614457 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 ) {
44674461 let crate_root = self . get_module ( DefId {
44684462 krate : crate_id,
44694463 index : CRATE_DEF_INDEX ,
@@ -4825,6 +4819,28 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
48254819 err. emit ( ) ;
48264820 self . name_already_seen . insert ( name, span) ;
48274821 }
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+ }
48284844}
48294845
48304846fn is_self_type ( path : & [ Ident ] , namespace : Namespace ) -> bool {
0 commit comments