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.rs | 172 |
1 files changed, 93 insertions, 79 deletions
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs index 2ac0f90fb2..bb292ac1a6 100644 --- a/crates/hir-def/src/resolver.rs +++ b/crates/hir-def/src/resolver.rs @@ -13,14 +13,13 @@ use rustc_hash::FxHashSet; use smallvec::{SmallVec, smallvec}; use span::SyntaxContext; use syntax::ast::HasName; -use triomphe::Arc; use crate::{ - AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, - ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, ImplId, - ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, - ModuleId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId, - TypeParamId, UseId, VariantId, + AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, + ExpressionStoreOwnerId, ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId, + GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId, + MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, + TypeOrConstParamId, TypeParamId, UseId, VariantId, builtin_type::BuiltinType, db::DefDatabase, expr_store::{ @@ -32,10 +31,11 @@ use crate::{ BindingId, ExprId, LabelId, generics::{GenericParams, TypeOrConstParamData}, }, - item_scope::{BUILTIN_SCOPE, BuiltinShadowMode, ImportOrExternCrate, ImportOrGlob, ItemScope}, + item_scope::{BUILTIN_SCOPE, BuiltinShadowMode, ImportOrExternCrate, ItemScope}, lang_item::LangItemTarget, nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo, block_def_map}, per_ns::PerNs, + signatures::ImplSignature, src::HasSource, type_ref::LifetimeRef, visibility::{RawVisibility, Visibility}, @@ -65,13 +65,13 @@ impl fmt::Debug for ModuleItemMap<'_> { } #[derive(Clone)] -struct ExprScope { - owner: DefWithBodyId, - expr_scopes: Arc<ExprScopes>, +struct ExprScope<'db> { + owner: ExpressionStoreOwnerId, + expr_scopes: &'db ExprScopes, scope_id: ScopeId, } -impl fmt::Debug for ExprScope { +impl fmt::Debug for ExprScope<'_> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("ExprScope") .field("owner", &self.owner) @@ -86,9 +86,9 @@ enum Scope<'db> { BlockScope(ModuleItemMap<'db>), /// 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> }, + GenericParams { def: GenericDefId, params: &'db GenericParams }, /// Local bindings - ExprScope(ExprScope), + ExprScope(ExprScope<'db>), /// Macro definition inside bodies that affects all paths after it in the same block. MacroDefScope(MacroDefId), } @@ -111,8 +111,8 @@ pub enum TypeNs { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub enum ResolveValueResult { - ValueNs(ValueNs, Option<ImportOrGlob>), - Partial(TypeNs, usize, Option<ImportOrExternCrate>), + ValueNs(ValueNs), + Partial(TypeNs, usize), } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -332,20 +332,17 @@ impl<'db> Resolver<'db> { Path::Normal(it) => &it.mod_path, Path::LangItem(l, None) => { return Some(( - ResolveValueResult::ValueNs( - match *l { - LangItemTarget::FunctionId(it) => ValueNs::FunctionId(it), - LangItemTarget::StaticId(it) => ValueNs::StaticId(it), - LangItemTarget::StructId(it) => ValueNs::StructId(it), - LangItemTarget::EnumVariantId(it) => ValueNs::EnumVariantId(it), - LangItemTarget::UnionId(_) - | LangItemTarget::ImplId(_) - | LangItemTarget::TypeAliasId(_) - | LangItemTarget::TraitId(_) - | LangItemTarget::EnumId(_) => return None, - }, - None, - ), + ResolveValueResult::ValueNs(match *l { + LangItemTarget::FunctionId(it) => ValueNs::FunctionId(it), + LangItemTarget::StaticId(it) => ValueNs::StaticId(it), + LangItemTarget::StructId(it) => ValueNs::StructId(it), + LangItemTarget::EnumVariantId(it) => ValueNs::EnumVariantId(it), + LangItemTarget::UnionId(_) + | LangItemTarget::ImplId(_) + | LangItemTarget::TypeAliasId(_) + | LangItemTarget::TraitId(_) + | LangItemTarget::EnumId(_) => return None, + }), ResolvePathResultPrefixInfo::default(), )); } @@ -363,7 +360,7 @@ impl<'db> Resolver<'db> { }; // Remaining segments start from 0 because lang paths have no segments other than the remaining. return Some(( - ResolveValueResult::Partial(type_ns, 0, None), + ResolveValueResult::Partial(type_ns, 0), ResolvePathResultPrefixInfo::default(), )); } @@ -388,10 +385,7 @@ impl<'db> Resolver<'db> { if let Some(e) = entry { return Some(( - ResolveValueResult::ValueNs( - ValueNs::LocalBinding(e.binding()), - None, - ), + ResolveValueResult::ValueNs(ValueNs::LocalBinding(e.binding())), ResolvePathResultPrefixInfo::default(), )); } @@ -404,14 +398,14 @@ impl<'db> Resolver<'db> { && *first_name == sym::Self_ { return Some(( - ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_), None), + ResolveValueResult::ValueNs(ValueNs::ImplSelf(impl_)), ResolvePathResultPrefixInfo::default(), )); } if let Some(id) = params.find_const_by_name(first_name, *def) { let val = ValueNs::GenericParam(id); return Some(( - ResolveValueResult::ValueNs(val, None), + ResolveValueResult::ValueNs(val), ResolvePathResultPrefixInfo::default(), )); } @@ -431,7 +425,7 @@ impl<'db> Resolver<'db> { if let &GenericDefId::ImplId(impl_) = def { if *first_name == sym::Self_ { return Some(( - ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1, None), + ResolveValueResult::Partial(TypeNs::SelfType(impl_), 1), ResolvePathResultPrefixInfo::default(), )); } @@ -440,14 +434,14 @@ impl<'db> Resolver<'db> { { let ty = TypeNs::AdtSelfType(adt); return Some(( - ResolveValueResult::Partial(ty, 1, None), + ResolveValueResult::Partial(ty, 1), ResolvePathResultPrefixInfo::default(), )); } if let Some(id) = params.find_type_by_name(first_name, *def) { let ty = TypeNs::GenericParam(id); return Some(( - ResolveValueResult::Partial(ty, 1, None), + ResolveValueResult::Partial(ty, 1), ResolvePathResultPrefixInfo::default(), )); } @@ -473,7 +467,7 @@ impl<'db> Resolver<'db> { && let Some(builtin) = BuiltinType::by_name(first_name) { return Some(( - ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1, None), + ResolveValueResult::Partial(TypeNs::BuiltinType(builtin), 1), ResolvePathResultPrefixInfo::default(), )); } @@ -488,7 +482,7 @@ impl<'db> Resolver<'db> { hygiene: HygieneId, ) -> Option<ValueNs> { match self.resolve_path_in_value_ns(db, path, hygiene)? { - ResolveValueResult::ValueNs(it, _) => Some(it), + ResolveValueResult::ValueNs(it) => Some(it), ResolveValueResult::Partial(..) => None, } } @@ -659,7 +653,7 @@ impl<'db> Resolver<'db> { match scope { Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()), &Scope::GenericParams { def: GenericDefId::ImplId(impl_), .. } => { - let impl_data = db.impl_signature(impl_); + let impl_data = ImplSignature::of(db, impl_); if let Some(target_trait) = impl_data.target_trait && let Some(TypeNs::TraitId(trait_)) = self .resolve_path_in_type_ns_fully(db, &impl_data.store[target_trait.path]) @@ -730,19 +724,19 @@ impl<'db> Resolver<'db> { pub fn generic_params(&self) -> Option<&GenericParams> { self.scopes().find_map(|scope| match scope { - Scope::GenericParams { params, .. } => Some(&**params), + &Scope::GenericParams { params, .. } => Some(params), _ => None, }) } - pub fn all_generic_params(&self) -> impl Iterator<Item = (&GenericParams, &GenericDefId)> { + pub fn all_generic_params(&self) -> impl Iterator<Item = (&GenericParams, GenericDefId)> { self.scopes().filter_map(|scope| match scope { - Scope::GenericParams { params, def } => Some((&**params, def)), + &Scope::GenericParams { params, def } => Some((params, def)), _ => None, }) } - pub fn body_owner(&self) -> Option<DefWithBodyId> { + pub fn expression_store_owner(&self) -> Option<ExpressionStoreOwnerId> { self.scopes().find_map(|scope| match scope { Scope::ExprScope(it) => Some(it.owner), _ => None, @@ -860,25 +854,30 @@ impl<'db> Resolver<'db> { pub fn update_to_inner_scope( &mut self, db: &'db dyn DefDatabase, - owner: DefWithBodyId, + owner: impl Into<ExpressionStoreOwnerId>, + expr_id: ExprId, + ) -> UpdateGuard { + self.update_to_inner_scope_(db, owner.into(), expr_id) + } + + fn update_to_inner_scope_( + &mut self, + db: &'db dyn DefDatabase, + owner: ExpressionStoreOwnerId, expr_id: ExprId, ) -> UpdateGuard { #[inline(always)] fn append_expr_scope<'db>( db: &'db dyn DefDatabase, resolver: &mut Resolver<'db>, - owner: DefWithBodyId, - expr_scopes: &Arc<ExprScopes>, + owner: ExpressionStoreOwnerId, + expr_scopes: &'db ExprScopes, scope_id: ScopeId, ) { if let Some(macro_id) = expr_scopes.macro_def(scope_id) { resolver.scopes.push(Scope::MacroDefScope(**macro_id)); } - resolver.scopes.push(Scope::ExprScope(ExprScope { - owner, - expr_scopes: expr_scopes.clone(), - scope_id, - })); + resolver.scopes.push(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })); if let Some(block) = expr_scopes.block(scope_id) { let def_map = block_def_map(db, block); let local_def_map = block.lookup(db).module.only_local_def_map(db); @@ -896,21 +895,20 @@ impl<'db> Resolver<'db> { let start = self.scopes.len(); let innermost_scope = self.scopes().find(|scope| !matches!(scope, Scope::MacroDefScope(_))); match innermost_scope { - Some(&Scope::ExprScope(ExprScope { scope_id, ref expr_scopes, owner })) => { - let expr_scopes = expr_scopes.clone(); + Some(&Scope::ExprScope(ExprScope { scope_id, expr_scopes, owner })) => { let scope_chain = expr_scopes .scope_chain(expr_scopes.scope_for(expr_id)) .take_while(|&it| it != scope_id); for scope_id in scope_chain { - append_expr_scope(db, self, owner, &expr_scopes, scope_id); + append_expr_scope(db, self, owner, expr_scopes, scope_id); } } _ => { - let expr_scopes = db.expr_scopes(owner); + let expr_scopes = ExprScopes::of(db, owner); let scope_chain = expr_scopes.scope_chain(expr_scopes.scope_for(expr_id)); for scope_id in scope_chain { - append_expr_scope(db, self, owner, &expr_scopes, scope_id); + append_expr_scope(db, self, owner, expr_scopes, scope_id); } } } @@ -1022,7 +1020,7 @@ impl<'db> Scope<'db> { }) }); } - &Scope::GenericParams { ref params, def: parent } => { + &Scope::GenericParams { 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 { @@ -1032,7 +1030,7 @@ impl<'db> Scope<'db> { for (local_id, param) in params.iter_type_or_consts() { if let Some(name) = ¶m.name() { let id = TypeOrConstParamId { parent, local_id }; - let data = &db.generic_params(parent)[local_id]; + let data = &GenericParams::of(db, parent)[local_id]; acc.add( name, ScopeDef::GenericParam(match data { @@ -1066,20 +1064,21 @@ impl<'db> Scope<'db> { pub fn resolver_for_scope( db: &dyn DefDatabase, - owner: DefWithBodyId, + owner: impl Into<ExpressionStoreOwnerId> + HasResolver, scope_id: Option<ScopeId>, ) -> Resolver<'_> { - let r = owner.resolver(db); - let scopes = db.expr_scopes(owner); - resolver_for_scope_(db, scopes, scope_id, r, owner) + let store_owner = owner.into(); + let r = store_owner.resolver(db); + let scopes = ExprScopes::of(db, store_owner); + resolver_for_scope_(db, scopes, scope_id, r, store_owner) } fn resolver_for_scope_<'db>( db: &'db dyn DefDatabase, - scopes: Arc<ExprScopes>, + scopes: &'db ExprScopes, scope_id: Option<ScopeId>, mut r: Resolver<'db>, - owner: DefWithBodyId, + owner: ExpressionStoreOwnerId, ) -> Resolver<'db> { let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>(); r.scopes.reserve(scope_chain.len()); @@ -1099,7 +1098,7 @@ fn resolver_for_scope_<'db>( r = r.push_scope(Scope::MacroDefScope(**macro_id)); } - r = r.push_expr_scope(owner, Arc::clone(&scopes), scope); + r = r.push_expr_scope(owner, scopes, scope); } r } @@ -1115,7 +1114,7 @@ impl<'db> Resolver<'db> { db: &'db dyn DefDatabase, def: GenericDefId, ) -> Resolver<'db> { - let params = db.generic_params(def); + let params = GenericParams::of(db, def); self.push_scope(Scope::GenericParams { def, params }) } @@ -1130,8 +1129,8 @@ impl<'db> Resolver<'db> { fn push_expr_scope( self, - owner: DefWithBodyId, - expr_scopes: Arc<ExprScopes>, + owner: ExpressionStoreOwnerId, + expr_scopes: &'db ExprScopes, scope_id: ScopeId, ) -> Resolver<'db> { self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id })) @@ -1153,12 +1152,12 @@ impl<'db> ModuleItemMap<'db> { ); match unresolved_idx { None => { - let (value, import) = to_value_ns(module_def)?; - Some((ResolveValueResult::ValueNs(value, import), prefix_info)) + let value = to_value_ns(module_def, self.def_map)?; + Some((ResolveValueResult::ValueNs(value), prefix_info)) } Some(unresolved_idx) => { - let def = module_def.take_types_full()?; - let ty = match def.def { + let def = module_def.take_types()?; + let ty = match def { ModuleDefId::AdtId(it) => TypeNs::AdtId(it), ModuleDefId::TraitId(it) => TypeNs::TraitId(it), ModuleDefId::TypeAliasId(it) => TypeNs::TypeAliasId(it), @@ -1171,7 +1170,7 @@ impl<'db> ModuleItemMap<'db> { | ModuleDefId::MacroId(_) | ModuleDefId::StaticId(_) => return None, }; - Some((ResolveValueResult::Partial(ty, unresolved_idx, def.import), prefix_info)) + Some((ResolveValueResult::Partial(ty, unresolved_idx), prefix_info)) } } } @@ -1194,8 +1193,13 @@ impl<'db> ModuleItemMap<'db> { } } -fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportOrGlob>)> { - let (def, import) = per_ns.take_values_import()?; +fn to_value_ns(per_ns: PerNs, def_map: &DefMap) -> Option<ValueNs> { + let def = per_ns.take_values().or_else(|| { + let Some(MacroId::ProcMacroId(proc_macro)) = per_ns.take_macros() else { return None }; + // If we cannot resolve to value ns, but we can resolve to a proc macro, and this is the crate + // defining this proc macro - inside this crate, we should treat the macro as a function. + def_map.proc_macro_as_fn(proc_macro).map(ModuleDefId::FunctionId) + })?; let res = match def { ModuleDefId::FunctionId(it) => ValueNs::FunctionId(it), ModuleDefId::AdtId(AdtId::StructId(it)) => ValueNs::StructId(it), @@ -1210,7 +1214,7 @@ fn to_value_ns(per_ns: PerNs) -> Option<(ValueNs, Option<ImportOrGlob>)> { | ModuleDefId::MacroId(_) | ModuleDefId::ModuleId(_) => return None, }; - Some((res, import)) + Some(res) } fn to_type_ns(per_ns: PerNs) -> Option<(TypeNs, Option<ImportOrExternCrate>)> { @@ -1410,6 +1414,16 @@ impl HasResolver for GenericDefId { } } +impl HasResolver for ExpressionStoreOwnerId { + fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { + match self { + ExpressionStoreOwnerId::Signature(def) => def.resolver(db), + ExpressionStoreOwnerId::Body(def) => def.resolver(db), + ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.resolver(db), + } + } +} + impl HasResolver for EnumVariantId { fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> { self.lookup(db).parent.resolver(db) |