about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2025-01-25 11:12:06 +0100
committerLukas Wirth <lukastw97@gmail.com>2025-01-25 11:12:06 +0100
commit592eceedf50c5e11b6099a413e47dfb906feb269 (patch)
tree268a60aadac534f8d9332f115c5129c08d489906 /src
parent3e6a9330d81dfb0dfbbf0db7831e2760703a80ac (diff)
downloadrust-592eceedf50c5e11b6099a413e47dfb906feb269.tar.gz
rust-592eceedf50c5e11b6099a413e47dfb906feb269.zip
Only collect implicit visibile use symbols if they have renames
Otherwise this will pollute the index too much with unnecessary symbols
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/symbols.rs87
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt33
2 files changed, 72 insertions, 48 deletions
diff --git a/src/tools/rust-analyzer/crates/hir/src/symbols.rs b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
index f379a2d4d65..db6ed8b3e7f 100644
--- a/src/tools/rust-analyzer/crates/hir/src/symbols.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/symbols.rs
@@ -158,24 +158,32 @@ impl<'a> SymbolCollector<'a> {
         // Nested trees are very common, so a cache here will hit a lot.
         let import_child_source_cache = &mut FxHashMap::default();
 
-        let mut push_import = |this: &mut Self, i: ImportId, name: &Name, def: ModuleDefId| {
+        let is_explicit_import = |vis| match vis {
+            Visibility::Public => true,
+            Visibility::Module(_, VisibilityExplicitness::Explicit) => true,
+            Visibility::Module(_, VisibilityExplicitness::Implicit) => false,
+        };
+
+        let mut push_import = |this: &mut Self, i: ImportId, name: &Name, def: ModuleDefId, vis| {
             let source = import_child_source_cache
                 .entry(i.import)
                 .or_insert_with(|| i.import.child_source(this.db.upcast()));
             let Some(use_tree_src) = source.value.get(i.idx) else { return };
-            let Some(name_ptr) = use_tree_src
-                .rename()
-                .and_then(|rename| rename.name())
-                .map(Either::Left)
-                .or_else(|| use_tree_src.path()?.segment()?.name_ref().map(Either::Right))
-                .map(|it| AstPtr::new(&it))
-            else {
+            let rename = use_tree_src.rename().and_then(|rename| rename.name());
+            let name_syntax = match rename {
+                Some(name) => Some(Either::Left(name)),
+                None if is_explicit_import(vis) => {
+                    (|| use_tree_src.path()?.segment()?.name_ref().map(Either::Right))()
+                }
+                None => None,
+            };
+            let Some(name_syntax) = name_syntax else {
                 return;
             };
             let dec_loc = DeclarationLocation {
                 hir_file_id: source.file_id,
                 ptr: SyntaxNodePtr::new(use_tree_src.syntax()),
-                name_ptr,
+                name_ptr: AstPtr::new(&name_syntax),
             };
             this.symbols.insert(FileSymbol {
                 name: name.symbol().clone(),
@@ -188,23 +196,23 @@ impl<'a> SymbolCollector<'a> {
         };
 
         let push_extern_crate =
-            |this: &mut Self, i: ExternCrateId, name: &Name, def: ModuleDefId| {
+            |this: &mut Self, i: ExternCrateId, name: &Name, def: ModuleDefId, vis| {
                 let loc = i.lookup(this.db.upcast());
                 let source = loc.source(this.db.upcast());
-                let Some(name_ptr) = source
-                    .value
-                    .rename()
-                    .and_then(|rename| rename.name())
-                    .map(Either::Left)
-                    .or_else(|| source.value.name_ref().map(Either::Right))
-                    .map(|it| AstPtr::new(&it))
-                else {
+                let rename = source.value.rename().and_then(|rename| rename.name());
+
+                let name_syntax = match rename {
+                    Some(name) => Some(Either::Left(name)),
+                    None if is_explicit_import(vis) => None,
+                    None => source.value.name_ref().map(Either::Right),
+                };
+                let Some(name_syntax) = name_syntax else {
                     return;
                 };
                 let dec_loc = DeclarationLocation {
                     hir_file_id: source.file_id,
                     ptr: SyntaxNodePtr::new(source.value.syntax()),
-                    name_ptr,
+                    name_ptr: AstPtr::new(&name_syntax),
                 };
                 this.symbols.insert(FileSymbol {
                     name: name.symbol().clone(),
@@ -216,18 +224,6 @@ impl<'a> SymbolCollector<'a> {
                 });
             };
 
-        let is_explicit_import = |vis| {
-            match vis {
-                Visibility::Module(_, VisibilityExplicitness::Explicit) => true,
-                Visibility::Module(_, VisibilityExplicitness::Implicit) => {
-                    // consider imports in the crate root explicit, as these are visibly
-                    // crate-wide anyways
-                    module_id.is_crate_root()
-                }
-                Visibility::Public => true,
-            }
-        };
-
         let def_map = module_id.def_map(self.db.upcast());
         let scope = &def_map[module_id.local_id].scope;
 
@@ -237,15 +233,14 @@ impl<'a> SymbolCollector<'a> {
 
         for (name, Item { def, vis, import }) in scope.types() {
             if let Some(i) = import {
-                if is_explicit_import(vis) {
-                    match i {
-                        ImportOrExternCrate::Import(i) => push_import(self, i, name, def),
-                        ImportOrExternCrate::Glob(_) => (),
-                        ImportOrExternCrate::ExternCrate(i) => {
-                            push_extern_crate(self, i, name, def)
-                        }
+                match i {
+                    ImportOrExternCrate::Import(i) => push_import(self, i, name, def, vis),
+                    ImportOrExternCrate::Glob(_) => (),
+                    ImportOrExternCrate::ExternCrate(i) => {
+                        push_extern_crate(self, i, name, def, vis)
                     }
                 }
+
                 continue;
             }
             // self is a declaration
@@ -254,11 +249,9 @@ impl<'a> SymbolCollector<'a> {
 
         for (name, Item { def, vis, import }) in scope.macros() {
             if let Some(i) = import {
-                if is_explicit_import(vis) {
-                    match i {
-                        ImportOrGlob::Import(i) => push_import(self, i, name, def.into()),
-                        ImportOrGlob::Glob(_) => (),
-                    }
+                match i {
+                    ImportOrGlob::Import(i) => push_import(self, i, name, def.into(), vis),
+                    ImportOrGlob::Glob(_) => (),
                 }
                 continue;
             }
@@ -268,11 +261,9 @@ impl<'a> SymbolCollector<'a> {
 
         for (name, Item { def, vis, import }) in scope.values() {
             if let Some(i) = import {
-                if is_explicit_import(vis) {
-                    match i {
-                        ImportOrGlob::Import(i) => push_import(self, i, name, def),
-                        ImportOrGlob::Glob(_) => (),
-                    }
+                match i {
+                    ImportOrGlob::Import(i) => push_import(self, i, name, def, vis),
+                    ImportOrGlob::Glob(_) => (),
                 }
                 continue;
             }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
index 535777dfcbe..7dce95592b8 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
+++ b/src/tools/rust-analyzer/crates/ide-db/src/test_data/test_symbol_index_collection.txt
@@ -1007,6 +1007,39 @@
                 is_alias: false,
                 is_assoc: false,
             },
+            FileSymbol {
+                name: "ThisStruct",
+                def: Adt(
+                    Struct(
+                        Struct {
+                            id: StructId(
+                                4,
+                            ),
+                        },
+                    ),
+                ),
+                loc: DeclarationLocation {
+                    hir_file_id: EditionedFileId(
+                        FileId(
+                            1,
+                        ),
+                        Edition2021,
+                    ),
+                    ptr: SyntaxNodePtr {
+                        kind: USE_TREE,
+                        range: 85..125,
+                    },
+                    name_ptr: AstPtr(
+                        SyntaxNodePtr {
+                            kind: NAME,
+                            range: 115..125,
+                        },
+                    ),
+                },
+                container_name: None,
+                is_alias: false,
+                is_assoc: false,
+            },
         ],
     ),
 ]