Skip to content

Commit 5e12175

Browse files
committed
resolve: Generalize early_resolve_ident_in_lexical_scope slightly
Flatten `ModuleOrUniformRoot` variants
1 parent c06e69e commit 5e12175

File tree

3 files changed

+78
-82
lines changed

3 files changed

+78
-82
lines changed

src/librustc_resolve/lib.rs

+25-26
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
}
@@ -1758,8 +1761,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
17581761
error_callback(self, span, ResolutionError::FailedToResolve(msg));
17591762
Def::Err
17601763
}
1761-
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
1762-
PathResult::Indeterminate => unreachable!(),
1764+
PathResult::Module(..) | PathResult::Indeterminate => unreachable!(),
17631765
PathResult::Failed(span, msg, _) => {
17641766
error_callback(self, span, ResolutionError::FailedToResolve(&msg));
17651767
Def::Err
@@ -2220,11 +2222,11 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
22202222
self.current_module = self.macro_def_scope(def);
22212223
}
22222224
}
2223-
ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude) => {
2225+
ModuleOrUniformRoot::ExternPrelude => {
22242226
ident.span = ident.span.modern();
22252227
ident.span.adjust(Mark::root());
22262228
}
2227-
ModuleOrUniformRoot::UniformRoot(UniformRootKind::CurrentScope) => {
2229+
ModuleOrUniformRoot::CurrentScope => {
22282230
// No adjustments
22292231
}
22302232
}
@@ -3667,8 +3669,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
36673669
resolve_error(self, span, ResolutionError::FailedToResolve(&msg));
36683670
err_path_resolution()
36693671
}
3670-
PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) |
3671-
PathResult::Failed(..) => return None,
3672+
PathResult::Module(..) | PathResult::Failed(..) => return None,
36723673
PathResult::Indeterminate => bug!("indetermined path result in resolve_qpath"),
36733674
};
36743675

@@ -3787,8 +3788,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
37873788
}
37883789
if name == keywords::Extern.name() ||
37893790
name == keywords::CrateRoot.name() && ident.span.rust_2018() {
3790-
module =
3791-
Some(ModuleOrUniformRoot::UniformRoot(UniformRootKind::ExternPrelude));
3791+
module = Some(ModuleOrUniformRoot::ExternPrelude);
37923792
continue;
37933793
}
37943794
if name == keywords::CrateRoot.name() ||
@@ -3821,9 +3821,9 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
38213821
self.resolve_ident_in_module(module, ident, ns, None, record_used, path_span)
38223822
} else if opt_ns.is_none() || opt_ns == Some(MacroNS) {
38233823
assert!(ns == TypeNS);
3824-
self.early_resolve_ident_in_lexical_scope(ident, ns, None, opt_ns.is_none(),
3825-
parent_scope, record_used, record_used,
3826-
path_span)
3824+
let scopes = if opt_ns.is_none() { ScopeSet::Import(ns) } else { ScopeSet::Module };
3825+
self.early_resolve_ident_in_lexical_scope(ident, scopes, parent_scope, record_used,
3826+
record_used, path_span)
38273827
} else {
38283828
let record_used_id =
38293829
if record_used { crate_lint.node_id().or(Some(CRATE_NODE_ID)) } else { None };
@@ -3912,8 +3912,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> {
39123912

39133913
PathResult::Module(match module {
39143914
Some(module) => module,
3915-
None if path.is_empty() =>
3916-
ModuleOrUniformRoot::UniformRoot(UniformRootKind::CurrentScope),
3915+
None if path.is_empty() => ModuleOrUniformRoot::CurrentScope,
39173916
_ => span_bug!(path_span, "resolve_path: non-empty path `{:?}` has no module", path),
39183917
})
39193918
}

src/librustc_resolve/macros.rs

+13-11
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, Segment, Weak};
13-
use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding};
12+
use {CrateLint, Resolver, ResolutionError, ScopeSet, Weak};
13+
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

+40-45
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,45 +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) = self.extern_prelude_get(ident, !record_used) {
170-
Ok(binding)
171-
} else if !self.graph_root.unresolved_invocations.borrow().is_empty() {
172-
// Macro-expanded `extern crate` items can add names to extern prelude.
173-
Err((Undetermined, Weak::No))
174-
} else {
175-
Err((Determined, Weak::No))
176-
}
177-
}
178-
UniformRootKind::CurrentScope => {
179-
let parent_scope =
180-
parent_scope.expect("no parent scope for a single-segment import");
181-
182-
if ns == TypeNS {
183-
if ident.name == keywords::Crate.name() ||
184-
ident.name == keywords::DollarCrate.name() {
185-
let module = self.resolve_crate_root(ident);
186-
let binding = (module, ty::Visibility::Public,
187-
module.span, Mark::root())
188-
.to_name_binding(self.arenas);
189-
return Ok(binding);
190-
} else if ident.name == keywords::Super.name() ||
191-
ident.name == keywords::SelfValue.name() {
192-
// FIXME: Implement these with renaming requirements so that e.g.
193-
// `use super;` doesn't work, but `use super as name;` does.
194-
// Fall through here to get an error from `early_resolve_...`.
195-
}
196-
}
197-
198-
let binding = self.early_resolve_ident_in_lexical_scope(
199-
ident, ns, None, true, parent_scope, record_used, record_used, path_span
200-
);
201-
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_...`.
202194
}
203195
}
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));
204201
}
205202
};
206203

@@ -333,7 +330,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> {
333330
}
334331
let module = match glob_import.imported_module.get() {
335332
Some(ModuleOrUniformRoot::Module(module)) => module,
336-
Some(ModuleOrUniformRoot::UniformRoot(_)) => continue,
333+
Some(_) => continue,
337334
None => return Err((Undetermined, Weak::Yes)),
338335
};
339336
let (orig_current_module, mut ident) = (self.current_module, ident.modern());
@@ -966,9 +963,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
966963

967964
return if all_ns_failed {
968965
let resolutions = match module {
969-
ModuleOrUniformRoot::Module(module) =>
970-
Some(module.resolutions.borrow()),
971-
ModuleOrUniformRoot::UniformRoot(_) => None,
966+
ModuleOrUniformRoot::Module(module) => Some(module.resolutions.borrow()),
967+
_ => None,
972968
};
973969
let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
974970
let names = resolutions.filter_map(|(&(ref i, _), resolution)| {
@@ -1006,7 +1002,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
10061002
format!("no `{}` in the root{}", ident, lev_suggestion)
10071003
}
10081004
}
1009-
ModuleOrUniformRoot::UniformRoot(_) => {
1005+
_ => {
10101006
if !ident.is_path_segment_keyword() {
10111007
format!("no `{}` external crate{}", ident, lev_suggestion)
10121008
} else {
@@ -1107,9 +1103,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> {
11071103
fn resolve_glob_import(&mut self, directive: &'b ImportDirective<'b>) {
11081104
let module = match directive.imported_module.get().unwrap() {
11091105
ModuleOrUniformRoot::Module(module) => module,
1110-
ModuleOrUniformRoot::UniformRoot(_) => {
1111-
self.session.span_err(directive.span,
1112-
"cannot glob-import all possible crates");
1106+
_ => {
1107+
self.session.span_err(directive.span, "cannot glob-import all possible crates");
11131108
return;
11141109
}
11151110
};

0 commit comments

Comments
 (0)