diff options
Diffstat (limited to 'crates/ide-db/src/traits.rs')
| -rw-r--r-- | crates/ide-db/src/traits.rs | 44 |
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}; |
