This commit is contained in:
Aleksey Kladov 2019-12-22 15:37:07 +01:00
parent e8da7d4061
commit 6c3ddcfa50
7 changed files with 41 additions and 58 deletions

View file

@ -184,7 +184,7 @@ impl Module {
db.crate_def_map(self.id.krate)[self.id.local_id] db.crate_def_map(self.id.krate)[self.id.local_id]
.scope .scope
.entries() .entries()
.map(|(name, res)| (name.clone(), res.def.into())) .map(|(name, def)| (name.clone(), def.into()))
.collect() .collect()
} }

View file

@ -183,8 +183,8 @@ mod tests {
let crate_def_map = db.crate_def_map(krate); let crate_def_map = db.crate_def_map(krate);
let module = crate_def_map.modules_for_file(file_id).next().unwrap(); let module = crate_def_map.modules_for_file(file_id).next().unwrap();
let (_, res) = crate_def_map[module].scope.entries().next().unwrap(); let (_, def) = crate_def_map[module].scope.entries().next().unwrap();
match res.def.take_values().unwrap() { match def.take_values().unwrap() {
ModuleDefId::FunctionId(it) => it, ModuleDefId::FunctionId(it) => it,
_ => panic!(), _ => panic!(),
} }

View file

@ -9,7 +9,7 @@ use crate::{per_ns::PerNs, AdtId, BuiltinType, ImplId, MacroDefId, ModuleDefId,
#[derive(Debug, Default, PartialEq, Eq)] #[derive(Debug, Default, PartialEq, Eq)]
pub struct ItemScope { pub struct ItemScope {
visible: FxHashMap<Name, Resolution>, visible: FxHashMap<Name, PerNs>,
defs: Vec<ModuleDefId>, defs: Vec<ModuleDefId>,
impls: Vec<ImplId>, impls: Vec<ImplId>,
/// Macros visible in current module in legacy textual scope /// Macros visible in current module in legacy textual scope
@ -27,10 +27,10 @@ pub struct ItemScope {
legacy_macros: FxHashMap<Name, MacroDefId>, legacy_macros: FxHashMap<Name, MacroDefId>,
} }
static BUILTIN_SCOPE: Lazy<FxHashMap<Name, Resolution>> = Lazy::new(|| { static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
BuiltinType::ALL BuiltinType::ALL
.iter() .iter()
.map(|(name, ty)| (name.clone(), Resolution { def: PerNs::types(ty.clone().into()) })) .map(|(name, ty)| (name.clone(), PerNs::types(ty.clone().into())))
.collect() .collect()
}); });
@ -46,9 +46,9 @@ pub(crate) enum BuiltinShadowMode {
/// Legacy macros can only be accessed through special methods like `get_legacy_macros`. /// Legacy macros can only be accessed through special methods like `get_legacy_macros`.
/// Other methods will only resolve values, types and module scoped macros only. /// Other methods will only resolve values, types and module scoped macros only.
impl ItemScope { impl ItemScope {
pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, &'a Resolution)> + 'a { pub fn entries<'a>(&'a self) -> impl Iterator<Item = (&'a Name, PerNs)> + 'a {
//FIXME: shadowing //FIXME: shadowing
self.visible.iter().chain(BUILTIN_SCOPE.iter()) self.visible.iter().chain(BUILTIN_SCOPE.iter()).map(|(n, def)| (n, *def))
} }
pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ { pub fn declarations(&self) -> impl Iterator<Item = ModuleDefId> + '_ {
@ -61,9 +61,7 @@ impl ItemScope {
/// Iterate over all module scoped macros /// Iterate over all module scoped macros
pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a { pub(crate) fn macros<'a>(&'a self) -> impl Iterator<Item = (&'a Name, MacroDefId)> + 'a {
self.visible self.visible.iter().filter_map(|(name, def)| def.take_macros().map(|macro_| (name, macro_)))
.iter()
.filter_map(|(name, res)| res.def.take_macros().map(|macro_| (name, macro_)))
} }
/// Iterate over all legacy textual scoped macros visible at the end of the module /// Iterate over all legacy textual scoped macros visible at the end of the module
@ -72,13 +70,13 @@ impl ItemScope {
} }
/// Get a name from current module scope, legacy macros are not included /// Get a name from current module scope, legacy macros are not included
pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&Resolution> { pub(crate) fn get(&self, name: &Name, shadow: BuiltinShadowMode) -> Option<&PerNs> {
match shadow { match shadow {
BuiltinShadowMode::Module => self.visible.get(name).or_else(|| BUILTIN_SCOPE.get(name)), BuiltinShadowMode::Module => self.visible.get(name).or_else(|| BUILTIN_SCOPE.get(name)),
BuiltinShadowMode::Other => { BuiltinShadowMode::Other => {
let item = self.visible.get(name); let item = self.visible.get(name);
if let Some(res) = item { if let Some(def) = item {
if let Some(ModuleDefId::ModuleId(_)) = res.def.take_types() { if let Some(ModuleDefId::ModuleId(_)) = def.take_types() {
return BUILTIN_SCOPE.get(name).or(item); return BUILTIN_SCOPE.get(name).or(item);
} }
} }
@ -89,7 +87,7 @@ impl ItemScope {
} }
pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a { pub(crate) fn traits<'a>(&'a self) -> impl Iterator<Item = TraitId> + 'a {
self.visible.values().filter_map(|r| match r.def.take_types() { self.visible.values().filter_map(|def| match def.take_types() {
Some(ModuleDefId::TraitId(t)) => Some(t), Some(ModuleDefId::TraitId(t)) => Some(t),
_ => None, _ => None,
}) })
@ -111,27 +109,27 @@ impl ItemScope {
self.legacy_macros.insert(name, mac); self.legacy_macros.insert(name, mac);
} }
pub(crate) fn push_res(&mut self, name: Name, res: &Resolution) -> bool { pub(crate) fn push_res(&mut self, name: Name, def: &PerNs) -> bool {
let mut changed = false; let mut changed = false;
let existing = self.visible.entry(name.clone()).or_default(); let existing = self.visible.entry(name.clone()).or_default();
if existing.def.types.is_none() && res.def.types.is_some() { if existing.types.is_none() && def.types.is_some() {
existing.def.types = res.def.types; existing.types = def.types;
changed = true; changed = true;
} }
if existing.def.values.is_none() && res.def.values.is_some() { if existing.values.is_none() && def.values.is_some() {
existing.def.values = res.def.values; existing.values = def.values;
changed = true; changed = true;
} }
if existing.def.macros.is_none() && res.def.macros.is_some() { if existing.macros.is_none() && def.macros.is_some() {
existing.def.macros = res.def.macros; existing.macros = def.macros;
changed = true; changed = true;
} }
changed changed
} }
pub(crate) fn collect_resolutions(&self) -> Vec<(Name, Resolution)> { pub(crate) fn collect_resolutions(&self) -> Vec<(Name, PerNs)> {
self.visible.iter().map(|(name, res)| (name.clone(), res.clone())).collect() self.visible.iter().map(|(name, res)| (name.clone(), res.clone())).collect()
} }
@ -140,12 +138,6 @@ impl ItemScope {
} }
} }
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct Resolution {
/// None for unresolved
pub def: PerNs,
}
impl From<ModuleDefId> for PerNs { impl From<ModuleDefId> for PerNs {
fn from(def: ModuleDefId) -> PerNs { fn from(def: ModuleDefId) -> PerNs {
match def { match def {

View file

@ -18,7 +18,6 @@ use test_utils::tested_by;
use crate::{ use crate::{
attr::Attrs, attr::Attrs,
db::DefDatabase, db::DefDatabase,
item_scope::Resolution,
nameres::{ nameres::{
diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint,
raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode,
@ -215,7 +214,7 @@ where
// In Rust, `#[macro_export]` macros are unconditionally visible at the // In Rust, `#[macro_export]` macros are unconditionally visible at the
// crate root, even if the parent modules is **not** visible. // crate root, even if the parent modules is **not** visible.
if export { if export {
self.update(self.def_map.root, &[(name, Resolution { def: PerNs::macros(macro_) })]); self.update(self.def_map.root, &[(name, PerNs::macros(macro_))]);
} }
} }
@ -397,8 +396,7 @@ where
.map(|(local_id, variant_data)| { .map(|(local_id, variant_data)| {
let name = variant_data.name.clone(); let name = variant_data.name.clone();
let variant = EnumVariantId { parent: e, local_id }; let variant = EnumVariantId { parent: e, local_id };
let res = let res = PerNs::both(variant.into(), variant.into());
Resolution { def: PerNs::both(variant.into(), variant.into()) };
(name, res) (name, res)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@ -424,22 +422,21 @@ where
} }
} }
let resolution = Resolution { def }; self.update(module_id, &[(name, def)]);
self.update(module_id, &[(name, resolution)]);
} }
None => tested_by!(bogus_paths), None => tested_by!(bogus_paths),
} }
} }
} }
fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, Resolution)]) { fn update(&mut self, module_id: LocalModuleId, resolutions: &[(Name, PerNs)]) {
self.update_recursive(module_id, resolutions, 0) self.update_recursive(module_id, resolutions, 0)
} }
fn update_recursive( fn update_recursive(
&mut self, &mut self,
module_id: LocalModuleId, module_id: LocalModuleId,
resolutions: &[(Name, Resolution)], resolutions: &[(Name, PerNs)],
depth: usize, depth: usize,
) { ) {
if depth > 100 { if depth > 100 {
@ -705,8 +702,7 @@ where
let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res }; let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: res };
let def: ModuleDefId = module.into(); let def: ModuleDefId = module.into();
self.def_collector.def_map.modules[self.module_id].scope.define_def(def); self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
let resolution = Resolution { def: def.into() }; self.def_collector.update(self.module_id, &[(name, def.into())]);
self.def_collector.update(self.module_id, &[(name, resolution)]);
res res
} }
@ -765,8 +761,7 @@ where
.into(), .into(),
}; };
self.def_collector.def_map.modules[self.module_id].scope.define_def(def); self.def_collector.def_map.modules[self.module_id].scope.define_def(def);
let resolution = Resolution { def: def.into() }; self.def_collector.update(self.module_id, &[(name, def.into())])
self.def_collector.update(self.module_id, &[(name, resolution)])
} }
fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) {

View file

@ -181,7 +181,7 @@ impl CrateDefMap {
// Since it is a qualified path here, it should not contains legacy macros // Since it is a qualified path here, it should not contains legacy macros
match self[module.local_id].scope.get(&segment, prefer_module(i)) { match self[module.local_id].scope.get(&segment, prefer_module(i)) {
Some(res) => res.def, Some(def) => *def,
_ => { _ => {
log::debug!("path segment {:?} not found", segment); log::debug!("path segment {:?} not found", segment);
return ResolvePathResult::empty(ReachedFixedPoint::No); return ResolvePathResult::empty(ReachedFixedPoint::No);
@ -243,8 +243,7 @@ impl CrateDefMap {
// - std prelude // - std prelude
let from_legacy_macro = let from_legacy_macro =
self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros); self[module].scope.get_legacy_macro(name).map_or_else(PerNs::none, PerNs::macros);
let from_scope = let from_scope = self[module].scope.get(name, shadow).copied().unwrap_or_else(PerNs::none);
self[module].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def);
let from_extern_prelude = let from_extern_prelude =
self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
let from_prelude = self.resolve_in_prelude(db, name, shadow); let from_prelude = self.resolve_in_prelude(db, name, shadow);
@ -258,7 +257,7 @@ impl CrateDefMap {
shadow: BuiltinShadowMode, shadow: BuiltinShadowMode,
) -> PerNs { ) -> PerNs {
let from_crate_root = let from_crate_root =
self[self.root].scope.get(name, shadow).map_or_else(PerNs::none, |res| res.def); self[self.root].scope.get(name, shadow).copied().unwrap_or_else(PerNs::none);
let from_extern_prelude = self.resolve_name_in_extern_prelude(name); let from_extern_prelude = self.resolve_name_in_extern_prelude(name);
from_crate_root.or(from_extern_prelude) from_crate_root.or(from_extern_prelude)
@ -279,10 +278,7 @@ impl CrateDefMap {
keep = db.crate_def_map(prelude.krate); keep = db.crate_def_map(prelude.krate);
&keep &keep
}; };
def_map[prelude.local_id] def_map[prelude.local_id].scope.get(name, shadow).copied().unwrap_or_else(PerNs::none)
.scope
.get(name, shadow)
.map_or_else(PerNs::none, |res| res.def)
} else { } else {
PerNs::none() PerNs::none()
} }

View file

@ -35,19 +35,19 @@ fn render_crate_def_map(map: &CrateDefMap) -> String {
let mut entries = map.modules[module].scope.collect_resolutions(); let mut entries = map.modules[module].scope.collect_resolutions();
entries.sort_by_key(|(name, _)| name.clone()); entries.sort_by_key(|(name, _)| name.clone());
for (name, res) in entries { for (name, def) in entries {
*buf += &format!("{}:", name); *buf += &format!("{}:", name);
if res.def.types.is_some() { if def.types.is_some() {
*buf += " t"; *buf += " t";
} }
if res.def.values.is_some() { if def.values.is_some() {
*buf += " v"; *buf += " v";
} }
if res.def.macros.is_some() { if def.macros.is_some() {
*buf += " m"; *buf += " m";
} }
if res.def.is_none() { if def.is_none() {
*buf += " _"; *buf += " _";
} }

View file

@ -413,8 +413,8 @@ impl Scope {
// def: m.module.into(), // def: m.module.into(),
// }), // }),
// ); // );
m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| { m.crate_def_map[m.module_id].scope.entries().for_each(|(name, def)| {
f(name.clone(), ScopeDef::PerNs(res.def)); f(name.clone(), ScopeDef::PerNs(def));
}); });
m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| { m.crate_def_map[m.module_id].scope.legacy_macros().for_each(|(name, macro_)| {
f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_))); f(name.clone(), ScopeDef::PerNs(PerNs::macros(macro_)));
@ -424,8 +424,8 @@ impl Scope {
}); });
if let Some(prelude) = m.crate_def_map.prelude { if let Some(prelude) = m.crate_def_map.prelude {
let prelude_def_map = db.crate_def_map(prelude.krate); let prelude_def_map = db.crate_def_map(prelude.krate);
prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, res)| { prelude_def_map[prelude.local_id].scope.entries().for_each(|(name, def)| {
f(name.clone(), ScopeDef::PerNs(res.def)); f(name.clone(), ScopeDef::PerNs(def));
}); });
} }
} }