about summary refs log tree commit diff
path: root/crates
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-07-18 18:23:50 +0200
committerLukas Wirth <lukastw97@gmail.com>2022-07-18 18:28:02 +0200
commit38c11bea217847d81da397881f754ae8a8e2725a (patch)
treedf5bfc42613ced8a6ccc3dd3ea366dfe928e6686 /crates
parentdcb4837b2d07aeac2126dc6312a7a48992d11b85 (diff)
downloadrust-38c11bea217847d81da397881f754ae8a8e2725a.tar.gz
rust-38c11bea217847d81da397881f754ae8a8e2725a.zip
Move `convert_to_def_in_trait` into `ide-db`
Diffstat (limited to 'crates')
-rw-r--r--crates/ide-db/src/imports/import_assets.rs2
-rw-r--r--crates/ide-db/src/rename.rs46
-rw-r--r--crates/ide-db/src/search.rs3
-rw-r--r--crates/ide-db/src/traits.rs26
4 files changed, 30 insertions, 47 deletions
diff --git a/crates/ide-db/src/imports/import_assets.rs b/crates/ide-db/src/imports/import_assets.rs
index 08b0f9535d7..81467ab07a2 100644
--- a/crates/ide-db/src/imports/import_assets.rs
+++ b/crates/ide-db/src/imports/import_assets.rs
@@ -401,7 +401,7 @@ fn import_for_item(
     })
 }
 
-fn item_for_path_search(db: &RootDatabase, item: ItemInNs) -> Option<ItemInNs> {
+pub fn item_for_path_search(db: &RootDatabase, item: ItemInNs) -> Option<ItemInNs> {
     Some(match item {
         ItemInNs::Types(_) | ItemInNs::Values(_) => match item_as_assoc(db, item) {
             Some(assoc_item) => match assoc_item.container(db) {
diff --git a/crates/ide-db/src/rename.rs b/crates/ide-db/src/rename.rs
index bade88c5783..f114d934e4f 100644
--- a/crates/ide-db/src/rename.rs
+++ b/crates/ide-db/src/rename.rs
@@ -24,7 +24,7 @@ use std::fmt;
 
 use base_db::{AnchoredPathBuf, FileId, FileRange};
 use either::Either;
-use hir::{AsAssocItem, FieldSource, HasSource, InFile, ModuleSource, Semantics};
+use hir::{FieldSource, HasSource, InFile, ModuleSource, Semantics};
 use stdx::never;
 use syntax::{
     ast::{self, HasName},
@@ -37,6 +37,7 @@ use crate::{
     search::FileReference,
     source_change::{FileSystemEdit, SourceChange},
     syntax_helpers::node_ext::expr_as_name_ref,
+    traits::convert_to_def_in_trait,
     RootDatabase,
 };
 
@@ -271,7 +272,7 @@ fn rename_reference(
         }
     }
 
-    let def = convert_to_def_in_trait(def, sema);
+    let def = convert_to_def_in_trait(sema.db, def);
     let usages = def.usages(sema).all();
 
     if !usages.is_empty() && ident_kind == IdentifierKind::Underscore {
@@ -298,47 +299,6 @@ fn rename_reference(
     Ok(source_change)
 }
 
-pub(crate) fn convert_to_def_in_trait(
-    def: Definition,
-    sema: &Semantics<RootDatabase>,
-) -> Definition {
-    // HACK: resolve trait impl items to the item def of the trait definition
-    // so that we properly resolve all trait item references
-    let assoc_item = match def {
-        Definition::Function(it) => it.as_assoc_item(sema.db),
-        Definition::TypeAlias(it) => it.as_assoc_item(sema.db),
-        Definition::Const(it) => it.as_assoc_item(sema.db),
-        _ => None,
-    };
-    match assoc_item {
-        Some(assoc) => assoc
-            .containing_trait_impl(sema.db)
-            .and_then(|trait_| {
-                trait_.items(sema.db).into_iter().find_map(|it| match (it, assoc) {
-                    (hir::AssocItem::Function(trait_func), hir::AssocItem::Function(func))
-                        if trait_func.name(sema.db) == func.name(sema.db) =>
-                    {
-                        Some(Definition::Function(trait_func))
-                    }
-                    (hir::AssocItem::Const(trait_konst), hir::AssocItem::Const(konst))
-                        if trait_konst.name(sema.db) == konst.name(sema.db) =>
-                    {
-                        Some(Definition::Const(trait_konst))
-                    }
-                    (
-                        hir::AssocItem::TypeAlias(trait_type_alias),
-                        hir::AssocItem::TypeAlias(type_alias),
-                    ) if trait_type_alias.name(sema.db) == type_alias.name(sema.db) => {
-                        Some(Definition::TypeAlias(trait_type_alias))
-                    }
-                    _ => None,
-                })
-            })
-            .unwrap_or(def),
-        None => def,
-    }
-}
-
 pub fn source_edit_from_references(
     references: &[FileReference],
     def: Definition,
diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs
index ce38fe145bd..b3b957c0ef2 100644
--- a/crates/ide-db/src/search.rs
+++ b/crates/ide-db/src/search.rs
@@ -16,6 +16,7 @@ use syntax::{ast, match_ast, AstNode, TextRange, TextSize};
 
 use crate::{
     defs::{Definition, NameClass, NameRefClass},
+    traits::convert_to_def_in_trait,
     RootDatabase,
 };
 
@@ -620,7 +621,7 @@ impl<'a> FindUsages<'a> {
                 sink(file_id, reference)
             }
             Some(NameRefClass::Definition(def))
-                if crate::rename::convert_to_def_in_trait(def, self.sema) == self.def =>
+                if convert_to_def_in_trait(self.sema.db, def) == self.def =>
             {
                 let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
                 let reference = FileReference {
diff --git a/crates/ide-db/src/traits.rs b/crates/ide-db/src/traits.rs
index 0fbfd869921..666499ed7a5 100644
--- a/crates/ide-db/src/traits.rs
+++ b/crates/ide-db/src/traits.rs
@@ -1,7 +1,7 @@
 //! Functionality for obtaining data related to traits from the DB.
 
-use crate::RootDatabase;
-use hir::Semantics;
+use crate::{defs::Definition, RootDatabase};
+use hir::{db::HirDatabase, AsAssocItem, Semantics};
 use rustc_hash::FxHashSet;
 use syntax::{ast, AstNode};
 
@@ -69,6 +69,28 @@ 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))
+    })()
+    .unwrap_or(def)
+}
+
 #[cfg(test)]
 mod tests {
     use base_db::{fixture::ChangeFixture, FilePosition};