@@ -1407,6 +1407,7 @@ pub struct Resolver<'a> {
1407
1407
graph_root : Module < ' a > ,
1408
1408
1409
1409
prelude : Option < Module < ' a > > ,
1410
+ extern_prelude : FxHashSet < Name > ,
1410
1411
1411
1412
/// n.b. This is used only for better diagnostics, not name resolution itself.
1412
1413
has_self : FxHashSet < DefId > ,
@@ -1715,6 +1716,7 @@ impl<'a> Resolver<'a> {
1715
1716
// AST.
1716
1717
graph_root,
1717
1718
prelude : None ,
1719
+ extern_prelude : session. opts . externs . iter ( ) . map ( |kv| Symbol :: intern ( kv. 0 ) ) . collect ( ) ,
1718
1720
1719
1721
has_self : FxHashSet ( ) ,
1720
1722
field_names : FxHashMap ( ) ,
@@ -1970,13 +1972,32 @@ impl<'a> Resolver<'a> {
1970
1972
}
1971
1973
}
1972
1974
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
+ }
1977
1997
}
1978
- _ => None ,
1979
1998
}
1999
+
2000
+ None
1980
2001
}
1981
2002
1982
2003
fn hygienic_lexical_parent ( & mut self , mut module : Module < ' a > , span : & mut Span )
@@ -3587,8 +3608,9 @@ impl<'a> Resolver<'a> {
3587
3608
// We can see through blocks
3588
3609
} else {
3589
3610
// 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 {
3592
3614
add_module_candidates ( prelude, & mut names) ;
3593
3615
}
3594
3616
}
0 commit comments