Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/lib.rs')
| -rw-r--r-- | crates/hir/src/lib.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index beaa6dd4d6..2d8811cf5e 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -2653,6 +2653,37 @@ impl ItemInNs { } } +/// Invariant: `inner.as_extern_assoc_item(db).is_some()` +/// We do not actively enforce this invariant. +#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] +pub enum ExternAssocItem { + Function(Function), + Static(Static), + TypeAlias(TypeAlias), +} + +pub trait AsExternAssocItem { + fn as_extern_assoc_item(self, db: &dyn HirDatabase) -> Option<ExternAssocItem>; +} + +impl AsExternAssocItem for Function { + fn as_extern_assoc_item(self, db: &dyn HirDatabase) -> Option<ExternAssocItem> { + as_extern_assoc_item(db, ExternAssocItem::Function, self.id) + } +} + +impl AsExternAssocItem for Static { + fn as_extern_assoc_item(self, db: &dyn HirDatabase) -> Option<ExternAssocItem> { + as_extern_assoc_item(db, ExternAssocItem::Static, self.id) + } +} + +impl AsExternAssocItem for TypeAlias { + fn as_extern_assoc_item(self, db: &dyn HirDatabase) -> Option<ExternAssocItem> { + as_extern_assoc_item(db, ExternAssocItem::TypeAlias, self.id) + } +} + /// Invariant: `inner.as_assoc_item(db).is_some()` /// We do not actively enforce this invariant. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -2727,6 +2758,63 @@ where } } +fn as_extern_assoc_item<'db, ID, DEF, LOC>( + db: &(dyn HirDatabase + 'db), + ctor: impl FnOnce(DEF) -> ExternAssocItem, + id: ID, +) -> Option<ExternAssocItem> +where + ID: Lookup<Database<'db> = dyn DefDatabase + 'db, Data = AssocItemLoc<LOC>>, + DEF: From<ID>, + LOC: ItemTreeNode, +{ + match id.lookup(db.upcast()).container { + ItemContainerId::ExternBlockId(_) => Some(ctor(DEF::from(id))), + ItemContainerId::TraitId(_) | ItemContainerId::ImplId(_) | ItemContainerId::ModuleId(_) => { + None + } + } +} + +impl ExternAssocItem { + pub fn name(self, db: &dyn HirDatabase) -> Name { + match self { + Self::Function(it) => it.name(db), + Self::Static(it) => it.name(db), + Self::TypeAlias(it) => it.name(db), + } + } + + pub fn module(self, db: &dyn HirDatabase) -> Module { + match self { + Self::Function(f) => f.module(db), + Self::Static(c) => c.module(db), + Self::TypeAlias(t) => t.module(db), + } + } + + pub fn as_function(self) -> Option<Function> { + match self { + Self::Function(v) => Some(v), + _ => None, + } + } + + pub fn as_static(self) -> Option<Static> { + match self { + Self::Static(v) => Some(v), + _ => None, + } + } + + pub fn as_type_alias(self) -> Option<TypeAlias> { + match self { + Self::TypeAlias(v) => Some(v), + _ => None, + } + } +} + impl AssocItem { pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { match self { |