about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-05-02 11:56:48 +0200
committerLukas Wirth <lukastw97@gmail.com>2023-05-02 12:11:42 +0200
commitf501c6a5167fff7e0343f8d8ac7bc3a1f505e674 (patch)
tree1ce6e8c2832de673268388093674b6f6602b37e1
parent9c0c13ec8e47cfe487f46136b394c0372e957968 (diff)
downloadrust-f501c6a5167fff7e0343f8d8ac7bc3a1f505e674.tar.gz
rust-f501c6a5167fff7e0343f8d8ac7bc3a1f505e674.zip
Refactor symbol index
-rw-r--r--crates/hir/src/lib.rs97
-rw-r--r--crates/hir/src/symbols.rs231
-rw-r--r--crates/ide-db/src/defs.rs23
-rw-r--r--crates/ide-db/src/items_locator.rs31
-rw-r--r--crates/ide-db/src/lib.rs33
-rw-r--r--crates/ide-db/src/symbol_index.rs9
-rw-r--r--crates/ide-db/src/test_data/test_symbol_index_collection.txt468
-rw-r--r--crates/ide/src/call_hierarchy.rs8
-rw-r--r--crates/ide/src/hover/tests.rs88
-rw-r--r--crates/ide/src/lib.rs2
-rw-r--r--crates/ide/src/navigation_target.rs96
-rw-r--r--crates/ide/src/references.rs18
-rw-r--r--crates/ide/src/runnables.rs2
13 files changed, 422 insertions, 684 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 145506a89df..113398c8383 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -51,7 +51,7 @@ use hir_def::{
     per_ns::PerNs,
     resolver::{HasResolver, Resolver},
     src::HasSource as _,
-    AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
+    AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
     EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
     LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
     TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
@@ -118,11 +118,9 @@ pub use {
         path::{ModPath, PathKind},
         type_ref::{Mutability, TypeRef},
         visibility::Visibility,
-        // FIXME: This is here since it is input of a method in `HirWrite`
-        // and things outside of hir need to implement that trait. We probably
-        // should move whole `hir_ty::display` to this crate so we will become
-        // able to use `ModuleDef` or `Definition` instead of `ModuleDefId`.
-        ModuleDefId,
+        // FIXME: This is here since some queries take it as input that are used
+        // outside of hir.
+        {AdtId, ModuleDefId},
     },
     hir_expand::{
         attrs::Attr,
@@ -4408,3 +4406,90 @@ impl HasCrate for Module {
         Module::krate(*self)
     }
 }
+
+pub trait HasContainer {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer;
+}
+
+impl HasContainer for Module {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        // FIXME: handle block expressions as modules (their parent is in a different DefMap)
+        let def_map = self.id.def_map(db.upcast());
+        match def_map[self.id.local_id].parent {
+            Some(parent_id) => ItemContainer::Module(Module { id: def_map.module_id(parent_id) }),
+            None => ItemContainer::Crate(def_map.krate()),
+        }
+    }
+}
+
+impl HasContainer for Function {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        container_id_to_hir(self.id.lookup(db.upcast()).container)
+    }
+}
+
+impl HasContainer for Struct {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
+    }
+}
+
+impl HasContainer for Union {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
+    }
+}
+
+impl HasContainer for Enum {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
+    }
+}
+
+impl HasContainer for TypeAlias {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        container_id_to_hir(self.id.lookup(db.upcast()).container)
+    }
+}
+
+impl HasContainer for Const {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        container_id_to_hir(self.id.lookup(db.upcast()).container)
+    }
+}
+
+impl HasContainer for Static {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        container_id_to_hir(self.id.lookup(db.upcast()).container)
+    }
+}
+
+impl HasContainer for Trait {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
+    }
+}
+
+impl HasContainer for TraitAlias {
+    fn container(&self, db: &dyn HirDatabase) -> ItemContainer {
+        ItemContainer::Module(Module { id: self.id.lookup(db.upcast()).container })
+    }
+}
+
+fn container_id_to_hir(c: ItemContainerId) -> ItemContainer {
+    match c {
+        ItemContainerId::ExternBlockId(_id) => ItemContainer::ExternBlock(),
+        ItemContainerId::ModuleId(id) => ItemContainer::Module(Module { id }),
+        ItemContainerId::ImplId(id) => ItemContainer::Impl(Impl { id }),
+        ItemContainerId::TraitId(id) => ItemContainer::Trait(Trait { id }),
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum ItemContainer {
+    Trait(Trait),
+    Impl(Impl),
+    Module(Module),
+    ExternBlock(),
+    Crate(CrateId),
+}
diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs
index da5aaf22570..386758ccab4 100644
--- a/crates/hir/src/symbols.rs
+++ b/crates/hir/src/symbols.rs
@@ -1,89 +1,20 @@
 //! File symbol extraction.
 
-use base_db::FileRange;
 use hir_def::{
-    item_tree::ItemTreeNode, src::HasSource, AdtId, AssocItemId, AssocItemLoc, DefWithBodyId,
-    HasModule, ImplId, ItemContainerId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId,
+    AdtId, AssocItemId, DefWithBodyId, HasModule, ImplId, MacroId, ModuleDefId, ModuleId, TraitId,
 };
-use hir_expand::{HirFileId, InFile};
 use hir_ty::db::HirDatabase;
-use syntax::{ast::HasName, AstNode, SmolStr, SyntaxNode, SyntaxNodePtr};
+use syntax::SmolStr;
 
-use crate::{Module, Semantics};
+use crate::{Module, ModuleDef};
 
 /// The actual data that is stored in the index. It should be as compact as
 /// possible.
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FileSymbol {
+    // even though name can be derived from the def, we store it for efficiency
     pub name: SmolStr,
-    pub loc: DeclarationLocation,
-    pub kind: FileSymbolKind,
-    pub container_name: Option<SmolStr>,
-}
-
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct DeclarationLocation {
-    /// The file id for both the `ptr` and `name_ptr`.
-    pub hir_file_id: HirFileId,
-    /// This points to the whole syntax node of the declaration.
-    pub ptr: SyntaxNodePtr,
-    /// This points to the [`syntax::ast::Name`] identifier of the declaration.
-    pub name_ptr: SyntaxNodePtr,
-}
-
-impl DeclarationLocation {
-    pub fn syntax<DB: HirDatabase>(&self, sema: &Semantics<'_, DB>) -> SyntaxNode {
-        let root = sema.parse_or_expand(self.hir_file_id);
-        self.ptr.to_node(&root)
-    }
-
-    pub fn original_range(&self, db: &dyn HirDatabase) -> FileRange {
-        let node = resolve_node(db, self.hir_file_id, &self.ptr);
-        node.as_ref().original_file_range(db.upcast())
-    }
-
-    pub fn original_name_range(&self, db: &dyn HirDatabase) -> Option<FileRange> {
-        let node = resolve_node(db, self.hir_file_id, &self.name_ptr);
-        node.as_ref().original_file_range_opt(db.upcast())
-    }
-}
-
-fn resolve_node(
-    db: &dyn HirDatabase,
-    file_id: HirFileId,
-    ptr: &SyntaxNodePtr,
-) -> InFile<SyntaxNode> {
-    let root = db.parse_or_expand(file_id);
-    let node = ptr.to_node(&root);
-    InFile::new(file_id, node)
-}
-
-#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
-pub enum FileSymbolKind {
-    Const,
-    Enum,
-    Function,
-    Macro,
-    Module,
-    Static,
-    Struct,
-    Trait,
-    TraitAlias,
-    TypeAlias,
-    Union,
-}
-
-impl FileSymbolKind {
-    pub fn is_type(self: FileSymbolKind) -> bool {
-        matches!(
-            self,
-            FileSymbolKind::Struct
-                | FileSymbolKind::Enum
-                | FileSymbolKind::Trait
-                | FileSymbolKind::TypeAlias
-                | FileSymbolKind::Union
-        )
-    }
+    pub def: ModuleDef,
 }
 
 /// Represents an outstanding module that the symbol collector must collect symbols from.
@@ -146,36 +77,34 @@ impl<'a> SymbolCollector<'a> {
             match module_def_id {
                 ModuleDefId::ModuleId(id) => self.push_module(id),
                 ModuleDefId::FunctionId(id) => {
-                    self.push_decl_assoc(id, FileSymbolKind::Function);
+                    self.push_decl(id);
                     self.collect_from_body(id);
                 }
-                ModuleDefId::AdtId(AdtId::StructId(id)) => {
-                    self.push_decl(id, FileSymbolKind::Struct)
-                }
-                ModuleDefId::AdtId(AdtId::EnumId(id)) => self.push_decl(id, FileSymbolKind::Enum),
-                ModuleDefId::AdtId(AdtId::UnionId(id)) => self.push_decl(id, FileSymbolKind::Union),
+                ModuleDefId::AdtId(AdtId::StructId(id)) => self.push_decl(id),
+                ModuleDefId::AdtId(AdtId::EnumId(id)) => self.push_decl(id),
+                ModuleDefId::AdtId(AdtId::UnionId(id)) => self.push_decl(id),
                 ModuleDefId::ConstId(id) => {
-                    self.push_decl_assoc(id, FileSymbolKind::Const);
+                    self.push_decl(id);
                     self.collect_from_body(id);
                 }
                 ModuleDefId::StaticId(id) => {
-                    self.push_decl_assoc(id, FileSymbolKind::Static);
+                    self.push_decl(id);
                     self.collect_from_body(id);
                 }
                 ModuleDefId::TraitId(id) => {
-                    self.push_decl(id, FileSymbolKind::Trait);
+                    self.push_decl(id);
                     self.collect_from_trait(id);
                 }
                 ModuleDefId::TraitAliasId(id) => {
-                    self.push_decl(id, FileSymbolKind::TraitAlias);
+                    self.push_decl(id);
                 }
                 ModuleDefId::TypeAliasId(id) => {
-                    self.push_decl_assoc(id, FileSymbolKind::TypeAlias);
+                    self.push_decl(id);
                 }
                 ModuleDefId::MacroId(id) => match id {
-                    MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro),
-                    MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro),
-                    MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro),
+                    MacroId::Macro2Id(id) => self.push_decl(id),
+                    MacroId::MacroRulesId(id) => self.push_decl(id),
+                    MacroId::ProcMacroId(id) => self.push_decl(id),
                 },
                 // Don't index these.
                 ModuleDefId::BuiltinType(_) => {}
@@ -195,9 +124,9 @@ impl<'a> SymbolCollector<'a> {
             for &id in id {
                 if id.module(self.db.upcast()) == module_id {
                     match id {
-                        MacroId::Macro2Id(id) => self.push_decl(id, FileSymbolKind::Macro),
-                        MacroId::MacroRulesId(id) => self.push_decl(id, FileSymbolKind::Macro),
-                        MacroId::ProcMacroId(id) => self.push_decl(id, FileSymbolKind::Macro),
+                        MacroId::Macro2Id(id) => self.push_decl(id),
+                        MacroId::MacroRulesId(id) => self.push_decl(id),
+                        MacroId::ProcMacroId(id) => self.push_decl(id),
                     }
                 }
             }
@@ -245,124 +174,36 @@ impl<'a> SymbolCollector<'a> {
         }
     }
 
-    fn current_container_name(&self) -> Option<SmolStr> {
-        self.current_container_name.clone()
-    }
-
     fn def_with_body_id_name(&self, body_id: DefWithBodyId) -> Option<SmolStr> {
         match body_id {
-            DefWithBodyId::FunctionId(id) => Some(
-                id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(),
-            ),
-            DefWithBodyId::StaticId(id) => Some(
-                id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(),
-            ),
-            DefWithBodyId::ConstId(id) => Some(
-                id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(),
-            ),
-            DefWithBodyId::VariantId(id) => Some({
-                let db = self.db.upcast();
-                id.parent.lookup(db).source(db).value.name()?.text().into()
-            }),
+            DefWithBodyId::FunctionId(id) => Some(self.db.function_data(id).name.to_smol_str()),
+            DefWithBodyId::StaticId(id) => Some(self.db.static_data(id).name.to_smol_str()),
+            DefWithBodyId::ConstId(id) => Some(self.db.const_data(id).name.as_ref()?.to_smol_str()),
+            DefWithBodyId::VariantId(id) => {
+                Some(self.db.enum_data(id.parent).variants[id.local_id].name.to_smol_str())
+            }
         }
     }
 
     fn push_assoc_item(&mut self, assoc_item_id: AssocItemId) {
         match assoc_item_id {
-            AssocItemId::FunctionId(id) => self.push_decl_assoc(id, FileSymbolKind::Function),
-            AssocItemId::ConstId(id) => self.push_decl_assoc(id, FileSymbolKind::Const),
-            AssocItemId::TypeAliasId(id) => self.push_decl_assoc(id, FileSymbolKind::TypeAlias),
+            AssocItemId::FunctionId(id) => self.push_decl(id),
+            AssocItemId::ConstId(id) => self.push_decl(id),
+            AssocItemId::TypeAliasId(id) => self.push_decl(id),
         }
     }
 
-    fn push_decl_assoc<L, T>(&mut self, id: L, kind: FileSymbolKind)
-    where
-        L: Lookup<Data = AssocItemLoc<T>>,
-        T: ItemTreeNode,
-        <T as ItemTreeNode>::Source: HasName,
-    {
-        fn container_name(db: &dyn HirDatabase, container: ItemContainerId) -> Option<SmolStr> {
-            match container {
-                ItemContainerId::ModuleId(module_id) => {
-                    let module = Module::from(module_id);
-                    module.name(db).and_then(|name| name.as_text())
-                }
-                ItemContainerId::TraitId(trait_id) => {
-                    let trait_data = db.trait_data(trait_id);
-                    trait_data.name.as_text()
-                }
-                ItemContainerId::ImplId(_) | ItemContainerId::ExternBlockId(_) => None,
-            }
+    fn push_decl(&mut self, id: impl Into<ModuleDefId>) {
+        let def = ModuleDef::from(id.into());
+        if let Some(name) = def.name(self.db) {
+            self.symbols.push(FileSymbol { name: name.to_smol_str(), def });
         }
-
-        self.push_file_symbol(|s| {
-            let loc = id.lookup(s.db.upcast());
-            let source = loc.source(s.db.upcast());
-            let name_node = source.value.name()?;
-            let container_name =
-                container_name(s.db, loc.container).or_else(|| s.current_container_name());
-
-            Some(FileSymbol {
-                name: name_node.text().into(),
-                kind,
-                container_name,
-                loc: DeclarationLocation {
-                    hir_file_id: source.file_id,
-                    ptr: SyntaxNodePtr::new(source.value.syntax()),
-                    name_ptr: SyntaxNodePtr::new(name_node.syntax()),
-                },
-            })
-        })
-    }
-
-    fn push_decl<L>(&mut self, id: L, kind: FileSymbolKind)
-    where
-        L: Lookup,
-        <L as Lookup>::Data: HasSource,
-        <<L as Lookup>::Data as HasSource>::Value: HasName,
-    {
-        self.push_file_symbol(|s| {
-            let loc = id.lookup(s.db.upcast());
-            let source = loc.source(s.db.upcast());
-            let name_node = source.value.name()?;
-
-            Some(FileSymbol {
-                name: name_node.text().into(),
-                kind,
-                container_name: s.current_container_name(),
-                loc: DeclarationLocation {
-                    hir_file_id: source.file_id,
-                    ptr: SyntaxNodePtr::new(source.value.syntax()),
-                    name_ptr: SyntaxNodePtr::new(name_node.syntax()),
-                },
-            })
-        })
     }
 
     fn push_module(&mut self, module_id: ModuleId) {
-        self.push_file_symbol(|s| {
-            let def_map = module_id.def_map(s.db.upcast());
-            let module_data = &def_map[module_id.local_id];
-            let declaration = module_data.origin.declaration()?;
-            let module = declaration.to_node(s.db.upcast());
-            let name_node = module.name()?;
-
-            Some(FileSymbol {
-                name: name_node.text().into(),
-                kind: FileSymbolKind::Module,
-                container_name: s.current_container_name(),
-                loc: DeclarationLocation {
-                    hir_file_id: declaration.file_id,
-                    ptr: SyntaxNodePtr::new(module.syntax()),
-                    name_ptr: SyntaxNodePtr::new(name_node.syntax()),
-                },
-            })
-        })
-    }
-
-    fn push_file_symbol(&mut self, f: impl FnOnce(&Self) -> Option<FileSymbol>) {
-        if let Some(file_symbol) = f(self) {
-            self.symbols.push(file_symbol);
+        let def = Module::from(module_id);
+        if let Some(name) = def.name(self.db) {
+            self.symbols.push(FileSymbol { name: name.to_smol_str(), def: ModuleDef::Module(def) });
         }
     }
 }
diff --git a/crates/ide-db/src/defs.rs b/crates/ide-db/src/defs.rs
index 4071c490b7f..760834bfafc 100644
--- a/crates/ide-db/src/defs.rs
+++ b/crates/ide-db/src/defs.rs
@@ -8,8 +8,8 @@
 use arrayvec::ArrayVec;
 use hir::{
     Adt, AsAssocItem, AssocItem, BuiltinAttr, BuiltinType, Const, Crate, DeriveHelper, Field,
-    Function, GenericParam, HasVisibility, Impl, ItemInNs, Label, Local, Macro, Module, ModuleDef,
-    Name, PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias, TypeAlias, Variant,
+    Function, GenericParam, HasVisibility, Impl, Label, Local, Macro, Module, ModuleDef, Name,
+    PathResolution, Semantics, Static, ToolModule, Trait, TraitAlias, TypeAlias, Variant,
     Visibility,
 };
 use stdx::impl_from;
@@ -622,22 +622,3 @@ impl From<ModuleDef> for Definition {
         }
     }
 }
-
-impl From<Definition> for Option<ItemInNs> {
-    fn from(def: Definition) -> Self {
-        let item = match def {
-            Definition::Module(it) => ModuleDef::Module(it),
-            Definition::Function(it) => ModuleDef::Function(it),
-            Definition::Adt(it) => ModuleDef::Adt(it),
-            Definition::Variant(it) => ModuleDef::Variant(it),
-            Definition::Const(it) => ModuleDef::Const(it),
-            Definition::Static(it) => ModuleDef::Static(it),
-            Definition::Trait(it) => ModuleDef::Trait(it),
-            Definition::TraitAlias(it) => ModuleDef::TraitAlias(it),
-            Definition::TypeAlias(it) => ModuleDef::TypeAlias(it),
-            Definition::BuiltinType(it) => ModuleDef::BuiltinType(it),
-            _ => return None,
-        };
-        Some(ItemInNs::from(item))
-    }
-}
diff --git a/crates/ide-db/src/items_locator.rs b/crates/ide-db/src/items_locator.rs
index 5631741e1e8..46f1353e2e1 100644
--- a/crates/ide-db/src/items_locator.rs
+++ b/crates/ide-db/src/items_locator.rs
@@ -5,17 +5,11 @@
 use either::Either;
 use hir::{
     import_map::{self, ImportKind},
-    symbols::FileSymbol,
     AsAssocItem, Crate, ItemInNs, Semantics,
 };
 use limit::Limit;
-use syntax::{ast, AstNode, SyntaxKind::NAME};
 
-use crate::{
-    defs::{Definition, NameClass},
-    imports::import_assets::NameToImport,
-    symbol_index, RootDatabase,
-};
+use crate::{imports::import_assets::NameToImport, symbol_index, RootDatabase};
 
 /// A value to use, when uncertain which limit to pick.
 pub static DEFAULT_QUERY_SEARCH_LIMIT: Limit = Limit::new(40);
@@ -118,10 +112,9 @@ fn find_items<'a>(
     let local_results = local_query
         .search(&symbol_index::crate_symbols(db, krate))
         .into_iter()
-        .filter_map(move |local_candidate| get_name_definition(sema, &local_candidate))
-        .filter_map(|name_definition_to_import| match name_definition_to_import {
-            Definition::Macro(macro_def) => Some(ItemInNs::from(macro_def)),
-            def => <Option<_>>::from(def),
+        .filter_map(|local_candidate| match local_candidate.def {
+            hir::ModuleDef::Macro(macro_def) => Some(ItemInNs::Macros(macro_def)),
+            def => Some(ItemInNs::from(def)),
         });
 
     external_importables.chain(local_results).filter(move |&item| match assoc_item_search {
@@ -131,22 +124,6 @@ fn find_items<'a>(
     })
 }
 
-fn get_name_definition(
-    sema: &Semantics<'_, RootDatabase>,
-    import_candidate: &FileSymbol,
-) -> Option<Definition> {
-    let _p = profile::span("get_name_definition");
-
-    let candidate_node = import_candidate.loc.syntax(sema);
-    let candidate_name_node = if candidate_node.kind() != NAME {
-        candidate_node.children().find(|it| it.kind() == NAME)?
-    } else {
-        candidate_node
-    };
-    let name = ast::Name::cast(candidate_name_node)?;
-    NameClass::classify(sema, &name)?.defined()
-}
-
 fn is_assoc_item(item: ItemInNs, db: &RootDatabase) -> bool {
     item.as_module_def().and_then(|module_def| module_def.as_assoc_item(db)).is_some()
 }
diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs
index b0c5820fb09..0c6b0f20cf5 100644
--- a/crates/ide-db/src/lib.rs
+++ b/crates/ide-db/src/lib.rs
@@ -49,10 +49,7 @@ use base_db::{
     salsa::{self, Durability},
     AnchoredPath, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast,
 };
-use hir::{
-    db::{DefDatabase, ExpandDatabase, HirDatabase},
-    symbols::FileSymbolKind,
-};
+use hir::db::{DefDatabase, ExpandDatabase, HirDatabase};
 
 use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
 pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
@@ -378,20 +375,22 @@ impl From<hir::MacroKind> for SymbolKind {
     }
 }
 
-impl From<FileSymbolKind> for SymbolKind {
-    fn from(it: FileSymbolKind) -> Self {
+impl From<hir::ModuleDefId> for SymbolKind {
+    fn from(it: hir::ModuleDefId) -> Self {
         match it {
-            FileSymbolKind::Const => SymbolKind::Const,
-            FileSymbolKind::Enum => SymbolKind::Enum,
-            FileSymbolKind::Function => SymbolKind::Function,
-            FileSymbolKind::Macro => SymbolKind::Macro,
-            FileSymbolKind::Module => SymbolKind::Module,
-            FileSymbolKind::Static => SymbolKind::Static,
-            FileSymbolKind::Struct => SymbolKind::Struct,
-            FileSymbolKind::Trait => SymbolKind::Trait,
-            FileSymbolKind::TraitAlias => SymbolKind::TraitAlias,
-            FileSymbolKind::TypeAlias => SymbolKind::TypeAlias,
-            FileSymbolKind::Union => SymbolKind::Union,
+            hir::ModuleDefId::ConstId(..) => SymbolKind::Const,
+            hir::ModuleDefId::EnumVariantId(..) => SymbolKind::Variant,
+            hir::ModuleDefId::FunctionId(..) => SymbolKind::Function,
+            hir::ModuleDefId::MacroId(..) => SymbolKind::Macro,
+            hir::ModuleDefId::ModuleId(..) => SymbolKind::Module,
+            hir::ModuleDefId::StaticId(..) => SymbolKind::Static,
+            hir::ModuleDefId::AdtId(hir::AdtId::StructId(..)) => SymbolKind::Struct,
+            hir::ModuleDefId::AdtId(hir::AdtId::EnumId(..)) => SymbolKind::Enum,
+            hir::ModuleDefId::AdtId(hir::AdtId::UnionId(..)) => SymbolKind::Union,
+            hir::ModuleDefId::TraitId(..) => SymbolKind::Trait,
+            hir::ModuleDefId::TraitAliasId(..) => SymbolKind::TraitAlias,
+            hir::ModuleDefId::TypeAliasId(..) => SymbolKind::TypeAlias,
+            hir::ModuleDefId::BuiltinType(..) => SymbolKind::TypeAlias,
         }
     }
 }
diff --git a/crates/ide-db/src/symbol_index.rs b/crates/ide-db/src/symbol_index.rs
index 6f953dba0c3..a6f86c83df7 100644
--- a/crates/ide-db/src/symbol_index.rs
+++ b/crates/ide-db/src/symbol_index.rs
@@ -317,7 +317,14 @@ impl Query {
                 let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value);
 
                 for symbol in &symbol_index.symbols[start..end] {
-                    if self.only_types && !symbol.kind.is_type() {
+                    if self.only_types
+                        && !matches!(
+                            symbol.def,
+                            hir::ModuleDef::Adt(..)
+                                | hir::ModuleDef::TypeAlias(..)
+                                | hir::ModuleDef::BuiltinType(..)
+                        )
+                    {
                         continue;
                     }
                     if self.exact {
diff --git a/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/crates/ide-db/src/test_data/test_symbol_index_collection.txt
index 7bda07ace2d..1223e8d6b69 100644
--- a/crates/ide-db/src/test_data/test_symbol_index_collection.txt
+++ b/crates/ide-db/src/test_data/test_symbol_index_collection.txt
@@ -10,368 +10,226 @@
         [
             FileSymbol {
                 name: "Alias",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: TYPE_ALIAS,
-                        range: 397..417,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 402..407,
+                def: TypeAlias(
+                    TypeAlias {
+                        id: TypeAliasId(
+                            0,
+                        ),
                     },
-                },
-                kind: TypeAlias,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "CONST",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: CONST,
-                        range: 340..361,
+                def: Const(
+                    Const {
+                        id: ConstId(
+                            0,
+                        ),
                     },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 346..351,
-                    },
-                },
-                kind: Const,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "CONST_WITH_INNER",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: CONST,
-                        range: 520..592,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 526..542,
+                def: Const(
+                    Const {
+                        id: ConstId(
+                            2,
+                        ),
                     },
-                },
-                kind: Const,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "Enum",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
+                def: Adt(
+                    Enum(
+                        Enum {
+                            id: EnumId(
+                                0,
+                            ),
+                        },
                     ),
-                    ptr: SyntaxNodePtr {
-                        kind: ENUM,
-                        range: 185..207,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 190..194,
-                    },
-                },
-                kind: Enum,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "Macro",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: MACRO_DEF,
-                        range: 153..168,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 159..164,
+                def: Macro(
+                    Macro {
+                        id: Macro2Id(
+                            Macro2Id(
+                                0,
+                            ),
+                        ),
                     },
-                },
-                kind: Macro,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "STATIC",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: STATIC,
-                        range: 362..396,
+                def: Static(
+                    Static {
+                        id: StaticId(
+                            0,
+                        ),
                     },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 369..375,
-                    },
-                },
-                kind: Static,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "Struct",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                1,
+                            ),
+                        },
                     ),
-                    ptr: SyntaxNodePtr {
-                        kind: STRUCT,
-                        range: 170..184,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 177..183,
-                    },
-                },
-                kind: Struct,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "StructFromMacro",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        2147483648,
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                0,
+                            ),
+                        },
                     ),
