From 79614c486b109484d7717c92cf68998f192016c2 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 10 Jul 2021 17:57:33 +0200 Subject: [PATCH] Enable `auto_import` on ident patterns --- .../ide_assists/src/handlers/auto_import.rs | 30 +++++++++++++++++ crates/ide_db/src/helpers/import_assets.rs | 33 ++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs index b220a4ba418..3ecb3d38ea7 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 9634d872e49..58fea3b1de5 100644 --- a/crates/ide_db/src/helpers/import_assets.rs +++ b/crates/ide_db/src/helpers/import_assets.rs @@ -5,7 +5,11 @@ }; 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 @@ pub fn for_exact_path( }) } + 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 @@ fn for_regular_path(sema: &Semantics, path: &ast::Path) -> Option< ) } + 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,