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.rs92
1 files changed, 90 insertions, 2 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 08f7bb14ca..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 {
@@ -3798,9 +3886,9 @@ impl Type {
// For non-phantom_data adts we check variants/fields as well as generic parameters
TyKind::Adt(adt_id, substitution)
- if !db.struct_datum(krate, *adt_id).flags.phantom_data =>
+ if !db.adt_datum(krate, *adt_id).flags.phantom_data =>
{
- let adt_datum = &db.struct_datum(krate, *adt_id);
+ let adt_datum = &db.adt_datum(krate, *adt_id);
let adt_datum_bound =
adt_datum.binders.clone().substitute(Interner, substitution);
adt_datum_bound