Unnamed repository; edit this file 'description' to name the repository.
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 666499ed7a..b607cdfee3 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};