Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/nameres/collector.rs')
-rw-r--r--crates/hir-def/src/nameres/collector.rs109
1 files changed, 72 insertions, 37 deletions
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 8df0f092cd..350c97c398 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -26,7 +26,7 @@ use syntax::ast;
use triomphe::Arc;
use crate::{
- AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, ExternBlockLoc,
+ AdtId, AssocItemId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, ExternBlockLoc,
ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId,
LocalModuleId, Lookup, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId,
MacroRulesLoc, MacroRulesLocFlags, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc,
@@ -43,9 +43,10 @@ use crate::{
nameres::{
BuiltinShadowMode, DefMap, LocalDefMap, MacroSubNs, ModuleData, ModuleOrigin, ResolveMode,
attr_resolution::{attr_macro_as_call_id, derive_macro_as_call_id},
+ crate_def_map,
diagnostics::DefDiagnostic,
mod_resolution::ModDir,
- path_resolution::ReachedFixedPoint,
+ path_resolution::{ReachedFixedPoint, ResolvePathResult},
proc_macro::{ProcMacroDef, ProcMacroKind, parse_macro_name_and_helper_attrs},
sub_namespace_match,
},
@@ -61,7 +62,7 @@ pub(super) fn collect_defs(
db: &dyn DefDatabase,
def_map: DefMap,
tree_id: TreeId,
- crate_local_def_map: Option<Arc<LocalDefMap>>,
+ crate_local_def_map: Option<&LocalDefMap>,
) -> (DefMap, LocalDefMap) {
let krate = &def_map.krate.data(db);
let cfg_options = def_map.krate.cfg_options(db);
@@ -216,7 +217,7 @@ struct DefCollector<'a> {
def_map: DefMap,
local_def_map: LocalDefMap,
/// Set only in case of blocks.
- crate_local_def_map: Option<Arc<LocalDefMap>>,
+ crate_local_def_map: Option<&'a LocalDefMap>,
// The dependencies of the current crate, including optional deps like `test`.
deps: FxHashMap<Name, BuiltDependency>,
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility, GlobId)>>,
@@ -533,7 +534,7 @@ impl DefCollector<'_> {
);
let (per_ns, _) = self.def_map.resolve_path(
- self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
+ self.crate_local_def_map.unwrap_or(&self.local_def_map),
self.db,
DefMap::ROOT,
&path,
@@ -556,7 +557,7 @@ impl DefCollector<'_> {
}
fn local_def_map(&mut self) -> &LocalDefMap {
- self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map)
+ self.crate_local_def_map.unwrap_or(&self.local_def_map)
}
/// Adds a definition of procedural macro `name` to the root module.
@@ -688,7 +689,7 @@ impl DefCollector<'_> {
let vis = self
.def_map
.resolve_visibility(
- self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
+ self.crate_local_def_map.unwrap_or(&self.local_def_map),
self.db,
module_id,
vis,
@@ -731,7 +732,7 @@ impl DefCollector<'_> {
names: Option<Vec<Name>>,
extern_crate: Option<ExternCrateId>,
) {
- let def_map = self.db.crate_def_map(krate);
+ let def_map = crate_def_map(self.db, krate);
// `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!`
// macros.
let root_scope = &def_map[DefMap::ROOT].scope;
@@ -811,32 +812,35 @@ impl DefCollector<'_> {
let _p = tracing::info_span!("resolve_import", import_path = %import.path.display(self.db, Edition::LATEST))
.entered();
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition);
- let res = self.def_map.resolve_path_fp_with_macro(
- self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
- self.db,
- ResolveMode::Import,
- module_id,
- &import.path,
- BuiltinShadowMode::Module,
- None, // An import may resolve to any kind of macro.
- );
+ let ResolvePathResult { resolved_def, segment_index, reached_fixedpoint, prefix_info } =
+ self.def_map.resolve_path_fp_with_macro(
+ self.crate_local_def_map.unwrap_or(&self.local_def_map),
+ self.db,
+ ResolveMode::Import,
+ module_id,
+ &import.path,
+ BuiltinShadowMode::Module,
+ None, // An import may resolve to any kind of macro.
+ );
- let def = res.resolved_def;
- if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() {
+ if reached_fixedpoint == ReachedFixedPoint::No
+ || resolved_def.is_none()
+ || segment_index.is_some()
+ {
return PartialResolvedImport::Unresolved;
}
- if res.prefix_info.differing_crate {
+ if prefix_info.differing_crate {
return PartialResolvedImport::Resolved(
- def.filter_visibility(|v| matches!(v, Visibility::Public)),
+ resolved_def.filter_visibility(|v| matches!(v, Visibility::Public)),
);
}
// Check whether all namespaces are resolved.
- if def.is_full() {
- PartialResolvedImport::Resolved(def)
+ if resolved_def.is_full() {
+ PartialResolvedImport::Resolved(resolved_def)
} else {
- PartialResolvedImport::Indeterminate(def)
+ PartialResolvedImport::Indeterminate(resolved_def)
}
}
@@ -849,7 +853,7 @@ impl DefCollector<'_> {
let vis = self
.def_map
.resolve_visibility(
- self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
+ self.crate_local_def_map.unwrap_or(&self.local_def_map),
self.db,
module_id,
&directive.import.visibility,
@@ -986,6 +990,43 @@ impl DefCollector<'_> {
Some(ImportOrExternCrate::Glob(glob)),
);
}
+ Some(ModuleDefId::TraitId(it)) => {
+ // FIXME: Implement this correctly
+ // We can't actually call `trait_items`, the reason being that if macro calls
+ // occur, they will call back into the def map which we might be computing right
+ // now resulting in a cycle.
+ // To properly implement this, trait item collection needs to be done in def map
+ // collection...
+ let resolutions = if true {
+ vec![]
+ } else {
+ self.db
+ .trait_items(it)
+ .items
+ .iter()
+ .map(|&(ref name, variant)| {
+ let res = match variant {
+ AssocItemId::FunctionId(it) => {
+ PerNs::values(it.into(), vis, None)
+ }
+ AssocItemId::ConstId(it) => {
+ PerNs::values(it.into(), vis, None)
+ }
+ AssocItemId::TypeAliasId(it) => {
+ PerNs::types(it.into(), vis, None)
+ }
+ };
+ (Some(name.clone()), res)
+ })
+ .collect::<Vec<_>>()
+ };
+ self.update(
+ module_id,
+ &resolutions,
+ vis,
+ Some(ImportOrExternCrate::Glob(glob)),
+ );
+ }
Some(d) => {
tracing::debug!("glob import {:?} from non-module/enum {:?}", import, d);
}
@@ -1240,7 +1281,7 @@ impl DefCollector<'_> {
};
let resolver = |path: &_| {
let resolved_res = self.def_map.resolve_path_fp_with_macro(
- self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
+ self.crate_local_def_map.unwrap_or(&self.local_def_map),
self.db,
ResolveMode::Other,
directive.module_id,
@@ -1307,7 +1348,7 @@ impl DefCollector<'_> {
);
// Record its helper attributes.
if def_id.krate != self.def_map.krate {
- let def_map = self.db.crate_def_map(def_id.krate);
+ let def_map = crate_def_map(self.db, def_id.krate);
if let Some(helpers) = def_map.data.exported_derives.get(&def_id) {
self.def_map
.derive_helpers_in_scope
@@ -1553,7 +1594,7 @@ impl DefCollector<'_> {
self.def_map.krate,
|path| {
let resolved_res = self.def_map.resolve_path_fp_with_macro(
- self.crate_local_def_map.as_deref().unwrap_or(&self.local_def_map),
+ self.crate_local_def_map.unwrap_or(&self.local_def_map),
self.db,
ResolveMode::Other,
directive.module_id,
@@ -1702,11 +1743,8 @@ impl ModCollector<'_, '_> {
let module = self.def_collector.def_map.module_id(module_id);
let def_map = &mut self.def_collector.def_map;
- let local_def_map = self
- .def_collector
- .crate_local_def_map
- .as_deref()
- .unwrap_or(&self.def_collector.local_def_map);
+ let local_def_map =
+ self.def_collector.crate_local_def_map.unwrap_or(&self.def_collector.local_def_map);
match item {
ModItem::Mod(m) => self.collect_module(m, &attrs),
@@ -2133,10 +2171,7 @@ impl ModCollector<'_, '_> {
let def_map = &mut self.def_collector.def_map;
let vis = def_map
.resolve_visibility(
- self.def_collector
- .crate_local_def_map
- .as_deref()
- .unwrap_or(&self.def_collector.local_def_map),
+ self.def_collector.crate_local_def_map.unwrap_or(&self.def_collector.local_def_map),
self.def_collector.db,
self.module_id,
visibility,