diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs index b220a4ba4183..3ecb3d38ea72 100644 --- a/crates/ide_assists/src/handlers/auto_import.rs +++ b/crates/ide_assists/src/handlers/auto_import.rs @@ -123,6 +123,11 @@ pub(super) fn find_importable_node(ctx: &AssistContext) -> Option<(ImportAssets, { ImportAssets::for_method_call(&method_under_caret, &ctx.sema) .zip(Some(method_under_caret.syntax().clone())) + } else if let Some(pat) = ctx + .find_node_at_offset_with_descend::() + .filter(ast::IdentPat::is_simple_ident) + { + ImportAssets::for_ident_pat(&pat, &ctx.sema).zip(Some(pat.syntax().clone())) } else { None } @@ -995,6 +1000,31 @@ mod foo {} const _: () = { Foo }; +"#, + ); + } + + #[test] + fn works_on_ident_patterns() { + check_assist( + auto_import, + r#" +mod foo { + pub struct Foo {} +} +fn foo() { + let Foo$0; +} +"#, + r#" +use foo::Foo; + +mod foo { + pub struct Foo {} +} +fn foo() { + let Foo; +} "#, ); } diff --git a/crates/ide_db/src/helpers/import_assets.rs b/crates/ide_db/src/helpers/import_assets.rs index 9634d872e49c..58fea3b1de5a 100644 --- a/crates/ide_db/src/helpers/import_assets.rs +++ b/crates/ide_db/src/helpers/import_assets.rs @@ -5,7 +5,11 @@ use hir::{ }; use itertools::Itertools; use rustc_hash::FxHashSet; -use syntax::{ast, utils::path_to_string_stripping_turbo_fish, AstNode, SyntaxNode}; +use syntax::{ + ast::{self, NameOwner}, + utils::path_to_string_stripping_turbo_fish, + AstNode, SyntaxNode, +}; use crate::{ items_locator::{self, AssocItemSearch, DEFAULT_QUERY_SEARCH_LIMIT}, @@ -115,6 +119,19 @@ impl ImportAssets { }) } + pub fn for_ident_pat(pat: &ast::IdentPat, sema: &Semantics) -> Option { + let name = pat.name()?; + let candidate_node = pat.syntax().clone(); + if !pat.is_simple_ident() { + return None; + } + Some(Self { + import_candidate: ImportCandidate::for_name(sema, &name)?, + module_with_candidate: sema.scope(&candidate_node).module()?, + candidate_node, + }) + } + pub fn for_fuzzy_path( module_with_candidate: Module, qualifier: Option, @@ -543,6 +560,20 @@ impl ImportCandidate { ) } + fn for_name(sema: &Semantics, name: &ast::Name) -> Option { + if sema + .scope(name.syntax()) + .speculative_resolve(&ast::make::ext::ident_path(&name.text())) + .is_some() + { + return None; + } + Some(ImportCandidate::Path(PathImportCandidate { + qualifier: None, + name: NameToImport::Exact(name.to_string()), + })) + } + fn for_fuzzy_path( qualifier: Option, fuzzy_name: String,