Skip to content

Commit 1b9b13b

Browse files
Merge #3068
3068: Do not import anything if first segment of the qualified path resolves r=matklad a=SomeoneToIgnore Part of initial #3061, closing 2nd issue mentioned in the last comment there. Co-authored-by: Kirill Bulatov <[email protected]>
2 parents 360890f + d39d401 commit 1b9b13b

File tree

1 file changed

+37
-13
lines changed

1 file changed

+37
-13
lines changed

crates/ra_assists/src/handlers/auto_import.rs

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,31 +27,34 @@ use std::collections::BTreeSet;
2727
// # pub mod std { pub mod collections { pub struct HashMap { } } }
2828
// ```
2929
pub(crate) fn auto_import(ctx: AssistCtx) -> Option<Assist> {
30-
let path_to_import: ast::Path = ctx.find_node_at_offset()?;
31-
let path_to_import_syntax = path_to_import.syntax();
32-
if path_to_import_syntax.ancestors().find_map(ast::UseItem::cast).is_some() {
30+
let path_under_caret: ast::Path = ctx.find_node_at_offset()?;
31+
if path_under_caret.syntax().ancestors().find_map(ast::UseItem::cast).is_some() {
3332
return None;
3433
}
35-
let name_to_import =
36-
path_to_import_syntax.descendants().find_map(ast::NameRef::cast)?.syntax().to_string();
3734

38-
let module = path_to_import_syntax.ancestors().find_map(ast::Module::cast);
35+
let module = path_under_caret.syntax().ancestors().find_map(ast::Module::cast);
3936
let position = match module.and_then(|it| it.item_list()) {
4037
Some(item_list) => item_list.syntax().clone(),
4138
None => {
42-
let current_file = path_to_import_syntax.ancestors().find_map(ast::SourceFile::cast)?;
39+
let current_file =
40+
path_under_caret.syntax().ancestors().find_map(ast::SourceFile::cast)?;
4341
current_file.syntax().clone()
4442
}
4543
};
4644
let source_analyzer = ctx.source_analyzer(&position, None);
4745
let module_with_name_to_import = source_analyzer.module()?;
48-
if source_analyzer.resolve_path(ctx.db, &path_to_import).is_some() {
46+
47+
let name_ref_to_import =
48+
path_under_caret.syntax().descendants().find_map(ast::NameRef::cast)?;
49+
if source_analyzer
50+
.resolve_path(ctx.db, &name_ref_to_import.syntax().ancestors().find_map(ast::Path::cast)?)
51+
.is_some()
52+
{
4953
return None;
5054
}
5155

52-
let mut imports_locator = ImportsLocator::new(ctx.db);
53-
54-
let proposed_imports = imports_locator
56+
let name_to_import = name_ref_to_import.syntax().to_string();
57+
let proposed_imports = ImportsLocator::new(ctx.db)
5558
.find_imports(&name_to_import)
5659
.into_iter()
5760
.filter_map(|module_def| module_with_name_to_import.find_use_path(ctx.db, module_def))
@@ -66,10 +69,10 @@ pub(crate) fn auto_import(ctx: AssistCtx) -> Option<Assist> {
6669
let mut group = ctx.add_assist_group(format!("Import {}", name_to_import));
6770
for import in proposed_imports {
6871
group.add_assist(AssistId("auto_import"), format!("Import `{}`", &import), |edit| {
69-
edit.target(path_to_import_syntax.text_range());
72+
edit.target(path_under_caret.syntax().text_range());
7073
insert_use_statement(
7174
&position,
72-
path_to_import_syntax,
75+
path_under_caret.syntax(),
7376
&import,
7477
edit.text_edit_builder(),
7578
);
@@ -266,4 +269,25 @@ mod tests {
266269
"GroupLabel",
267270
)
268271
}
272+
273+
#[test]
274+
fn not_applicable_when_path_start_is_imported() {
275+
check_assist_not_applicable(
276+
auto_import,
277+
r"
278+
pub mod mod1 {
279+
pub mod mod2 {
280+
pub mod mod3 {
281+
pub struct TestStruct;
282+
}
283+
}
284+
}
285+
286+
use mod1::mod2;
287+
fn main() {
288+
mod2::mod3::TestStruct<|>
289+
}
290+
",
291+
);
292+
}
269293
}

0 commit comments

Comments
 (0)