aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/semantics.rs2
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs4
-rw-r--r--crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs31
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs11
-rw-r--r--crates/ide_completion/src/lib.rs2
-rw-r--r--crates/ide_db/src/helpers/import_assets.rs47
-rw-r--r--crates/ide_db/src/items_locator.rs2
7 files changed, 49 insertions, 50 deletions
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 69370ef3d..945638cc5 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -774,7 +774,7 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode {
774/// 774///
775/// Note that if you are wondering "what does this specific existing name mean?", 775/// Note that if you are wondering "what does this specific existing name mean?",
776/// you'd better use the `resolve_` family of methods. 776/// you'd better use the `resolve_` family of methods.
777#[derive(Debug, Clone)] 777#[derive(Debug)]
778pub struct SemanticsScope<'a> { 778pub struct SemanticsScope<'a> {
779 pub db: &'a dyn HirDatabase, 779 pub db: &'a dyn HirDatabase,
780 file_id: HirFileId, 780 file_id: HirFileId,
diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs
index eb8d35e95..5546c3a4e 100644
--- a/crates/ide_assists/src/handlers/auto_import.rs
+++ b/crates/ide_assists/src/handlers/auto_import.rs
@@ -112,9 +112,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
112 Some(()) 112 Some(())
113} 113}
114 114
115pub(super) fn find_importable_node<'a>( 115pub(super) fn find_importable_node(ctx: &AssistContext) -> Option<(ImportAssets, SyntaxNode)> {
116 ctx: &'a AssistContext,
117) -> Option<(ImportAssets<'a>, SyntaxNode)> {
118 if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() { 116 if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::<ast::Path>() {
119 ImportAssets::for_exact_path(&path_under_caret, &ctx.sema) 117 ImportAssets::for_exact_path(&path_under_caret, &ctx.sema)
120 .zip(Some(path_under_caret.syntax().clone())) 118 .zip(Some(path_under_caret.syntax().clone()))
diff --git a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
index 93a03e8b2..88fe2fe90 100644
--- a/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
+++ b/crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs
@@ -65,23 +65,20 @@ pub(crate) fn replace_derive_with_manual_impl(
65 let current_module = ctx.sema.scope(annotated_name.syntax()).module()?; 65 let current_module = ctx.sema.scope(annotated_name.syntax()).module()?;
66 let current_crate = current_module.krate(); 66 let current_crate = current_module.krate();
67 67
68 let found_traits = items_locator::with_for_exact_name( 68 let found_traits =
69 &ctx.sema, 69 items_locator::with_exact_name(&ctx.sema, current_crate, trait_token.text().to_string())
70 current_crate, 70 .into_iter()
71 trait_token.text().to_string(), 71 .filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) {
72 ) 72 ModuleDef::Trait(trait_) => Some(trait_),
73 .into_iter() 73 _ => None,
74 .filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) { 74 })
75 ModuleDef::Trait(trait_) => Some(trait_), 75 .flat_map(|trait_| {
76 _ => None, 76 current_module
77 }) 77 .find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_))
78 .flat_map(|trait_| { 78 .as_ref()
79 current_module 79 .map(mod_path_to_ast)
80 .find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_)) 80 .zip(Some(trait_))
81 .as_ref() 81 });
82 .map(mod_path_to_ast)
83 .zip(Some(trait_))
84 });
85 82
86 let mut no_traits_found = true; 83 let mut no_traits_found = true;
87 for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) { 84 for (trait_path, trait_) in found_traits.inspect(|_| no_traits_found = false) {
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs
index 8a11cba41..391a11c91 100644
--- a/crates/ide_completion/src/completions/flyimport.rs
+++ b/crates/ide_completion/src/completions/flyimport.rs
@@ -169,23 +169,28 @@ pub(crate) fn position_for_import<'a>(
169 }) 169 })
170} 170}
171 171
172fn import_assets<'a>(ctx: &'a CompletionContext, fuzzy_name: String) -> Option<ImportAssets<'a>> { 172fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option<ImportAssets> {
173 let current_module = ctx.scope.module()?; 173 let current_module = ctx.scope.module()?;
174 if let Some(dot_receiver) = &ctx.dot_receiver { 174 if let Some(dot_receiver) = &ctx.dot_receiver {
175 ImportAssets::for_fuzzy_method_call( 175 ImportAssets::for_fuzzy_method_call(
176 current_module, 176 current_module,
177 ctx.sema.type_of_expr(dot_receiver)?, 177 ctx.sema.type_of_expr(dot_receiver)?,
178 fuzzy_name, 178 fuzzy_name,
179 ctx.scope.clone(), 179 dot_receiver.syntax().clone(),
180 ) 180 )
181 } else { 181 } else {
182 let fuzzy_name_length = fuzzy_name.len(); 182 let fuzzy_name_length = fuzzy_name.len();
183 let approximate_node = match current_module.definition_source(ctx.db).value {
184 hir::ModuleSource::SourceFile(s) => s.syntax().clone(),
185 hir::ModuleSource::Module(m) => m.syntax().clone(),
186 hir::ModuleSource::BlockExpr(b) => b.syntax().clone(),
187 };
183 let assets_for_path = ImportAssets::for_fuzzy_path( 188 let assets_for_path = ImportAssets::for_fuzzy_path(
184 current_module, 189 current_module,
185 ctx.path_qual.clone(), 190 ctx.path_qual.clone(),
186 fuzzy_name, 191 fuzzy_name,
187 &ctx.sema, 192 &ctx.sema,
188 ctx.scope.clone(), 193 approximate_node,
189 )?; 194 )?;
190 195
191 if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_)) 196 if matches!(assets_for_path.import_candidate(), ImportCandidate::Path(_))
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index 5470914fb..a0c8c374d 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -150,7 +150,7 @@ pub fn resolve_completion_edits(
150 let current_crate = current_module.krate(); 150 let current_crate = current_module.krate();
151 151
152 let (import_path, item_to_import) = 152 let (import_path, item_to_import) =
153 items_locator::with_for_exact_name(&ctx.sema, current_crate, imported_name) 153 items_locator::with_exact_name(&ctx.sema, current_crate, imported_name)
154 .into_iter() 154 .into_iter()
155 .filter_map(|candidate| { 155 .filter_map(|candidate| {
156 current_module 156 current_module
diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs
index 9bdc93877..f2866af13 100644
--- a/crates/ide_db/src/helpers/import_assets.rs
+++ b/crates/ide_db/src/helpers/import_assets.rs
@@ -1,11 +1,11 @@
1//! Look up accessible paths for items. 1//! Look up accessible paths for items.
2use hir::{ 2use hir::{
3 AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module, 3 AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module,
4 ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Type, 4 ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, Type,
5}; 5};
6use itertools::Itertools; 6use itertools::Itertools;
7use rustc_hash::FxHashSet; 7use rustc_hash::FxHashSet;
8use syntax::{ast, AstNode}; 8use syntax::{ast, AstNode, SyntaxNode};
9 9
10use crate::{ 10use crate::{
11 items_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT}, 11 items_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT},
@@ -62,38 +62,37 @@ impl NameToImport {
62} 62}
63 63
64#[derive(Debug)] 64#[derive(Debug)]
65pub struct ImportAssets<'a> { 65pub struct ImportAssets {
66 import_candidate: ImportCandidate, 66 import_candidate: ImportCandidate,
67 candidate_node: SyntaxNode,
67 module_with_candidate: Module, 68 module_with_candidate: Module,
68 scope: SemanticsScope<'a>,
69} 69}
70 70
71impl<'a> ImportAssets<'a> { 71impl ImportAssets {
72 pub fn for_method_call( 72 pub fn for_method_call(
73 method_call: &ast::MethodCallExpr, 73 method_call: &ast::MethodCallExpr,
74 sema: &'a Semantics<RootDatabase>, 74 sema: &Semantics<RootDatabase>,
75 ) -> Option<Self> { 75 ) -> Option<Self> {
76 let scope = sema.scope(method_call.syntax()); 76 let candidate_node = method_call.syntax().clone();
77 Some(Self { 77 Some(Self {
78 import_candidate: ImportCandidate::for_method_call(sema, method_call)?, 78 import_candidate: ImportCandidate::for_method_call(sema, method_call)?,
79 module_with_candidate: scope.module()?, 79 module_with_candidate: sema.scope(&candidate_node).module()?,
80 scope, 80 candidate_node,
81 }) 81 })
82 } 82 }
83 83
84 pub fn for_exact_path( 84 pub fn for_exact_path(
85 fully_qualified_path: &ast::Path, 85 fully_qualified_path: &ast::Path,
86 sema: &'a Semantics<RootDatabase>, 86 sema: &Semantics<RootDatabase>,
87 ) -> Option<Self> { 87 ) -> Option<Self> {
88 let syntax_under_caret = fully_qualified_path.syntax(); 88 let candidate_node = fully_qualified_path.syntax().clone();
89 if syntax_under_caret.ancestors().find_map(ast::Use::cast).is_some() { 89 if candidate_node.ancestors().find_map(ast::Use::cast).is_some() {
90 return None; 90 return None;
91 } 91 }
92 let scope = sema.scope(syntax_under_caret);
93 Some(Self { 92 Some(Self {
94 import_candidate: ImportCandidate::for_regular_path(sema, fully_qualified_path)?, 93 import_candidate: ImportCandidate::for_regular_path(sema, fully_qualified_path)?,
95 module_with_candidate: scope.module()?, 94 module_with_candidate: sema.scope(&candidate_node).module()?,
96 scope, 95 candidate_node,
97 }) 96 })
98 } 97 }
99 98
@@ -102,12 +101,12 @@ impl<'a> ImportAssets<'a> {
102 qualifier: Option<ast::Path>, 101 qualifier: Option<ast::Path>,
103 fuzzy_name: String, 102 fuzzy_name: String,
104 sema: &Semantics<RootDatabase>, 103 sema: &Semantics<RootDatabase>,
105 scope: SemanticsScope<'a>, 104 candidate_node: SyntaxNode,
106 ) -> Option<Self> { 105 ) -> Option<Self> {
107 Some(Self { 106 Some(Self {
108 import_candidate: ImportCandidate::for_fuzzy_path(qualifier, fuzzy_name, sema)?, 107 import_candidate: ImportCandidate::for_fuzzy_path(qualifier, fuzzy_name, sema)?,
109 module_with_candidate, 108 module_with_candidate,
110 scope, 109 candidate_node,
111 }) 110 })
112 } 111 }
113 112
@@ -115,7 +114,7 @@ impl<'a> ImportAssets<'a> {
115 module_with_method_call: Module, 114 module_with_method_call: Module,
116 receiver_ty: Type, 115 receiver_ty: Type,
117 fuzzy_method_name: String, 116 fuzzy_method_name: String,
118 scope: SemanticsScope<'a>, 117 candidate_node: SyntaxNode,
119 ) -> Option<Self> { 118 ) -> Option<Self> {
120 Some(Self { 119 Some(Self {
121 import_candidate: ImportCandidate::TraitMethod(TraitImportCandidate { 120 import_candidate: ImportCandidate::TraitMethod(TraitImportCandidate {
@@ -123,7 +122,7 @@ impl<'a> ImportAssets<'a> {
123 name: NameToImport::Fuzzy(fuzzy_method_name), 122 name: NameToImport::Fuzzy(fuzzy_method_name),
124 }), 123 }),
125 module_with_candidate: module_with_method_call, 124 module_with_candidate: module_with_method_call,
126 scope, 125 candidate_node,
127 }) 126 })
128 } 127 }
129} 128}
@@ -156,7 +155,7 @@ impl LocatedImport {
156 } 155 }
157} 156}
158 157
159impl<'a> ImportAssets<'a> { 158impl ImportAssets {
160 pub fn import_candidate(&self) -> &ImportCandidate { 159 pub fn import_candidate(&self) -> &ImportCandidate {
161 &self.import_candidate 160 &self.import_candidate
162 } 161 }
@@ -182,7 +181,7 @@ impl<'a> ImportAssets<'a> {
182 prefixed: Option<PrefixKind>, 181 prefixed: Option<PrefixKind>,
183 ) -> Vec<LocatedImport> { 182 ) -> Vec<LocatedImport> {
184 let items_with_candidate_name = match self.name_to_import() { 183 let items_with_candidate_name = match self.name_to_import() {
185 NameToImport::Exact(exact_name) => items_locator::with_for_exact_name( 184 NameToImport::Exact(exact_name) => items_locator::with_exact_name(
186 sema, 185 sema,
187 self.module_with_candidate.krate(), 186 self.module_with_candidate.krate(),
188 exact_name.clone(), 187 exact_name.clone(),
@@ -209,7 +208,7 @@ impl<'a> ImportAssets<'a> {
209 } 208 }
210 }; 209 };
211 210
212 let scope_definitions = self.scope_definitions(); 211 let scope_definitions = self.scope_definitions(sema);
213 self.applicable_defs(sema.db, prefixed, items_with_candidate_name) 212 self.applicable_defs(sema.db, prefixed, items_with_candidate_name)
214 .into_iter() 213 .into_iter()
215 .filter(|import| import.import_path.len() > 1) 214 .filter(|import| import.import_path.len() > 1)
@@ -218,9 +217,9 @@ impl<'a> ImportAssets<'a> {
218 .collect() 217 .collect()
219 } 218 }
220 219
221 fn scope_definitions(&self) -> FxHashSet<ScopeDef> { 220 fn scope_definitions(&self, sema: &Semantics<RootDatabase>) -> FxHashSet<ScopeDef> {
222 let mut scope_definitions = FxHashSet::default(); 221 let mut scope_definitions = FxHashSet::default();
223 self.scope.process_all_names(&mut |_, scope_def| { 222 sema.scope(&self.candidate_node).process_all_names(&mut |_, scope_def| {
224 scope_definitions.insert(scope_def); 223 scope_definitions.insert(scope_def);
225 }); 224 });
226 scope_definitions 225 scope_definitions
diff --git a/crates/ide_db/src/items_locator.rs b/crates/ide_db/src/items_locator.rs
index b81c14618..8a7f02935 100644
--- a/crates/ide_db/src/items_locator.rs
+++ b/crates/ide_db/src/items_locator.rs
@@ -17,7 +17,7 @@ use rustc_hash::FxHashSet;
17 17
18pub(crate) const DEFAULT_QUERY_SEARCH_LIMIT: usize = 40; 18pub(crate) const DEFAULT_QUERY_SEARCH_LIMIT: usize = 40;
19 19
20pub fn with_for_exact_name( 20pub fn with_exact_name(
21 sema: &Semantics<'_, RootDatabase>, 21 sema: &Semantics<'_, RootDatabase>,
22 krate: Crate, 22 krate: Crate,
23 exact_name: String, 23 exact_name: String,