X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=crates%2Fhir%2Fsrc%2Fsemantics%2Fsource_to_def.rs;h=4672e7db40c25fe30a4c3cf245221dcdf3f9d23a;hb=b301b040f5781a9083348936369a01c37138756f;hp=20e2481af6c96f3220f3dc866e41c20bd968a2d8;hpb=f185d1c5332cf80566401b4de74cb6cb210db4cb;p=rust.git diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 20e2481af6c..4672e7db40c 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs @@ -87,21 +87,22 @@ use base_db::FileId; use hir_def::{ + attr::AttrId, child_by_source::ChildBySource, dyn_map::DynMap, expr::{LabelId, PatId}, keys::{self, Key}, AdtId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, - GenericDefId, ImplId, LifetimeParamId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, - TypeParamId, UnionId, VariantId, + GenericDefId, GenericParamId, ImplId, LifetimeParamId, MacroId, ModuleId, StaticId, StructId, + TraitId, TypeAliasId, TypeParamId, UnionId, VariantId, }; -use hir_expand::{name::AsName, AstId, HirFileId, MacroCallId, MacroDefId, MacroDefKind}; +use hir_expand::{name::AsName, HirFileId, MacroCallId}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use stdx::impl_from; use syntax::{ ast::{self, HasName}, - match_ast, AstNode, SyntaxNode, + AstNode, SyntaxNode, }; use crate::{db::HirDatabase, InFile}; @@ -133,13 +134,8 @@ pub(super) fn module_to_def(&mut self, src: InFile) -> Option self.module_to_def(parent_declaration), @@ -151,7 +147,7 @@ pub(super) fn module_to_def(&mut self, src: InFile) -> Option) -> Option { let map = self.dyn_map(src.as_ref())?; - map[keys::ATTR_MACRO].get(&src).copied() + map[keys::ATTR_MACRO_CALL].get(&src.value).copied() } pub(super) fn attr_to_derive_macro_call( &mut self, - item: InFile<&ast::Item>, + item: InFile<&ast::Adt>, src: InFile, - ) -> Option<&[MacroCallId]> { + ) -> Option<(AttrId, MacroCallId, &[Option])> { let map = self.dyn_map(item)?; - map[keys::DERIVE_MACRO].get(&src).map(AsRef::as_ref) + map[keys::DERIVE_MACRO_CALL] + .get(&src.value) + .map(|&(attr_id, call_id, ref ids)| (attr_id, call_id, &**ids)) + } + pub(super) fn has_derives(&mut self, adt: InFile<&ast::Adt>) -> bool { + self.dyn_map(adt).as_ref().map_or(false, |map| !map[keys::DERIVE_MACRO_CALL].is_empty()) } fn to_def( @@ -260,7 +261,7 @@ fn to_def( src: InFile, key: Key, ) -> Option { - self.dyn_map(src.as_ref())?[key].get(&src).copied() + self.dyn_map(src.as_ref())?[key].get(&src.value).copied() } fn dyn_map(&mut self, src: InFile<&Ast>) -> Option<&DynMap> { @@ -278,7 +279,7 @@ fn cache_for(&mut self, container: ChildContainer, file_id: HirFileId) -> &DynMa pub(super) fn type_param_to_def(&mut self, src: InFile) -> Option { let container: ChildContainer = self.find_generic_param_container(src.syntax())?.into(); let dyn_map = self.cache_for(container, src.file_id); - dyn_map[keys::TYPE_PARAM].get(&src).copied() + dyn_map[keys::TYPE_PARAM].get(&src.value).copied().map(|x| TypeParamId::from_unchecked(x)) } pub(super) fn lifetime_param_to_def( @@ -287,7 +288,7 @@ pub(super) fn lifetime_param_to_def( ) -> Option { let container: ChildContainer = self.find_generic_param_container(src.syntax())?.into(); let dyn_map = self.cache_for(container, src.file_id); - dyn_map[keys::LIFETIME_PARAM].get(&src).copied() + dyn_map[keys::LIFETIME_PARAM].get(&src.value).copied() } pub(super) fn const_param_to_def( @@ -296,22 +297,42 @@ pub(super) fn const_param_to_def( ) -> Option { let container: ChildContainer = self.find_generic_param_container(src.syntax())?.into(); let dyn_map = self.cache_for(container, src.file_id); - dyn_map[keys::CONST_PARAM].get(&src).copied() + dyn_map[keys::CONST_PARAM].get(&src.value).copied().map(|x| ConstParamId::from_unchecked(x)) } - // FIXME: use DynMap as well? - pub(super) fn macro_to_def(&mut self, src: InFile) -> Option { - let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); - let ast_id = AstId::new(src.file_id, file_ast_id.upcast()); - let kind = MacroDefKind::Declarative(ast_id); - let file_id = src.file_id.original_file(self.db.upcast()); - let krate = self.file_to_def(file_id).get(0).copied()?.krate(); - Some(MacroDefId { krate, kind, local_inner: false }) + pub(super) fn generic_param_to_def( + &mut self, + InFile { file_id, value }: InFile, + ) -> Option { + match value { + ast::GenericParam::ConstParam(it) => { + self.const_param_to_def(InFile::new(file_id, it)).map(GenericParamId::ConstParamId) + } + ast::GenericParam::LifetimeParam(it) => self + .lifetime_param_to_def(InFile::new(file_id, it)) + .map(GenericParamId::LifetimeParamId), + ast::GenericParam::TypeParam(it) => { + self.type_param_to_def(InFile::new(file_id, it)).map(GenericParamId::TypeParamId) + } + } + } + + pub(super) fn macro_to_def(&mut self, src: InFile) -> Option { + self.dyn_map(src.as_ref()).and_then(|it| match &src.value { + ast::Macro::MacroRules(value) => { + it[keys::MACRO_RULES].get(value).copied().map(MacroId::from) + } + ast::Macro::MacroDef(value) => it[keys::MACRO2].get(value).copied().map(MacroId::from), + }) + } + + pub(super) fn proc_macro_to_def(&mut self, src: InFile) -> Option { + self.dyn_map(src.as_ref()) + .and_then(|it| it[keys::PROC_MACRO].get(&src.value).copied().map(MacroId::from)) } pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option { - for container in src.cloned().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) - { + for container in src.ancestors_with_macros_skip_attr_item(self.db.upcast()) { if let Some(res) = self.container_to_def(container) { return Some(res); } @@ -322,71 +343,62 @@ pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option) -> Option { - let cont = match_ast! { - match (container.value) { - ast::Module(it) => { - let def = self.module_to_def(container.with_value(it))?; - def.into() - }, - ast::Trait(it) => { - let def = self.trait_to_def(container.with_value(it))?; - def.into() - }, - ast::Impl(it) => { - let def = self.impl_to_def(container.with_value(it))?; - def.into() - }, - ast::Fn(it) => { - let def = self.fn_to_def(container.with_value(it))?; - DefWithBodyId::from(def).into() - }, - ast::Struct(it) => { + let cont = if let Some(item) = ast::Item::cast(container.value.clone()) { + match item { + ast::Item::Module(it) => self.module_to_def(container.with_value(it))?.into(), + ast::Item::Trait(it) => self.trait_to_def(container.with_value(it))?.into(), + ast::Item::Impl(it) => self.impl_to_def(container.with_value(it))?.into(), + ast::Item::Enum(it) => self.enum_to_def(container.with_value(it))?.into(), + ast::Item::TypeAlias(it) => { + self.type_alias_to_def(container.with_value(it))?.into() + } + ast::Item::Struct(it) => { let def = self.struct_to_def(container.with_value(it))?; VariantId::from(def).into() - }, - ast::Enum(it) => { - let def = self.enum_to_def(container.with_value(it))?; - def.into() - }, - ast::Union(it) => { + } + ast::Item::Union(it) => { let def = self.union_to_def(container.with_value(it))?; VariantId::from(def).into() - }, - ast::Static(it) => { + } + ast::Item::Fn(it) => { + let def = self.fn_to_def(container.with_value(it))?; + DefWithBodyId::from(def).into() + } + ast::Item::Static(it) => { let def = self.static_to_def(container.with_value(it))?; DefWithBodyId::from(def).into() - }, - ast::Const(it) => { + } + ast::Item::Const(it) => { let def = self.const_to_def(container.with_value(it))?; DefWithBodyId::from(def).into() - }, - ast::TypeAlias(it) => { - let def = self.type_alias_to_def(container.with_value(it))?; - def.into() - }, - ast::Variant(it) => { - let def = self.enum_variant_to_def(container.with_value(it))?; - VariantId::from(def).into() - }, + } _ => return None, } + } else { + let it = ast::Variant::cast(container.value)?; + let def = self.enum_variant_to_def(InFile::new(container.file_id, it))?; + VariantId::from(def).into() }; Some(cont) } fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option { - for container in src.cloned().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) - { - let res: GenericDefId = match_ast! { - match (container.value) { - ast::Fn(it) => self.fn_to_def(container.with_value(it))?.into(), - ast::Struct(it) => self.struct_to_def(container.with_value(it))?.into(), - ast::Enum(it) => self.enum_to_def(container.with_value(it))?.into(), - ast::Trait(it) => self.trait_to_def(container.with_value(it))?.into(), - ast::TypeAlias(it) => self.type_alias_to_def(container.with_value(it))?.into(), - ast::Impl(it) => self.impl_to_def(container.with_value(it))?.into(), - _ => continue, + let ancestors = src.ancestors_with_macros_skip_attr_item(self.db.upcast()); + for InFile { file_id, value } in ancestors { + let item = match ast::Item::cast(value) { + Some(it) => it, + None => continue, + }; + let res: GenericDefId = match item { + ast::Item::Fn(it) => self.fn_to_def(InFile::new(file_id, it))?.into(), + ast::Item::Struct(it) => self.struct_to_def(InFile::new(file_id, it))?.into(), + ast::Item::Enum(it) => self.enum_to_def(InFile::new(file_id, it))?.into(), + ast::Item::Trait(it) => self.trait_to_def(InFile::new(file_id, it))?.into(), + ast::Item::TypeAlias(it) => { + self.type_alias_to_def(InFile::new(file_id, it))?.into() } + ast::Item::Impl(it) => self.impl_to_def(InFile::new(file_id, it))?.into(), + _ => continue, }; return Some(res); } @@ -394,15 +406,17 @@ fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option) -> Option { - for container in src.cloned().ancestors_with_macros_skip_attr_item(self.db.upcast()).skip(1) - { - let res: DefWithBodyId = match_ast! { - match (container.value) { - ast::Const(it) => self.const_to_def(container.with_value(it))?.into(), - ast::Static(it) => self.static_to_def(container.with_value(it))?.into(), - ast::Fn(it) => self.fn_to_def(container.with_value(it))?.into(), - _ => continue, - } + let ancestors = src.ancestors_with_macros_skip_attr_item(self.db.upcast()); + for InFile { file_id, value } in ancestors { + let item = match ast::Item::cast(value) { + Some(it) => it, + None => continue, + }; + let res: DefWithBodyId = match item { + ast::Item::Const(it) => self.const_to_def(InFile::new(file_id, it))?.into(), + ast::Item::Static(it) => self.static_to_def(InFile::new(file_id, it))?.into(), + ast::Item::Fn(it) => self.fn_to_def(InFile::new(file_id, it))?.into(), + _ => continue, }; return Some(res); }