-                    ptr: SyntaxNodePtr {
-                        kind: STRUCT,
-                        range: 0..22,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 6..21,
-                    },
-                },
-                kind: Struct,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "StructInFn",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                4,
+                            ),
+                        },
                     ),
-                    ptr: SyntaxNodePtr {
-                        kind: STRUCT,
-                        range: 318..336,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 325..335,
-                    },
-                },
-                kind: Struct,
-                container_name: Some(
-                    "main",
                 ),
             },
             FileSymbol {
                 name: "StructInNamedConst",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                5,
+                            ),
+                        },
                     ),
-                    ptr: SyntaxNodePtr {
-                        kind: STRUCT,
-                        range: 555..581,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 562..580,
-                    },
-                },
-                kind: Struct,
-                container_name: Some(
-                    "CONST_WITH_INNER",
                 ),
             },
             FileSymbol {
                 name: "StructInUnnamedConst",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                6,
+                            ),
+                        },
                     ),
-                    ptr: SyntaxNodePtr {
-                        kind: STRUCT,
-                        range: 479..507,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 486..506,
-                    },
-                },
-                kind: Struct,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "Trait",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: TRAIT,
-                        range: 261..300,
+                def: Trait(
+                    Trait {
+                        id: TraitId(
+                            0,
+                        ),
                     },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 267..272,
-                    },
-                },
-                kind: Trait,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "Union",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
+                def: Adt(
+                    Union(
+                        Union {
+                            id: UnionId(
+                                0,
+                            ),
+                        },
                     ),
-                    ptr: SyntaxNodePtr {
-                        kind: UNION,
-                        range: 208..222,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 214..219,
-                    },
-                },
-                kind: Union,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "a_mod",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: MODULE,
-                        range: 419..457,
+                def: Module(
+                    Module {
+                        id: ModuleId {
+                            krate: Idx::<CrateData>(0),
+                            block: None,
+                            local_id: Idx::<ModuleData>(1),
+                        },
                     },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 423..428,
-                    },
-                },
-                kind: Module,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "b_mod",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: MODULE,
-                        range: 594..604,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 598..603,
+                def: Module(
+                    Module {
+                        id: ModuleId {
+                            krate: Idx::<CrateData>(0),
+                            block: None,
+                            local_id: Idx::<ModuleData>(2),
+                        },
                     },
-                },
-                kind: Module,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "define_struct",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: MACRO_RULES,
-                        range: 51..131,
+                def: Macro(
+                    Macro {
+                        id: MacroRulesId(
+                            MacroRulesId(
+                                1,
+                            ),
+                        ),
                     },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 64..77,
-                    },
-                },
-                kind: Macro,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "impl_fn",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: FN,
-                        range: 242..257,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 245..252,
+                def: Function(
+                    Function {
+                        id: FunctionId(
+                            2,
+                        ),
                     },
-                },
-                kind: Function,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "macro_rules_macro",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: MACRO_RULES,
-                        range: 1..48,
+                def: Macro(
+                    Macro {
+                        id: MacroRulesId(
+                            MacroRulesId(
+                                0,
+                            ),
+                        ),
                     },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 14..31,
-                    },
-                },
-                kind: Macro,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "main",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: FN,
-                        range: 302..338,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 305..309,
+                def: Function(
+                    Function {
+                        id: FunctionId(
+                            0,
+                        ),
                     },
-                },
-                kind: Function,
-                container_name: None,
+                ),
             },
             FileSymbol {
                 name: "trait_fn",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
-                    ),
-                    ptr: SyntaxNodePtr {
-                        kind: FN,
-                        range: 279..298,
+                def: Function(
+                    Function {
+                        id: FunctionId(
+                            1,
+                        ),
                     },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 282..290,
-                    },
-                },
-                kind: Function,
-                container_name: Some(
-                    "Trait",
                 ),
             },
         ],
