about summary refs log tree commit diff
path: root/crates/ide-db/src/traits.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide-db/src/traits.rs')
-rw-r--r--crates/ide-db/src/traits.rs44
1 files changed, 31 insertions, 13 deletions
diff --git a/crates/ide-db/src/traits.rs b/crates/ide-db/src/traits.rs
index 666499ed7a5..b607cdfee38 100644
--- a/crates/ide-db/src/traits.rs
+++ b/crates/ide-db/src/traits.rs
@@ -71,26 +71,44 @@ pub fn get_missing_assoc_items(
 
 /// Converts associated trait impl items to their trait definition counterpart
 pub(crate) fn convert_to_def_in_trait(db: &dyn HirDatabase, def: Definition) -> Definition {
-    use hir::AssocItem::*;
     (|| {
         let assoc = def.as_assoc_item(db)?;
         let trait_ = assoc.containing_trait_impl(db)?;
-        let name = match assoc {
-            Function(it) => it.name(db),
-            Const(it) => it.name(db)?,
-            TypeAlias(it) => it.name(db),
-        };
-        let item = trait_.items(db).into_iter().find(|it| match (it, assoc) {
-            (Function(trait_func), Function(_)) => trait_func.name(db) == name,
-            (Const(trait_konst), Const(_)) => trait_konst.name(db).map_or(false, |it| it == name),
-            (TypeAlias(trait_type_alias), TypeAlias(_)) => trait_type_alias.name(db) == name,
-            _ => false,
-        })?;
-        Some(Definition::from(item))
+        assoc_item_of_trait(db, assoc, trait_)
     })()
     .unwrap_or(def)
 }
 
+/// If this is an trait (impl) assoc item, returns the assoc item of the corresponding trait definition.
+pub(crate) fn as_trait_assoc_def(db: &dyn HirDatabase, def: Definition) -> Option<Definition> {
+    let assoc = def.as_assoc_item(db)?;
+    let trait_ = match assoc.container(db) {
+        hir::AssocItemContainer::Trait(_) => return Some(def),
+        hir::AssocItemContainer::Impl(i) => i.trait_(db),
+    }?;
+    assoc_item_of_trait(db, assoc, trait_)
+}
+
+fn assoc_item_of_trait(
+    db: &dyn HirDatabase,
+    assoc: hir::AssocItem,
+    trait_: hir::Trait,
+) -> Option<Definition> {
+    use hir::AssocItem::*;
+    let name = match assoc {
+        Function(it) => it.name(db),
+        Const(it) => it.name(db)?,
+        TypeAlias(it) => it.name(db),
+    };
+    let item = trait_.items(db).into_iter().find(|it| match (it, assoc) {
+        (Function(trait_func), Function(_)) => trait_func.name(db) == name,
+        (Const(trait_konst), Const(_)) => trait_konst.name(db).map_or(false, |it| it == name),
+        (TypeAlias(trait_type_alias), TypeAlias(_)) => trait_type_alias.name(db) == name,
+        _ => false,
+    })?;
+    Some(Definition::from(item))
+}
+
 #[cfg(test)]
 mod tests {
     use base_db::{fixture::ChangeFixture, FilePosition};