Skip to content

Commit 07af4ec

Browse files
committed
resolve: Resolve single-segment imports using in-scope resolution on 2018 edition
1 parent 1cfd08c commit 07af4ec

File tree

7 files changed

+148
-124
lines changed

7 files changed

+148
-124
lines changed

src/librustc_resolve/build_reduced_graph.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
809809
ModuleOrUniformRoot::Module(module),
810810
ident,
811811
MacroNS,
812+
None,
812813
false,
813814
span,
814815
);

src/librustc_resolve/lib.rs

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
107116
struct 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 &&

src/librustc_resolve/macros.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,11 +371,11 @@ impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> {
371371
}
372372

373373
impl<'a, 'cl> Resolver<'a, 'cl> {
374-
pub fn dummy_parent_scope(&mut self) -> ParentScope<'a> {
374+
pub fn dummy_parent_scope(&self) -> ParentScope<'a> {
375375
self.invoc_parent_scope(Mark::root(), Vec::new())
376376
}
377377

378-
fn invoc_parent_scope(&mut self, invoc_id: Mark, derives: Vec<ast::Path>) -> ParentScope<'a> {
378+
fn invoc_parent_scope(&self, invoc_id: Mark, derives: Vec<ast::Path>) -> ParentScope<'a> {
379379
let invoc = self.invocations[&invoc_id];
380380
ParentScope {
381381
module: invoc.module.get().nearest_item_scope(),
@@ -610,6 +610,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
610610
assert!(macro_kind.is_none() || !is_import); // `is_import` implies no macro kind
611611
ident = ident.modern();
612612

613+
// Make sure `self`, `super` etc produce an error when passed to here.
614+
if ident.is_path_segment_keyword() {
615+
return Err(Determinacy::Determined);
616+
}
617+
613618
// This is *the* result, resolution from the scope closest to the resolved identifier.
614619
// However, sometimes this result is "weak" because it comes from a glob import or
615620
// a macro expansion, and in this case it cannot shadow names from outer scopes, e.g.
@@ -671,6 +676,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
671676
ModuleOrUniformRoot::Module(module),
672677
ident,
673678
ns,
679+
None,
674680
true,
675681
record_used,
676682
path_span,

0 commit comments

Comments
 (0)