diff options
-rw-r--r-- | crates/hir/src/semantics.rs | 2 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/auto_import.rs | 4 | ||||
-rw-r--r-- | crates/ide_assists/src/handlers/replace_derive_with_manual_impl.rs | 31 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/flyimport.rs | 11 | ||||
-rw-r--r-- | crates/ide_completion/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ide_db/src/helpers/import_assets.rs | 47 | ||||
-rw-r--r-- | crates/ide_db/src/items_locator.rs | 2 |
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)] |
778 | pub struct SemanticsScope<'a> { | 778 | pub 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 | ||
115 | pub(super) fn find_importable_node<'a>( | 115 | pub(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 | ||
172 | fn import_assets<'a>(ctx: &'a CompletionContext, fuzzy_name: String) -> Option<ImportAssets<'a>> { | 172 | fn 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. |
2 | use hir::{ | 2 | use 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 | }; |
6 | use itertools::Itertools; | 6 | use itertools::Itertools; |
7 | use rustc_hash::FxHashSet; | 7 | use rustc_hash::FxHashSet; |
8 | use syntax::{ast, AstNode}; | 8 | use syntax::{ast, AstNode, SyntaxNode}; |
9 | 9 | ||
10 | use crate::{ | 10 | use 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)] |
65 | pub struct ImportAssets<'a> { | 65 | pub 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 | ||
71 | impl<'a> ImportAssets<'a> { | 71 | impl 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 | ||
159 | impl<'a> ImportAssets<'a> { | 158 | impl 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 | ||
18 | pub(crate) const DEFAULT_QUERY_SEARCH_LIMIT: usize = 40; | 18 | pub(crate) const DEFAULT_QUERY_SEARCH_LIMIT: usize = 40; |
19 | 19 | ||
20 | pub fn with_for_exact_name( | 20 | pub 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, |