diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 79eeae1847952..76620bb31232c 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -653,7 +653,9 @@ impl<'a> Resolver<'a> { span); self.define(parent, ident, TypeNS, (module, vis, DUMMY_SP, expansion)); } - Res::Def(DefKind::Variant, _) + Res::Def(DefKind::Struct, _) + | Res::Def(DefKind::Union, _) + | Res::Def(DefKind::Variant, _) | Res::Def(DefKind::TyAlias, _) | Res::Def(DefKind::ForeignTy, _) | Res::Def(DefKind::Existential, _) @@ -663,37 +665,33 @@ impl<'a> Resolver<'a> { | Res::PrimTy(..) | Res::ToolMod => { self.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion)); + + if let Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) = res { + // Record field names for error reporting. + let field_names = self.cstore.struct_field_names_untracked(def_id); + self.insert_field_names(def_id, field_names); + } } Res::Def(DefKind::Fn, _) + | Res::Def(DefKind::Method, _) | Res::Def(DefKind::Static, _) | Res::Def(DefKind::Const, _) | Res::Def(DefKind::AssocConst, _) - | Res::Def(DefKind::Ctor(CtorOf::Variant, ..), _) => { - self.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)); - } - Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) => { - self.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)); - - if let Some(struct_def_id) = - self.cstore.def_key(def_id).parent - .map(|index| DefId { krate: def_id.krate, index: index }) { - self.struct_constructors.insert(struct_def_id, (res, vis)); - } - } - Res::Def(DefKind::Method, def_id) => { + | Res::Def(DefKind::Ctor(..), _) => { self.define(parent, ident, ValueNS, (res, vis, DUMMY_SP, expansion)); - if self.cstore.associated_item_cloned_untracked(def_id).method_has_self_argument { - self.has_self.insert(def_id); + if let Res::Def(DefKind::Method, def_id) = res { + let assoc_item = self.cstore.associated_item_cloned_untracked(def_id); + if assoc_item.method_has_self_argument { + self.has_self.insert(def_id); + } + } else if let Res::Def(DefKind::Ctor(CtorOf::Struct, ..), def_id) = res { + let parent = self.cstore.def_key(def_id).parent; + if let Some(struct_def_id) = parent.map(|index| DefId { index, ..def_id }) { + self.struct_constructors.insert(struct_def_id, (res, vis)); + } } } - Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) => { - self.define(parent, ident, TypeNS, (res, vis, DUMMY_SP, expansion)); - - // Record field names for error reporting. - let field_names = self.cstore.struct_field_names_untracked(def_id); - self.insert_field_names(def_id, field_names); - } Res::Def(DefKind::Macro(..), _) | Res::NonMacroAttr(..) => { self.define(parent, ident, MacroNS, (res, vis, DUMMY_SP, expansion)); } @@ -837,7 +835,7 @@ impl<'a> Resolver<'a> { if let Some(span) = import_all { let directive = macro_use_directive(span); self.potentially_unused_imports.push(directive); - module.for_each_child(self, |this, ident, ns, binding| if ns == MacroNS { + self.for_each_child(module, |this, ident, ns, binding| if ns == MacroNS { let imported_binding = this.import(binding, directive); this.legacy_import_macro(ident.name, imported_binding, span, allow_shadowing); }); diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs index 177c51cdb1ebd..87d5a53f7a842 100644 --- a/src/librustc_resolve/diagnostics.rs +++ b/src/librustc_resolve/diagnostics.rs @@ -65,23 +65,23 @@ fn add_typo_suggestion( false } -fn add_module_candidates<'a>( - resolver: &mut Resolver<'a>, - module: Module<'a>, - names: &mut Vec, - filter_fn: &impl Fn(Res) -> bool, -) { - for (&(ident, _), resolution) in resolver.resolutions(module).borrow().iter() { - if let Some(binding) = resolution.borrow().binding { - let res = binding.res(); - if filter_fn(res) { - names.push(TypoSuggestion::from_res(ident.name, res)); +impl<'a> Resolver<'a> { + fn add_module_candidates( + &mut self, + module: Module<'a>, + names: &mut Vec, + filter_fn: &impl Fn(Res) -> bool, + ) { + for (&(ident, _), resolution) in self.resolutions(module).borrow().iter() { + if let Some(binding) = resolution.borrow().binding { + let res = binding.res(); + if filter_fn(res) { + names.push(TypoSuggestion::from_res(ident.name, res)); + } } } } -} -impl<'a> Resolver<'a> { /// Handles error reporting for `smart_resolve_path_fragment` function. /// Creates base error and amends it with one short label and possibly some longer helps/notes. pub(crate) fn smart_resolve_report_errors( @@ -596,10 +596,10 @@ impl<'a> Resolver<'a> { Scope::CrateRoot => { let root_ident = Ident::new(kw::PathRoot, ident.span); let root_module = this.resolve_crate_root(root_ident); - add_module_candidates(this, root_module, &mut suggestions, filter_fn); + this.add_module_candidates(root_module, &mut suggestions, filter_fn); } Scope::Module(module) => { - add_module_candidates(this, module, &mut suggestions, filter_fn); + this.add_module_candidates(module, &mut suggestions, filter_fn); } Scope::MacroUsePrelude => { suggestions.extend(this.macro_use_prelude.iter().filter_map(|(name, binding)| { @@ -647,7 +647,7 @@ impl<'a> Resolver<'a> { Scope::StdLibPrelude => { if let Some(prelude) = this.prelude { let mut tmp_suggestions = Vec::new(); - add_module_candidates(this, prelude, &mut tmp_suggestions, filter_fn); + this.add_module_candidates(prelude, &mut tmp_suggestions, filter_fn); suggestions.extend(tmp_suggestions.into_iter().filter(|s| { use_prelude || this.is_builtin_macro(s.res.opt_def_id()) })); @@ -709,7 +709,7 @@ impl<'a> Resolver<'a> { // Items in scope if let RibKind::ModuleRibKind(module) = rib.kind { // Items from this module - add_module_candidates(self, module, &mut names, &filter_fn); + self.add_module_candidates(module, &mut names, &filter_fn); if let ModuleKind::Block(..) = module.kind { // We can see through blocks @@ -737,7 +737,7 @@ impl<'a> Resolver<'a> { })); if let Some(prelude) = self.prelude { - add_module_candidates(self, prelude, &mut names, &filter_fn); + self.add_module_candidates(prelude, &mut names, &filter_fn); } } break; @@ -759,7 +759,7 @@ impl<'a> Resolver<'a> { mod_path, Some(TypeNS), false, span, CrateLint::No ) { if let ModuleOrUniformRoot::Module(module) = module { - add_module_candidates(self, module, &mut names, &filter_fn); + self.add_module_candidates(module, &mut names, &filter_fn); } } } @@ -799,7 +799,7 @@ impl<'a> Resolver<'a> { in_module_is_extern)) = worklist.pop() { // We have to visit module children in deterministic order to avoid // instabilities in reported imports (#43552). - in_module.for_each_child_stable(self, |this, ident, ns, name_binding| { + self.for_each_child_stable(in_module, |this, ident, ns, name_binding| { // avoid imports entirely if name_binding.is_import() && !name_binding.is_extern_crate() { return; } // avoid non-importable candidates as well @@ -911,7 +911,7 @@ impl<'a> Resolver<'a> { // abort if the module is already found if result.is_some() { break; } - in_module.for_each_child_stable(self, |_, ident, _, name_binding| { + self.for_each_child_stable(in_module, |_, ident, _, name_binding| { // abort if the module is already found or if name_binding is private external if result.is_some() || !name_binding.vis.is_visible_locally() { return @@ -943,7 +943,7 @@ impl<'a> Resolver<'a> { fn collect_enum_variants(&mut self, def_id: DefId) -> Option> { self.find_module(def_id).map(|(enum_module, enum_import_suggestion)| { let mut variants = Vec::new(); - enum_module.for_each_child_stable(self, |_, ident, _, name_binding| { + self.for_each_child_stable(enum_module, |_, ident, _, name_binding| { if let Res::Def(DefKind::Variant, _) = name_binding.res() { let mut segms = enum_import_suggestion.path.segments.clone(); segms.push(ast::PathSegment::from_ident(ident)); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 715ea29b9ded1..37ef815ad6c90 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1222,25 +1222,6 @@ impl<'a> ModuleData<'a> { } } - fn for_each_child(&'a self, resolver: &mut Resolver<'a>, mut f: F) - where F: FnMut(&mut Resolver<'a>, Ident, Namespace, &'a NameBinding<'a>) - { - for (&(ident, ns), name_resolution) in resolver.resolutions(self).borrow().iter() { - name_resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding)); - } - } - - fn for_each_child_stable(&'a self, resolver: &mut Resolver<'a>, mut f: F) - where F: FnMut(&mut Resolver<'a>, Ident, Namespace, &'a NameBinding<'a>) - { - let resolutions = resolver.resolutions(self).borrow(); - let mut resolutions = resolutions.iter().collect::>(); - resolutions.sort_by_cached_key(|&(&(ident, ns), _)| (ident.as_str(), ns)); - for &(&(ident, ns), &resolution) in resolutions.iter() { - resolution.borrow().binding.map(|binding| f(resolver, ident, ns, binding)); - } - } - fn res(&self) -> Option { match self.kind { ModuleKind::Def(kind, def_id, _) => Some(Res::Def(kind, def_id)), @@ -1900,9 +1881,7 @@ impl<'a> Resolver<'a> { seg.id = self.session.next_node_id(); seg } -} -impl<'a> Resolver<'a> { pub fn new(session: &'a Session, cstore: &'a CStore, krate: &Crate, @@ -2107,6 +2086,43 @@ impl<'a> Resolver<'a> { self.arenas.alloc_module(module) } + 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")); + self.build_reduced_graph_for_external_crate_res(module, child); + } + } + &module.lazy_resolutions + } + + fn resolution(&mut self, module: Module<'a>, ident: Ident, ns: Namespace) + -> &'a RefCell> { + *self.resolutions(module).borrow_mut().entry((ident.modern(), ns)) + .or_insert_with(|| self.arenas.alloc_name_resolution()) + } + + fn for_each_child(&mut self, module: Module<'a>, mut f: F) + where F: FnMut(&mut Resolver<'a>, Ident, Namespace, &'a NameBinding<'a>) + { + for (&(ident, ns), name_resolution) in self.resolutions(module).borrow().iter() { + name_resolution.borrow().binding.map(|binding| f(self, ident, ns, binding)); + } + } + + fn for_each_child_stable(&mut self, module: Module<'a>, mut f: F) + where F: FnMut(&mut Resolver<'a>, Ident, Namespace, &'a NameBinding<'a>) + { + let resolutions = self.resolutions(module).borrow(); + let mut resolutions = resolutions.iter().collect::>(); + resolutions.sort_by_cached_key(|&(&(ident, ns), _)| (ident.as_str(), ns)); + for &(&(ident, ns), &resolution) in resolutions.iter() { + resolution.borrow().binding.map(|binding| f(self, ident, ns, binding)); + } + } + fn record_use(&mut self, ident: Ident, ns: Namespace, used_binding: &'a NameBinding<'a>, is_lexical_scope: bool) { if let Some((b2, kind)) = used_binding.ambiguity { @@ -4522,7 +4538,7 @@ impl<'a> Resolver<'a> { let mut traits = module.traits.borrow_mut(); if traits.is_none() { let mut collected_traits = Vec::new(); - module.for_each_child(self, |_, name, ns, binding| { + self.for_each_child(module, |_, name, ns, binding| { if ns != TypeNS { return } match binding.res() { Res::Def(DefKind::Trait, _) | diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 70bd347dbbca9..93271eb17d80a 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -5,7 +5,7 @@ use crate::{CrateLint, Module, ModuleOrUniformRoot, PerNS, ScopeSet, ParentScope use crate::Determinacy::{self, *}; use crate::Namespace::{self, TypeNS, MacroNS}; use crate::{NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; -use crate::{Resolutions, Resolver, Segment}; +use crate::{Resolver, Segment}; use crate::{names_to_string, module_to_string}; use crate::{resolve_error, ResolutionError}; use crate::ModuleKind; @@ -36,7 +36,7 @@ use syntax_pos::{MultiSpan, Span}; use log::*; -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::{mem, ptr}; type Res = def::Res; @@ -156,24 +156,6 @@ impl<'a> NameResolution<'a> { } impl<'a> Resolver<'a> { - 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")); - self.build_reduced_graph_for_external_crate_res(module, child); - } - } - &module.lazy_resolutions - } - - fn resolution(&mut self, module: Module<'a>, ident: Ident, ns: Namespace) - -> &'a RefCell> { - *self.resolutions(module).borrow_mut().entry((ident.modern(), ns)) - .or_insert_with(|| self.arenas.alloc_name_resolution()) - } - crate fn resolve_ident_in_module_unadjusted( &mut self, module: ModuleOrUniformRoot<'a>,