@@ -387,21 +245,15 @@
         [
             FileSymbol {
                 name: "StructInModA",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        0,
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                2,
+                            ),
+                        },
                     ),
-                    ptr: SyntaxNodePtr {
-                        kind: STRUCT,
-                        range: 435..455,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 442..454,
-                    },
-                },
-                kind: Struct,
-                container_name: None,
+                ),
             },
         ],
     ),
@@ -416,21 +268,15 @@
         [
             FileSymbol {
                 name: "StructInModB",
-                loc: DeclarationLocation {
-                    hir_file_id: HirFileId(
-                        1,
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                3,
+                            ),
+                        },
                     ),
-                    ptr: SyntaxNodePtr {
-                        kind: STRUCT,
-                        range: 0..20,
-                    },
-                    name_ptr: SyntaxNodePtr {
-                        kind: NAME,
-                        range: 7..19,
-                    },
-                },
-                kind: Struct,
-                container_name: None,
+                ),
             },
         ],
     ),
diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs
index 48bcd37b62c..dd1d0d75c63 100644
--- a/crates/ide/src/call_hierarchy.rs
+++ b/crates/ide/src/call_hierarchy.rs
@@ -263,7 +263,7 @@ mod tests {
             expect![["callee Function FileId(0) 0..14 3..9"]],
             expect![[r#"
                 caller1 Function FileId(0) 15..45 18..25 : [34..40]
-                test_caller Function FileId(0) 95..149 110..121 : [134..140]"#]],
+                test_caller Function FileId(0) 95..149 110..121 tests : [134..140]"#]],
             expect![[]],
         );
     }
@@ -283,7 +283,7 @@ fn caller() {
 //- /foo/mod.rs
 pub fn callee() {}
 "#,
-            expect![["callee Function FileId(1) 0..18 7..13"]],
+            expect!["callee Function FileId(1) 0..18 7..13 foo"],
             expect![["caller Function FileId(0) 27..56 30..36 : [45..51]"]],
             expect![[]],
         );
@@ -323,7 +323,7 @@ pub fn callee() {}
 "#,
             expect![["caller Function FileId(0) 27..56 30..36"]],
             expect![[]],
-            expect![["callee Function FileId(1) 0..18 7..13 : [45..51]"]],
+            expect!["callee Function FileId(1) 0..18 7..13 foo : [45..51]"],
         );
     }
 
