Skip to content

Commit 2a0adc3

Browse files
committed
resolve: Generalize early_resolve_ident_in_lexical_scope slightly
Flatten `ModuleOrUniformRoot` variants
1 parent 4909733 commit 2a0adc3

File tree

3 files changed

+77
-82
lines changed

3 files changed

+77
-82
lines changed

src/librustc_resolve/lib.rs

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ enum Weak {
102102
No,
103103
}
104104

105+
enum ScopeSet {
106+
Import(Namespace),
107+
Macro(MacroKind),
108+
Module,
109+
}
110+
105111
/// A free importable items suggested in case of resolution failure.
106112
struct ImportSuggestion {
107113
path: Path,
@@ -997,31 +1003,28 @@ impl<'a> LexicalScopeBinding<'a> {
9971003
}
9981004
}
9991005

1000-
1001-
#[derive(Clone, Copy, PartialEq, Debug)]
1002-
enum UniformRootKind {
1003-
CurrentScope,
1004-
ExternPrelude,
1005-
}
1006-
10071006
#[derive(Copy, Clone, Debug)]
10081007
enum ModuleOrUniformRoot<'a> {
10091008
/// Regular module.
10101009
Module(Module<'a>),
10111010

1012-
/// This "virtual module" denotes either resolution in extern prelude
1013-
/// for paths starting with `::` on 2018 edition or `extern::`,
1014-
/// or resolution in current scope for single-segment imports.
1015-
UniformRoot(UniformRootKind),
1011+
/// Virtual module that denotes resolution in extern prelude.
1012+
/// Used for paths starting with `::` on 2018 edition or `extern::`.
1013+
ExternPrelude,
1014+
1015+
/// Virtual module that denotes resolution in current scope.
1016+
/// Used only for resolving single-segment imports. The reason it exists is that import paths
1017+
/// are always split into two parts, the first of which should be some kind of module.
1018+
CurrentScope,
10161019
}
10171020

10181021
impl<'a> PartialEq for ModuleOrUniformRoot<'a> {
10191022
fn eq(&self, other: &Self) -> bool {
10201023
match (*self, *other) {
10211024
(ModuleOrUniformRoot::Module(lhs), ModuleOrUniformRoot::Module(rhs)) =>
10221025
ptr::eq(lhs, rhs),
1023-
(ModuleOrUniformRoot::UniformRoot(lhs), ModuleOrUniformRoot::UniformRoot(rhs)) =>
1024-
lhs == rhs,
1026+
(ModuleOrUniformRoot::ExternPrelude, ModuleOrUniformRoot::ExternPrelude) => true,
1027+
(ModuleOrUniformRoot::CurrentScope, ModuleOrUniformRoot::CurrentScope) => true,
10251028
_ => false,
10261029
}
10271030
}
@@ -1763,8 +1766,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
17631766
error_callback(self, span, ResolutionError::FailedToResolve(msg));
17641767
Def::Err
17651768
}
1766-
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
1767-
PathResult::Indeterminate => unreachable!(),
1769+
PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
17681770
PathResult::Failed(span, msg, _) => {
17691771
error_callback(self, span, ResolutionError::FailedToResolve(&msg));
17701772
Def::Err
@@ -2225,11 +2227,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
22252227
self.current_module = self.macro_def_scope(def);
22262228
}
22272229
}
2228-
ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude) => {
2230+
ModuleOrUniformRoot::ExternPrelude => {
22292231
ident.span = ident.span.modern();
22302232
ident.span.adjust(Mark::root());
22312233
}
2232-
ModuleOrUniformRoot::UniformRoot(UniformRootKind::CurrentScope) => {
2234+
ModuleOrUniformRoot::CurrentScope => {
22332235
// No adjustments
22342236
}
22352237
}
@@ -3669,8 +3671,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
36693671
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
36703672
err_path_resolution()
36713673
}
3672-
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
3673-
PathResult::Failed(..) => return None,
3674+
PathResult::Module(..) | PathResult::Failed(..) => return None,
36743675
PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"),
36753676
};
36763677

@@ -3789,8 +3790,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
37893790
}
37903791
if name == keywords::Extern.name() ||
37913792
name == keywords::CrateRoot.name() && ident.span.rust_2018() {
3792-
module =
3793-
Some(ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude));
3793+
module = Some(ModuleOrUniformRoot::ExternPrelude);
37943794
continue;
37953795
}
37963796
if name == keywords::CrateRoot.name() ||
@@ -3823,9 +3823,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
38233823
self.resolve_ident_in_module(module, ident, ns, None, record_used, path_span)
38243824
} else if opt_ns.is_none() || opt_ns == Some(MacroNS) {
38253825
assert!(ns == TypeNS);
3826-
self.early_resolve_ident_in_lexical_scope(ident, ns, None, opt_ns.is_none(),
3827-
parent_scope, record_used, record_used,
3828-
path_span)
3826+
let scopes = if opt_ns.is_none() { ScopeSet::Import(ns) } else { ScopeSet::Module };
3827+
self.early_resolve_ident_in_lexical_scope(ident, scopes, parent_scope, record_used,
3828+
record_used, path_span)
38293829
} else {
38303830
let record_used_id =
38313831
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
@@ -3914,8 +3914,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
39143914

39153915
PathResult::Module(match module {
39163916
Some(module) => module,
3917-
None if path.is_empty() =>
3918-
ModuleOrUniformRoot::UniformRoot(UniformRootKind::CurrentScope),
3917+
None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
39193918
_ => span_bug!(path_span, "resolve_path: non-empty path `{:?}` has no module", path),
39203919
})
39213920
}

