@@ -103,6 +103,15 @@ enum DeterminacyExt {
103103 WeakUndetermined ,
104104}
105105
106+ impl DeterminacyExt {
107+ fn to_determinacy ( self ) -> Determinacy {
108+ match self {
109+ DeterminacyExt :: Determined => Determined ,
110+ DeterminacyExt :: Undetermined | DeterminacyExt :: WeakUndetermined => Undetermined ,
111+ }
112+ }
113+ }
114+
106115/// A free importable items suggested in case of resolution failure.
107116struct ImportSuggestion {
108117 path : Path ,
@@ -998,15 +1007,22 @@ impl<'a> LexicalScopeBinding<'a> {
9981007 }
9991008}
10001009
1010+
1011+ #[ derive( Clone , Copy , PartialEq , Debug ) ]
1012+ enum UniformRootKind {
1013+ CurrentScope ,
1014+ ExternPrelude ,
1015+ }
1016+
10011017#[ derive( Copy , Clone , Debug ) ]
1002- pub enum ModuleOrUniformRoot < ' a > {
1018+ enum ModuleOrUniformRoot < ' a > {
10031019 /// Regular module.
10041020 Module ( Module < ' a > ) ,
10051021
1006- /// The `{{root}}` (`CrateRoot` aka "global") / ` extern` initial segment
1007- /// in which external crates resolve, and also `crate` (only in `{{root}} `,
1008- /// but *not* `extern`), in the Rust 2018 edition .
1009- UniformRoot ( Name ) ,
1022+ /// This "virtual module" denotes either resolution in extern prelude
1023+ /// for paths starting with `::` on 2018 edition or `extern:: `,
1024+ /// or resolution in current scope for single-segment imports .
1025+ UniformRoot ( UniformRootKind ) ,
10101026}
10111027
10121028#[ derive( Clone , Debug ) ]
@@ -2158,23 +2174,31 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
21582174 None
21592175 }
21602176
2161- fn resolve_ident_in_module ( & mut self ,
2162- module : ModuleOrUniformRoot < ' a > ,
2163- mut ident : Ident ,
2164- ns : Namespace ,
2165- record_used : bool ,
2166- span : Span )
2167- -> Result < & ' a NameBinding < ' a > , Determinacy > {
2177+ fn resolve_ident_in_module (
2178+ & mut self ,
2179+ module : ModuleOrUniformRoot < ' a > ,
2180+ mut ident : Ident ,
2181+ ns : Namespace ,
2182+ parent_scope : Option < & ParentScope < ' a > > ,
2183+ record_used : bool ,
2184+ path_span : Span
2185+ ) -> Result < & ' a NameBinding < ' a > , Determinacy > {
21682186 ident. span = ident. span . modern ( ) ;
21692187 let orig_current_module = self . current_module ;
2170- if let ModuleOrUniformRoot :: Module ( module) = module {
2171- if let Some ( def) = ident. span . adjust ( module. expansion ) {
2172- self . current_module = self . macro_def_scope ( def) ;
2188+ match module {
2189+ ModuleOrUniformRoot :: Module ( module) => {
2190+ if let Some ( def) = ident. span . adjust ( module. expansion ) {
2191+ self . current_module = self . macro_def_scope ( def) ;
2192+ }
2193+ }
2194+ ModuleOrUniformRoot :: UniformRoot ( UniformRootKind :: ExternPrelude ) => {
2195+ ident. span . adjust ( Mark :: root ( ) ) ;
21732196 }
2197+ _ => { }
21742198 }
2175- let result = self . resolve_ident_in_module_unadjusted (
2176- module, ident, ns, record_used, span ,
2177- ) ;
2199+ let result = self . resolve_ident_in_module_unadjusted_ext (
2200+ module, ident, ns, parent_scope , false , record_used, path_span ,
2201+ ) . map_err ( DeterminacyExt :: to_determinacy ) ;
21782202 self . current_module = orig_current_module;
21792203 result
21802204 }
@@ -2671,6 +2695,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
26712695 ModuleOrUniformRoot :: Module ( module) ,
26722696 ident,
26732697 ns,
2698+ None ,
26742699 false ,
26752700 span,
26762701 ) . is_err ( ) {
@@ -3699,9 +3724,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
36993724 continue ;
37003725 }
37013726 if name == keywords:: Extern . name ( ) ||
3702- name == keywords:: CrateRoot . name ( ) &&
3703- self . session . rust_2018 ( ) {
3704- module = Some ( ModuleOrUniformRoot :: UniformRoot ( name ) ) ;
3727+ name == keywords:: CrateRoot . name ( ) && self . session . rust_2018 ( ) {
3728+ module =
3729+ Some ( ModuleOrUniformRoot :: UniformRoot ( UniformRootKind :: ExternPrelude ) ) ;
37053730 continue ;
37063731 }
37073732 if name == keywords:: CrateRoot . name ( ) ||
@@ -3731,7 +3756,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
37313756 }
37323757
37333758 let binding = if let Some ( module) = module {
3734- self . resolve_ident_in_module ( module, ident, ns, record_used, path_span)
3759+ self . resolve_ident_in_module ( module, ident, ns, None , record_used, path_span)
37353760 } else if opt_ns. is_none ( ) || opt_ns == Some ( MacroNS ) {
37363761 assert ! ( ns == TypeNS ) ;
37373762 self . early_resolve_ident_in_lexical_scope ( ident, ns, None , opt_ns. is_none ( ) ,
@@ -3751,7 +3776,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
37513776 def, path. len ( ) - 1
37523777 ) ) ;
37533778 }
3754- _ => Err ( if record_used { Determined } else { Undetermined } ) ,
3779+ _ => Err ( Determinacy :: determined ( record_used) ) ,
37553780 }
37563781 } ;
37573782
@@ -3825,7 +3850,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
38253850
38263851 PathResult :: Module ( match module {
38273852 Some ( module) => module,
3828- None if path. is_empty ( ) => ModuleOrUniformRoot :: UniformRoot ( keywords:: Invalid . name ( ) ) ,
3853+ None if path. is_empty ( ) =>
3854+ ModuleOrUniformRoot :: UniformRoot ( UniformRootKind :: CurrentScope ) ,
38293855 _ => span_bug ! ( path_span, "resolve_path: non-empty path `{:?}` has no module" , path) ,
38303856 } )
38313857 }
@@ -4037,6 +4063,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
40374063 ModuleOrUniformRoot :: Module ( module) ,
40384064 ident,
40394065 ns,
4066+ None ,
40404067 false ,
40414068 module. span ,
40424069 ) {
@@ -4359,6 +4386,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
43594386 ModuleOrUniformRoot :: Module ( module) ,
43604387 ident,
43614388 ns,
4389+ None ,
43624390 false ,
43634391 module. span ,
43644392 ) . is_ok ( ) {
@@ -4945,6 +4973,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
49454973
49464974 fn extern_prelude_get ( & mut self , ident : Ident , speculative : bool , skip_feature_gate : bool )
49474975 -> Option < & ' a NameBinding < ' a > > {
4976+ if ident. is_path_segment_keyword ( ) {
4977+ // Make sure `self`, `super` etc produce an error when passed to here.
4978+ return None ;
4979+ }
49484980 self . extern_prelude . get ( & ident. modern ( ) ) . cloned ( ) . and_then ( |entry| {
49494981 if let Some ( binding) = entry. extern_crate_item {
49504982 if !speculative && !skip_feature_gate && entry. introduced_by_item &&
0 commit comments