diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 69370ef3d8..945638cc56 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -774,7 +774,7 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode { /// /// Note that if you are wondering "what does this specific existing name mean?", /// you'd better use the `resolve_` family of methods. -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct SemanticsScope<'a> { pub db: &'a dyn HirDatabase, file_id: HirFileId, diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs index eb8d35e957..5546c3a4e1 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<()> Some(()) } -pub(super) fn find_importable_node<'a>( - ctx: &'a AssistContext, -) -> Option<(ImportAssets<'a>, SyntaxNode)> { +pub(super) fn find_importable_node(ctx: &AssistContext) -> Option<(ImportAssets, SyntaxNode)> { if let Some(path_under_caret) = ctx.find_node_at_offset_with_descend::() { ImportAssets::for_exact_path(&path_under_caret, &ctx.sema) .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 93a03e8b25..88fe2fe904 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( let current_module = ctx.sema.scope(annotated_name.syntax()).module()?; let current_crate = current_module.krate(); - let found_traits = items_locator::with_for_exact_name( - &ctx.sema, - current_crate, - trait_token.text().to_string(), - ) - .into_iter() - .filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) { - ModuleDef::Trait(trait_) => Some(trait_), - _ => None, - }) - .flat_map(|trait_| { - current_module - .find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_)) - .as_ref() - .map(mod_path_to_ast) - .zip(Some(trait_)) - }); + let found_traits = + items_locator::with_exact_name(&ctx.sema, current_crate, trait_token.text().to_string()) + .into_iter() + .filter_map(|item| match ModuleDef::from(item.as_module_def_id()?) { + ModuleDef::Trait(trait_) => Some(trait_), + _ => None, + }) + .flat_map(|trait_| { + current_module + .find_use_path(ctx.sema.db, hir::ModuleDef::Trait(trait_)) + .as_ref() + .map(mod_path_to_ast) + .zip(Some(trait_)) + }); let mut no_traits_found = true; 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 8a11cba411..391a11c91c 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>( }) } -fn import_assets<'a>(ctx: &'a CompletionContext, fuzzy_name: String) -> Option> { +fn import_assets(ctx: &CompletionContext, fuzzy_name: String) -> Option { let current_module = ctx.scope.module()?; if let Some(dot_receiver) = &ctx.dot_receiver { ImportAssets::for_fuzzy_method_call( current_module, ctx.sema.type_of_expr(dot_receiver)?, fuzzy_name, - ctx.scope.clone(), + dot_receiver.syntax().clone(), ) } else { let fuzzy_name_length = fuzzy_name.len(); + let approximate_node = match current_module.definition_source(ctx.db).value { + hir::ModuleSource::SourceFile(s) => s.syntax().clone(), + hir::ModuleSource::Module(m) => m.syntax().clone(), + hir::ModuleSource::BlockExpr(b) => b.syntax().clone(), + }; let assets_for_path = ImportAssets::for_fuzzy_path( current_module, ctx.path_qual.clone(), fuzzy_name, &ctx.sema, - ctx.scope.clone(), + approximate_node, )?; 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 5470914fbf..a0c8c374d0 100644 --- a/crates/ide_completion/src/lib.rs +++ b/crates/ide_completion/src/lib.rs @@ -150,7 +150,7 @@ pub fn resolve_completion_edits( let current_crate = current_module.krate(); let (import_path, item_to_import) = - items_locator::with_for_exact_name(&ctx.sema, current_crate, imported_name) + items_locator::with_exact_name(&ctx.sema, current_crate, imported_name) .into_iter() .filter_map(|candidate| { current_module diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs index 9bdc938774..f2866af136 100644 --- a/crates/ide_db/src/helpers/import_assets.rs +++ b/crates/ide_db/src/helpers/import_assets.rs @@ -1,11 +1,11 @@ //! Look up accessible paths for items. use hir::{ AsAssocItem, AssocItem, AssocItemContainer, Crate, ItemInNs, MacroDef, ModPath, Module, - ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, SemanticsScope, Type, + ModuleDef, Name, PathResolution, PrefixKind, ScopeDef, Semantics, Type, }; use itertools::Itertools; use rustc_hash::FxHashSet; -use syntax::{ast, AstNode}; +use syntax::{ast, AstNode, SyntaxNode}; use crate::{ items_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT}, @@ -62,38 +62,37 @@ impl NameToImport { } #[derive(Debug)] -pub struct ImportAssets<'a> { +pub struct ImportAssets { import_candidate: ImportCandidate, + candidate_node: SyntaxNode, module_with_candidate: Module, - scope: SemanticsScope<'a>, } -impl<'a> ImportAssets<'a> { +impl ImportAssets { pub fn for_method_call( method_call: &ast::MethodCallExpr, - sema: &'a Semantics, + sema: &Semantics, ) -> Option { - let scope = sema.scope(method_call.syntax()); + let candidate_node = method_call.syntax().clone(); Some(Self { import_candidate: ImportCandidate::for_method_call(sema, method_call)?, - module_with_candidate: scope.module()?, - scope, + module_with_candidate: sema.scope(&candidate_node).module()?, + candidate_node, }) } pub fn for_exact_path( fully_qualified_path: &ast::Path, - sema: &'a Semantics, + sema: &Semantics, ) -> Option { - let syntax_under_caret = fully_qualified_path.syntax(); - if syntax_under_caret.ancestors().find_map(ast::Use::cast).is_some() { + let candidate_node = fully_qualified_path.syntax().clone(); + if candidate_node.ancestors().find_map(ast::Use::cast).is_some() { return None; } - let scope = sema.scope(syntax_under_caret); Some(Self { import_candidate: ImportCandidate::for_regular_path(sema, fully_qualified_path)?, - module_with_candidate: scope.module()?, - scope, + module_with_candidate: sema.scope(&candidate_node).module()?, + candidate_node, }) } @@ -102,12 +101,12 @@ impl<'a> ImportAssets<'a> { qualifier: Option, fuzzy_name: String, sema: &Semantics, - scope: SemanticsScope<'a>, + candidate_node: SyntaxNode, ) -> Option { Some(Self { import_candidate: ImportCandidate::for_fuzzy_path(qualifier, fuzzy_name, sema)?, module_with_candidate, - scope, + candidate_node, }) } @@ -115,7 +114,7 @@ impl<'a> ImportAssets<'a> { module_with_method_call: Module, receiver_ty: Type, fuzzy_method_name: String, - scope: SemanticsScope<'a>, + candidate_node: SyntaxNode, ) -> Option { Some(Self { import_candidate: ImportCandidate::TraitMethod(TraitImportCandidate { @@ -123,7 +122,7 @@ impl<'a> ImportAssets<'a> { name: NameToImport::Fuzzy(fuzzy_method_name), }), module_with_candidate: module_with_method_call, - scope, + candidate_node, }) } } @@ -156,7 +155,7 @@ impl LocatedImport { } } -impl<'a> ImportAssets<'a> { +impl ImportAssets { pub fn import_candidate(&self) -> &ImportCandidate { &self.import_candidate } @@ -182,7 +181,7 @@ impl<'a> ImportAssets<'a> { prefixed: Option, ) -> Vec { let items_with_candidate_name = match self.name_to_import() { - NameToImport::Exact(exact_name) => items_locator::with_for_exact_name( + NameToImport::Exact(exact_name) => items_locator::with_exact_name( sema, self.module_with_candidate.krate(), exact_name.clone(), @@ -209,7 +208,7 @@ impl<'a> ImportAssets<'a> { } }; - let scope_definitions = self.scope_definitions(); + let scope_definitions = self.scope_definitions(sema); self.applicable_defs(sema.db, prefixed, items_with_candidate_name) .into_iter() .filter(|import| import.import_path.len() > 1) @@ -218,9 +217,9 @@ impl<'a> ImportAssets<'a> { .collect() } - fn scope_definitions(&self) -> FxHashSet { + fn scope_definitions(&self, sema: &Semantics) -> FxHashSet { let mut scope_definitions = FxHashSet::default(); - self.scope.process_all_names(&mut |_, scope_def| { + sema.scope(&self.candidate_node).process_all_names(&mut |_, scope_def| { scope_definitions.insert(scope_def); }); scope_definitions diff --git a/crates/ide_db/src/items_locator.rs b/crates/ide_db/src/items_locator.rs index b81c14618a..8a7f029353 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; pub(crate) const DEFAULT_QUERY_SEARCH_LIMIT: usize = 40; -pub fn with_for_exact_name( +pub fn with_exact_name( sema: &Semantics<'_, RootDatabase>, krate: Crate, exact_name: String,