Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/lib.rs')
-rw-r--r--crates/hir-def/src/lib.rs59
1 files changed, 58 insertions, 1 deletions
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index c8efd90432..95700b54db 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -55,6 +55,7 @@ pub mod visibility;
use intern::Interned;
pub use rustc_abi as layout;
+use src::HasSource;
use triomphe::Arc;
#[cfg(test)]
@@ -77,6 +78,7 @@ use hir_expand::{
builtin::{BuiltinAttrExpander, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerExpander},
db::ExpandDatabase,
eager::expand_eager_macro_input,
+ files::InFileWrapper,
impl_intern_lookup,
name::Name,
proc_macro::{CustomProcMacroExpander, ProcMacroKind},
@@ -519,6 +521,41 @@ pub struct FieldId {
pub local_id: LocalFieldId,
}
+impl FieldId {
+ pub fn record_field_source(
+ &self,
+ db: &dyn DefDatabase,
+ ) -> InFileWrapper<HirFileId, Option<ast::RecordField>> {
+ let field_list = match self.parent {
+ crate::VariantId::EnumVariantId(it) => {
+ let s = it.lookup(db);
+ s.source(db).map(|it| {
+ it.field_list().and_then(|it| match it {
+ ast::FieldList::RecordFieldList(it) => Some(it),
+ _ => None,
+ })
+ })
+ }
+ crate::VariantId::StructId(it) => {
+ let s = it.lookup(db);
+ s.source(db).map(|it| {
+ it.field_list().and_then(|it| match it {
+ ast::FieldList::RecordFieldList(it) => Some(it),
+ _ => None,
+ })
+ })
+ }
+ crate::VariantId::UnionId(it) => {
+ let s = it.lookup(db);
+ s.source(db).map(|it| it.record_field_list())
+ }
+ };
+ field_list.map(|it| {
+ it.and_then(|it| it.fields().nth(self.local_id.into_raw().into_u32() as usize))
+ })
+ }
+}
+
pub type LocalFieldId = Idx<data::adt::FieldData>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -686,6 +723,7 @@ pub enum TypeOwnerId {
TypeAliasId(TypeAliasId),
ImplId(ImplId),
EnumVariantId(EnumVariantId),
+ FieldId(FieldId),
}
impl TypeOwnerId {
@@ -703,6 +741,11 @@ impl TypeOwnerId {
GenericDefId::AdtId(AdtId::EnumId(it.lookup(db).parent))
}
TypeOwnerId::InTypeConstId(_) => return None,
+ TypeOwnerId::FieldId(it) => GenericDefId::AdtId(match it.parent {
+ VariantId::EnumVariantId(it) => AdtId::EnumId(it.lookup(db).parent),
+ VariantId::StructId(it) => it.into(),
+ VariantId::UnionId(it) => it.into(),
+ }),
})
}
}
@@ -717,7 +760,8 @@ impl_from!(
TraitAliasId,
TypeAliasId,
ImplId,
- EnumVariantId
+ EnumVariantId,
+ FieldId
for TypeOwnerId
);
@@ -730,6 +774,7 @@ impl From<DefWithBodyId> for TypeOwnerId {
DefWithBodyId::ConstId(it) => it.into(),
DefWithBodyId::InTypeConstId(it) => it.into(),
DefWithBodyId::VariantId(it) => it.into(),
+ DefWithBodyId::FieldId(it) => it.into(),
}
}
}
@@ -885,6 +930,7 @@ pub enum DefWithBodyId {
ConstId(ConstId),
InTypeConstId(InTypeConstId),
VariantId(EnumVariantId),
+ FieldId(FieldId),
}
impl_from!(FunctionId, ConstId, StaticId, InTypeConstId for DefWithBodyId);
@@ -905,6 +951,7 @@ impl DefWithBodyId {
// FIXME: stable rust doesn't allow generics in constants, but we should
// use `TypeOwnerId::as_generic_def_id` when it does.
DefWithBodyId::InTypeConstId(_) => None,
+ DefWithBodyId::FieldId(_) => None,
}
}
}
@@ -1332,6 +1379,11 @@ impl HasModule for TypeOwnerId {
TypeOwnerId::ImplId(it) => it.module(db),
TypeOwnerId::EnumVariantId(it) => it.module(db),
TypeOwnerId::InTypeConstId(it) => it.lookup(db).owner.module(db),
+ TypeOwnerId::FieldId(it) => match it.parent {
+ VariantId::EnumVariantId(it) => it.module(db),
+ VariantId::StructId(it) => it.module(db),
+ VariantId::UnionId(it) => it.module(db),
+ },
}
}
}
@@ -1344,6 +1396,11 @@ impl HasModule for DefWithBodyId {
DefWithBodyId::ConstId(it) => it.module(db),
DefWithBodyId::VariantId(it) => it.module(db),
DefWithBodyId::InTypeConstId(it) => it.lookup(db).owner.module(db),
+ DefWithBodyId::FieldId(it) => match it.parent {
+ VariantId::EnumVariantId(it) => it.module(db),
+ VariantId::StructId(it) => it.module(db),
+ VariantId::UnionId(it) => it.module(db),
+ },
}
}
}