@@ -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 ,
@@ -961,15 +970,22 @@ impl<'a> LexicalScopeBinding<'a> {
961
970
}
962
971
}
963
972
973
+
974
+ #[ derive( Clone , Copy , PartialEq , Debug ) ]
975
+ enum UniformRootKind {
976
+ CurrentScope ,
977
+ ExternPrelude ,
978
+ }
979
+
964
980
#[ derive( Copy , Clone , Debug ) ]
965
- pub enum ModuleOrUniformRoot < ' a > {
981
+ enum ModuleOrUniformRoot < ' a > {
966
982
/// Regular module.
967
983
Module ( Module < ' a > ) ,
968
984
969
- /// The `{{root}}` (`CrateRoot` aka "global") / ` extern` initial segment
970
- /// in which external crates resolve, and also `crate` (only in `{{root}} `,
971
- /// but *not* `extern`), in the Rust 2018 edition .
972
- UniformRoot ( Name ) ,
985
+ /// This "virtual module" denotes either resolution in extern prelude
986
+ /// for paths starting with `::` on 2018 edition or `extern:: `,
987
+ /// or resolution in current scope for single-segment imports .
988
+ UniformRoot ( UniformRootKind ) ,
973
989
}
974
990
975
991
#[ derive( Clone , Debug ) ]
@@ -2099,23 +2115,31 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
2099
2115
None
2100
2116
}
2101
2117
2102
- fn resolve_ident_in_module ( & mut self ,
2103
- module : ModuleOrUniformRoot < ' a > ,
2104
- mut ident : Ident ,
2105
- ns : Namespace ,
2106
- record_used : bool ,
2107
- span : Span )
2108
- -> Result < & ' a NameBinding < ' a > , Determinacy > {
2118
+ fn resolve_ident_in_module (
2119
+ & mut self ,
2120
+ module : ModuleOrUniformRoot < ' a > ,
2121
+ mut ident : Ident ,
2122
+ ns : Namespace ,
2123
+ parent_scope : Option < & ParentScope < ' a > > ,
2124
+ record_used : bool ,
2125
+ path_span : Span
2126
+ ) -> Result < & ' a NameBinding < ' a > , Determinacy > {
2109
2127
ident. span = ident. span . modern ( ) ;
2110
2128
let orig_current_module = self . current_module ;
2111
- if let ModuleOrUniformRoot :: Module ( module) = module {
2112
- if let Some ( def) = ident. span . adjust ( module. expansion ) {
2113
- self . current_module = self . macro_def_scope ( def) ;
2129
+ match module {
2130
+ ModuleOrUniformRoot :: Module ( module) => {
2131
+ if let Some ( def) = ident. span . adjust ( module. expansion ) {
2132
+ self . current_module = self . macro_def_scope ( def) ;
2133
+ }
2134
+ }
2135
+ ModuleOrUniformRoot :: UniformRoot ( UniformRootKind :: ExternPrelude ) => {
2136
+ ident. span . adjust ( Mark :: root ( ) ) ;
2114
2137
}
2138
+ _ => { }
2115
2139
}
2116
- let result = self . resolve_ident_in_module_unadjusted (
2117
- module, ident, ns, record_used, span ,
2118
- ) ;
2140
+ let result = self . resolve_ident_in_module_unadjusted_ext (
2141
+ module, ident, ns, parent_scope , false , record_used, path_span ,
2142
+ ) . map_err ( DeterminacyExt :: to_determinacy ) ;
2119
2143
self . current_module = orig_current_module;
2120
2144
result
2121
2145
}
@@ -2614,6 +2638,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
2614
2638
ModuleOrUniformRoot :: Module ( module) ,
2615
2639
ident,
2616
2640
ns,
2641
+ None ,
2617
2642
false ,
2618
2643
span,
2619
2644
) . is_err ( ) {
@@ -3624,9 +3649,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3624
3649
continue ;
3625
3650
}
3626
3651
if name == keywords:: Extern . name ( ) ||
3627
- name == keywords:: CrateRoot . name ( ) &&
3628
- self . session . rust_2018 ( ) {
3629
- module = Some ( ModuleOrUniformRoot :: UniformRoot ( name ) ) ;
3652
+ name == keywords:: CrateRoot . name ( ) && self . session . rust_2018 ( ) {
3653
+ module =
3654
+ Some ( ModuleOrUniformRoot :: UniformRoot ( UniformRootKind :: ExternPrelude ) ) ;
3630
3655
continue ;
3631
3656
}
3632
3657
if name == keywords:: CrateRoot . name ( ) ||
@@ -3656,7 +3681,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3656
3681
}
3657
3682
3658
3683
let binding = if let Some ( module) = module {
3659
- self . resolve_ident_in_module ( module, ident, ns, record_used, path_span)
3684
+ self . resolve_ident_in_module ( module, ident, ns, None , record_used, path_span)
3660
3685
} else if opt_ns. is_none ( ) || opt_ns == Some ( MacroNS ) {
3661
3686
assert ! ( ns == TypeNS ) ;
3662
3687
self . early_resolve_ident_in_lexical_scope ( ident, ns, None , opt_ns. is_none ( ) ,
@@ -3675,7 +3700,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3675
3700
def, path. len ( ) - 1
3676
3701
) ) ;
3677
3702
}
3678
- _ => Err ( if record_used { Determined } else { Undetermined } ) ,
3703
+ _ => Err ( Determinacy :: determined ( record_used) ) ,
3679
3704
}
3680
3705
} ;
3681
3706
@@ -3748,7 +3773,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3748
3773
3749
3774
PathResult :: Module ( match module {
3750
3775
Some ( module) => module,
3751
- None if path. is_empty ( ) => ModuleOrUniformRoot :: UniformRoot ( keywords:: Invalid . name ( ) ) ,
3776
+ None if path. is_empty ( ) =>
3777
+ ModuleOrUniformRoot :: UniformRoot ( UniformRootKind :: CurrentScope ) ,
3752
3778
_ => span_bug ! ( path_span, "resolve_path: non-empty path `{:?}` has no module" , path) ,
3753
3779
} )
3754
3780
}
@@ -3960,6 +3986,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
3960
3986
ModuleOrUniformRoot :: Module ( module) ,
3961
3987
ident,
3962
3988
ns,
3989
+ None ,
3963
3990
false ,
3964
3991
module. span ,
3965
3992
) {
@@ -4282,6 +4309,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4282
4309
ModuleOrUniformRoot :: Module ( module) ,
4283
4310
ident,
4284
4311
ns,
4312
+ None ,
4285
4313
false ,
4286
4314
module. span ,
4287
4315
) . is_ok ( ) {
@@ -4879,6 +4907,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
4879
4907
4880
4908
fn extern_prelude_get ( & mut self , ident : Ident , speculative : bool , skip_feature_gate : bool )
4881
4909
-> Option < & ' a NameBinding < ' a > > {
4910
+ if ident. is_path_segment_keyword ( ) {
4911
+ // Make sure `self`, `super` etc produce an error when passed to here.
4912
+ return None ;
4913
+ }
4882
4914
self . extern_prelude . get ( & ident. modern ( ) ) . cloned ( ) . and_then ( |entry| {
4883
4915
if let Some ( binding) = entry. extern_crate_item {
4884
4916
if !speculative && !skip_feature_gate && entry. introduced_by_item &&
0 commit comments