src/librustc_resolve/macros.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
// except according to those terms.
1010

1111
use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
12-
use {CrateLint, Resolver, ResolutionError, Weak};
12+
use {CrateLint, Resolver, ResolutionError, ScopeSet, Weak};
1313
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding};
1414
use {is_known_tool, resolve_error};
1515
use ModuleOrUniformRoot;
16-
use Namespace::{self, *};
16+
use Namespace::*;
1717
use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport};
1818
use resolve_imports::ImportResolver;
1919
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX, DefIndex,
@@ -502,7 +502,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
502502
def
503503
} else {
504504
let binding = self.early_resolve_ident_in_lexical_scope(
505-
path[0].ident, MacroNS, Some(kind), false, parent_scope, false, force, path_span
505+
path[0].ident, ScopeSet::Macro(kind), parent_scope, false, force, path_span
506506
);
507507
match binding {
508508
Ok(..) => {}
@@ -527,9 +527,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
527527
crate fn early_resolve_ident_in_lexical_scope(
528528
&mut self,
529529
orig_ident: Ident,
530-
ns: Namespace,
531-
macro_kind: Option<MacroKind>,
532-
is_import: bool,
530+
scope_set: ScopeSet,
533531
parent_scope: &ParentScope<'a>,
534532
record_used: bool,
535533
force: bool,
@@ -605,8 +603,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
605603
}
606604

607605
assert!(force || !record_used); // `record_used` implies `force`
608-
assert!(macro_kind.is_none() || !is_import); // `is_import` implies no macro kind
609-
let rust_2015 = orig_ident.span.rust_2015();
610606
let mut ident = orig_ident.modern();
611607

612608
// Make sure `self`, `super` etc produce an error when passed to here.
@@ -628,6 +624,12 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
628624
let mut innermost_result: Option<(&NameBinding, Flags)> = None;
629625

630626
// Go through all the scopes and try to resolve the name.
627+
let rust_2015 = orig_ident.span.rust_2015();
628+
let (ns, macro_kind, is_import) = match scope_set {
629+
ScopeSet::Import(ns) => (ns, None, true),
630+
ScopeSet::Macro(macro_kind) => (MacroNS, Some(macro_kind), false),
631+
ScopeSet::Module => (TypeNS, None, false),
632+
};
631633
let mut where_to_resolve = match ns {
632634
_ if is_import && rust_2015 => WhereToResolve::CrateRoot,
633635
TypeNS | ValueNS => WhereToResolve::Module(parent_scope.module),
@@ -1041,7 +1043,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
10411043
let macro_resolutions =
10421044
mem::replace(&mut *module.single_segment_macro_resolutions.borrow_mut(), Vec::new());
10431045
for (ident, kind, parent_scope, initial_binding) in macro_resolutions {
1044-
match self.early_resolve_ident_in_lexical_scope(ident, MacroNS, Some(kind), false,
1046+
match self.early_resolve_ident_in_lexical_scope(ident, ScopeSet::Macro(kind),
10451047
&parent_scope, true, true, ident.span) {
10461048
Ok(binding) => {
10471049
let initial_def = initial_binding.map(|initial_binding| {
@@ -1067,7 +1069,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> {
10671069
let builtin_attrs = mem::replace(&mut *module.builtin_attrs.borrow_mut(), Vec::new());
10681070
for (ident, parent_scope) in builtin_attrs {
10691071
let _ = self.early_resolve_ident_in_lexical_scope(
1070-
ident, MacroNS, Some(MacroKind::Attr), false, &parent_scope, true, true, ident.span
1072+
ident, ScopeSet::Macro(MacroKind::Attr), &parent_scope, true, true, ident.span
10711073
);
10721074
}
10731075
}

src/librustc_resolve/resolve_imports.rs

Lines changed: 40 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use self::ImportDirectiveSubclass::*;
1212

1313
use {AmbiguityError, AmbiguityKind, AmbiguityErrorMisc};
14-
use {CrateLint, Module, ModuleOrUniformRoot, PerNS, UniformRootKind, Weak};
14+
use {CrateLint, Module, ModuleOrUniformRoot, PerNS, ScopeSet, Weak};
1515
use Namespace::{self, TypeNS, MacroNS};
1616
use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
1717
use {Resolver, Segment};
@@ -162,46 +162,42 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
162162
) -> Result<&'a NameBinding<'a>, (Determinacy, Weak)> {
163163
let module = match module {
164164
ModuleOrUniformRoot::Module(module) => module,
165-
ModuleOrUniformRoot::UniformRoot(uniform_root_kind) => {
165+
ModuleOrUniformRoot::ExternPrelude => {
166166
assert!(!restricted_shadowing);
167-
match uniform_root_kind {
168-
UniformRootKind::ExternPrelude => {
169-
return if let Some(binding) =
170-
self.extern_prelude_get(ident, !record_used) {
171-
Ok(binding)
172-
} else if !self.graph_root.unresolved_invocations.borrow().is_empty() {
173-
// Macro-expanded `extern crate` items can add names to extern prelude.
174-
Err((Undetermined, Weak::No))
175-
} else {
176-
Err((Determined, Weak::No))
177-
}
178-
}
179-
UniformRootKind::CurrentScope => {
180-
let parent_scope =
181-
parent_scope.expect("no parent scope for a single-segment import");
182-
183-
if ns == TypeNS {
184-
if ident.name == keywords::Crate.name() ||
185-
ident.name == keywords::DollarCrate.name() {
186-
let module = self.resolve_crate_root(ident);
187-
let binding = (module, ty::Visibility::Public,
188-
module.span, Mark::root())
189-
.to_name_binding(self.arenas);
190-
return Ok(binding);
191-
} else if ident.name == keywords::Super.name() ||
192-
ident.name == keywords::SelfValue.name() {
193-
// FIXME: Implement these with renaming requirements so that e.g.
194-
// `use super;` doesn't work, but `use super as name;` does.
195-
// Fall through here to get an error from `early_resolve_...`.
196-
}
197-
}
198-
199-
let binding = self.early_resolve_ident_in_lexical_scope(
200-
ident, ns, None, true, parent_scope, record_used, record_used, path_span
201-
);
202-
return binding.map_err(|determinacy| (determinacy, Weak::No));
167+
return if let Some(binding) = self.extern_prelude_get(ident, !record_used) {
168+
Ok(binding)
169+
} else if !self.graph_root.unresolved_invocations.borrow().is_empty() {
170+
// Macro-expanded `extern crate` items can add names to extern prelude.
171+
Err((Undetermined, Weak::No))
172+
} else {
173+
Err((Determined, Weak::No))
174+
}
175+
}
176+
ModuleOrUniformRoot::CurrentScope => {
177+
assert!(!restricted_shadowing);
178+
let parent_scope =
179+
parent_scope.expect("no parent scope for a single-segment import");
180+
181+
if ns == TypeNS {
182+
if ident.name == keywords::Crate.name() ||
183+
ident.name == keywords::DollarCrate.name() {
184+
let module = self.resolve_crate_root(ident);
185+
let binding = (module, ty::Visibility::Public,
186+
module.span, Mark::root())
187+
.to_name_binding(self.arenas);
188+
return Ok(binding);
189+
} else if ident.name == keywords::Super.name() ||
190+
ident.name == keywords::SelfValue.name() {
191+
// FIXME: Implement these with renaming requirements so that e.g.
192+
// `use super;` doesn't work, but `use super as name;` does.
193+
// Fall through here to get an error from `early_resolve_...`.
203194
}
204195
}
196+
197+
let binding = self.early_resolve_ident_in_lexical_scope(
198+
ident, ScopeSet::Import(ns), parent_scope, record_used, record_used, path_span
199+
);
200+
return binding.map_err(|determinacy| (determinacy, Weak::No));
205201
}
206202
};
207203

@@ -334,7 +330,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
334330
}
335331
let module = match glob_import.imported_module.get() {
336332
Some(ModuleOrUniformRoot::Module(module)) => module,
337-
Some(ModuleOrUniformRoot::UniformRoot(_)) => continue,
333+
Some(_) => continue,
338334
None => return Err((Undetermined, Weak::Yes)),
339335
};
340336
let (orig_current_module, mut ident) = (self.current_module, ident.modern());
@@ -967,9 +963,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
967963

968964
return if all_ns_failed {
969965
let resolutions = match module {
970-
ModuleOrUniformRoot::Module(module) =>
971-
Some(module.resolutions.borrow()),
972-
ModuleOrUniformRoot::UniformRoot(_) => None,
966+
ModuleOrUniformRoot::Module(module) => Some(module.resolutions.borrow()),
967+
_ => None,
973968
};
974969
let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
975970
let names = resolutions.filter_map(|(&(ref i, _), resolution)| {
@@ -1007,7 +1002,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
10071002
format!("no `{}` in the root{}", ident, lev_suggestion)
10081003
}
10091004
}
1010-
ModuleOrUniformRoot::UniformRoot(_) => {
1005+
_ => {
10111006
if !ident.is_path_segment_keyword() {
10121007
format!("no `{}` external crate{}", ident, lev_suggestion)
10131008
} else {
@@ -1108,9 +1103,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
11081103
fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
11091104
let module = match directive.imported_module.get().unwrap() {
11101105
ModuleOrUniformRoot::Module(module) => module,
1111-
ModuleOrUniformRoot::UniformRoot(_) => {
1112-
self.session.span_err(directive.span,
1113-
"cannot glob-import all possible crates");
1106+
_ => {
1107+
self.session.span_err(directive.span, "cannot glob-import all possible crates");
11141108
return;
11151109
}
11161110
};

0 commit comments

Comments
 (0)