@@ -477,7 +477,7 @@ fn caller() {
     S1::callee();
 }
 "#,
-            expect![["callee Function FileId(0) 15..27 18..24"]],
+            expect!["callee Function FileId(0) 15..27 18..24 T1"],
             expect![["caller Function FileId(0) 82..115 85..91 : [104..110]"]],
             expect![[]],
         );
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index 082e5372d42..3e5d508b5d8 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -2157,52 +2157,53 @@ mod M {
 fn main() { let s$0t = (A(1), B(2), M::C(3) ); }
 "#,
         expect![[r#"
-                [
-                    GoToType(
-                        [
-                            HoverGotoTypeData {
-                                mod_path: "test::A",
-                                nav: NavigationTarget {
-                                    file_id: FileId(
-                                        0,
-                                    ),
-                                    full_range: 0..14,
-                                    focus_range: 7..8,
-                                    name: "A",
-                                    kind: Struct,
-                                    description: "struct A",
-                                },
+            [
+                GoToType(
+                    [
+                        HoverGotoTypeData {
+                            mod_path: "test::A",
+                            nav: NavigationTarget {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                full_range: 0..14,
+                                focus_range: 7..8,
+                                name: "A",
+                                kind: Struct,
+                                description: "struct A",
                             },
-                            HoverGotoTypeData {
-                                mod_path: "test::B",
-                                nav: NavigationTarget {
-                                    file_id: FileId(
-                                        0,
-                                    ),
-                                    full_range: 15..29,
-                                    focus_range: 22..23,
-                                    name: "B",
-                                    kind: Struct,
-                                    description: "struct B",
-                                },
+                        },
+                        HoverGotoTypeData {
+                            mod_path: "test::B",
+                            nav: NavigationTarget {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                full_range: 15..29,
+                                focus_range: 22..23,
+                                name: "B",
+                                kind: Struct,
+                                description: "struct B",
                             },
-                            HoverGotoTypeData {
-                                mod_path: "test::M::C",
-                                nav: NavigationTarget {
-                                    file_id: FileId(
-                                        0,
-                                    ),
-                                    full_range: 42..60,
-                                    focus_range: 53..54,
-                                    name: "C",
-                                    kind: Struct,
-                                    description: "pub struct C",
-                                },
+                        },
+                        HoverGotoTypeData {
+                            mod_path: "test::M::C",
+                            nav: NavigationTarget {
+                                file_id: FileId(
+                                    0,
+                                ),
+                                full_range: 42..60,
+                                focus_range: 53..54,
+                                name: "C",
+                                kind: Struct,
+                                container_name: "M",
+                                description: "pub struct C",
                             },
-                        ],
-                    ),
-                ]
-            "#]],
+                        },
+                    ],
+                ),
+            ]
+        "#]],
     );
 }
 
@@ -2531,6 +2532,7 @@ pub mod future {
                                 focus_range: 60..66,
                                 name: "Future",
                                 kind: Trait,
+                                container_name: "future",
                                 description: "pub trait Future",
                             },
                         },
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 3509dee0c96..e3900fa0d63 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -398,7 +398,7 @@ impl Analysis {
         self.with_db(|db| {
             symbol_index::world_symbols(db, query)
                 .into_iter() // xx: should we make this a par iter?
-                .filter_map(|s| s.try_to_nav(db))
+                .filter_map(|s| s.def.try_to_nav(db))
                 .collect::<Vec<_>>()
         })
     }
diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs
index c1a775136f6..b5e410eaeb9 100644
--- a/crates/ide/src/navigation_target.rs
+++ b/crates/ide/src/navigation_target.rs
@@ -4,8 +4,8 @@ use std::fmt;
 
 use either::Either;
 use hir::{
-    symbols::FileSymbol, AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirDisplay,
-    InFile, LocalSource, ModuleSource, Semantics,
+    AssocItem, Documentation, FieldSource, HasAttrs, HasContainer, HasSource, HirDisplay, InFile,
+    LocalSource, ModuleSource,
 };
 use ide_db::{
     base_db::{FileId, FileRange},
@@ -15,7 +15,7 @@ use ide_db::{defs::Definition, RootDatabase};
 use stdx::never;
 use syntax::{
     ast::{self, HasName},
-    match_ast, AstNode, SmolStr, SyntaxNode, TextRange,
+    AstNode, SmolStr, SyntaxNode, TextRange,
 };
 
 /// `NavigationTarget` represents an element in the editor's UI which you can
@@ -158,24 +158,6 @@ impl NavigationTarget {
     }
 }
 
-impl TryToNav for FileSymbol {
-    fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
-        let full_range = self.loc.original_range(db);
-        let name_range = self.loc.original_name_range(db)?;
-
-        Some(NavigationTarget {
-            file_id: full_range.file_id,
-            name: self.name.clone(),
-            kind: Some(self.kind.into()),
-            full_range: full_range.range,
-            focus_range: Some(name_range.range),
-            container_name: self.container_name.clone(),
-            description: description_from_symbol(db, self),
-            docs: None,
-        })
-    }
-}
-
 impl TryToNav for Definition {
     fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
         match self {
@@ -221,38 +203,80 @@ impl TryToNav for hir::ModuleDef {
     }
 }
 
-pub(crate) trait ToNavFromAst {
+pub(crate) trait ToNavFromAst: Sized {
     const KIND: SymbolKind;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        _ = db;
+        None
+    }
 }
+
+fn container_name(db: &RootDatabase, t: impl HasContainer) -> Option<SmolStr> {
+    match t.container(db) {
+        hir::ItemContainer::Trait(it) => Some(it.name(db).to_smol_str()),
+        // FIXME: Handle owners of blocks correctly here
+        hir::ItemContainer::Module(it) => it.name(db).map(|name| name.to_smol_str()),
+        _ => None,
+    }
+}
+
 impl ToNavFromAst for hir::Function {
     const KIND: SymbolKind = SymbolKind::Function;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        container_name(db, self)
+    }
 }
+
 impl ToNavFromAst for hir::Const {
     const KIND: SymbolKind = SymbolKind::Const;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        container_name(db, self)
+    }
 }
 impl ToNavFromAst for hir::Static {
     const KIND: SymbolKind = SymbolKind::Static;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        container_name(db, self)
+    }
 }
 impl ToNavFromAst for hir::Struct {
     const KIND: SymbolKind = SymbolKind::Struct;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        container_name(db, self)
+    }
 }
 impl ToNavFromAst for hir::Enum {
     const KIND: SymbolKind = SymbolKind::Enum;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        container_name(db, self)
+    }
 }
 impl ToNavFromAst for hir::Variant {
     const KIND: SymbolKind = SymbolKind::Variant;
 }
 impl ToNavFromAst for hir::Union {
     const KIND: SymbolKind = SymbolKind::Union;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        container_name(db, self)
+    }
 }
 impl ToNavFromAst for hir::TypeAlias {
     const KIND: SymbolKind = SymbolKind::TypeAlias;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        container_name(db, self)
+    }
 }
 impl ToNavFromAst for hir::Trait {
     const KIND: SymbolKind = SymbolKind::Trait;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        container_name(db, self)
+    }
 }
 impl ToNavFromAst for hir::TraitAlias {
     const KIND: SymbolKind = SymbolKind::TraitAlias;
+    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+        container_name(db, self)
+    }
 }
 
 impl<D> TryToNav for D
