@@ -103,6 +103,15 @@ enum DeterminacyExt {
103
103
WeakUndetermined ,
104
104
}
105
105
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
+
106
115
/// A free importable items suggested in case of resolution failure.
107
116
struct ImportSuggestion {
108
117
path : Path ,
@@ -998,15 +1007,22 @@ impl<'a> LexicalScopeBinding<'a> {
998
1007
}
999
1008
}
1000
1009
1010
+
1011
+ #[ derive( Clone , Copy , PartialEq , Debug ) ]
1012
+ enum UniformRootKind {
1013
+ CurrentScope ,
1014
+ ExternPrelude ,
1015
+ }
1016
+
1001
1017
#[ derive( Copy , Clone , Debug ) ]
1002
- pub enum ModuleOrUniformRoot < ' a > {
1018
+ enum ModuleOrUniformRoot < ' a > {
1003
1019
/// Regular module.
1004
1020
Module ( Module < ' a > ) ,
1005
1021
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 ) ,
1010
1026
}
1011
1027
1012
1028
#[ derive( Clone , Debug ) ]
@@ -2158,23 +2174,31 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
2158
2174
None
2159
2175
}
2160
2176
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 > {
2168
2186
ident. span = ident. span . modern ( ) ;
2169
2187
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 ( ) ) ;
2173
2196
}
2197
+ _ => { }
2174
2198
}
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 ) ;
2178
2202
self . current_module = orig_current_module;
2179
2203
result
2180
2204
}
@@ -2671,6 +2695,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
2671
2695
ModuleOrUniformRoot :: Module ( module) ,
2672
2696
ident,
2673
2697
ns,
2698
+ None ,
2674
2699
false ,
2675
2700
span,
2676
2701
) . is_err ( ) {
@@ -3699,9 +3724,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3699
3724
continue ;
3700
3725
}
3701
3726
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 ) ) ;
3705
3730
continue ;
3706
3731
}
3707
3732
if name == keywords:: CrateRoot . name ( ) ||
@@ -3731,7 +3756,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3731
3756
}
3732
3757
3733
3758
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)
3735
3760
} else if opt_ns. is_none ( ) || opt_ns == Some ( MacroNS ) {
3736
3761
assert ! ( ns == TypeNS ) ;
3737
3762
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> {
3751
3776
def, path. len ( ) - 1
3752
3777
) ) ;
3753
3778
}
3754
- _ => Err ( if record_used { Determined } else { Undetermined } ) ,
3779
+ _ => Err ( Determinacy :: determined ( record_used) ) ,
3755
3780
}
3756
3781
} ;
3757
3782
@@ -3825,7 +3850,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3825
3850
3826
3851
PathResult :: Module ( match module {
3827
3852
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 ) ,
3829
3855
_ => span_bug ! ( path_span, "resolve_path: non-empty path `{:?}` has no module" , path) ,
3830
3856
} )
3831
3857
}
@@ -4037,6 +4063,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4037
4063
ModuleOrUniformRoot :: Module ( module) ,
4038
4064
ident,
4039
4065
ns,
4066
+ None ,
4040
4067
false ,
4041
4068
module. span ,
4042
4069
) {
@@ -4359,6 +4386,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4359
4386
ModuleOrUniformRoot :: Module ( module) ,
4360
4387
ident,
4361
4388
ns,
4389
+ None ,
4362
4390
false ,
4363
4391
module. span ,
4364
4392
) . is_ok ( ) {
@@ -4945,6 +4973,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4945
4973
4946
4974
fn extern_prelude_get ( & mut self , ident : Ident , speculative : bool , skip_feature_gate : bool )
4947
4975
-> 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
+ }
4948
4980
self . extern_prelude . get ( & ident. modern ( ) ) . cloned ( ) . and_then ( |entry| {
4949
4981
if let Some ( binding) = entry. extern_crate_item {
4950
4982
if !speculative && !skip_feature_gate && entry. introduced_by_item &&
0 commit comments