Merge pull request #20994 from Veykril/push-npvyklkuxnlr

perf: Reduce memory usage of symbol index
diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs
index d8c624e..e472de9 100644
--- a/crates/hir/src/symbols.rs
+++ b/crates/hir/src/symbols.rs
@@ -18,7 +18,7 @@
 };
 use intern::Symbol;
 use rustc_hash::FxHashMap;
-use syntax::{AstNode, AstPtr, SmolStr, SyntaxNode, SyntaxNodePtr, ToSmolStr, ast::HasName};
+use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, ToSmolStr, ast::HasName};
 
 use crate::{HasCrate, Module, ModuleDef, Semantics};
 
@@ -29,7 +29,7 @@
     pub name: Symbol,
     pub def: ModuleDef,
     pub loc: DeclarationLocation,
-    pub container_name: Option<SmolStr>,
+    pub container_name: Option<Symbol>,
     /// Whether this symbol is a doc alias for the original symbol.
     pub is_alias: bool,
     pub is_assoc: bool,
@@ -65,7 +65,7 @@
     db: &'a dyn HirDatabase,
     symbols: FxIndexSet<FileSymbol>,
     work: Vec<SymbolCollectorWork>,
-    current_container_name: Option<SmolStr>,
+    current_container_name: Option<Symbol>,
 }
 
 /// Given a [`ModuleId`] and a [`HirDatabase`], use the DefMap for the module's crate to collect
@@ -108,7 +108,7 @@
         tracing::info!(?work, "SymbolCollector::do_work");
         self.db.unwind_if_revision_cancelled();
 
-        let parent_name = work.parent.map(|name| name.as_str().to_smolstr());
+        let parent_name = work.parent.map(|name| Symbol::intern(name.as_str()));
         self.with_container_name(parent_name, |s| s.collect_from_module(work.module_id));
     }
 
