about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyan Mehri <rmehri01@pm.me>2025-09-08 11:12:57 -0400
committerRyan Mehri <rmehri01@pm.me>2025-09-08 11:16:11 -0400
commitbb5b153b7bccab4347d1a4deead6dcc9ca400a34 (patch)
treee5798d008aa032a5b8eed98f2b3791e0b91980c2
parent3b7313b4d424e26a5c82162dd6a7342c2d947186 (diff)
downloadrust-bb5b153b7bccab4347d1a4deead6dcc9ca400a34.tar.gz
rust-bb5b153b7bccab4347d1a4deead6dcc9ca400a34.zip
feat: support navigation on primitives
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/defs.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/goto_definition.rs27
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs15
3 files changed, 27 insertions, 17 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
index 61a21ccf2f7..43d4611b18a 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/defs.rs
@@ -363,7 +363,7 @@ impl Definition {
     }
 }
 
-fn find_std_module(
+pub fn find_std_module(
     famous_defs: &FamousDefs<'_, '_>,
     name: &str,
     edition: Edition,
diff --git a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
index f768d4b68f4..002f5b3fe8f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/goto_definition.rs
@@ -6,12 +6,13 @@ use crate::{
     navigation_target::{self, ToNav},
 };
 use hir::{
-    AsAssocItem, AssocItem, CallableKind, FileRange, HasCrate, InFile, ModuleDef, Semantics, sym,
+    AsAssocItem, AssocItem, CallableKind, FileRange, HasCrate, InFile, ModuleDef, PathResolution,
+    Semantics, sym,
 };
 use ide_db::{
     RootDatabase, SymbolKind,
     base_db::{AnchoredPath, SourceDatabase},
-    defs::{Definition, IdentClass},
+    defs::{Definition, IdentClass, find_std_module},
     famous_defs::FamousDefs,
     helpers::pick_best_token,
 };
@@ -90,6 +91,9 @@ pub(crate) fn goto_definition(
             if let Some(navs) = find_definition_for_known_blanket_dual_impls(sema, &token.value) {
                 return Some(navs);
             }
+            if let Some(navs) = find_definition_for_builtin_types(sema, &token.value, edition) {
+                return Some(navs);
+            }
 
             let parent = token.value.parent()?;
 
@@ -204,6 +208,25 @@ fn find_definition_for_known_blanket_dual_impls(
     Some(def_to_nav(sema.db, def))
 }
 
+// If the token is a builtin type search the definition from the rustdoc module shims.
+fn find_definition_for_builtin_types(
+    sema: &Semantics<'_, RootDatabase>,
+    original_token: &SyntaxToken,
+    edition: Edition,
+) -> Option<Vec<NavigationTarget>> {
+    let path = original_token.parent_ancestors().find_map(ast::Path::cast)?;
+    let res = sema.resolve_path(&path)?;
+    let PathResolution::Def(ModuleDef::BuiltinType(builtin)) = res else {
+        return None;
+    };
+
+    let fd = FamousDefs(sema, sema.scope(path.syntax())?.krate());
+    let primitive_mod = format!("prim_{}", builtin.name().display(fd.0.db, edition));
+    let doc_owner = find_std_module(&fd, &primitive_mod, edition)?;
+
+    Some(def_to_nav(sema.db, doc_owner.into()))
+}
+
 fn try_lookup_include_path(
     sema: &Semantics<'_, RootDatabase>,
     token: InFile<ast::String>,
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index 290ee80984e..2adafbb7af6 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -10,7 +10,7 @@ use hir::{
 };
 use ide_db::{
     RootDatabase,
-    defs::Definition,
+    defs::{Definition, find_std_module},
     documentation::{DocsRangeMap, HasDocs},
     famous_defs::FamousDefs,
     generated::lints::{CLIPPY_LINTS, DEFAULT_LINTS, FEATURES},
@@ -1160,19 +1160,6 @@ fn markup(
     }
 }
 
-fn find_std_module(
-    famous_defs: &FamousDefs<'_, '_>,
-    name: &str,
-    edition: Edition,
-) -> Option<hir::Module> {
-    let db = famous_defs.0.db;
-    let std_crate = famous_defs.std()?;
-    let std_root_module = std_crate.root_module();
-    std_root_module.children(db).find(|module| {
-        module.name(db).is_some_and(|module| module.display(db, edition).to_string() == name)
-    })
-}
-
 fn render_memory_layout(
     config: Option<MemoryLayoutHoverConfig>,
     layout: impl FnOnce() -> Result<Layout, LayoutError>,