remove ItemMap

This commit is contained in:
Aleksey Kladov 2019-03-14 12:54:03 +03:00
parent 71e5adf694
commit c7259a899c
7 changed files with 59 additions and 569 deletions

View File

@ -173,7 +173,7 @@ impl Module {
/// Returns a `ModuleScope`: a set of items, visible in this module.
pub fn scope(&self, db: &impl HirDatabase) -> ModuleScope {
db.item_map(self.krate)[self.module_id].clone()
db.crate_def_map(self.krate)[self.module_id].scope.clone()
}
pub fn problems(&self, db: &impl HirDatabase) -> Vec<(TreeArc<SyntaxNode>, Problem)> {
@ -181,8 +181,8 @@ impl Module {
}
pub fn resolver(&self, db: &impl HirDatabase) -> Resolver {
let item_map = db.item_map(self.krate);
Resolver::default().push_module_scope(item_map, *self)
let def_map = db.crate_def_map(self.krate);
Resolver::default().push_module_scope(def_map, self.module_id)
}
pub fn declarations(self, db: &impl HirDatabase) -> Vec<ModuleDef> {

View File

@ -10,7 +10,7 @@ use crate::{
Struct, Enum, StructField,
Const, ConstSignature, Static,
macros::MacroExpansion,
nameres::{Namespace, ItemMap, lower::{LoweredModule, ImportSourceMap}, crate_def_map::{RawItems, CrateDefMap}},
nameres::{Namespace, lower::{LoweredModule, ImportSourceMap}, crate_def_map::{RawItems, CrateDefMap}},
ty::{InferenceResult, Ty, method_resolution::CrateImplBlocks, TypableDef, CallableDef, FnSig},
adt::{StructData, EnumData},
impl_block::{ModuleImplBlocks, ImplSourceMap},
@ -50,9 +50,6 @@ pub trait PersistentHirDatabase: SourceDatabase + AsRef<HirInterner> {
#[salsa::invoke(RawItems::raw_items_query)]
fn raw_items(&self, file_id: FileId) -> Arc<RawItems>;
#[salsa::invoke(crate::nameres::ItemMap::item_map_query)]
fn item_map(&self, krate: Crate) -> Arc<ItemMap>;
#[salsa::invoke(CrateDefMap::crate_def_map_query)]
fn crate_def_map(&self, krate: Crate) -> Arc<CrateDefMap>;

View File

@ -54,7 +54,7 @@ pub use self::{
name::Name,
ids::{HirFileId, MacroCallId, MacroCallLoc, HirInterner},
macros::{MacroDef, MacroInput, MacroExpansion},
nameres::{ItemMap, PerNs, Namespace},
nameres::{PerNs, Namespace},
ty::{Ty, Substs, display::HirDisplay},
impl_block::{ImplBlock, ImplItem},
docs::{Docs, Documentation},

View File

@ -17,43 +17,15 @@
pub(crate) mod lower;
pub(crate) mod crate_def_map;
use std::{time, sync::Arc};
use rustc_hash::{FxHashMap, FxHashSet};
use ra_arena::map::ArenaMap;
use rustc_hash::FxHashMap;
use ra_db::Edition;
use test_utils::tested_by;
use crate::{
Module, ModuleDef,
Path, PathKind, PersistentHirDatabase,
Crate, Name,
nameres::{
crate_def_map::{CrateDefMap, ModuleId},
lower::{ImportId, LoweredModule, ImportData}
},
ModuleDef, Name,
nameres::lower::ImportId,
};
/// `ItemMap` is the result of module name resolution. It contains, for each
/// module, the set of visible items.
#[derive(Debug, PartialEq, Eq)]
pub struct ItemMap {
edition: Edition,
/// The prelude module for this crate. This either comes from an import
/// marked with the `prelude_import` attribute, or (in the normal case) from
/// a dependency (`std` or `core`).
pub(crate) prelude: Option<Module>,
pub(crate) extern_prelude: FxHashMap<Name, ModuleDef>,
per_module: ArenaMap<ModuleId, ModuleScope>,
}
impl std::ops::Index<ModuleId> for ItemMap {
type Output = ModuleScope;
fn index(&self, id: ModuleId) -> &ModuleScope {
&self.per_module[id]
}
}
pub(crate) use self::crate_def_map::{CrateDefMap, ModuleId};
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct ModuleScope {
@ -158,292 +130,6 @@ impl<T> PerNs<T> {
}
}
struct Resolver<'a, DB> {
db: &'a DB,
input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
krate: Crate,
def_map: Arc<CrateDefMap>,
processed_imports: FxHashSet<(ModuleId, ImportId)>,
/// If module `a` has `use b::*`, then this contains the mapping b -> a (and the import)
glob_imports: FxHashMap<ModuleId, Vec<(ModuleId, ImportId)>>,
result: ItemMap,
}
impl<'a, DB> Resolver<'a, DB>
where
DB: PersistentHirDatabase,
{
fn new(
db: &'a DB,
input: &'a FxHashMap<ModuleId, Arc<LoweredModule>>,
krate: Crate,
) -> Resolver<'a, DB> {
Resolver {
db,
input,
krate,
def_map: db.crate_def_map(krate),
processed_imports: FxHashSet::default(),
glob_imports: FxHashMap::default(),
result: ItemMap {
edition: krate.edition(db),
prelude: None,
extern_prelude: FxHashMap::default(),
per_module: ArenaMap::default(),
},
}
}
pub(crate) fn resolve(mut self) -> ItemMap {
self.populate_extern_prelude();
for (&module_id, items) in self.input.iter() {
self.populate_module(module_id, Arc::clone(items));
}
let mut iter = 0;
loop {
iter += 1;
if iter > 1000 {
panic!("failed to reach fixedpoint after 1000 iters")
}
let processed_imports_count = self.processed_imports.len();
for &module_id in self.input.keys() {
self.db.check_canceled();
self.resolve_imports(module_id);
}
if processed_imports_count == self.processed_imports.len() {
// no new imports resolved
break;
}
}
self.result
}
fn populate_extern_prelude(&mut self) {
for dep in self.krate.dependencies(self.db) {
log::debug!("crate dep {:?} -> {:?}", dep.name, dep.krate);
if let Some(module) = dep.krate.root_module(self.db) {
self.result.extern_prelude.insert(dep.name.clone(), module.into());
}
// look for the prelude
if self.result.prelude.is_none() {
let item_map = self.db.item_map(dep.krate);
if item_map.prelude.is_some() {
self.result.prelude = item_map.prelude;
}
}
}
}
fn populate_module(&mut self, module_id: ModuleId, input: Arc<LoweredModule>) {
let mut module_items = ModuleScope::default();
for (import_id, import_data) in input.imports.iter() {
if let Some(last_segment) = import_data.path.segments.iter().last() {
if !import_data.is_glob {
let name =
import_data.alias.clone().unwrap_or_else(|| last_segment.name.clone());
module_items
.items
.insert(name, Resolution { def: PerNs::none(), import: Some(import_id) });
}
}
}
// Populate explicitly declared items, except modules
for (name, &def) in input.declarations.iter() {
let resolution = Resolution { def, import: None };
module_items.items.insert(name.clone(), resolution);
}
// Populate modules
for (name, module_id) in self.def_map[module_id].children.iter() {
let module = Module { module_id: *module_id, krate: self.krate };
self.add_module_item(&mut module_items, name.clone(), PerNs::types(module.into()));
}
self.result.per_module.insert(module_id, module_items);
}
fn add_module_item(&self, module_items: &mut ModuleScope, name: Name, def: PerNs<ModuleDef>) {
let resolution = Resolution { def, import: None };
module_items.items.insert(name, resolution);
}
fn resolve_imports(&mut self, module_id: ModuleId) {
for (import_id, import_data) in self.input[&module_id].imports.iter() {
if self.processed_imports.contains(&(module_id, import_id)) {
// already done
continue;
}
if self.resolve_import(module_id, import_id, import_data) == ReachedFixedPoint::Yes {
log::debug!("import {:?} resolved (or definite error)", import_id);
self.processed_imports.insert((module_id, import_id));
}
}
}
fn resolve_import(
&mut self,
module_id: ModuleId,
import_id: ImportId,
import: &ImportData,
) -> ReachedFixedPoint {
log::debug!("resolving import: {:?} ({:?})", import, self.result.edition);
let original_module = Module { krate: self.krate, module_id };
let (def, reached_fixedpoint) = if import.is_extern_crate {
let res = self.result.resolve_name_in_extern_prelude(
&import
.path
.as_ident()
.expect("extern crate should have been desugared to one-element path"),
);
(res, if res.is_none() { ReachedFixedPoint::No } else { ReachedFixedPoint::Yes })
} else {
let res = self.result.resolve_path_fp(
self.db,
ResolveMode::Import,
original_module,
&import.path,
);
(res.resolved_def, res.reached_fixedpoint)
};
if reached_fixedpoint != ReachedFixedPoint::Yes {
return reached_fixedpoint;
}
if import.is_glob {
log::debug!("glob import: {:?}", import);
match def.take_types() {
Some(ModuleDef::Module(m)) => {
if import.is_prelude {
tested_by!(std_prelude);
self.result.prelude = Some(m);
} else if m.krate != self.krate {
tested_by!(glob_across_crates);
// glob import from other crate => we can just import everything once
let item_map = self.db.item_map(m.krate);
let scope = &item_map[m.module_id];
let items = scope
.items
.iter()
.map(|(name, res)| (name.clone(), res.clone()))
.collect::<Vec<_>>();
self.update(module_id, Some(import_id), &items);
} else {
// glob import from same crate => we do an initial
// import, and then need to propagate any further
// additions
let scope = &self.result[m.module_id];
let items = scope
.items
.iter()
.map(|(name, res)| (name.clone(), res.clone()))
.collect::<Vec<_>>();
self.update(module_id, Some(import_id), &items);
// record the glob import in case we add further items
self.glob_imports
.entry(m.module_id)
.or_default()
.push((module_id, import_id));
}
}
Some(ModuleDef::Enum(e)) => {
tested_by!(glob_enum);
// glob import from enum => just import all the variants
let variants = e.variants(self.db);
let resolutions = variants
.into_iter()
.filter_map(|variant| {
let res = Resolution {
def: PerNs::both(variant.into(), variant.into()),
import: Some(import_id),
};
let name = variant.name(self.db)?;
Some((name, res))
})
.collect::<Vec<_>>();
self.update(module_id, Some(import_id), &resolutions);
}
Some(d) => {
log::debug!("glob import {:?} from non-module/enum {:?}", import, d);
}
None => {
log::debug!("glob import {:?} didn't resolve as type", import);
}
}
} else {
let last_segment = import.path.segments.last().unwrap();
let name = import.alias.clone().unwrap_or_else(|| last_segment.name.clone());
log::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
// extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
if let Some(root_module) = self.krate.root_module(self.db) {
if import.is_extern_crate && module_id == root_module.module_id {
if let Some(def) = def.take_types() {
self.result.extern_prelude.insert(name.clone(), def);
}
}
}
let resolution = Resolution { def, import: Some(import_id) };
self.update(module_id, None, &[(name, resolution)]);
}
reached_fixedpoint
}
fn update(
&mut self,
module_id: ModuleId,
import: Option<ImportId>,
resolutions: &[(Name, Resolution)],
) {
self.update_recursive(module_id, import, resolutions, 0)
}
fn update_recursive(
&mut self,
module_id: ModuleId,
import: Option<ImportId>,
resolutions: &[(Name, Resolution)],
depth: usize,
) {
if depth > 100 {
// prevent stack overflows (but this shouldn't be possible)
panic!("infinite recursion in glob imports!");
}
let module_items = self.result.per_module.get_mut(module_id).unwrap();
let mut changed = false;
for (name, res) in resolutions {
let existing = module_items.items.entry(name.clone()).or_default();
if existing.def.types.is_none() && res.def.types.is_some() {
existing.def.types = res.def.types;
existing.import = import.or(res.import);
changed = true;
}
if existing.def.values.is_none() && res.def.values.is_some() {
existing.def.values = res.def.values;
existing.import = import.or(res.import);
changed = true;
}
}
if !changed {
return;
}
let glob_imports = self
.glob_imports
.get(&module_id)
.into_iter()
.flat_map(|v| v.iter())
.cloned()
.collect::<Vec<_>>();
for (glob_importing_module, glob_import) in glob_imports {
// We pass the glob import so that the tracked import in those modules is that glob import
self.update_recursive(glob_importing_module, Some(glob_import), resolutions, depth + 1);
}
}
}
#[derive(Debug, Clone)]
struct ResolvePathResult {
resolved_def: PerNs<ModuleDef>,
@ -476,220 +162,3 @@ enum ReachedFixedPoint {
Yes,
No,
}
impl ItemMap {
pub(crate) fn item_map_query(db: &impl PersistentHirDatabase, krate: Crate) -> Arc<ItemMap> {
let start = time::Instant::now();
let def_map = db.crate_def_map(krate);
let input = def_map
.modules()
.map(|module_id| (module_id, db.lower_module(Module { krate, module_id })))
.collect::<FxHashMap<_, _>>();
let resolver = Resolver::new(db, &input, krate);
let res = resolver.resolve();
let elapsed = start.elapsed();
log::info!("item_map: {:?}", elapsed);
Arc::new(res)
}
pub(crate) fn resolve_path(
&self,
db: &impl PersistentHirDatabase,
original_module: Module,
path: &Path,
) -> (PerNs<ModuleDef>, Option<usize>) {
let res = self.resolve_path_fp(db, ResolveMode::Other, original_module, path);
(res.resolved_def, res.segment_index)
}
fn resolve_in_prelude(
&self,
db: &impl PersistentHirDatabase,
original_module: Module,
name: &Name,
) -> PerNs<ModuleDef> {
if let Some(prelude) = self.prelude {
let resolution = if prelude.krate == original_module.krate {
self[prelude.module_id].items.get(name).cloned()
} else {
db.item_map(prelude.krate)[prelude.module_id].items.get(name).cloned()
};
resolution.map(|r| r.def).unwrap_or_else(PerNs::none)
} else {
PerNs::none()
}
}
pub(crate) fn resolve_name_in_module(
&self,
db: &impl PersistentHirDatabase,
module: Module,
name: &Name,
) -> PerNs<ModuleDef> {
// Resolve in:
// - current module / scope
// - extern prelude
// - std prelude
let from_scope = self[module.module_id].items.get(name).map_or(PerNs::none(), |it| it.def);
let from_extern_prelude =
self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it));
let from_prelude = self.resolve_in_prelude(db, module, name);
from_scope.or(from_extern_prelude).or(from_prelude)
}
fn resolve_name_in_extern_prelude(&self, name: &Name) -> PerNs<ModuleDef> {
self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it))
}
fn resolve_name_in_crate_root_or_extern_prelude(
&self,
db: &impl PersistentHirDatabase,
module: Module,
name: &Name,
) -> PerNs<ModuleDef> {
let crate_root = module.crate_root(db);
let from_crate_root =
self[crate_root.module_id].items.get(name).map_or(PerNs::none(), |it| it.def);
let from_extern_prelude = self.resolve_name_in_extern_prelude(name);
from_crate_root.or(from_extern_prelude)
}
// Returns Yes if we are sure that additions to `ItemMap` wouldn't change
// the result.
fn resolve_path_fp(
&self,
db: &impl PersistentHirDatabase,
mode: ResolveMode,
original_module: Module,
path: &Path,
) -> ResolvePathResult {
let mut segments = path.segments.iter().enumerate();
let mut curr_per_ns: PerNs<ModuleDef> = match path.kind {
PathKind::Crate => PerNs::types(original_module.crate_root(db).into()),
PathKind::Self_ => PerNs::types(original_module.into()),
// plain import or absolute path in 2015: crate-relative with
// fallback to extern prelude (with the simplification in
// rust-lang/rust#57745)
// TODO there must be a nicer way to write this condition
PathKind::Plain | PathKind::Abs
if self.edition == Edition::Edition2015
&& (path.kind == PathKind::Abs || mode == ResolveMode::Import) =>
{
let segment = match segments.next() {
Some((_, segment)) => segment,
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
};
log::debug!("resolving {:?} in crate root (+ extern prelude)", segment);
self.resolve_name_in_crate_root_or_extern_prelude(
db,
original_module,
&segment.name,
)
}
PathKind::Plain => {
let segment = match segments.next() {
Some((_, segment)) => segment,
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
};
log::debug!("resolving {:?} in module", segment);
self.resolve_name_in_module(db, original_module, &segment.name)
}
PathKind::Super => {
if let Some(p) = original_module.parent(db) {
PerNs::types(p.into())
} else {
log::debug!("super path in root module");
return ResolvePathResult::empty(ReachedFixedPoint::Yes);
}
}
PathKind::Abs => {
// 2018-style absolute path -- only extern prelude
let segment = match segments.next() {
Some((_, segment)) => segment,
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
};
if let Some(def) = self.extern_prelude.get(&segment.name) {
log::debug!("absolute path {:?} resolved to crate {:?}", path, def);
PerNs::types(*def)
} else {
return ResolvePathResult::empty(ReachedFixedPoint::No); // extern crate declarations can add to the extern prelude
}
}
};
for (i, segment) in segments {
let curr = match curr_per_ns.as_ref().take_types() {
Some(r) => r,
None => {
// we still have path segments left, but the path so far
// didn't resolve in the types namespace => no resolution
// (don't break here because `curr_per_ns` might contain
// something in the value namespace, and it would be wrong
// to return that)
return ResolvePathResult::empty(ReachedFixedPoint::No);
}
};
// resolve segment in curr
curr_per_ns = match curr {
ModuleDef::Module(module) => {
if module.krate != original_module.krate {
let path = Path {
segments: path.segments[i..].iter().cloned().collect(),
kind: PathKind::Self_,
};
log::debug!("resolving {:?} in other crate", path);
let item_map = db.item_map(module.krate);
let (def, s) = item_map.resolve_path(db, *module, &path);
return ResolvePathResult::with(
def,
ReachedFixedPoint::Yes,
s.map(|s| s + i),
);
}
match self[module.module_id].items.get(&segment.name) {
Some(res) if !res.def.is_none() => res.def,
_ => {
log::debug!("path segment {:?} not found", segment.name);
return ResolvePathResult::empty(ReachedFixedPoint::No);
}
}
}
ModuleDef::Enum(e) => {
// enum variant
tested_by!(can_import_enum_variant);
match e.variant(db, &segment.name) {
Some(variant) => PerNs::both(variant.into(), variant.into()),
None => {
return ResolvePathResult::with(
PerNs::types((*e).into()),
ReachedFixedPoint::Yes,
Some(i),
);
}
}
}
s => {
// could be an inherent method call in UFCS form
// (`Struct::method`), or some other kind of associated item
log::debug!(
"path segment {:?} resolved to non-module {:?}, but is not last",
segment.name,
curr,
);
return ResolvePathResult::with(
PerNs::types((*s).into()),
ReachedFixedPoint::Yes,
Some(i),
);
}
};
}
ResolvePathResult::with(curr_per_ns, ReachedFixedPoint::Yes, None)
}
}

View File

@ -149,8 +149,16 @@ impl CrateDefMap {
&self.problems
}
pub(crate) fn modules<'a>(&'a self) -> impl Iterator<Item = ModuleId> + 'a {
self.modules.iter().map(|(id, _data)| id)
pub(crate) fn mk_module(&self, module_id: ModuleId) -> Module {
Module { krate: self.krate, module_id }
}
pub(crate) fn prelude(&self) -> Option<Module> {
self.prelude
}
pub(crate) fn extern_prelude(&self) -> &FxHashMap<Name, ModuleDef> {
&self.extern_prelude
}
pub(crate) fn find_module_by_source(
@ -169,6 +177,16 @@ impl CrateDefMap {
Some(module_id)
}
pub(crate) fn resolve_path(
&self,
db: &impl PersistentHirDatabase,
original_module: ModuleId,
path: &Path,
) -> (PerNs<ModuleDef>, Option<usize>) {
let res = self.resolve_path_fp(db, ResolveMode::Other, original_module, path);
(res.resolved_def, res.segment_index)
}
// Returns Yes if we are sure that additions to `ItemMap` wouldn't change
// the result.
fn resolve_path_fp(
@ -254,8 +272,8 @@ impl CrateDefMap {
kind: PathKind::Self_,
};
log::debug!("resolving {:?} in other crate", path);
let item_map = db.item_map(module.krate);
let (def, s) = item_map.resolve_path(db, *module, &path);
let defp_map = db.crate_def_map(module.krate);
let (def, s) = defp_map.resolve_path(db, module.module_id, &path);
return ResolvePathResult::with(
def,
ReachedFixedPoint::Yes,
@ -313,7 +331,7 @@ impl CrateDefMap {
from_crate_root.or(from_extern_prelude)
}
fn resolve_name_in_module(
pub(crate) fn resolve_name_in_module(
&self,
db: &impl PersistentHirDatabase,
module: ModuleId,
@ -340,7 +358,7 @@ impl CrateDefMap {
let resolution = if prelude.krate == self.krate {
self[prelude.module_id].scope.items.get(name).cloned()
} else {
db.item_map(prelude.krate)[prelude.module_id].items.get(name).cloned()
db.crate_def_map(prelude.krate)[prelude.module_id].scope.items.get(name).cloned()
};
resolution.map(|r| r.def).unwrap_or_else(PerNs::none)
} else {

View File

@ -26,9 +26,9 @@ pub(super) fn collect_defs(
}
// look for the prelude
if def_map.prelude.is_none() {
let item_map = db.item_map(dep.krate);
if item_map.prelude.is_some() {
def_map.prelude = item_map.prelude;
let map = db.crate_def_map(dep.krate);
if map.prelude.is_some() {
def_map.prelude = map.prelude;
}
}
}
@ -162,8 +162,8 @@ where
} else if m.krate != self.def_map.krate {
tested_by!(glob_across_crates);
// glob import from other crate => we can just import everything once
let item_map = self.db.item_map(m.krate);
let scope = &item_map[m.module_id];
let item_map = self.db.crate_def_map(m.krate);
let scope = &item_map[m.module_id].scope;
let items = scope
.items
.iter()

View File

@ -4,10 +4,10 @@ use std::sync::Arc;
use rustc_hash::FxHashMap;
use crate::{
ModuleDef, Module,
ModuleDef,
db::HirDatabase,
name::{Name, KnownName},
nameres::{PerNs, ItemMap},
nameres::{PerNs, CrateDefMap, ModuleId},
generics::GenericParams,
expr::{scope::{ExprScopes, ScopeId}, PatId, Body},
impl_block::ImplBlock,
@ -22,8 +22,8 @@ pub struct Resolver {
// TODO how to store these best
#[derive(Debug, Clone)]
pub(crate) struct ModuleItemMap {
item_map: Arc<ItemMap>,
module: Module,
crate_def_map: Arc<CrateDefMap>,
module_id: ModuleId,
}
#[derive(Debug, Clone)]
@ -175,9 +175,9 @@ impl Resolver {
names
}
fn module(&self) -> Option<(&ItemMap, Module)> {
fn module(&self) -> Option<(&CrateDefMap, ModuleId)> {
self.scopes.iter().rev().find_map(|scope| match scope {
Scope::ModuleScope(m) => Some((&*m.item_map, m.module.clone())),
Scope::ModuleScope(m) => Some((&*m.crate_def_map, m.module_id)),
_ => None,
})
@ -206,8 +206,12 @@ impl Resolver {
self.push_scope(Scope::ImplBlockScope(impl_block))
}
pub(crate) fn push_module_scope(self, item_map: Arc<ItemMap>, module: Module) -> Resolver {
self.push_scope(Scope::ModuleScope(ModuleItemMap { item_map, module }))
pub(crate) fn push_module_scope(
self,
crate_def_map: Arc<CrateDefMap>,
module_id: ModuleId,
) -> Resolver {
self.push_scope(Scope::ModuleScope(ModuleItemMap { crate_def_map, module_id }))
}
pub(crate) fn push_expr_scope(
@ -224,9 +228,11 @@ impl Scope {
match self {
Scope::ModuleScope(m) => {
if let Some(KnownName::SelfParam) = name.as_known_name() {
PerNs::types(Resolution::Def(m.module.into()))
PerNs::types(Resolution::Def(m.crate_def_map.mk_module(m.module_id).into()))
} else {
m.item_map.resolve_name_in_module(db, m.module, name).map(Resolution::Def)
m.crate_def_map
.resolve_name_in_module(db, m.module_id, name)
.map(Resolution::Def)
}
}
Scope::GenericParams(gp) => match gp.find_by_name(name) {
@ -261,15 +267,15 @@ impl Scope {
// def: m.module.into(),
// }),
// );
m.item_map[m.module.module_id].entries().for_each(|(name, res)| {
m.crate_def_map[m.module_id].scope.entries().for_each(|(name, res)| {
f(name.clone(), res.def.map(Resolution::Def));
});
m.item_map.extern_prelude.iter().for_each(|(name, def)| {
m.crate_def_map.extern_prelude().iter().for_each(|(name, def)| {
f(name.clone(), PerNs::types(Resolution::Def(*def)));
});
if let Some(prelude) = m.item_map.prelude {
let prelude_item_map = db.item_map(prelude.krate);
prelude_item_map[prelude.module_id].entries().for_each(|(name, res)| {
if let Some(prelude) = m.crate_def_map.prelude() {
let prelude_def_map = db.crate_def_map(prelude.krate);
prelude_def_map[prelude.module_id].scope.entries().for_each(|(name, res)| {
f(name.clone(), res.def.map(Resolution::Def));
});
}