Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-completion/src/completions.rs1
-rw-r--r--crates/ide-completion/src/completions/item_list.rs48
-rw-r--r--crates/ide-completion/src/completions/keyword.rs2
-rw-r--r--crates/ide-completion/src/completions/pattern.rs5
-rw-r--r--crates/ide-completion/src/completions/qualified_path.rs19
-rw-r--r--crates/ide-completion/src/completions/snippet.rs2
-rw-r--r--crates/ide-completion/src/completions/trait_impl.rs7
-rw-r--r--crates/ide-completion/src/completions/unqualified_path.rs17
-rw-r--r--crates/ide-completion/src/context.rs7
-rw-r--r--crates/ide-completion/src/lib.rs1
-rw-r--r--crates/ide-completion/src/tests/item.rs12
-rw-r--r--crates/ide-completion/src/tests/item_list.rs30
-rw-r--r--crates/ide-completion/src/tests/pattern.rs14
13 files changed, 97 insertions, 68 deletions
diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs
index 36cee48aed..f8b1ff7310 100644
--- a/crates/ide-completion/src/completions.rs
+++ b/crates/ide-completion/src/completions.rs
@@ -6,6 +6,7 @@ pub(crate) mod extern_abi;
pub(crate) mod flyimport;
pub(crate) mod fn_param;
pub(crate) mod format_string;
+pub(crate) mod item_list;
pub(crate) mod keyword;
pub(crate) mod lifetime;
pub(crate) mod mod_;
diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs
new file mode 100644
index 0000000000..5ae119c534
--- /dev/null
+++ b/crates/ide-completion/src/completions/item_list.rs
@@ -0,0 +1,48 @@
+//! Completion of paths and keywords at item list position.
+
+use crate::{
+ completions::module_or_fn_macro,
+ context::{PathCompletionCtx, PathKind, PathQualifierCtx},
+ CompletionContext, Completions,
+};
+
+pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext) {
+ let _p = profile::span("complete_unqualified_path");
+ if ctx.is_path_disallowed() || ctx.has_unfinished_impl_or_trait_prev_sibling() {
+ return;
+ }
+
+ let (&is_absolute_path, qualifier) = match &ctx.path_context {
+ Some(PathCompletionCtx {
+ kind: Some(PathKind::Item), is_absolute_path, qualifier, ..
+ }) => (is_absolute_path, qualifier),
+ _ => return,
+ };
+
+ match qualifier {
+ Some(PathQualifierCtx { resolution, is_super_chain, .. }) => {
+ if let Some(hir::PathResolution::Def(hir::ModuleDef::Module(module))) = resolution {
+ for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
+ if let Some(def) = module_or_fn_macro(ctx.db, def) {
+ acc.add_resolution(ctx, name, def);
+ }
+ }
+ }
+
+ if *is_super_chain {
+ acc.add_keyword(ctx, "super::");
+ }
+ }
+ None if is_absolute_path => {
+ acc.add_crate_roots(ctx);
+ }
+ None => {
+ ctx.process_all_names(&mut |name, def| {
+ if let Some(def) = module_or_fn_macro(ctx.db, def) {
+ acc.add_resolution(ctx, name, def);
+ }
+ });
+ acc.add_nameref_keywords_with_colon(ctx);
+ }
+ }
+}
diff --git a/crates/ide-completion/src/completions/keyword.rs b/crates/ide-completion/src/completions/keyword.rs
index 07cfad81d2..93bd346846 100644
--- a/crates/ide-completion/src/completions/keyword.rs
+++ b/crates/ide-completion/src/completions/keyword.rs
@@ -40,7 +40,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
if let Some(PathKind::Vis { .. }) = ctx.path_kind() {
return;
}
- if ctx.has_impl_or_trait_prev_sibling() {
+ if ctx.has_unfinished_impl_or_trait_prev_sibling() {
add_keyword("where", "where");
if ctx.has_impl_prev_sibling() {
add_keyword("for", "for");
diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs
index 16666eba45..a761eeebb2 100644
--- a/crates/ide-completion/src/completions/pattern.rs
+++ b/crates/ide-completion/src/completions/pattern.rs
@@ -196,12 +196,13 @@ fn pattern_path_completion(
// qualifier can only be none here if we are in a TuplePat or RecordPat in which case special characters have to follow the path
None if *is_absolute_path => acc.add_crate_roots(ctx),
None => {
- cov_mark::hit!(unqualified_path_only_modules_in_import);
ctx.process_all_names(&mut |name, res| {
- if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
+ // FIXME: properly filter here
+ if let ScopeDef::ModuleDef(_) = res {
acc.add_resolution(ctx, name, res);
}
});
+
acc.add_nameref_keywords_with_colon(ctx);
}
}
diff --git a/crates/ide-completion/src/completions/qualified_path.rs b/crates/ide-completion/src/completions/qualified_path.rs
index ad92820bca..d12f8490bd 100644
--- a/crates/ide-completion/src/completions/qualified_path.rs
+++ b/crates/ide-completion/src/completions/qualified_path.rs
@@ -5,14 +5,12 @@ use ide_db::FxHashSet;
use syntax::ast;
use crate::{
- completions::module_or_fn_macro,
context::{PathCompletionCtx, PathKind},
- patterns::ImmediateLocation,
CompletionContext, Completions,
};
pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
- if ctx.is_path_disallowed() || ctx.has_impl_or_trait_prev_sibling() {
+ if ctx.is_path_disallowed() || ctx.has_unfinished_impl_or_trait_prev_sibling() {
return;
}
if ctx.pattern_ctx.is_some() {
@@ -54,26 +52,13 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
None => return,
};
- match ctx.completion_location {
- Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
- if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
- for (name, def) in module.scope(ctx.db, Some(ctx.module)) {
- if let Some(def) = module_or_fn_macro(ctx.db, def) {
- acc.add_resolution(ctx, name, def);
- }
- }
- }
- return;
- }
- _ => (),
- }
-
match kind {
Some(
PathKind::Pat
| PathKind::Attr { .. }
| PathKind::Vis { .. }
| PathKind::Use
+ | PathKind::Item
| PathKind::Derive,
) => {
return;
diff --git a/crates/ide-completion/src/completions/snippet.rs b/crates/ide-completion/src/completions/snippet.rs
index c00de6ff50..a1675b896d 100644
--- a/crates/ide-completion/src/completions/snippet.rs
+++ b/crates/ide-completion/src/completions/snippet.rs
@@ -46,7 +46,7 @@ pub(crate) fn complete_item_snippet(acc: &mut Completions, ctx: &CompletionConte
if !(ctx.expects_item() || ctx.has_block_expr_parent())
|| ctx.previous_token_is(T![unsafe])
|| ctx.path_qual().is_some()
- || ctx.has_impl_or_trait_prev_sibling()
+ || ctx.has_unfinished_impl_or_trait_prev_sibling()
{
return;
}
diff --git a/crates/ide-completion/src/completions/trait_impl.rs b/crates/ide-completion/src/completions/trait_impl.rs
index 80fbaffd71..d5272be882 100644
--- a/crates/ide-completion/src/completions/trait_impl.rs
+++ b/crates/ide-completion/src/completions/trait_impl.rs
@@ -547,12 +547,7 @@ impl Test for T {
type Test = fn $0;
}
",
- expect![[r#"
- sp Self
- st T
- tt Test
- bt u32
- "#]],
+ expect![[r#""#]],
);
}
diff --git a/crates/ide-completion/src/completions/unqualified_path.rs b/crates/ide-completion/src/completions/unqualified_path.rs
index c4d4c5549e..5de602e613 100644
--- a/crates/ide-completion/src/completions/unqualified_path.rs
+++ b/crates/ide-completion/src/completions/unqualified_path.rs
@@ -4,7 +4,6 @@ use hir::ScopeDef;
use syntax::{ast, AstNode};
use crate::{
- completions::module_or_fn_macro,
context::{PathCompletionCtx, PathKind},
patterns::ImmediateLocation,
CompletionContext, Completions,
@@ -12,14 +11,15 @@ use crate::{
pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
let _p = profile::span("complete_unqualified_path");
- if ctx.is_path_disallowed() || ctx.has_impl_or_trait_prev_sibling() {
+ if ctx.is_path_disallowed() || ctx.has_unfinished_impl_or_trait_prev_sibling() {
return;
}
- match ctx.path_context {
+
+ match &ctx.path_context {
Some(PathCompletionCtx {
is_absolute_path: false,
qualifier: None,
- kind: None | Some(PathKind::Expr | PathKind::Type | PathKind::Item),
+ kind: None | Some(PathKind::Expr | PathKind::Type),
..
}) => (),
_ => return,
@@ -28,15 +28,6 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
acc.add_nameref_keywords(ctx);
match &ctx.completion_location {
- Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
- // only show macros in {Assoc}ItemList
- ctx.process_all_names(&mut |name, def| {
- if let Some(def) = module_or_fn_macro(ctx.db, def) {
- acc.add_resolution(ctx, name, def);
- }
- });
- return;
- }
Some(ImmediateLocation::TypeBound) => {
ctx.process_all_names(&mut |name, res| {
let add_resolution = match res {
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index a41d89859a..6682bc56d1 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -270,13 +270,17 @@ impl<'a> CompletionContext<'a> {
|| matches!(self.name_ctx, Some(NameContext::RecordField))
}
- pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool {
+ /// Whether the cursor is right after a trait or impl header.
+ /// trait Foo ident$0
+ // FIXME: This probably shouldn't exist
+ pub(crate) fn has_unfinished_impl_or_trait_prev_sibling(&self) -> bool {
matches!(
self.prev_sibling,
Some(ImmediatePrevSibling::ImplDefType | ImmediatePrevSibling::TraitDefName)
)
}
+ // FIXME: This probably shouldn't exist
pub(crate) fn has_impl_prev_sibling(&self) -> bool {
matches!(self.prev_sibling, Some(ImmediatePrevSibling::ImplDefType))
}
@@ -289,6 +293,7 @@ impl<'a> CompletionContext<'a> {
matches!(self.prev_sibling, Some(ImmediatePrevSibling::IfExpr))
}
+ // FIXME: This shouldn't exist
pub(crate) fn is_path_disallowed(&self) -> bool {
self.previous_token_is(T![unsafe])
|| matches!(
diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs
index 6924ba1db6..473900397a 100644
--- a/crates/ide-completion/src/lib.rs
+++ b/crates/ide-completion/src/lib.rs
@@ -155,6 +155,7 @@ pub fn completions(
completions::flyimport::import_on_the_fly(&mut acc, &ctx);
completions::fn_param::complete_fn_param(&mut acc, &ctx);
completions::format_string::format_string(&mut acc, &ctx);
+ completions::item_list::complete_item_list(&mut acc, &ctx);
completions::inferred_type(&mut acc, &ctx);
completions::keyword::complete_expr_keyword(&mut acc, &ctx);
completions::lifetime::complete_label(&mut acc, &ctx);
diff --git a/crates/ide-completion/src/tests/item.rs b/crates/ide-completion/src/tests/item.rs
index 8f2f8a548a..5d324f0965 100644
--- a/crates/ide-completion/src/tests/item.rs
+++ b/crates/ide-completion/src/tests/item.rs
@@ -95,7 +95,7 @@ fn after_struct_name() {
ma makro!(…) macro_rules! makro
md module
kw const
- kw crate
+ kw crate::
kw enum
kw extern
kw fn
@@ -104,10 +104,10 @@ fn after_struct_name() {
kw pub
kw pub(crate)
kw pub(super)
- kw self
+ kw self::
kw static
kw struct
- kw super
+ kw super::
kw trait
kw type
kw union
@@ -129,7 +129,7 @@ fn after_fn_name() {
ma makro!(…) macro_rules! makro
md module
kw const
- kw crate
+ kw crate::
kw enum
kw extern
kw fn
@@ -138,10 +138,10 @@ fn after_fn_name() {
kw pub
kw pub(crate)
kw pub(super)
- kw self
+ kw self::
kw static
kw struct
- kw super
+ kw super::
kw trait
kw type
kw union
diff --git a/crates/ide-completion/src/tests/item_list.rs b/crates/ide-completion/src/tests/item_list.rs
index 40d3b90da9..f320812936 100644
--- a/crates/ide-completion/src/tests/item_list.rs
+++ b/crates/ide-completion/src/tests/item_list.rs
@@ -15,7 +15,7 @@ fn in_mod_item_list() {
expect![[r#"
ma makro!(…) macro_rules! makro
kw const
- kw crate
+ kw crate::
kw enum
kw extern
kw fn
@@ -24,10 +24,10 @@ fn in_mod_item_list() {
kw pub
kw pub(crate)
kw pub(super)
- kw self
+ kw self::
kw static
kw struct
- kw super
+ kw super::
kw trait
kw type
kw union
@@ -48,7 +48,7 @@ fn in_source_file_item_list() {
ma makro!(…) macro_rules! makro
md module
kw const
- kw crate
+ kw crate::
kw enum
kw extern
kw fn
@@ -57,10 +57,10 @@ fn in_source_file_item_list() {
kw pub
kw pub(crate)
kw pub(super)
- kw self
+ kw self::
kw static
kw struct
- kw super
+ kw super::
kw trait
kw type
kw union
@@ -166,13 +166,13 @@ fn in_impl_assoc_item_list() {
ma makro!(…) macro_rules! makro
md module
kw const
- kw crate
+ kw crate::
kw fn
kw pub
kw pub(crate)
kw pub(super)
- kw self
- kw super
+ kw self::
+ kw super::
kw type
kw unsafe
"#]],
@@ -203,10 +203,10 @@ fn in_trait_assoc_item_list() {
ma makro!(…) macro_rules! makro
md module
kw const
- kw crate
+ kw crate::
kw fn
- kw self
- kw super
+ kw self::
+ kw super::
kw type
kw unsafe
"#]],
@@ -240,13 +240,13 @@ impl Test for () {
md module
ta type Type1 =
kw const
- kw crate
+ kw crate::
kw fn
kw pub
kw pub(crate)
kw pub(super)
- kw self
- kw super
+ kw self::
+ kw super::
kw type
kw unsafe
"#]],
diff --git a/crates/ide-completion/src/tests/pattern.rs b/crates/ide-completion/src/tests/pattern.rs
index b353883bc7..3ecb2f1637 100644
--- a/crates/ide-completion/src/tests/pattern.rs
+++ b/crates/ide-completion/src/tests/pattern.rs
@@ -394,6 +394,9 @@ fn foo() {
}
"#,
expect![[r#"
+ fn foo() fn()
+ st Bar
+ bt u32
kw crate::
kw self::
kw super::
@@ -403,19 +406,18 @@ fn foo() {
r#"
struct Foo { bar: u32 }
fn foo() {
- match Foo { bar: 0 } {
+ match (Foo { bar: 0 }) {
F$0 { bar } => {}
}
}
"#,
expect![[r#"
- fn foo() fn()
+ fn foo() fn()
st Foo
bt u32
- kw crate
- kw return
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
check_empty(