diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index e665ab45d03..498a4c91724 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -1,7 +1,7 @@
 //! Defines database & queries for name resolution.
 use std::sync::Arc;
 
-use hir_expand::{db::AstDatabase, HirFileId};
+use hir_expand::{db::AstDatabase, name::Name, HirFileId};
 use ra_db::{salsa, CrateId, SourceDatabase, Upcast};
 use ra_prof::profile;
 use ra_syntax::SmolStr;
@@ -12,9 +12,12 @@ use crate::{
     body::{scope::ExprScopes, Body, BodySourceMap},
     data::{ConstData, FunctionData, ImplData, StaticData, TraitData, TypeAliasData},
     docs::Documentation,
+    find_path,
     generics::GenericParams,
+    item_scope::ItemInNs,
     lang_item::{LangItemTarget, LangItems},
     nameres::{raw::RawItems, CrateDefMap},
+    visibility::Visibility,
     AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
     GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId,
     TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
@@ -108,6 +111,13 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
     // Remove this query completely, in favor of `Attrs::docs` method
     #[salsa::invoke(Documentation::documentation_query)]
     fn documentation(&self, def: AttrDefId) -> Option<Documentation>;
+
+    #[salsa::invoke(find_path::importable_locations_in_crate)]
+    fn importable_locations_of(
+        &self,
+        item: ItemInNs,
+        krate: CrateId,
+    ) -> Arc<[(ModuleId, Name, Visibility)]>;
 }
 
 fn crate_def_map_wait(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> {
diff --git a/crates/ra_hir_def/src/find_path.rs b/crates/ra_hir_def/src/find_path.rs
index 70dcb03e6e3..1ca20fabd04 100644
--- a/crates/ra_hir_def/src/find_path.rs
+++ b/crates/ra_hir_def/src/find_path.rs
@@ -8,6 +8,7 @@ use crate::{
     CrateId, ModuleDefId, ModuleId,
 };
 use hir_expand::name::{known, AsName, Name};
+use std::sync::Arc;
 use test_utils::tested_by;
 
 const MAX_PATH_LEN: usize = 15;
@@ -45,6 +46,7 @@ impl ModPath {
 /// Find a path that can be used to refer to a certain item. This can depend on
 /// *from where* you're referring to the item, hence the `from` parameter.
 pub fn find_path(db: &dyn DefDatabase, item: ItemInNs, from: ModuleId) -> Option<ModPath> {
+    let _p = ra_prof::profile("find_path");
     find_path_inner(db, item, from, MAX_PATH_LEN)
 }
 
@@ -198,7 +200,7 @@ fn find_importable_locations(
         .chain(crate_graph[from.krate].dependencies.iter().map(|dep| dep.crate_id))
     {
         result.extend(
-            importable_locations_in_crate(db, item, krate)
+            db.importable_locations_of(item, krate)
                 .iter()
                 .filter(|(_, _, vis)| vis.is_visible_from(db, from))
                 .map(|(m, n, _)| (*m, n.clone())),
@@ -213,11 +215,11 @@ fn find_importable_locations(
 ///
 /// Note that the crate doesn't need to be the one in which the item is defined;
 /// it might be re-exported in other crates.
-fn importable_locations_in_crate(
+pub(crate) fn importable_locations_in_crate(
     db: &dyn DefDatabase,
     item: ItemInNs,
     krate: CrateId,
-) -> Vec<(ModuleId, Name, Visibility)> {
+) -> Arc<[(ModuleId, Name, Visibility)]> {
     let def_map = db.crate_def_map(krate);
     let mut result = Vec::new();
     for (local_id, data) in def_map.modules.iter() {
@@ -243,7 +245,8 @@ fn importable_locations_in_crate(
             result.push((ModuleId { krate, local_id }, name.clone(), vis));
         }
     }
-    result
+
+    Arc::from(result)
 }
 
 #[cfg(test)]