@@ -269,6 +293,7 @@ where
         );
         res.docs = self.docs(db);
         res.description = Some(self.display(db).to_string());
+        res.container_name = self.container_name(db);
         Some(res)
     }
 }
@@ -544,32 +569,6 @@ impl TryToNav for hir::ConstParam {
     }
 }
 
-/// Get a description of a symbol.
-///
-/// e.g. `struct Name`, `enum Name`, `fn Name`
-pub(crate) fn description_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
-    let sema = Semantics::new(db);
-    let node = symbol.loc.syntax(&sema);
-
-    match_ast! {
-        match node {
-            ast::Fn(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::Struct(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::Enum(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::Trait(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::TraitAlias(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::Module(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::TypeAlias(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::Const(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::Static(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::RecordField(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::Variant(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            ast::Union(it) => sema.to_def(&it).map(|it| it.display(db).to_string()),
-            _ => None,
-        }
-    }
-}
-
 fn orig_focus_range(
     db: &RootDatabase,
     file_id: hir::HirFileId,
@@ -614,7 +613,6 @@ fn foo() { enum FooInner { } }
                     focus_range: 34..42,
                     name: "FooInner",
                     kind: Enum,
-                    container_name: "foo",
                     description: "enum FooInner",
                 },
             ]
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 3684c1033f3..b8e05d4f625 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -715,7 +715,7 @@ fn f() {
 }
 "#,
             expect![[r#"
-                Foo Struct FileId(1) 17..51 28..31
+                Foo Struct FileId(1) 17..51 28..31 foo
 
                 FileId(0) 53..56
                 FileId(2) 79..82
@@ -803,7 +803,7 @@ pub(super) struct Foo$0 {
 }
 "#,
             expect![[r#"
-                Foo Struct FileId(2) 0..41 18..21
+                Foo Struct FileId(2) 0..41 18..21 some
 
                 FileId(1) 20..23 Import
                 FileId(1) 47..50
@@ -1542,7 +1542,7 @@ fn f() {
                 FileId(0) 161..165
 
 
-                func Function FileId(0) 137..146 140..144
+                func Function FileId(0) 137..146 140..144 module
 
                 FileId(0) 181..185
             "#]],
@@ -1581,7 +1581,7 @@ trait Trait {
 }
 "#,
             expect![[r#"
-                func Function FileId(0) 48..87 51..55
+                func Function FileId(0) 48..87 51..55 Trait
 
                 FileId(0) 74..78
             "#]],
@@ -1692,7 +1692,7 @@ fn f<T: Trait>() {
 }
 "#,
             expect![[r#"
-                CONST Const FileId(0) 18..37 24..29
+                CONST Const FileId(0) 18..37 24..29 Trait
 
                 FileId(0) 71..76
                 FileId(0) 125..130
@@ -1721,7 +1721,7 @@ fn f<T: Trait>() {
 }
 "#,
             expect![[r#"
-                TypeAlias TypeAlias FileId(0) 18..33 23..32
+                TypeAlias TypeAlias FileId(0) 18..33 23..32 Trait
 
                 FileId(0) 66..75
                 FileId(0) 117..126
@@ -1750,7 +1750,7 @@ fn f<T: Trait>() {
 }
 "#,
             expect![[r#"
-                function Function FileId(0) 18..34 21..29
+                function Function FileId(0) 18..34 21..29 Trait
 
                 FileId(0) 65..73
                 FileId(0) 112..120
@@ -1894,7 +1894,7 @@ fn f<T: Trait>() {
 }
 "#,
             expect![[r#"
-                TypeAlias TypeAlias FileId(0) 18..33 23..32
+                TypeAlias TypeAlias FileId(0) 18..33 23..32 Trait
 
                 FileId(0) 66..75
                 FileId(0) 117..126
@@ -1950,7 +1950,7 @@ impl Foo for Bar {
 fn method() {}
 "#,
             expect![[r#"
-                method Function FileId(0) 16..39 19..25
+                method Function FileId(0) 16..39 19..25 Foo
 
                 FileId(0) 101..107
             "#]],
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 8a8a9151c42..64150cc2f7f 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -2579,6 +2579,7 @@ mod r#mod {
                             ),
                             full_range: 47..84,
                             name: "r#for",
+                            container_name: "r#mod",
                         },
                         kind: DocTest {
                             test_id: Path(
@@ -2595,6 +2596,7 @@ mod r#mod {
                             ),
                             full_range: 90..146,
                             name: "r#struct",
+                            container_name: "r#mod",
                         },
                         kind: DocTest {
                             test_id: Path(