resolve: Populate external modules in more automatic and lazy way
The modules are now populated implicitly on the first access
This commit is contained in:
parent
9dd5c19199
commit
ea81d8cedb
6 changed files with 73 additions and 71 deletions
|
@ -159,19 +159,6 @@ impl<'a> Resolver<'a> {
|
||||||
Some(ext)
|
Some(ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures that the reduced graph rooted at the given external module
|
|
||||||
/// is built, building it if it is not.
|
|
||||||
crate fn populate_module_if_necessary(&mut self, module: Module<'a>) {
|
|
||||||
if module.populated.get() { return }
|
|
||||||
let def_id = module.def_id().unwrap();
|
|
||||||
for child in self.cstore.item_children_untracked(def_id, self.session) {
|
|
||||||
let child = child.map_id(|_| panic!("unexpected id"));
|
|
||||||
BuildReducedGraphVisitor { parent_scope: ParentScope::module(module), r: self }
|
|
||||||
.build_reduced_graph_for_external_crate_res(child);
|
|
||||||
}
|
|
||||||
module.populated.set(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
crate fn build_reduced_graph(
|
crate fn build_reduced_graph(
|
||||||
&mut self, fragment: &AstFragment, parent_scope: ParentScope<'a>
|
&mut self, fragment: &AstFragment, parent_scope: ParentScope<'a>
|
||||||
) -> LegacyScope<'a> {
|
) -> LegacyScope<'a> {
|
||||||
|
@ -186,6 +173,10 @@ struct BuildReducedGraphVisitor<'a, 'b> {
|
||||||
parent_scope: ParentScope<'a>,
|
parent_scope: ParentScope<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> AsMut<Resolver<'a>> for BuildReducedGraphVisitor<'a, '_> {
|
||||||
|
fn as_mut(&mut self) -> &mut Resolver<'a> { self.r }
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||||
fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
|
fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility {
|
||||||
let parent_scope = &self.parent_scope;
|
let parent_scope = &self.parent_scope;
|
||||||
|
@ -603,8 +594,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||||
self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
|
self.r.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX })
|
||||||
};
|
};
|
||||||
|
|
||||||
self.r.populate_module_if_necessary(module);
|
|
||||||
|
|
||||||
let used = self.process_legacy_macro_imports(item, module);
|
let used = self.process_legacy_macro_imports(item, module);
|
||||||
let binding =
|
let binding =
|
||||||
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
|
(module, ty::Visibility::Public, sp, expansion).to_name_binding(self.r.arenas);
|
||||||
|
@ -922,6 +911,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||||
span);
|
span);
|
||||||
self.r.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
|
self.r.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion));
|
||||||
|
|
||||||
|
module.populate_on_access.set(false);
|
||||||
for child in self.r.cstore.item_children_untracked(def_id, self.r.session) {
|
for child in self.r.cstore.item_children_untracked(def_id, self.r.session) {
|
||||||
let res = child.res.map_id(|_| panic!("unexpected id"));
|
let res = child.res.map_id(|_| panic!("unexpected id"));
|
||||||
let ns = if let Res::Def(DefKind::AssocTy, _) = res {
|
let ns = if let Res::Def(DefKind::AssocTy, _) = res {
|
||||||
|
@ -935,7 +925,6 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||||
self.r.has_self.insert(res.def_id());
|
self.r.has_self.insert(res.def_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.populated.set(true);
|
|
||||||
}
|
}
|
||||||
Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => {
|
Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => {
|
||||||
self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion));
|
self.r.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion));
|
||||||
|
@ -952,7 +941,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn legacy_import_macro(&mut self,
|
fn legacy_import_macro(&mut self,
|
||||||
name: Name,
|
name: ast::Name,
|
||||||
binding: &'a NameBinding<'a>,
|
binding: &'a NameBinding<'a>,
|
||||||
span: Span,
|
span: Span,
|
||||||
allow_shadowing: bool) {
|
allow_shadowing: bool) {
|
||||||
|
@ -1021,9 +1010,9 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||||
if let Some(span) = import_all {
|
if let Some(span) = import_all {
|
||||||
let directive = macro_use_directive(self, span);
|
let directive = macro_use_directive(self, span);
|
||||||
self.r.potentially_unused_imports.push(directive);
|
self.r.potentially_unused_imports.push(directive);
|
||||||
module.for_each_child(|ident, ns, binding| if ns == MacroNS {
|
module.for_each_child(self, |this, ident, ns, binding| if ns == MacroNS {
|
||||||
let imported_binding = self.r.import(binding, directive);
|
let imported_binding = this.r.import(binding, directive);
|
||||||
self.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
|
this.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
for ident in single_imports.iter().cloned() {
|
for ident in single_imports.iter().cloned() {
|
||||||
|
|
|
@ -73,10 +73,13 @@ crate fn add_typo_suggestion(
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn add_module_candidates(
|
crate fn add_module_candidates<'a>(
|
||||||
module: Module<'_>, names: &mut Vec<TypoSuggestion>, filter_fn: &impl Fn(Res) -> bool
|
resolver: &mut Resolver<'a>,
|
||||||
|
module: Module<'a>,
|
||||||
|
names: &mut Vec<TypoSuggestion>,
|
||||||
|
filter_fn: &impl Fn(Res) -> bool,
|
||||||
) {
|
) {
|
||||||
for (&(ident, _), resolution) in module.resolutions.borrow().iter() {
|
for (&(ident, _), resolution) in resolver.resolutions(module).borrow().iter() {
|
||||||
if let Some(binding) = resolution.borrow().binding {
|
if let Some(binding) = resolution.borrow().binding {
|
||||||
let res = binding.res();
|
let res = binding.res();
|
||||||
if filter_fn(res) {
|
if filter_fn(res) {
|
||||||
|
@ -402,10 +405,10 @@ impl<'a> Resolver<'a> {
|
||||||
Scope::CrateRoot => {
|
Scope::CrateRoot => {
|
||||||
let root_ident = Ident::new(kw::PathRoot, ident.span);
|
let root_ident = Ident::new(kw::PathRoot, ident.span);
|
||||||
let root_module = this.resolve_crate_root(root_ident);
|
let root_module = this.resolve_crate_root(root_ident);
|
||||||
add_module_candidates(root_module, &mut suggestions, filter_fn);
|
add_module_candidates(this, root_module, &mut suggestions, filter_fn);
|
||||||
}
|
}
|
||||||
Scope::Module(module) => {
|
Scope::Module(module) => {
|
||||||
add_module_candidates(module, &mut suggestions, filter_fn);
|
add_module_candidates(this, module, &mut suggestions, filter_fn);
|
||||||
}
|
}
|
||||||
Scope::MacroUsePrelude => {
|
Scope::MacroUsePrelude => {
|
||||||
suggestions.extend(this.macro_use_prelude.iter().filter_map(|(name, binding)| {
|
suggestions.extend(this.macro_use_prelude.iter().filter_map(|(name, binding)| {
|
||||||
|
@ -453,7 +456,7 @@ impl<'a> Resolver<'a> {
|
||||||
Scope::StdLibPrelude => {
|
Scope::StdLibPrelude => {
|
||||||
if let Some(prelude) = this.prelude {
|
if let Some(prelude) = this.prelude {
|
||||||
let mut tmp_suggestions = Vec::new();
|
let mut tmp_suggestions = Vec::new();
|
||||||
add_module_candidates(prelude, &mut tmp_suggestions, filter_fn);
|
add_module_candidates(this, prelude, &mut tmp_suggestions, filter_fn);
|
||||||
suggestions.extend(tmp_suggestions.into_iter().filter(|s| {
|
suggestions.extend(tmp_suggestions.into_iter().filter(|s| {
|
||||||
use_prelude || this.is_builtin_macro(s.res)
|
use_prelude || this.is_builtin_macro(s.res)
|
||||||
}));
|
}));
|
||||||
|
@ -509,11 +512,9 @@ impl<'a> Resolver<'a> {
|
||||||
while let Some((in_module,
|
while let Some((in_module,
|
||||||
path_segments,
|
path_segments,
|
||||||
in_module_is_extern)) = worklist.pop() {
|
in_module_is_extern)) = worklist.pop() {
|
||||||
self.populate_module_if_necessary(in_module);
|
|
||||||
|
|
||||||
// We have to visit module children in deterministic order to avoid
|
// We have to visit module children in deterministic order to avoid
|
||||||
// instabilities in reported imports (#43552).
|
// instabilities in reported imports (#43552).
|
||||||
in_module.for_each_child_stable(|ident, ns, name_binding| {
|
in_module.for_each_child_stable(self, |this, ident, ns, name_binding| {
|
||||||
// avoid imports entirely
|
// avoid imports entirely
|
||||||
if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
|
if name_binding.is_import() && !name_binding.is_extern_crate() { return; }
|
||||||
// avoid non-importable candidates as well
|
// avoid non-importable candidates as well
|
||||||
|
@ -547,7 +548,7 @@ impl<'a> Resolver<'a> {
|
||||||
// outside crate private modules => no need to check this)
|
// outside crate private modules => no need to check this)
|
||||||
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
|
if !in_module_is_extern || name_binding.vis == ty::Visibility::Public {
|
||||||
let did = match res {
|
let did = match res {
|
||||||
Res::Def(DefKind::Ctor(..), did) => self.parent(did),
|
Res::Def(DefKind::Ctor(..), did) => this.parent(did),
|
||||||
_ => res.opt_def_id(),
|
_ => res.opt_def_id(),
|
||||||
};
|
};
|
||||||
candidates.push(ImportSuggestion { did, path });
|
candidates.push(ImportSuggestion { did, path });
|
||||||
|
@ -607,8 +608,6 @@ impl<'a> Resolver<'a> {
|
||||||
krate: crate_id,
|
krate: crate_id,
|
||||||
index: CRATE_DEF_INDEX,
|
index: CRATE_DEF_INDEX,
|
||||||
});
|
});
|
||||||
self.populate_module_if_necessary(&crate_root);
|
|
||||||
|
|
||||||
suggestions.extend(self.lookup_import_candidates_from_module(
|
suggestions.extend(self.lookup_import_candidates_from_module(
|
||||||
lookup_ident, namespace, crate_root, ident, &filter_fn));
|
lookup_ident, namespace, crate_root, ident, &filter_fn));
|
||||||
}
|
}
|
||||||
|
@ -805,7 +804,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||||
/// at the root of the crate instead of the module where it is defined
|
/// at the root of the crate instead of the module where it is defined
|
||||||
/// ```
|
/// ```
|
||||||
pub(crate) fn check_for_module_export_macro(
|
pub(crate) fn check_for_module_export_macro(
|
||||||
&self,
|
&mut self,
|
||||||
directive: &'b ImportDirective<'b>,
|
directive: &'b ImportDirective<'b>,
|
||||||
module: ModuleOrUniformRoot<'b>,
|
module: ModuleOrUniformRoot<'b>,
|
||||||
ident: Ident,
|
ident: Ident,
|
||||||
|
@ -826,7 +825,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let resolutions = crate_module.resolutions.borrow();
|
let resolutions = self.r.resolutions(crate_module).borrow();
|
||||||
let resolution = resolutions.get(&(ident, MacroNS))?;
|
let resolution = resolutions.get(&(ident, MacroNS))?;
|
||||||
let binding = resolution.borrow().binding()?;
|
let binding = resolution.borrow().binding()?;
|
||||||
if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
|
if let Res::Def(DefKind::Macro(MacroKind::Bang), _) = binding.res() {
|
||||||
|
|
|
@ -1929,7 +1929,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
|
||||||
let mut traits = module.traits.borrow_mut();
|
let mut traits = module.traits.borrow_mut();
|
||||||
if traits.is_none() {
|
if traits.is_none() {
|
||||||
let mut collected_traits = Vec::new();
|
let mut collected_traits = Vec::new();
|
||||||
module.for_each_child(|name, ns, binding| {
|
module.for_each_child(self.r, |_, name, ns, binding| {
|
||||||
if ns != TypeNS { return }
|
if ns != TypeNS { return }
|
||||||
match binding.res() {
|
match binding.res() {
|
||||||
Res::Def(DefKind::Trait, _) |
|
Res::Def(DefKind::Trait, _) |
|
||||||
|
|
|
@ -548,7 +548,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
|
||||||
// Items in scope
|
// Items in scope
|
||||||
if let RibKind::ModuleRibKind(module) = rib.kind {
|
if let RibKind::ModuleRibKind(module) = rib.kind {
|
||||||
// Items from this module
|
// Items from this module
|
||||||
add_module_candidates(module, &mut names, &filter_fn);
|
add_module_candidates(self.r, module, &mut names, &filter_fn);
|
||||||
|
|
||||||
if let ModuleKind::Block(..) = module.kind {
|
if let ModuleKind::Block(..) = module.kind {
|
||||||
// We can see through blocks
|
// We can see through blocks
|
||||||
|
@ -577,7 +577,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
if let Some(prelude) = self.r.prelude {
|
if let Some(prelude) = self.r.prelude {
|
||||||
add_module_candidates(prelude, &mut names, &filter_fn);
|
add_module_candidates(self.r, prelude, &mut names, &filter_fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -599,7 +599,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
|
||||||
mod_path, Some(TypeNS), false, span, CrateLint::No
|
mod_path, Some(TypeNS), false, span, CrateLint::No
|
||||||
) {
|
) {
|
||||||
if let ModuleOrUniformRoot::Module(module) = module {
|
if let ModuleOrUniformRoot::Module(module) = module {
|
||||||
add_module_candidates(module, &mut names, &filter_fn);
|
add_module_candidates(self.r, module, &mut names, &filter_fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -717,9 +717,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
|
||||||
// abort if the module is already found
|
// abort if the module is already found
|
||||||
if result.is_some() { break; }
|
if result.is_some() { break; }
|
||||||
|
|
||||||
self.r.populate_module_if_necessary(in_module);
|
in_module.for_each_child_stable(self.r, |_, ident, _, name_binding| {
|
||||||
|
|
||||||
in_module.for_each_child_stable(|ident, _, name_binding| {
|
|
||||||
// abort if the module is already found or if name_binding is private external
|
// abort if the module is already found or if name_binding is private external
|
||||||
if result.is_some() || !name_binding.vis.is_visible_locally() {
|
if result.is_some() || !name_binding.vis.is_visible_locally() {
|
||||||
return
|
return
|
||||||
|
@ -750,10 +748,8 @@ impl<'a> LateResolutionVisitor<'a, '_> {
|
||||||
|
|
||||||
fn collect_enum_variants(&mut self, def_id: DefId) -> Option<Vec<Path>> {
|
fn collect_enum_variants(&mut self, def_id: DefId) -> Option<Vec<Path>> {
|
||||||
self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| {
|
self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| {
|
||||||
self.r.populate_module_if_necessary(enum_module);
|
|
||||||
|
|
||||||
let mut variants = Vec::new();
|
let mut variants = Vec::new();
|
||||||
enum_module.for_each_child_stable(|ident, _, name_binding| {
|
enum_module.for_each_child_stable(self.r, |_, ident, _, name_binding| {
|
||||||
if let Res::Def(DefKind::Variant, _) = name_binding.res() {
|
if let Res::Def(DefKind::Variant, _) = name_binding.res() {
|
||||||
let mut segms = enum_import_suggestion.path.segments.clone();
|
let mut segms = enum_import_suggestion.path.segments.clone();
|
||||||
segms.push(ast::PathSegment::from_ident(ident));
|
segms.push(ast::PathSegment::from_ident(ident));
|
||||||
|
|
|
@ -431,6 +431,8 @@ impl ModuleKind {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Resolutions<'a> = RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>;
|
||||||
|
|
||||||
/// One node in the tree of modules.
|
/// One node in the tree of modules.
|
||||||
pub struct ModuleData<'a> {
|
pub struct ModuleData<'a> {
|
||||||
parent: Option<Module<'a>>,
|
parent: Option<Module<'a>>,
|
||||||
|
@ -439,7 +441,11 @@ pub struct ModuleData<'a> {
|
||||||
// The def id of the closest normal module (`mod`) ancestor (including this module).
|
// The def id of the closest normal module (`mod`) ancestor (including this module).
|
||||||
normal_ancestor_id: DefId,
|
normal_ancestor_id: DefId,
|
||||||
|
|
||||||
resolutions: RefCell<FxHashMap<(Ident, Namespace), &'a RefCell<NameResolution<'a>>>>,
|
// Mapping between names and their (possibly in-progress) resolutions in this module.
|
||||||
|
// Resolutions in modules from other crates are not populated until accessed.
|
||||||
|
lazy_resolutions: Resolutions<'a>,
|
||||||
|
// True if this is a module from other crate that needs to be populated on access.
|
||||||
|
populate_on_access: Cell<bool>,
|
||||||
|
|
||||||
// Macro invocations that can expand into items in this module.
|
// Macro invocations that can expand into items in this module.
|
||||||
unresolved_invocations: RefCell<FxHashSet<ExpnId>>,
|
unresolved_invocations: RefCell<FxHashSet<ExpnId>>,
|
||||||
|
@ -452,11 +458,6 @@ pub struct ModuleData<'a> {
|
||||||
// Used to memoize the traits in this module for faster searches through all traits in scope.
|
// Used to memoize the traits in this module for faster searches through all traits in scope.
|
||||||
traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>,
|
traits: RefCell<Option<Box<[(Ident, &'a NameBinding<'a>)]>>>,
|
||||||
|
|
||||||
// Whether this module is populated. If not populated, any attempt to
|
|
||||||
// access the children must be preceded with a
|
|
||||||
// `populate_module_if_necessary` call.
|
|
||||||
populated: Cell<bool>,
|
|
||||||
|
|
||||||
/// Span of the module itself. Used for error reporting.
|
/// Span of the module itself. Used for error reporting.
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
||||||
|
@ -475,30 +476,34 @@ impl<'a> ModuleData<'a> {
|
||||||
parent,
|
parent,
|
||||||
kind,
|
kind,
|
||||||
normal_ancestor_id,
|
normal_ancestor_id,
|
||||||
resolutions: Default::default(),
|
lazy_resolutions: Default::default(),
|
||||||
|
populate_on_access: Cell::new(!normal_ancestor_id.is_local()),
|
||||||
unresolved_invocations: Default::default(),
|
unresolved_invocations: Default::default(),
|
||||||
no_implicit_prelude: false,
|
no_implicit_prelude: false,
|
||||||
glob_importers: RefCell::new(Vec::new()),
|
glob_importers: RefCell::new(Vec::new()),
|
||||||
globs: RefCell::new(Vec::new()),
|
globs: RefCell::new(Vec::new()),
|
||||||
traits: RefCell::new(None),
|
traits: RefCell::new(None),
|
||||||
populated: Cell::new(normal_ancestor_id.is_local()),
|
|
||||||
span,
|
span,
|
||||||
expansion,
|
expansion,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_each_child<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
|
fn for_each_child<R, F>(&'a self, resolver: &mut R, mut f: F)
|
||||||
for (&(ident, ns), name_resolution) in self.resolutions.borrow().iter() {
|
where R: AsMut<Resolver<'a>>, F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>)
|
||||||
name_resolution.borrow().binding.map(|binding| f(ident, ns, binding));
|
{
|
||||||
|
for (&(ident, ns), name_resolution) in resolver.as_mut().resolutions(self).borrow().iter() {
|
||||||
|
name_resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn for_each_child_stable<F: FnMut(Ident, Namespace, &'a NameBinding<'a>)>(&self, mut f: F) {
|
fn for_each_child_stable<R, F>(&'a self, resolver: &mut R, mut f: F)
|
||||||
let resolutions = self.resolutions.borrow();
|
where R: AsMut<Resolver<'a>>, F: FnMut(&mut R, Ident, Namespace, &'a NameBinding<'a>)
|
||||||
|
{
|
||||||
|
let resolutions = resolver.as_mut().resolutions(self).borrow();
|
||||||
let mut resolutions = resolutions.iter().collect::<Vec<_>>();
|
let mut resolutions = resolutions.iter().collect::<Vec<_>>();
|
||||||
resolutions.sort_by_cached_key(|&(&(ident, ns), _)| (ident.as_str(), ns));
|
resolutions.sort_by_cached_key(|&(&(ident, ns), _)| (ident.as_str(), ns));
|
||||||
for &(&(ident, ns), &resolution) in resolutions.iter() {
|
for &(&(ident, ns), &resolution) in resolutions.iter() {
|
||||||
resolution.borrow().binding.map(|binding| f(ident, ns, binding));
|
resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -983,6 +988,10 @@ impl<'a> ResolverArenas<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'a> AsMut<Resolver<'a>> for Resolver<'a> {
|
||||||
|
fn as_mut(&mut self) -> &mut Resolver<'a> { self }
|
||||||
|
}
|
||||||
|
|
||||||
impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> {
|
impl<'a, 'b> ty::DefIdTree for &'a Resolver<'b> {
|
||||||
fn parent(self, id: DefId) -> Option<DefId> {
|
fn parent(self, id: DefId) -> Option<DefId> {
|
||||||
match id.krate {
|
match id.krate {
|
||||||
|
@ -2634,7 +2643,6 @@ impl<'a> Resolver<'a> {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
|
let crate_root = self.get_module(DefId { krate: crate_id, index: CRATE_DEF_INDEX });
|
||||||
self.populate_module_if_necessary(&crate_root);
|
|
||||||
Some((crate_root, ty::Visibility::Public, DUMMY_SP, ExpnId::root())
|
Some((crate_root, ty::Visibility::Public, DUMMY_SP, ExpnId::root())
|
||||||
.to_name_binding(self.arenas))
|
.to_name_binding(self.arenas))
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,10 @@ use crate::{CrateLint, Module, ModuleOrUniformRoot, PerNS, ScopeSet, ParentScope
|
||||||
use crate::Determinacy::{self, *};
|
use crate::Determinacy::{self, *};
|
||||||
use crate::Namespace::{self, TypeNS, MacroNS};
|
use crate::Namespace::{self, TypeNS, MacroNS};
|
||||||
use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
|
use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError};
|
||||||
use crate::{Resolver, ResolutionError, Segment};
|
use crate::{Resolutions, Resolver, ResolutionError, Segment};
|
||||||
use crate::{names_to_string, module_to_string};
|
use crate::{names_to_string, module_to_string};
|
||||||
use crate::ModuleKind;
|
use crate::ModuleKind;
|
||||||
|
use crate::build_reduced_graph::BuildReducedGraphVisitor;
|
||||||
use crate::diagnostics::Suggestion;
|
use crate::diagnostics::Suggestion;
|
||||||
|
|
||||||
use errors::Applicability;
|
use errors::Applicability;
|
||||||
|
@ -161,9 +162,22 @@ impl<'a> NameResolution<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Resolver<'a> {
|
impl<'a> Resolver<'a> {
|
||||||
crate fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace)
|
crate fn resolutions(&mut self, module: Module<'a>) -> &'a Resolutions<'a> {
|
||||||
|
if module.populate_on_access.get() {
|
||||||
|
module.populate_on_access.set(false);
|
||||||
|
let def_id = module.def_id().expect("unpopulated module without a def-id");
|
||||||
|
for child in self.cstore.item_children_untracked(def_id, self.session) {
|
||||||
|
let child = child.map_id(|_| panic!("unexpected id"));
|
||||||
|
BuildReducedGraphVisitor { parent_scope: self.dummy_parent_scope(), r: self }
|
||||||
|
.build_reduced_graph_for_external_crate_res(module, child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&module.lazy_resolutions
|
||||||
|
}
|
||||||
|
|
||||||
|
crate fn resolution(&mut self, module: Module<'a>, ident: Ident, ns: Namespace)
|
||||||
-> &'a RefCell<NameResolution<'a>> {
|
-> &'a RefCell<NameResolution<'a>> {
|
||||||
*module.resolutions.borrow_mut().entry((ident.modern(), ns))
|
*self.resolutions(module).borrow_mut().entry((ident.modern(), ns))
|
||||||
.or_insert_with(|| self.arenas.alloc_name_resolution())
|
.or_insert_with(|| self.arenas.alloc_name_resolution())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,8 +256,6 @@ impl<'a> Resolver<'a> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.populate_module_if_necessary(module);
|
|
||||||
|
|
||||||
let resolution = self.resolution(module, ident, ns)
|
let resolution = self.resolution(module, ident, ns)
|
||||||
.try_borrow_mut()
|
.try_borrow_mut()
|
||||||
.map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
|
.map_err(|_| (Determined, Weak::No))?; // This happens when there is a cycle of imports.
|
||||||
|
@ -1027,7 +1039,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||||
|
|
||||||
return if all_ns_failed {
|
return if all_ns_failed {
|
||||||
let resolutions = match module {
|
let resolutions = match module {
|
||||||
ModuleOrUniformRoot::Module(module) => Some(module.resolutions.borrow()),
|
ModuleOrUniformRoot::Module(module) => Some(self.r.resolutions(module).borrow()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
|
let resolutions = resolutions.as_ref().into_iter().flat_map(|r| r.iter());
|
||||||
|
@ -1265,8 +1277,6 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.r.populate_module_if_necessary(module);
|
|
||||||
|
|
||||||
if module.is_trait() {
|
if module.is_trait() {
|
||||||
self.r.session.span_err(directive.span, "items in traits are not importable.");
|
self.r.session.span_err(directive.span, "items in traits are not importable.");
|
||||||
return;
|
return;
|
||||||
|
@ -1282,7 +1292,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||||
|
|
||||||
// Ensure that `resolutions` isn't borrowed during `try_define`,
|
// Ensure that `resolutions` isn't borrowed during `try_define`,
|
||||||
// since it might get updated via a glob cycle.
|
// since it might get updated via a glob cycle.
|
||||||
let bindings = module.resolutions.borrow().iter().filter_map(|(&ident, resolution)| {
|
let bindings = self.r.resolutions(module).borrow().iter().filter_map(|(&ident, resolution)| {
|
||||||
resolution.borrow().binding().map(|binding| (ident, binding))
|
resolution.borrow().binding().map(|binding| (ident, binding))
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
for ((mut ident, ns), binding) in bindings {
|
for ((mut ident, ns), binding) in bindings {
|
||||||
|
@ -1310,7 +1320,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||||
|
|
||||||
let mut reexports = Vec::new();
|
let mut reexports = Vec::new();
|
||||||
|
|
||||||
for (&(ident, ns), resolution) in module.resolutions.borrow().iter() {
|
for (&(ident, ns), resolution) in self.r.resolutions(module).borrow().iter() {
|
||||||
let resolution = &mut *resolution.borrow_mut();
|
let resolution = &mut *resolution.borrow_mut();
|
||||||
let binding = match resolution.binding {
|
let binding = match resolution.binding {
|
||||||
Some(binding) => binding,
|
Some(binding) => binding,
|
||||||
|
@ -1369,8 +1379,8 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
|
||||||
Some(ModuleOrUniformRoot::Module(module)) => module,
|
Some(ModuleOrUniformRoot::Module(module)) => module,
|
||||||
_ => bug!("module should exist"),
|
_ => bug!("module should exist"),
|
||||||
};
|
};
|
||||||
let resolutions = imported_module.parent.expect("parent should exist")
|
let parent_module = imported_module.parent.expect("parent should exist");
|
||||||
.resolutions.borrow();
|
let resolutions = self.r.resolutions(parent_module).borrow();
|
||||||
let enum_path_segment_index = directive.module_path.len() - 1;
|
let enum_path_segment_index = directive.module_path.len() - 1;
|
||||||
let enum_ident = directive.module_path[enum_path_segment_index].ident;
|
let enum_ident = directive.module_path[enum_path_segment_index].ident;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue