Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/resolver.rs')
-rw-r--r--crates/hir-def/src/resolver.rs444
1 files changed, 235 insertions, 209 deletions
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index a2e6e4cc04..46c12574fd 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -1,37 +1,43 @@
//! Name resolution façade.
-use std::{fmt, iter, mem};
+use std::{fmt, mem};
-use base_db::CrateId;
-use hir_expand::{name::Name, MacroDefId};
-use intern::{sym, Symbol};
+use base_db::Crate;
+use hir_expand::{
+ MacroDefId,
+ mod_path::{ModPath, PathKind},
+ name::Name,
+};
+use intern::{Symbol, sym};
use itertools::Itertools as _;
use rustc_hash::FxHashSet;
-use smallvec::{smallvec, SmallVec};
-use span::SyntaxContextId;
+use smallvec::{SmallVec, smallvec};
+use span::SyntaxContext;
use triomphe::Arc;
use crate::{
+ AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
+ ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule,
+ ImplId, ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id,
+ MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId,
+ TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UseId, VariantId,
builtin_type::BuiltinType,
- data::ExternCrateDeclData,
db::DefDatabase,
expr_store::{
- scope::{ExprScopes, ScopeId},
HygieneId,
+ path::Path,
+ scope::{ExprScopes, ScopeId},
},
- generics::{GenericParams, TypeOrConstParamData},
- hir::{BindingId, ExprId, LabelId},
- item_scope::{BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, BUILTIN_SCOPE},
+ hir::{
+ BindingId, ExprId, LabelId,
+ generics::{GenericParams, TypeOrConstParamData},
+ },
+ item_scope::{BUILTIN_SCOPE, BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, ItemScope},
+ item_tree::ImportAlias,
lang_item::LangItemTarget,
- nameres::{DefMap, MacroSubNs, ResolvePathResultPrefixInfo},
- path::{ModPath, Path, PathKind},
+ nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo},
per_ns::PerNs,
- type_ref::{LifetimeRef, TypesMap},
+ type_ref::LifetimeRef,
visibility::{RawVisibility, Visibility},
- AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
- ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule,
- ImplId, ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id,
- MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId,
- TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
};
#[derive(Debug, Clone)]
@@ -47,6 +53,7 @@ pub struct Resolver {
#[derive(Clone)]
struct ModuleItemMap {
def_map: Arc<DefMap>,
+ local_def_map: Arc<LocalDefMap>,
module_id: LocalModuleId,
}
@@ -76,16 +83,13 @@ impl fmt::Debug for ExprScope {
enum Scope {
/// All the items and imported names of a module
BlockScope(ModuleItemMap),
- /// Brings the generic parameters of an item into scope
+ /// Brings the generic parameters of an item into scope as well as the `Self` type alias /
+ /// generic for ADTs and impls.
GenericParams { def: GenericDefId, params: Arc<GenericParams> },
- /// Brings `Self` in `impl` block into scope
- ImplDefScope(ImplId),
- /// Brings `Self` in enum, struct and union definitions into scope
- AdtScope(AdtId),
/// Local bindings
ExprScope(ExprScope),
/// Macro definition inside bodies that affects all paths after it in the same block.
- MacroDefScope(Box<MacroDefId>),
+ MacroDefScope(MacroDefId),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -101,9 +105,8 @@ pub enum TypeNs {
BuiltinType(BuiltinType),
TraitId(TraitId),
TraitAliasId(TraitAliasId),
- // Module belong to type ns, but the resolver is used when all module paths
- // are fully resolved.
- // ModuleId(ModuleId)
+
+ ModuleId(ModuleId),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -180,7 +183,7 @@ impl Resolver {
{
let path = match path {
Path::BarePath(mod_path) => mod_path,
- Path::Normal(it) => it.mod_path(),
+ Path::Normal(it) => &it.mod_path,
Path::LangItem(l, seg) => {
let type_ns = match *l {
LangItemTarget::Union(it) => TypeNs::AdtId(it.into()),
@@ -207,12 +210,33 @@ impl Resolver {
return self.module_scope.resolve_path_in_type_ns(db, path);
}
- let remaining_idx = || if path.segments().len() == 1 { None } else { Some(1) };
+ let remaining_idx = || {
+ if path.segments().len() == 1 { None } else { Some(1) }
+ };
for scope in self.scopes() {
match scope {
Scope::ExprScope(_) | Scope::MacroDefScope(_) => continue,
Scope::GenericParams { params, def } => {
+ if let &GenericDefId::ImplId(impl_) = def {
+ if *first_name == sym::Self_ {
+ return Some((
+ TypeNs::SelfType(impl_),
+ remaining_idx(),
+ None,
+ ResolvePathResultPrefixInfo::default(),
+ ));
+ }
+ } else if let &GenericDefId::AdtId(adt) = def {
+ if *first_name == sym::Self_ {
+ return Some((
+ TypeNs::AdtSelfType(adt),
+ remaining_idx(),
+ None,
+ ResolvePathResultPrefixInfo::default(),
+ ));
+ }
+ }
if let Some(id) = params.find_type_by_name(first_name, *def) {
return Some((
TypeNs::GenericParam(id),
@@ -222,28 +246,26 @@ impl Resolver {
));
}
}
- &Scope::ImplDefScope(impl_) => {
- if *first_name == sym::Self_.clone() {
- return Some((
- TypeNs::SelfType(impl_),
- remaining_idx(),
- None,
- ResolvePathResultPrefixInfo::default(),
- ));
- }
- }
- &Scope::AdtScope(adt) => {
- if *first_name == sym::Self_.clone() {
- return Some((
- TypeNs::AdtSelfType(adt),
- remaining_idx(),
- None,
- ResolvePathResultPrefixInfo::default(),
- ));
- }
- }
Scope::BlockScope(m) => {
if let Some(res) = m.resolve_path_in_type_ns(db, path) {
+ let res = match res.0 {
+ TypeNs::ModuleId(_) if res.1.is_none() => {
+ if let Some(ModuleDefId::BuiltinType(builtin)) = BUILTIN_SCOPE
+ .get(first_name)
+ .and_then(|builtin| builtin.take_types())
+ {
+ (
+ TypeNs::BuiltinType(builtin),
+ remaining_idx(),
+ None,
+ ResolvePathResultPrefixInfo::default(),
+ )
+ } else {
+ res
+ }
+ }
+ _ => res,
+ };
return Some(res);
}
}
@@ -269,11 +291,18 @@ impl Resolver {
db: &dyn DefDatabase,
visibility: &RawVisibility,
) -> Option<Visibility> {
- let within_impl = self.scopes().any(|scope| matches!(scope, Scope::ImplDefScope(_)));
match visibility {
RawVisibility::Module(_, _) => {
- let (item_map, module) = self.item_scope();
- item_map.resolve_visibility(db, module, visibility, within_impl)
+ let (item_map, item_local_map, module) = self.item_scope_();
+ item_map.resolve_visibility(
+ item_local_map,
+ db,
+ module,
+ visibility,
+ self.scopes().any(|scope| {
+ matches!(scope, Scope::GenericParams { def: GenericDefId::ImplId(_), .. })
+ }),
+ )
}
RawVisibility::Public => Some(Visibility::Public),
}
@@ -296,7 +325,7 @@ impl Resolver {
) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> {
let path = match path {
Path::BarePath(mod_path) => mod_path,
- Path::Normal(it) => it.mod_path(),
+ Path::Normal(it) => &it.mod_path,
Path::LangItem(l, None) => {
return Some((
ResolveValueResult::ValueNs(
@@ -314,7 +343,7 @@ impl Resolver {
None,
),
ResolvePathResultPrefixInfo::default(),
- ))
+ ));
}
Path::LangItem(l, Some(_)) => {
let type_ns = match *l {
@@ -336,7 +365,7 @@ impl Resolver {
}
};
let n_segments = path.segments().len();
- let tmp = Name::new_symbol_root(sym::self_.clone());
+ let tmp = Name::new_symbol_root(sym::self_);
let first_name = if path.is_self() { &tmp } else { path.segments().first()? };
let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
if skip_to_mod {
@@ -367,6 +396,14 @@ impl Resolver {
handle_macro_def_scope(db, &mut hygiene_id, &mut hygiene_info, macro_id)
}
Scope::GenericParams { params, def } => {
+ if let &GenericDefId::ImplId(impl_) = def {
+ if *first_name == sym::Self_ {
+ return Some((
+ ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_), None),
+ ResolvePathResultPrefixInfo::default(),
+ ));
+ }
+ }
if let Some(id) = params.find_const_by_name(first_name, *def) {
let val = ValueNs::GenericParam(id);
return Some((
@@ -375,16 +412,6 @@ impl Resolver {
));
}
}
- &Scope::ImplDefScope(impl_) => {
- if *first_name == sym::Self_.clone() {
- return Some((
- ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_), None),
- ResolvePathResultPrefixInfo::default(),
- ));
- }
- }
- // bare `Self` doesn't work in the value namespace in a struct/enum definition
- Scope::AdtScope(_) => continue,
Scope::BlockScope(m) => {
if let Some(def) = m.resolve_path_in_value_ns(db, path) {
return Some(def);
@@ -397,6 +424,22 @@ impl Resolver {
match scope {
Scope::ExprScope(_) | Scope::MacroDefScope(_) => continue,
Scope::GenericParams { params, def } => {
+ if let &GenericDefId::ImplId(impl_) = def {
+ if *first_name == sym::Self_ {
+ return Some((
+ ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1, None),
+ ResolvePathResultPrefixInfo::default(),
+ ));
+ }
+ } else if let &GenericDefId::AdtId(adt) = def {
+ if *first_name == sym::Self_ {
+ let ty = TypeNs::AdtSelfType(adt);
+ return Some((
+ ResolveValueResult::Partial(ty, 1, None),
+ ResolvePathResultPrefixInfo::default(),
+ ));
+ }
+ }
if let Some(id) = params.find_type_by_name(first_name, *def) {
let ty = TypeNs::GenericParam(id);
return Some((
@@ -405,23 +448,6 @@ impl Resolver {
));
}
}
- &Scope::ImplDefScope(impl_) => {
- if *first_name == sym::Self_.clone() {
- return Some((
- ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1, None),
- ResolvePathResultPrefixInfo::default(),
- ));
- }
- }
- Scope::AdtScope(adt) => {
- if *first_name == sym::Self_.clone() {
- let ty = TypeNs::AdtSelfType(*adt);
- return Some((
- ResolveValueResult::Partial(ty, 1, None),
- ResolvePathResultPrefixInfo::default(),
- ));
- }
- }
Scope::BlockScope(m) => {
if let Some(def) = m.resolve_path_in_value_ns(db, path) {
return Some(def);
@@ -468,9 +494,16 @@ impl Resolver {
path: &ModPath,
expected_macro_kind: Option<MacroSubNs>,
) -> Option<(MacroId, Option<ImportOrGlob>)> {
- let (item_map, module) = self.item_scope();
+ let (item_map, item_local_map, module) = self.item_scope_();
item_map
- .resolve_path(db, module, path, BuiltinShadowMode::Other, expected_macro_kind)
+ .resolve_path(
+ item_local_map,
+ db,
+ module,
+ path,
+ BuiltinShadowMode::Other,
+ expected_macro_kind,
+ )
.0
.take_macros_import()
}
@@ -485,16 +518,19 @@ impl Resolver {
}
pub fn resolve_lifetime(&self, lifetime: &LifetimeRef) -> Option<LifetimeNs> {
- if lifetime.name == sym::tick_static.clone() {
- return Some(LifetimeNs::Static);
- }
-
- self.scopes().find_map(|scope| match scope {
- Scope::GenericParams { def, params } => {
- params.find_lifetime_by_name(&lifetime.name, *def).map(LifetimeNs::LifetimeParam)
+ match lifetime {
+ LifetimeRef::Static => Some(LifetimeNs::Static),
+ LifetimeRef::Named(name) => self.scopes().find_map(|scope| match scope {
+ Scope::GenericParams { def, params } => {
+ params.find_lifetime_by_name(name, *def).map(LifetimeNs::LifetimeParam)
+ }
+ _ => None,
+ }),
+ LifetimeRef::Placeholder | LifetimeRef::Error => None,
+ LifetimeRef::Param(lifetime_param_id) => {
+ Some(LifetimeNs::LifetimeParam(*lifetime_param_id))
}
- _ => None,
- })
+ }
}
/// Returns a set of names available in the current scope.
@@ -544,7 +580,7 @@ impl Resolver {
for scope in self.scopes() {
scope.process_names(&mut res, db);
}
- let ModuleItemMap { ref def_map, module_id } = self.module_scope;
+ let ModuleItemMap { ref def_map, module_id, ref local_def_map } = self.module_scope;
// FIXME: should we provide `self` here?
// f(
// Name::self_param(),
@@ -566,7 +602,7 @@ impl Resolver {
res.add(name, ScopeDef::ModuleDef(def.into()));
},
);
- def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| {
+ local_def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| {
res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into())));
});
BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
@@ -581,6 +617,7 @@ impl Resolver {
res.map
}
+ /// Note: Not to be used directly within hir-def/hir-ty
pub fn extern_crate_decls_in_scope<'a>(
&'a self,
db: &'a dyn DefDatabase,
@@ -588,12 +625,22 @@ impl Resolver {
self.module_scope.def_map[self.module_scope.module_id]
.scope
.extern_crate_decls()
- .map(|id| ExternCrateDeclData::extern_crate_decl_data_query(db, id).name.clone())
+ .filter_map(|id| {
+ let loc = id.lookup(db);
+ let tree = loc.item_tree_id().item_tree(db);
+ match &tree[loc.id.value].alias {
+ Some(alias) => match alias {
+ ImportAlias::Underscore => None,
+ ImportAlias::Alias(name) => Some(name.clone()),
+ },
+ None => Some(tree[loc.id.value].name.clone()),
+ }
+ })
}
pub fn extern_crates_in_scope(&self) -> impl Iterator<Item = (Name, ModuleId)> + '_ {
self.module_scope
- .def_map
+ .local_def_map
.extern_prelude()
.map(|(name, module_id)| (name.clone(), module_id.0.into()))
}
@@ -606,13 +653,12 @@ impl Resolver {
for scope in self.scopes() {
match scope {
Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()),
- &Scope::ImplDefScope(impl_) => {
- let impl_data = db.impl_data(impl_);
+ &Scope::GenericParams { def: GenericDefId::ImplId(impl_), .. } => {
+ let impl_data = db.impl_signature(impl_);
if let Some(target_trait) = impl_data.target_trait {
- if let Some(TypeNs::TraitId(trait_)) = self.resolve_path_in_type_ns_fully(
- db,
- &impl_data.types_map[target_trait.path],
- ) {
+ if let Some(TypeNs::TraitId(trait_)) = self
+ .resolve_path_in_type_ns_fully(db, &impl_data.store[target_trait.path])
+ {
traits.insert(trait_);
}
}
@@ -641,29 +687,21 @@ impl Resolver {
}
pub fn module(&self) -> ModuleId {
- let (def_map, local_id) = self.item_scope();
+ let (def_map, _, local_id) = self.item_scope_();
def_map.module_id(local_id)
}
- pub fn krate(&self) -> CrateId {
- self.module_scope.def_map.krate()
+ pub fn item_scope(&self) -> &ItemScope {
+ let (def_map, _, local_id) = self.item_scope_();
+ &def_map[local_id].scope
}
- pub fn def_map(&self) -> &DefMap {
- self.item_scope().0
+ pub fn krate(&self) -> Crate {
+ self.module_scope.def_map.krate()
}
- pub fn where_predicates_in_scope(
- &self,
- ) -> impl Iterator<Item = (&crate::generics::WherePredicate, (&GenericDefId, &TypesMap))> {
- self.scopes()
- .filter_map(|scope| match scope {
- Scope::GenericParams { params, def } => Some((params, def)),
- _ => None,
- })
- .flat_map(|(params, def)| {
- params.where_predicates().zip(iter::repeat((def, &params.types_map)))
- })
+ pub fn def_map(&self) -> &DefMap {
+ self.item_scope_().0
}
pub fn generic_def(&self) -> Option<GenericDefId> {
@@ -694,19 +732,9 @@ impl Resolver {
})
}
- pub fn type_owner(&self) -> Option<TypeOwnerId> {
- self.scopes().find_map(|scope| match scope {
- Scope::BlockScope(_) | Scope::MacroDefScope(_) => None,
- &Scope::GenericParams { def, .. } => Some(def.into()),
- &Scope::ImplDefScope(id) => Some(id.into()),
- &Scope::AdtScope(adt) => Some(adt.into()),
- Scope::ExprScope(it) => Some(it.owner.into()),
- })
- }
-
pub fn impl_def(&self) -> Option<ImplId> {
self.scopes().find_map(|scope| match scope {
- Scope::ImplDefScope(def) => Some(*def),
+ &Scope::GenericParams { def: GenericDefId::ImplId(def), .. } => Some(def),
_ => None,
})
}
@@ -748,7 +776,6 @@ impl Resolver {
return None;
}
}
- Scope::AdtScope(_) | Scope::ImplDefScope(_) => continue,
Scope::BlockScope(m) => {
if m.resolve_path_in_value_ns(db, current_name_as_path).is_some() {
// It does not resolve to our renamed variable.
@@ -801,7 +828,6 @@ impl Resolver {
return None;
}
}
- Scope::AdtScope(_) | Scope::ImplDefScope(_) => continue,
Scope::BlockScope(m) => {
if m.resolve_path_in_value_ns(db, name_as_path).is_some() {
return None;
@@ -829,7 +855,7 @@ impl Resolver {
scope_id: ScopeId,
) {
if let Some(macro_id) = expr_scopes.macro_def(scope_id) {
- resolver.scopes.push(Scope::MacroDefScope(macro_id.clone()));
+ resolver.scopes.push(Scope::MacroDefScope(**macro_id));
}
resolver.scopes.push(Scope::ExprScope(ExprScope {
owner,
@@ -838,9 +864,12 @@ impl Resolver {
}));
if let Some(block) = expr_scopes.block(scope_id) {
let def_map = db.block_def_map(block);
- resolver
- .scopes
- .push(Scope::BlockScope(ModuleItemMap { def_map, module_id: DefMap::ROOT }));
+ let local_def_map = block.lookup(db).module.only_local_def_map(db);
+ resolver.scopes.push(Scope::BlockScope(ModuleItemMap {
+ def_map,
+ local_def_map,
+ module_id: DefMap::ROOT,
+ }));
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
// already traverses all parents, so this is O(n²). I think we could only store the
// innermost module scope instead?
@@ -881,7 +910,7 @@ impl Resolver {
fn handle_macro_def_scope(
db: &dyn DefDatabase,
hygiene_id: &mut HygieneId,
- hygiene_info: &mut Option<(SyntaxContextId, MacroDefId)>,
+ hygiene_info: &mut Option<(SyntaxContext, MacroDefId)>,
macro_id: &MacroDefId,
) {
if let Some((parent_ctx, label_macro_id)) = hygiene_info {
@@ -889,11 +918,10 @@ fn handle_macro_def_scope(
// A macro is allowed to refer to variables from before its declaration.
// Therefore, if we got to the rib of its declaration, give up its hygiene
// and use its parent expansion.
- let parent_ctx = db.lookup_intern_syntax_context(*parent_ctx);
- *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent);
- *hygiene_info = parent_ctx.outer_expn.map(|expansion| {
- let expansion = db.lookup_intern_macro_call(expansion);
- (parent_ctx.parent, expansion.def)
+ *hygiene_id = HygieneId::new(parent_ctx.opaque_and_semitransparent(db));
+ *hygiene_info = parent_ctx.outer_expn(db).map(|expansion| {
+ let expansion = db.lookup_intern_macro_call(expansion.into());
+ (parent_ctx.parent(db), expansion.def)
});
}
}
@@ -903,12 +931,12 @@ fn handle_macro_def_scope(
fn hygiene_info(
db: &dyn DefDatabase,
hygiene_id: HygieneId,
-) -> Option<(SyntaxContextId, MacroDefId)> {
+) -> Option<(SyntaxContext, MacroDefId)> {
if !hygiene_id.is_root() {
- let ctx = hygiene_id.lookup(db);
- ctx.outer_expn.map(|expansion| {
- let expansion = db.lookup_intern_macro_call(expansion);
- (ctx.parent, expansion.def)
+ let ctx = hygiene_id.lookup();
+ ctx.outer_expn(db).map(|expansion| {
+ let expansion = db.lookup_intern_macro_call(expansion.into());
+ (ctx.parent(db), expansion.def)
})
} else {
None
@@ -928,9 +956,10 @@ impl Resolver {
path: &ModPath,
shadow: BuiltinShadowMode,
) -> PerNs {
- let (item_map, module) = self.item_scope();
+ let (item_map, item_local_map, module) = self.item_scope_();
// This method resolves `path` just like import paths, so no expected macro subns is given.
- let (module_res, segment_index) = item_map.resolve_path(db, module, path, shadow, None);
+ let (module_res, segment_index) =
+ item_map.resolve_path(item_local_map, db, module, path, shadow, None);
if segment_index.is_some() {
return PerNs::none();
}
@@ -938,13 +967,17 @@ impl Resolver {
}
/// The innermost block scope that contains items or the module scope that contains this resolver.
- fn item_scope(&self) -> (&DefMap, LocalModuleId) {
+ fn item_scope_(&self) -> (&DefMap, &LocalDefMap, LocalModuleId) {
self.scopes()
.find_map(|scope| match scope {
- Scope::BlockScope(m) => Some((&*m.def_map, m.module_id)),
+ Scope::BlockScope(m) => Some((&*m.def_map, &*m.local_def_map, m.module_id)),
_ => None,
})
- .unwrap_or((&self.module_scope.def_map, self.module_scope.module_id))
+ .unwrap_or((
+ &self.module_scope.def_map,
+ &self.module_scope.local_def_map,
+ self.module_scope.module_id,
+ ))
}
}
@@ -972,8 +1005,13 @@ impl Scope {
})
});
}
- Scope::GenericParams { params, def: parent } => {
- let parent = *parent;
+ &Scope::GenericParams { ref params, def: parent } => {
+ if let GenericDefId::ImplId(impl_) = parent {
+ acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::ImplSelfType(impl_));
+ } else if let GenericDefId::AdtId(adt) = parent {
+ acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::AdtSelfType(adt));
+ }
+
for (local_id, param) in params.iter_type_or_consts() {
if let Some(name) = &param.name() {
let id = TypeOrConstParamId { parent, local_id };
@@ -996,12 +1034,6 @@ impl Scope {
acc.add(&param.name, ScopeDef::GenericParam(id.into()))
}
}
- Scope::ImplDefScope(i) => {
- acc.add(&Name::new_symbol_root(sym::Self_.clone()), ScopeDef::ImplSelfType(*i));
- }
- Scope::AdtScope(i) => {
- acc.add(&Name::new_symbol_root(sym::Self_.clone()), ScopeDef::AdtSelfType(*i));
- }
Scope::ExprScope(scope) => {
if let Some((label, name)) = scope.expr_scopes.label(scope.scope_id) {
acc.add(&name, ScopeDef::Label(label))
@@ -1045,13 +1077,14 @@ fn resolver_for_scope_(
for scope in scope_chain.into_iter().rev() {
if let Some(block) = scopes.block(scope) {
let def_map = db.block_def_map(block);
- r = r.push_block_scope(def_map);
+ let local_def_map = block.lookup(db).module.only_local_def_map(db);
+ r = r.push_block_scope(def_map, local_def_map);
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
// already traverses all parents, so this is O(n²). I think we could only store the
// innermost module scope instead?
}
if let Some(macro_id) = scopes.macro_def(scope) {
- r = r.push_scope(Scope::MacroDefScope(macro_id.clone()));
+ r = r.push_scope(Scope::MacroDefScope(**macro_id));
}
r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
@@ -1070,13 +1103,12 @@ impl Resolver {
self.push_scope(Scope::GenericParams { def, params })
}
- fn push_impl_def_scope(self, impl_def: ImplId) -> Resolver {
- self.push_scope(Scope::ImplDefScope(impl_def))
- }
-
- fn push_block_scope(self, def_map: Arc<DefMap>) -> Resolver {
- debug_assert!(def_map.block_id().is_some());
- self.push_scope(Scope::BlockScope(ModuleItemMap { def_map, module_id: DefMap::ROOT }))
+ fn push_block_scope(self, def_map: Arc<DefMap>, local_def_map: Arc<LocalDefMap>) -> Resolver {
+ self.push_scope(Scope::BlockScope(ModuleItemMap {
+ def_map,
+ local_def_map,
+ module_id: DefMap::ROOT,
+ }))
}
fn push_expr_scope(
@@ -1095,8 +1127,13 @@ impl ModuleItemMap {
db: &dyn DefDatabase,
path: &ModPath,
) -> Option<(ResolveValueResult, ResolvePathResultPrefixInfo)> {
- let (module_def, unresolved_idx, prefix_info) =
- self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
+ let (module_def, unresolved_idx, prefix_info) = self.def_map.resolve_path_locally(
+ &self.local_def_map,
+ db,
+ self.module_id,
+ path,
+ BuiltinShadowMode::Other,
+ );
match unresolved_idx {
None => {
let (value, import) = to_value_ns(module_def)?;
@@ -1129,8 +1166,13 @@ impl ModuleItemMap {
path: &ModPath,
) -> Option<(TypeNs, Option<usize>, Option<ImportOrExternCrate>, ResolvePathResultPrefixInfo)>
{
- let (module_def, idx, prefix_info) =
- self.def_map.resolve_path_locally(db, self.module_id, path, BuiltinShadowMode::Other);
+ let (module_def, idx, prefix_info) = self.def_map.resolve_path_locally(
+ &self.local_def_map,
+ db,
+ self.module_id,
+ path,
+ BuiltinShadowMode::Other,
+ );
let (res, import) = to_type_ns(module_def)?;
Some((res, idx, import, prefix_info))
}
@@ -1168,11 +1210,12 @@ fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> {
ModuleDefId::TraitId(it) => TypeNs::TraitId(it),
ModuleDefId::TraitAliasId(it) => TypeNs::TraitAliasId(it),
+ ModuleDefId::ModuleId(it) => TypeNs::ModuleId(it),
+
ModuleDefId::FunctionId(_)
| ModuleDefId::ConstId(_)
| ModuleDefId::MacroId(_)
- | ModuleDefId::StaticId(_)
- | ModuleDefId::ModuleId(_) => return None,
+ | ModuleDefId::StaticId(_) => return None,
};
Some((res, def.import))
}
@@ -1225,11 +1268,14 @@ pub trait HasResolver: Copy {
impl HasResolver for ModuleId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- let mut def_map = self.def_map(db);
+ let (mut def_map, local_def_map) = self.local_def_map(db);
let mut module_id = self.local_id;
if !self.is_block_module() {
- return Resolver { scopes: vec![], module_scope: ModuleItemMap { def_map, module_id } };
+ return Resolver {
+ scopes: vec![],
+ module_scope: ModuleItemMap { def_map, local_def_map, module_id },
+ };
}
let mut modules: SmallVec<[_; 1]> = smallvec![];
@@ -1243,10 +1289,14 @@ impl HasResolver for ModuleId {
}
let mut resolver = Resolver {
scopes: Vec::with_capacity(modules.len()),
- module_scope: ModuleItemMap { def_map, module_id },
+ module_scope: ModuleItemMap {
+ def_map,
+ local_def_map: local_def_map.clone(),
+ module_id,
+ },
};
for def_map in modules.into_iter().rev() {
- resolver = resolver.push_block_scope(def_map);
+ resolver = resolver.push_block_scope(def_map, local_def_map.clone());
}
resolver
}
@@ -1254,9 +1304,10 @@ impl HasResolver for ModuleId {
impl HasResolver for CrateRootModuleId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
+ let (def_map, local_def_map) = self.local_def_map(db);
Resolver {
scopes: vec![],
- module_scope: ModuleItemMap { def_map: self.def_map(db), module_id: DefMap::ROOT },
+ module_scope: ModuleItemMap { def_map, local_def_map, module_id: DefMap::ROOT },
}
}
}
@@ -1276,10 +1327,7 @@ impl HasResolver for TraitAliasId {
impl<T: Into<AdtId> + Copy> HasResolver for T {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
let def = self.into();
- def.module(db)
- .resolver(db)
- .push_generic_params_scope(db, def.into())
- .push_scope(Scope::AdtScope(def))
+ def.module(db).resolver(db).push_generic_params_scope(db, def.into())
}
}
@@ -1309,11 +1357,7 @@ impl HasResolver for TypeAliasId {
impl HasResolver for ImplId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- self.lookup(db)
- .container
- .resolver(db)
- .push_generic_params_scope(db, self.into())
- .push_impl_def_scope(self)
+ self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
}
}
@@ -1336,23 +1380,6 @@ impl HasResolver for UseId {
}
}
-impl HasResolver for TypeOwnerId {
- fn resolver(self, db: &dyn DefDatabase) -> Resolver {
- match self {
- TypeOwnerId::FunctionId(it) => it.resolver(db),
- TypeOwnerId::StaticId(it) => it.resolver(db),
- TypeOwnerId::ConstId(it) => it.resolver(db),
- TypeOwnerId::InTypeConstId(it) => it.lookup(db).owner.resolver(db),
- TypeOwnerId::AdtId(it) => it.resolver(db),
- TypeOwnerId::TraitId(it) => it.resolver(db),
- TypeOwnerId::TraitAliasId(it) => it.resolver(db),
- TypeOwnerId::TypeAliasId(it) => it.resolver(db),
- TypeOwnerId::ImplId(it) => it.resolver(db),
- TypeOwnerId::EnumVariantId(it) => it.resolver(db),
- }
- }
-}
-
impl HasResolver for DefWithBodyId {
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
match self {
@@ -1360,7 +1387,6 @@ impl HasResolver for DefWithBodyId {
DefWithBodyId::FunctionId(f) => f.resolver(db),
DefWithBodyId::StaticId(s) => s.resolver(db),
DefWithBodyId::VariantId(v) => v.resolver(db),
- DefWithBodyId::InTypeConstId(c) => c.lookup(db).owner.resolver(db),
}
}
}
@@ -1438,7 +1464,7 @@ impl HasResolver for MacroRulesId {
fn lookup_resolver<'db>(
db: &(dyn DefDatabase + 'db),
lookup: impl Lookup<
- Database<'db> = dyn DefDatabase + 'db,
+ Database = dyn DefDatabase,
Data = impl ItemTreeLoc<Container = impl HasResolver>,
>,
) -> Resolver {