Skip to content

Commit 9e71dd9

Browse files
committed
Only complete modules in empty use-statements
1 parent 01bfc5f commit 9e71dd9

File tree

3 files changed

+27
-14
lines changed

3 files changed

+27
-14
lines changed

crates/ide_completion/src/completions/unqualified_path.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! Completion of names from the current scope, e.g. locals and imported items.
22
33
use hir::ScopeDef;
4-
use syntax::AstNode;
54

65
use crate::{CompletionContext, Completions};
76

@@ -24,6 +23,15 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
2423
return;
2524
}
2625

26+
if ctx.expects_use_tree() {
27+
cov_mark::hit!(only_completes_modules_in_import);
28+
ctx.scope.process_all_names(&mut |name, res| {
29+
if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
30+
acc.add_resolution(ctx, name.to_string(), &res);
31+
}
32+
});
33+
return;
34+
}
2735
if let Some(hir::Adt::Enum(e)) =
2836
ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
2937
{
@@ -37,14 +45,6 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
3745
cov_mark::hit!(skip_lifetime_completion);
3846
return;
3947
}
40-
if ctx.use_item_syntax.is_some() {
41-
if let (ScopeDef::Unknown, Some(name_ref)) = (&res, &ctx.name_ref_syntax) {
42-
if name_ref.syntax().text() == name.to_string().as_str() {
43-
cov_mark::hit!(self_fulfilling_completion);
44-
return;
45-
}
46-
}
47-
}
4848
acc.add_resolution(ctx, name.to_string(), &res);
4949
});
5050
}
@@ -68,15 +68,17 @@ mod tests {
6868
}
6969

7070
#[test]
71-
fn self_fulfilling_completion() {
72-
cov_mark::check!(self_fulfilling_completion);
71+
fn only_completes_modules_in_import() {
72+
cov_mark::check!(only_completes_modules_in_import);
7373
check(
7474
r#"
75-
use foo$0
76-
use std::collections;
75+
use f$0
76+
77+
struct Foo;
78+
mod foo {}
7779
"#,
7880
expect![[r#"
79-
?? collections
81+
md foo
8082
"#]],
8183
);
8284
}

crates/ide_completion/src/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ impl<'a> CompletionContext<'a> {
276276
)
277277
}
278278

279+
pub(crate) fn expects_use_tree(&self) -> bool {
280+
matches!(self.completion_location, Some(ImmediateLocation::Use))
281+
}
282+
279283
pub(crate) fn expects_non_trait_assoc_item(&self) -> bool {
280284
matches!(self.completion_location, Some(ImmediateLocation::Impl))
281285
}

crates/ide_completion/src/patterns.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use crate::test_utils::{check_pattern_is_applicable, check_pattern_is_not_applic
1414
/// Direct parent container of the cursor position
1515
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1616
pub(crate) enum ImmediateLocation {
17+
Use,
1718
Impl,
1819
Trait,
1920
RecordField,
@@ -58,6 +59,7 @@ pub(crate) fn determine_location(tok: SyntaxToken) -> Option<ImmediateLocation>
5859
let res = match_ast! {
5960
match parent {
6061
ast::IdentPat(_it) => ImmediateLocation::IdentPat,
62+
ast::Use(_it) => ImmediateLocation::Use,
6163
ast::BlockExpr(_it) => ImmediateLocation::BlockExpr,
6264
ast::SourceFile(_it) => ImmediateLocation::ItemList,
6365
ast::ItemList(_it) => ImmediateLocation::ItemList,
@@ -87,6 +89,11 @@ fn test_has_trait_parent() {
8789
check_location(r"trait A { f$0 }", ImmediateLocation::Trait);
8890
}
8991

92+
#[test]
93+
fn test_has_use_parent() {
94+
check_location(r"use f$0", ImmediateLocation::Use);
95+
}
96+
9097
#[test]
9198
fn test_has_impl_parent() {
9299
check_location(r"impl A { f$0 }", ImmediateLocation::Impl);

0 commit comments

Comments
 (0)