@@ -125,7 +125,7 @@
                 }
                 ModuleDefId::AdtId(AdtId::EnumId(id)) => {
                     this.push_decl(id, name, false, None);
-                    let enum_name = this.db.enum_signature(id).name.as_str().to_smolstr();
+                    let enum_name = Symbol::intern(this.db.enum_signature(id).name.as_str());
                     this.with_container_name(Some(enum_name), |this| {
                         let variants = id.enum_variants(this.db);
                         for (variant_id, variant_name, _) in &variants.variants {
@@ -328,7 +328,7 @@
                 )
                 .to_smolstr(),
         );
-        self.with_container_name(impl_name, |s| {
+        self.with_container_name(impl_name.as_deref().map(Symbol::intern), |s| {
             for &(ref name, assoc_item_id) in &impl_id.impl_items(self.db).items {
                 s.push_assoc_item(assoc_item_id, name, None)
             }
@@ -337,14 +337,14 @@
 
     fn collect_from_trait(&mut self, trait_id: TraitId, trait_do_not_complete: Complete) {
         let trait_data = self.db.trait_signature(trait_id);
-        self.with_container_name(Some(trait_data.name.as_str().into()), |s| {
+        self.with_container_name(Some(Symbol::intern(trait_data.name.as_str())), |s| {
             for &(ref name, assoc_item_id) in &trait_id.trait_items(self.db).items {
                 s.push_assoc_item(assoc_item_id, name, Some(trait_do_not_complete));
             }
         });
     }
 
-    fn with_container_name(&mut self, container_name: Option<SmolStr>, f: impl FnOnce(&mut Self)) {
+    fn with_container_name(&mut self, container_name: Option<Symbol>, f: impl FnOnce(&mut Self)) {
         if let Some(container_name) = container_name {
             let prev = self.current_container_name.replace(container_name);
             f(self);
diff --git a/crates/ide-db/src/ra_fixture.rs b/crates/ide-db/src/ra_fixture.rs
index 1f056a8..a9d596d 100644
--- a/crates/ide-db/src/ra_fixture.rs
+++ b/crates/ide-db/src/ra_fixture.rs
@@ -2,7 +2,7 @@
 
 use std::hash::{BuildHasher, Hash};
 
-use hir::{CfgExpr, FilePositionWrapper, FileRangeWrapper, Semantics};
+use hir::{CfgExpr, FilePositionWrapper, FileRangeWrapper, Semantics, Symbol};
 use smallvec::SmallVec;
 use span::{TextRange, TextSize};
 use syntax::{
@@ -524,6 +524,7 @@
     f64,
     &str,
     String,
+    Symbol,
     SmolStr,
     Documentation,
     SymbolKind,
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs
index 0ee9795..d663b70 100644
--- a/crates/ide/src/goto_definition.rs
+++ b/crates/ide/src/goto_definition.rs
@@ -245,7 +245,7 @@
     Some(NavigationTarget {
         file_id,
         full_range: TextRange::new(0.into(), size),
-        name: path.into(),
+        name: hir::Symbol::intern(&path),
         alias: None,
         focus_range: None,
         kind: None,
@@ -598,7 +598,13 @@
     let value_range = value.syntax().text_range();
     let navs = navigation_target::orig_range_with_focus_r(db, file_id, value_range, focus_range);
     navs.map(|(hir::FileRangeWrapper { file_id, range }, focus_range)| {
-        NavigationTarget::from_syntax(file_id, "<expr>".into(), focus_range, range, kind)
+        NavigationTarget::from_syntax(
+            file_id,
+            hir::Symbol::intern("<expr>"),
+            focus_range,
+            range,
+            kind,
+        )
     })
 }
 
@@ -607,7 +613,6 @@
     use crate::{GotoDefinitionConfig, fixture};
     use ide_db::{FileRange, MiniCore};
     use itertools::Itertools;
-    use syntax::SmolStr;
 
     const TEST_CONFIG: GotoDefinitionConfig<'_> =
         GotoDefinitionConfig { minicore: MiniCore::default() };
@@ -658,7 +663,7 @@
         let Some(target) = navs.into_iter().next() else {
             panic!("expected single navigation target but encountered none");
         };
-        assert_eq!(target.name, SmolStr::new_inline(expected_name));
+        assert_eq!(target.name, hir::Symbol::intern(expected_name));
     }
 
     #[test]
diff --git a/crates/ide/src/navigation_target.rs b/crates/ide/src/navigation_target.rs
index b222ff3..7d5d905 100644
--- a/crates/ide/src/navigation_target.rs
+++ b/crates/ide/src/navigation_target.rs
@@ -6,7 +6,8 @@
 use either::Either;
 use hir::{
     AssocItem, Crate, FieldSource, HasContainer, HasCrate, HasSource, HirDisplay, HirFileId,
-    InFile, LocalSource, ModuleSource, Semantics, db::ExpandDatabase, symbols::FileSymbol,
+    InFile, LocalSource, ModuleSource, Semantics, Symbol, db::ExpandDatabase, sym,
+    symbols::FileSymbol,
 };
 use ide_db::{
     FileId, FileRange, RootDatabase, SymbolKind,
@@ -16,12 +17,10 @@
     famous_defs::FamousDefs,
     ra_fixture::UpmapFromRaFixture,
 };
-use span::Edition;
 use stdx::never;
 use syntax::{
-    AstNode, SmolStr, SyntaxNode, TextRange, ToSmolStr,
+    AstNode, SyntaxNode, TextRange,
     ast::{self, HasName},
-    format_smolstr,
 };
 
 /// `NavigationTarget` represents an element in the editor's UI which you can
@@ -48,17 +47,14 @@
     ///
     /// This range must be contained within [`Self::full_range`].
     pub focus_range: Option<TextRange>,
-    // FIXME: Symbol
-    pub name: SmolStr,
+    pub name: Symbol,
     pub kind: Option<SymbolKind>,
-    // FIXME: Symbol
-    pub container_name: Option<SmolStr>,
+    pub container_name: Option<Symbol>,
     pub description: Option<String>,
     pub docs: Option<Documentation>,
     /// In addition to a `name` field, a `NavigationTarget` may also be aliased
     /// In such cases we want a `NavigationTarget` to be accessible by its alias
-    // FIXME: Symbol
-    pub alias: Option<SmolStr>,
+    pub alias: Option<Symbol>,
 }
 
 impl fmt::Debug for NavigationTarget {
@@ -149,9 +145,7 @@
         db: &RootDatabase,
         module: hir::Module,
     ) -> UpmappingResult<NavigationTarget> {
-        let edition = module.krate().edition(db);
-        let name =
-            module.name(db).map(|it| it.display_no_db(edition).to_smolstr()).unwrap_or_default();
+        let name = module.name(db).map(|it| it.symbol().clone()).unwrap_or_else(|| sym::underscore);
         match module.declaration_source(db) {
             Some(InFile { value, file_id }) => {
                 orig_range_with_focus(db, file_id, value.syntax(), value.name()).map(
@@ -199,7 +193,8 @@
         InFile { file_id, value }: InFile<&dyn ast::HasName>,
         kind: SymbolKind,
     ) -> UpmappingResult<NavigationTarget> {
-        let name: SmolStr = value.name().map(|it| it.text().into()).unwrap_or_else(|| "_".into());
+        let name =
+            value.name().map(|it| Symbol::intern(&it.text())).unwrap_or_else(|| sym::underscore);
 
         orig_range_with_focus(db, file_id, value.syntax(), value.name()).map(
             |(FileRange { file_id, range: full_range }, focus_range)| {
@@ -210,7 +205,7 @@
 
     pub(crate) fn from_syntax(
         file_id: FileId,
-        name: SmolStr,
+        name: Symbol,
         focus_range: Option<TextRange>,
         full_range: TextRange,
         kind: SymbolKind,
@@ -235,8 +230,6 @@
         sema: &Semantics<'_, RootDatabase>,
     ) -> Option<UpmappingResult<NavigationTarget>> {
         let db = sema.db;
-        let edition =
-            self.def.module(db).map(|it| it.krate().edition(db)).unwrap_or(Edition::CURRENT);
         let display_target = self.def.krate(db).to_display_target(db);
         Some(
             orig_range_with_focus_r(
@@ -248,11 +241,12 @@
             .map(|(FileRange { file_id, range: full_range }, focus_range)| {
                 NavigationTarget {
                     file_id,
-                    name: self.is_alias.then(|| self.def.name(db)).flatten().map_or_else(
-                        || self.name.as_str().into(),
-                        |it| it.display_no_db(edition).to_smolstr(),
-                    ),
-                    alias: self.is_alias.then(|| self.name.as_str().into()),
+                    name: self
+                        .is_alias
+                        .then(|| self.def.name(db))
+                        .flatten()
+                        .map_or_else(|| self.name.clone(), |it| it.symbol().clone()),
+                    alias: self.is_alias.then(|| self.name.clone()),
                     kind: Some(self.def.into()),
                     full_range,
                     focus_range,
@@ -349,52 +343,50 @@
 
 pub(crate) trait ToNavFromAst: Sized {
     const KIND: SymbolKind;
-    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
+    fn container_name(self, db: &RootDatabase) -> Option<Symbol> {
         _ = db;
         None
     }
 }
 
-fn container_name(db: &RootDatabase, t: impl HasContainer, edition: Edition) -> Option<SmolStr> {
+fn container_name(db: &RootDatabase, t: impl HasContainer) -> Option<Symbol> {
     match t.container(db) {
-        hir::ItemContainer::Trait(it) => Some(it.name(db).display_no_db(edition).to_smolstr()),
+        hir::ItemContainer::Trait(it) => Some(it.name(db).symbol().clone()),
         // FIXME: Handle owners of blocks correctly here
-        hir::ItemContainer::Module(it) => {
-            it.name(db).map(|name| name.display_no_db(edition).to_smolstr())
-        }
+        hir::ItemContainer::Module(it) => it.name(db).map(|name| name.symbol().clone()),
         _ => None,
     }
 }
 
 impl ToNavFromAst for hir::Function {
     const KIND: SymbolKind = SymbolKind::Function;
-    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
-        container_name(db, self, self.krate(db).edition(db))
+    fn container_name(self, db: &RootDatabase) -> Option<Symbol> {
+        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, self.krate(db).edition(db))
+    fn container_name(self, db: &RootDatabase) -> Option<Symbol> {
+        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, self.krate(db).edition(db))
+    fn container_name(self, db: &RootDatabase) -> Option<Symbol> {
+        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, self.krate(db).edition(db))
+    fn container_name(self, db: &RootDatabase) -> Option<Symbol> {
+        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, self.krate(db).edition(db))
+    fn container_name(self, db: &RootDatabase) -> Option<Symbol> {
+        container_name(db, self)
     }
 }
 impl ToNavFromAst for hir::Variant {
@@ -402,20 +394,20 @@
 }
 impl ToNavFromAst for hir::Union {
     const KIND: SymbolKind = SymbolKind::Union;
-    fn container_name(self, db: &RootDatabase) -> Option<SmolStr> {
-        container_name(db, self, self.krate(db).edition(db))
+    fn container_name(self, db: &RootDatabase) -> Option<Symbol> {
+        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, self.krate(db).edition(db))
+    fn container_name(self, db: &RootDatabase) -> Option<Symbol> {
+        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, self.krate(db).edition(db))
+    fn container_name(self, db: &RootDatabase) -> Option<Symbol> {
+        container_name(db, self)
     }
 }
 
@@ -451,10 +443,8 @@
 impl ToNav for hir::Module {
     fn to_nav(&self, db: &RootDatabase) -> UpmappingResult<NavigationTarget> {
         let InFile { file_id, value } = self.definition_source(db);
-        let edition = self.krate(db).edition(db);
 
-        let name =
-            self.name(db).map(|it| it.display_no_db(edition).to_smolstr()).unwrap_or_default();
+        let name = self.name(db).map(|it| it.symbol().clone()).unwrap_or_else(|| sym::underscore);
         let (syntax, focus) = match &value {
             ModuleSource::SourceFile(node) => (node.syntax(), None),
             ModuleSource::Module(node) => (node.syntax(), node.name()),
@@ -499,7 +489,7 @@
             |(FileRange { file_id, range: full_range }, focus_range)| {
                 NavigationTarget::from_syntax(
                     file_id,
-                    "impl".into(),
+                    sym::kw_impl,
                     focus_range,
                     full_range,
                     SymbolKind::Impl,
@@ -521,16 +511,12 @@
             .rename()
             .map_or_else(|| value.name_ref().map(Either::Left), |it| it.name().map(Either::Right));
         let krate = self.module(db).krate();
-        let edition = krate.edition(db);
 
         Some(orig_range_with_focus(db, file_id, value.syntax(), focus).map(
             |(FileRange { file_id, range: full_range }, focus_range)| {
                 let mut res = NavigationTarget::from_syntax(
                     file_id,
-                    self.alias_or_name(db)
-                        .unwrap_or_else(|| self.name(db))
-                        .display_no_db(edition)
-                        .to_smolstr(),
+                    self.alias_or_name(db).unwrap_or_else(|| self.name(db)).symbol().clone(),
                     focus_range,
                     full_range,
                     SymbolKind::Module,
@@ -538,7 +524,7 @@
 
                 res.docs = self.docs(db);
                 res.description = Some(self.display(db, krate.to_display_target(db)).to_string());
-                res.container_name = container_name(db, *self, edition);
+                res.container_name = container_name(db, *self);
                 res
             },
         ))
@@ -570,7 +556,7 @@
                 |(FileRange { file_id, range: full_range }, focus_range)| {
                     NavigationTarget::from_syntax(
                         file_id,
-                        format_smolstr!("{}", self.index()),
+                        Symbol::integer(self.index()),
                         focus_range,
                         full_range,
                         SymbolKind::Field,
@@ -655,11 +641,10 @@
             Either::Left(bind_pat) => (bind_pat.syntax(), bind_pat.name()),
             Either::Right(it) => (it.syntax(), it.name()),
         };
-        let edition = self.local.parent(db).module(db).krate().edition(db);
 
         orig_range_with_focus(db, file_id, node, name).map(
             |(FileRange { file_id, range: full_range }, focus_range)| {
-                let name = local.name(db).display_no_db(edition).to_smolstr();
+                let name = local.name(db).symbol().clone();
                 let kind = if local.is_self(db) {
                     SymbolKind::SelfParam
                 } else if local.is_param(db) {
@@ -696,8 +681,7 @@
     ) -> Option<UpmappingResult<NavigationTarget>> {
         let db = sema.db;
         let InFile { file_id, value } = self.source(db)?;
-        // Labels can't be keywords, so no escaping needed.
-        let name = self.name(db).display_no_db(Edition::Edition2015).to_smolstr();
+        let name = self.name(db).symbol().clone();
 
         Some(orig_range_with_focus(db, file_id, value.syntax(), value.lifetime()).map(
             |(FileRange { file_id, range: full_range }, focus_range)| NavigationTarget {
@@ -722,8 +706,7 @@
     ) -> Option<UpmappingResult<NavigationTarget>> {
         let db = sema.db;
         let InFile { file_id, value } = self.merge().source(db)?;
-        let edition = self.module(db).krate().edition(db);
-        let name = self.name(db).display_no_db(edition).to_smolstr();
+        let name = self.name(db).symbol().clone();
 
         let value = match value {
             Either::Left(ast::TypeOrConstParam::Type(x)) => Either::Left(x),
@@ -772,8 +755,7 @@
     ) -> Option<UpmappingResult<NavigationTarget>> {
         let db = sema.db;
         let InFile { file_id, value } = self.source(db)?;
-        // Lifetimes cannot be keywords, so not escaping needed.
-        let name = self.name(db).display_no_db(Edition::Edition2015).to_smolstr();
+        let name = self.name(db).symbol().clone();
 
         Some(orig_range(db, file_id, value.syntax()).map(
             |(FileRange { file_id, range: full_range }, focus_range)| NavigationTarget {
@@ -798,8 +780,7 @@
     ) -> Option<UpmappingResult<NavigationTarget>> {
         let db = sema.db;
         let InFile { file_id, value } = self.merge().source(db)?;
-        let edition = self.module(db).krate().edition(db);
-        let name = self.name(db).display_no_db(edition).to_smolstr();
+        let name = self.name(db).symbol().clone();
 
         let value = match value {
             Either::Left(ast::TypeOrConstParam::Const(x)) => x,
@@ -834,21 +815,17 @@
         let InFile { file_id, value } = &self.source(db)?;
         let file_id = *file_id;
         Some(orig_range_with_focus(db, file_id, value.syntax(), value.name()).map(
-            |(FileRange { file_id, range: full_range }, focus_range)| {
-                let edition = self.parent(db).module(db).krate().edition(db);
-                NavigationTarget {
-                    file_id,
-                    name: self
-                        .name(db)
-                        .map_or_else(|| "_".into(), |it| it.display(db, edition).to_smolstr()),
-                    alias: None,
-                    kind: Some(SymbolKind::Local),
-                    full_range,
-                    focus_range,
-                    container_name: None,
-                    description: None,
-                    docs: None,
-                }
+            |(FileRange { file_id, range: full_range }, focus_range)| NavigationTarget {
+                file_id,
+                name:
+                    self.name(db).map_or_else(|| sym::underscore.clone(), |it| it.symbol().clone()),
+                alias: None,
+                kind: Some(SymbolKind::Local),
+                full_range,
+                focus_range,
+                container_name: None,
+                description: None,
+                docs: None,
             },
         ))
     }
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index a53a192..516cc7f 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -1058,7 +1058,7 @@
 use self$0;
 "#,
             expect![[r#"
-                Module FileId(0) 0..10
+                _ Module FileId(0) 0..10
 
                 FileId(0) 4..8 import
             "#]],
@@ -3130,7 +3130,7 @@
 }
         "#,
             expect![[r#"
-                'r#break Label FileId(0) 87..96 87..95
+                'break Label FileId(0) 87..96 87..95
 
                 FileId(0) 113..121
             "#]],
@@ -3146,7 +3146,7 @@
 }
         "#,
             expect![[r#"
-                'r#fn LifetimeParam FileId(0) 7..12
+                'fn LifetimeParam FileId(0) 7..12
 
                 FileId(0) 18..23
                 FileId(0) 44..49
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 494701d..2086a19 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -231,7 +231,7 @@
                 .cmp(&nav_b.focus_range.map_or_else(t_0, |it| it.start()))
         })
         .then_with(|| kind.disc().cmp(&kind_b.disc()))
-        .then_with(|| nav.name.cmp(&nav_b.name))
+        .then_with(|| nav.name.as_str().cmp(nav_b.name.as_str()))
 }
 
 fn find_related_tests(
@@ -817,7 +817,7 @@
 "#,
             expect![[r#"
                 [
-                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..331, name: \"\", kind: Module })",
+                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..331, name: \"_\", kind: Module })",
                     "(Bin, NavigationTarget { file_id: FileId(0), full_range: 1..13, focus_range: 4..8, name: \"main\", kind: Function })",
                     "(Bin, NavigationTarget { file_id: FileId(0), full_range: 15..76, focus_range: 42..71, name: \"__cortex_m_rt_main_trampoline\", kind: Function })",
                     "(Bin, NavigationTarget { file_id: FileId(0), full_range: 78..154, focus_range: 113..149, name: \"__cortex_m_rt_main_trampoline_unsafe\", kind: Function })",
@@ -1138,7 +1138,7 @@
 "#,
             expect![[r#"
                 [
-                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..51, name: \"\", kind: Module })",
+                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..51, name: \"_\", kind: Module })",
                     "(Test, NavigationTarget { file_id: FileId(0), full_range: 1..50, focus_range: 36..45, name: \"test_foo1\", kind: Function }, Atom(KeyValue { key: \"feature\", value: \"foo\" }))",
                 ]
             "#]],
@@ -1157,7 +1157,7 @@
 "#,
             expect![[r#"
                 [
-                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..73, name: \"\", kind: Module })",
+                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..73, name: \"_\", kind: Module })",
                     "(Test, NavigationTarget { file_id: FileId(0), full_range: 1..72, focus_range: 58..67, name: \"test_foo1\", kind: Function }, All([Atom(KeyValue { key: \"feature\", value: \"foo\" }), Atom(KeyValue { key: \"feature\", value: \"bar\" })]))",
                 ]
             "#]],
@@ -1236,7 +1236,7 @@
 "#,
             expect![[r#"
                 [
-                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..345, name: \"\", kind: Module })",
+                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 0..345, name: \"_\", kind: Module })",
                     "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 282..312, focus_range: 286..291, name: \"tests\", kind: Module, description: \"mod tests\" })",
                     "(Test, NavigationTarget { file_id: FileId(0), full_range: 298..307, name: \"foo_test\", kind: Function })",
                     "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 313..323, name: \"tests2\", kind: Module, description: \"mod tests2\" }, true)",
@@ -1679,10 +1679,10 @@
 "#,
             expect![[r#"
                 [
-                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 1..461, focus_range: 5..10, name: \"r#mod\", kind: Module, description: \"mod r#mod\" })",
+                    "(TestMod, NavigationTarget { file_id: FileId(0), full_range: 1..461, focus_range: 5..10, name: \"mod\", kind: Module, description: \"mod r#mod\" })",
                     "(Test, NavigationTarget { file_id: FileId(0), full_range: 17..41, focus_range: 32..36, name: \"r#fn\", kind: Function })",
-                    "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 47..84, name: \"r#for\", container_name: \"r#mod\" })",
-                    "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 90..146, name: \"r#struct\", container_name: \"r#mod\" })",
+                    "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 47..84, name: \"r#for\", container_name: \"mod\" })",
+                    "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 90..146, name: \"r#struct\", container_name: \"mod\" })",
                     "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 152..266, focus_range: 189..205, name: \"impl\", kind: Impl })",
                     "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 216..260, name: \"r#fn\" })",
                     "(DocTest, NavigationTarget { file_id: FileId(0), full_range: 323..367, name: \"r#fn\" })",
diff --git a/crates/intern/src/symbol/symbols.rs b/crates/intern/src/symbol/symbols.rs
index 756377f..5a9d451 100644
--- a/crates/intern/src/symbol/symbols.rs
+++ b/crates/intern/src/symbol/symbols.rs
@@ -85,6 +85,7 @@
     false_ = "false",
     let_ = "let",
     const_ = "const",
+    kw_impl = "impl",
     proc_dash_macro = "proc-macro",
     aapcs_dash_unwind = "aapcs-unwind",
     avr_dash_interrupt = "avr-interrupt",