@@ -1407,6 +1407,7 @@ pub struct Resolver<'a> {
14071407 graph_root : Module < ' a > ,
14081408
14091409 prelude : Option < Module < ' a > > ,
1410+ extern_prelude : FxHashSet < Name > ,
14101411
14111412 /// n.b. This is used only for better diagnostics, not name resolution itself.
14121413 has_self : FxHashSet < DefId > ,
@@ -1715,6 +1716,7 @@ impl<'a> Resolver<'a> {
17151716 // AST.
17161717 graph_root,
17171718 prelude : None ,
1719+ extern_prelude : session. opts . externs . iter ( ) . map ( |kv| Symbol :: intern ( kv. 0 ) ) . collect ( ) ,
17181720
17191721 has_self : FxHashSet ( ) ,
17201722 field_names : FxHashMap ( ) ,
@@ -1970,13 +1972,32 @@ impl<'a> Resolver<'a> {
19701972 }
19711973 }
19721974
1973- match self . prelude {
1974- Some ( prelude) if !module. no_implicit_prelude => {
1975- self . resolve_ident_in_module_unadjusted ( prelude, ident, ns, false , false , path_span)
1976- . ok ( ) . map ( LexicalScopeBinding :: Item )
1975+ if !module. no_implicit_prelude {
1976+ // `record_used` means that we don't try to load crates during speculative resolution
1977+ if record_used && ns == TypeNS && self . extern_prelude . contains ( & ident. name ) {
1978+ if !self . session . features_untracked ( ) . extern_prelude {
1979+ feature_err ( & self . session . parse_sess , "extern_prelude" ,
1980+ ident. span , GateIssue :: Language ,
1981+ "access to extern crates through prelude is experimental" ) . emit ( ) ;
1982+ }
1983+
1984+ let crate_id = self . crate_loader . process_path_extern ( ident. name , ident. span ) ;
1985+ let crate_root = self . get_module ( DefId { krate : crate_id, index : CRATE_DEF_INDEX } ) ;
1986+ self . populate_module_if_necessary ( crate_root) ;
1987+
1988+ let binding = ( crate_root, ty:: Visibility :: Public ,
1989+ ident. span , Mark :: root ( ) ) . to_name_binding ( self . arenas ) ;
1990+ return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1991+ }
1992+ if let Some ( prelude) = self . prelude {
1993+ if let Ok ( binding) = self . resolve_ident_in_module_unadjusted ( prelude, ident, ns,
1994+ false , false , path_span) {
1995+ return Some ( LexicalScopeBinding :: Item ( binding) ) ;
1996+ }
19771997 }
1978- _ => None ,
19791998 }
1999+
2000+ None
19802001 }
19812002
19822003 fn hygienic_lexical_parent ( & mut self , mut module : Module < ' a > , span : & mut Span )
@@ -3587,8 +3608,9 @@ impl<'a> Resolver<'a> {
35873608 // We can see through blocks
35883609 } else {
35893610 // Items from the prelude
3590- if let Some ( prelude) = self . prelude {
3591- if !module. no_implicit_prelude {
3611+ if !module. no_implicit_prelude {
3612+ names. extend ( self . extern_prelude . iter ( ) . cloned ( ) ) ;
3613+ if let Some ( prelude) = self . prelude {
35923614 add_module_candidates ( prelude, & mut names) ;
35933615 }
35943616 }
0 commit comments