Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/attr.rs')
-rw-r--r--crates/hir-def/src/attr.rs89
1 files changed, 67 insertions, 22 deletions
diff --git a/crates/hir-def/src/attr.rs b/crates/hir-def/src/attr.rs
index fa3025e030..35c9d63979 100644
--- a/crates/hir-def/src/attr.rs
+++ b/crates/hir-def/src/attr.rs
@@ -7,7 +7,10 @@ mod tests;
use std::{hash::Hash, ops, slice::Iter as SliceIter};
-use base_db::CrateId;
+use base_db::{
+ span::{ErasedFileAstId, SpanAnchor},
+ CrateId,
+};
use cfg::{CfgExpr, CfgOptions};
use either::Either;
use hir_expand::{
@@ -28,8 +31,8 @@ use crate::{
lang_item::LangItem,
nameres::{ModuleOrigin, ModuleSource},
src::{HasChildSource, HasSource},
- AdtId, AssocItemLoc, AttrDefId, EnumId, GenericParamId, ItemLoc, LocalEnumVariantId,
- LocalFieldId, Lookup, MacroId, VariantId,
+ AdtId, AssocItemLoc, AttrDefId, EnumId, GenericDefId, GenericParamId, ItemLoc,
+ LocalEnumVariantId, LocalFieldId, Lookup, MacroId, VariantId,
};
#[derive(Default, Debug, Clone, PartialEq, Eq)]
@@ -415,26 +418,48 @@ impl AttrsWithOwner {
AttrDefId::StaticId(it) => attrs_from_item_tree_assoc(db, it),
AttrDefId::FunctionId(it) => attrs_from_item_tree_assoc(db, it),
AttrDefId::TypeAliasId(it) => attrs_from_item_tree_assoc(db, it),
- AttrDefId::GenericParamId(it) => match it {
- GenericParamId::ConstParamId(it) => {
- let src = it.parent().child_source(db);
- RawAttrs::from_attrs_owner(
- db.upcast(),
- src.with_value(&src.value[it.local_id()]),
- )
- }
- GenericParamId::TypeParamId(it) => {
- let src = it.parent().child_source(db);
- RawAttrs::from_attrs_owner(
- db.upcast(),
- src.with_value(&src.value[it.local_id()]),
- )
- }
- GenericParamId::LifetimeParamId(it) => {
- let src = it.parent.child_source(db);
- RawAttrs::from_attrs_owner(db.upcast(), src.with_value(&src.value[it.local_id]))
+ AttrDefId::GenericParamId(it) => {
+ let ast_id = |p| match p {
+ GenericDefId::AdtId(AdtId::StructId(it)) => {
+ erased_ast_id_from_item_tree(db, it)
+ }
+ GenericDefId::AdtId(AdtId::EnumId(it)) => erased_ast_id_from_item_tree(db, it),
+ GenericDefId::AdtId(AdtId::UnionId(it)) => erased_ast_id_from_item_tree(db, it),
+ GenericDefId::TraitId(it) => erased_ast_id_from_item_tree(db, it),
+ GenericDefId::TraitAliasId(it) => erased_ast_id_from_item_tree(db, it),
+ GenericDefId::ImplId(it) => erased_ast_id_from_item_tree(db, it),
+ GenericDefId::EnumVariantId(it) => erased_ast_id_from_item_tree(db, it.parent),
+ GenericDefId::TypeAliasId(it) => erased_ast_id_from_item_tree_assoc(db, it),
+ GenericDefId::FunctionId(it) => erased_ast_id_from_item_tree_assoc(db, it),
+ GenericDefId::ConstId(it) => erased_ast_id_from_item_tree_assoc(db, it),
+ };
+ match it {
+ GenericParamId::ConstParamId(it) => {
+ let src = it.parent().child_source(db);
+ RawAttrs::from_attrs_owner(
+ db.upcast(),
+ SpanAnchor { file_id: src.file_id, ast_id: ast_id(it.parent()) },
+ src.with_value(&src.value[it.local_id()]),
+ )
+ }
+ GenericParamId::TypeParamId(it) => {
+ let src = it.parent().child_source(db);
+ RawAttrs::from_attrs_owner(
+ db.upcast(),
+ SpanAnchor { file_id: src.file_id, ast_id: ast_id(it.parent()) },
+ src.with_value(&src.value[it.local_id()]),
+ )
+ }
+ GenericParamId::LifetimeParamId(it) => {
+ let src = it.parent.child_source(db);
+ RawAttrs::from_attrs_owner(
+ db.upcast(),
+ SpanAnchor { file_id: src.file_id, ast_id: ast_id(it.parent) },
+ src.with_value(&src.value[it.local_id]),
+ )
+ }
}
- },
+ }
AttrDefId::ExternBlockId(it) => attrs_from_item_tree_loc(db, it),
AttrDefId::ExternCrateId(it) => attrs_from_item_tree_loc(db, it),
AttrDefId::UseId(it) => attrs_from_item_tree_loc(db, it),
@@ -638,6 +663,26 @@ fn any_has_attrs(
id.lookup(db).source(db).map(ast::AnyHasAttrs::new)
}
+fn erased_ast_id_from_item_tree<N: ItemTreeNode>(
+ db: &dyn DefDatabase,
+ lookup: impl Lookup<Data = ItemLoc<N>>,
+) -> ErasedFileAstId {
+ let id = lookup.lookup(db).id;
+ let tree = id.item_tree(db);
+ let mod_item = N::id_to_mod_item(id.value);
+ mod_item.ast_id(&tree).erase()
+}
+
+fn erased_ast_id_from_item_tree_assoc<N: ItemTreeNode>(
+ db: &dyn DefDatabase,
+ lookup: impl Lookup<Data = AssocItemLoc<N>>,
+) -> ErasedFileAstId {
+ let id = lookup.lookup(db).id;
+ let tree = id.item_tree(db);
+ let mod_item = N::id_to_mod_item(id.value);
+ mod_item.ast_id(&tree).erase()
+}
+
fn attrs_from_item_tree<N: ItemTreeNode>(db: &dyn DefDatabase, id: ItemTreeId<N>) -> RawAttrs {
let tree = id.item_tree(db);
let mod_item = N::id_to_mod_item(id.value);