Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #12164 - Veykril:completion-rev, r=Veykril
internal: Remove `unqualified_path` completions module cc https://github.com/rust-lang/rust-analyzer/issues/12144
bors 2022-05-05
parent 4b1eb98 · parent 16d2e79 · commit 7dfd1cb
-rw-r--r--crates/ide-completion/src/completions.rs3
-rw-r--r--crates/ide-completion/src/completions/expr.rs49
-rw-r--r--crates/ide-completion/src/completions/item_list.rs2
-rw-r--r--crates/ide-completion/src/completions/type.rs90
-rw-r--r--crates/ide-completion/src/completions/unqualified_path.rs289
-rw-r--r--crates/ide-completion/src/context.rs9
-rw-r--r--crates/ide-completion/src/lib.rs58
-rw-r--r--crates/ide-completion/src/tests.rs3
-rw-r--r--crates/ide-completion/src/tests/expression.rs73
-rw-r--r--crates/ide-completion/src/tests/item.rs12
-rw-r--r--crates/ide-completion/src/tests/predicate.rs36
-rw-r--r--crates/ide-completion/src/tests/record.rs6
-rw-r--r--crates/ide-completion/src/tests/special.rs183
-rw-r--r--crates/ide-completion/src/tests/type_pos.rs72
14 files changed, 464 insertions, 421 deletions
diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs
index f8b1ff7310..b22124cc69 100644
--- a/crates/ide-completion/src/completions.rs
+++ b/crates/ide-completion/src/completions.rs
@@ -2,6 +2,7 @@
pub(crate) mod attribute;
pub(crate) mod dot;
+pub(crate) mod expr;
pub(crate) mod extern_abi;
pub(crate) mod flyimport;
pub(crate) mod fn_param;
@@ -16,7 +17,7 @@ pub(crate) mod qualified_path;
pub(crate) mod record;
pub(crate) mod snippet;
pub(crate) mod trait_impl;
-pub(crate) mod unqualified_path;
+pub(crate) mod r#type;
pub(crate) mod use_;
pub(crate) mod vis;
diff --git a/crates/ide-completion/src/completions/expr.rs b/crates/ide-completion/src/completions/expr.rs
new file mode 100644
index 0000000000..f9717f1c2c
--- /dev/null
+++ b/crates/ide-completion/src/completions/expr.rs
@@ -0,0 +1,49 @@
+//! Completion of names from the current scope in expression position.
+
+use hir::ScopeDef;
+
+use crate::{
+ context::{PathCompletionCtx, PathKind, PathQualifierCtx},
+ CompletionContext, Completions,
+};
+
+pub(crate) fn complete_expr_path(acc: &mut Completions, ctx: &CompletionContext) {
+ let _p = profile::span("complete_expr_path");
+ if ctx.is_path_disallowed() {
+ return;
+ }
+
+ let (&is_absolute_path, qualifier) = match &ctx.path_context {
+ Some(PathCompletionCtx {
+ kind: Some(PathKind::Expr), is_absolute_path, qualifier, ..
+ }) => (is_absolute_path, qualifier),
+ _ => return,
+ };
+
+ match qualifier {
+ Some(PathQualifierCtx { .. }) => return,
+ None if is_absolute_path => acc.add_crate_roots(ctx),
+ None => {
+ acc.add_nameref_keywords_with_colon(ctx);
+ if let Some(hir::Adt::Enum(e)) =
+ ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
+ {
+ super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
+ acc.add_qualified_enum_variant(ctx, variant, path)
+ });
+ }
+ ctx.process_all_names(&mut |name, def| {
+ use hir::{GenericParam::*, ModuleDef::*};
+ let add_resolution = match def {
+ ScopeDef::GenericParam(LifetimeParam(_)) | ScopeDef::Label(_) => false,
+ // Don't suggest attribute macros and derives.
+ ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
+ _ => true,
+ };
+ if add_resolution {
+ acc.add_resolution(ctx, name, def);
+ }
+ });
+ }
+ }
+}
diff --git a/crates/ide-completion/src/completions/item_list.rs b/crates/ide-completion/src/completions/item_list.rs
index 5ae119c534..ff1abd715d 100644
--- a/crates/ide-completion/src/completions/item_list.rs
+++ b/crates/ide-completion/src/completions/item_list.rs
@@ -7,7 +7,7 @@ use crate::{
};
pub(crate) fn complete_item_list(acc: &mut Completions, ctx: &CompletionContext) {
- let _p = profile::span("complete_unqualified_path");
+ let _p = profile::span("complete_item_list");
if ctx.is_path_disallowed() || ctx.has_unfinished_impl_or_trait_prev_sibling() {
return;
}
diff --git a/crates/ide-completion/src/completions/type.rs b/crates/ide-completion/src/completions/type.rs
new file mode 100644
index 0000000000..4d0e2fb59a
--- /dev/null
+++ b/crates/ide-completion/src/completions/type.rs
@@ -0,0 +1,90 @@
+//! Completion of names from the current scope in type position.
+
+use hir::ScopeDef;
+use syntax::{ast, AstNode};
+
+use crate::{
+ context::{PathCompletionCtx, PathKind, PathQualifierCtx},
+ patterns::ImmediateLocation,
+ CompletionContext, Completions,
+};
+
+pub(crate) fn complete_type_path(acc: &mut Completions, ctx: &CompletionContext) {
+ let _p = profile::span("complete_type_path");
+ if ctx.is_path_disallowed() {
+ return;
+ }
+
+ let (&is_absolute_path, qualifier) = match &ctx.path_context {
+ Some(PathCompletionCtx {
+ kind: Some(PathKind::Type), is_absolute_path, qualifier, ..
+ }) => (is_absolute_path, qualifier),
+ _ => return,
+ };
+
+ match qualifier {
+ Some(PathQualifierCtx { .. }) => return,
+ None if is_absolute_path => acc.add_crate_roots(ctx),
+ None => {
+ acc.add_nameref_keywords_with_colon(ctx);
+ if let Some(ImmediateLocation::TypeBound) = &ctx.completion_location {
+ ctx.process_all_names(&mut |name, res| {
+ let add_resolution = match res {
+ ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
+ ScopeDef::ModuleDef(
+ hir::ModuleDef::Trait(_) | hir::ModuleDef::Module(_),
+ ) => true,
+ _ => false,
+ };
+ if add_resolution {
+ acc.add_resolution(ctx, name, res);
+ }
+ });
+ return;
+ }
+ if let Some(ImmediateLocation::GenericArgList(arg_list)) = &ctx.completion_location {
+ if let Some(path_seg) = arg_list.syntax().parent().and_then(ast::PathSegment::cast)
+ {
+ if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(trait_))) =
+ ctx.sema.resolve_path(&path_seg.parent_path())
+ {
+ trait_.items(ctx.sema.db).into_iter().for_each(|it| {
+ if let hir::AssocItem::TypeAlias(alias) = it {
+ acc.add_type_alias_with_eq(ctx, alias)
+ }
+ });
+ }
+ }
+ }
+ ctx.process_all_names(&mut |name, def| {
+ use hir::{GenericParam::*, ModuleDef::*};
+ let add_resolution = match def {
+ ScopeDef::GenericParam(LifetimeParam(_)) | ScopeDef::Label(_) => false,
+ // no values in type places
+ ScopeDef::ModuleDef(Function(_) | Variant(_) | Static(_))
+ | ScopeDef::Local(_) => false,
+ // unless its a constant in a generic arg list position
+ ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => {
+ ctx.expects_generic_arg()
+ }
+ ScopeDef::ImplSelfType(_) => {
+ !ctx.previous_token_is(syntax::T![impl])
+ && !ctx.previous_token_is(syntax::T![for])
+ }
+ // Don't suggest attribute macros and derives.
+ ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
+ // Type things are fine
+ ScopeDef::ModuleDef(
+ BuiltinType(_) | Adt(_) | Module(_) | Trait(_) | TypeAlias(_),
+ )
+ | ScopeDef::AdtSelfType(_)
+ | ScopeDef::Unknown
+ | ScopeDef::GenericParam(TypeParam(_)) => true,
+ };
+ if add_resolution {
+ acc.add_resolution(ctx, name, def);
+ }
+ });
+ }
+ }
+}
diff --git a/crates/ide-completion/src/completions/unqualified_path.rs b/crates/ide-completion/src/completions/unqualified_path.rs
deleted file mode 100644
index 5de602e613..0000000000
--- a/crates/ide-completion/src/completions/unqualified_path.rs
+++ /dev/null
@@ -1,289 +0,0 @@
-//! Completion of names from the current scope, e.g. locals and imported items.
-
-use hir::ScopeDef;
-use syntax::{ast, AstNode};
-
-use crate::{
- context::{PathCompletionCtx, PathKind},
- patterns::ImmediateLocation,
- CompletionContext, Completions,
-};
-
-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_unfinished_impl_or_trait_prev_sibling() {
- return;
- }
-
- match &ctx.path_context {
- Some(PathCompletionCtx {
- is_absolute_path: false,
- qualifier: None,
- kind: None | Some(PathKind::Expr | PathKind::Type),
- ..
- }) => (),
- _ => return,
- }
-
- acc.add_nameref_keywords(ctx);
-
- match &ctx.completion_location {
- Some(ImmediateLocation::TypeBound) => {
- ctx.process_all_names(&mut |name, res| {
- let add_resolution = match res {
- ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
- ScopeDef::ModuleDef(hir::ModuleDef::Trait(_) | hir::ModuleDef::Module(_)) => {
- true
- }
- _ => false,
- };
- if add_resolution {
- acc.add_resolution(ctx, name, res);
- }
- });
- return;
- }
- _ => (),
- }
-
- if !ctx.expects_type() {
- if let Some(hir::Adt::Enum(e)) =
- ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
- {
- super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
- acc.add_qualified_enum_variant(ctx, variant, path)
- });
- }
- }
-
- if let Some(ImmediateLocation::GenericArgList(arg_list)) = &ctx.completion_location {
- if let Some(path_seg) = arg_list.syntax().parent().and_then(ast::PathSegment::cast) {
- if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(trait_))) =
- ctx.sema.resolve_path(&path_seg.parent_path())
- {
- trait_.items(ctx.sema.db).into_iter().for_each(|it| {
- if let hir::AssocItem::TypeAlias(alias) = it {
- acc.add_type_alias_with_eq(ctx, alias)
- }
- });
- }
- }
- }
-
- ctx.process_all_names(&mut |name, res| {
- let add_resolution = match res {
- ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) | ScopeDef::Label(_) => {
- cov_mark::hit!(unqualified_skip_lifetime_completion);
- return;
- }
- ScopeDef::ImplSelfType(_) => {
- !ctx.previous_token_is(syntax::T![impl]) && !ctx.previous_token_is(syntax::T![for])
- }
- // Don't suggest attribute macros and derives.
- ScopeDef::ModuleDef(hir::ModuleDef::Macro(mac)) => mac.is_fn_like(ctx.db),
- // no values in type places
- ScopeDef::ModuleDef(
- hir::ModuleDef::Function(_)
- | hir::ModuleDef::Variant(_)
- | hir::ModuleDef::Static(_),
- )
- | ScopeDef::Local(_) => !ctx.expects_type(),
- // unless its a constant in a generic arg list position
- ScopeDef::ModuleDef(hir::ModuleDef::Const(_))
- | ScopeDef::GenericParam(hir::GenericParam::ConstParam(_)) => {
- !ctx.expects_type() || ctx.expects_generic_arg()
- }
- _ => true,
- };
- if add_resolution {
- acc.add_resolution(ctx, name, res);
- }
- });
-}
-
-#[cfg(test)]
-mod tests {
- use expect_test::{expect, Expect};
-
- use crate::tests::{check_edit, completion_list_no_kw};
-
- fn check(ra_fixture: &str, expect: Expect) {
- let actual = completion_list_no_kw(ra_fixture);
- expect.assert_eq(&actual)
- }
-
- #[test]
- fn completes_if_prefix_is_keyword() {
- check_edit(
- "wherewolf",
- r#"
-fn main() {
- let wherewolf = 92;
- drop(where$0)
-}
-"#,
- r#"
-fn main() {
- let wherewolf = 92;
- drop(wherewolf)
-}
-"#,
- )
- }
-
- /// Regression test for issue #6091.
- #[test]
- fn correctly_completes_module_items_prefixed_with_underscore() {
- check_edit(
- "_alpha",
- r#"
-fn main() {
- _$0
-}
-fn _alpha() {}
-"#,
- r#"
-fn main() {
- _alpha()$0
-}
-fn _alpha() {}
-"#,
- )
- }
-
- #[test]
- fn completes_prelude() {
- check(
- r#"
-//- /main.rs crate:main deps:std
-fn foo() { let x: $0 }
-
-//- /std/lib.rs crate:std
-pub mod prelude {
- pub mod rust_2018 {
- pub struct Option;
- }
-}
-"#,
- expect![[r#"
- md std
- st Option
- bt u32
- "#]],
- );
- }
-
- #[test]
- fn completes_prelude_macros() {
- check(
- r#"
-//- /main.rs crate:main deps:std
-fn f() {$0}
-
-//- /std/lib.rs crate:std
-pub mod prelude {
- pub mod rust_2018 {
- pub use crate::concat;
- }
-}
-
-mod macros {
- #[rustc_builtin_macro]
- #[macro_export]
- macro_rules! concat { }
-}
-"#,
- expect![[r#"
- fn f() fn()
- ma concat!(…) macro_rules! concat
- md std
- bt u32
- "#]],
- );
- }
-
- #[test]
- fn completes_std_prelude_if_core_is_defined() {
- check(
- r#"
-//- /main.rs crate:main deps:core,std
-fn foo() { let x: $0 }
-
-//- /core/lib.rs crate:core
-pub mod prelude {
- pub mod rust_2018 {
- pub struct Option;
- }
-}
-
-//- /std/lib.rs crate:std deps:core
-pub mod prelude {
- pub mod rust_2018 {
- pub struct String;
- }
-}
-"#,
- expect![[r#"
- md core
- md std
- st String
- bt u32
- "#]],
- );
- }
-
- #[test]
- fn respects_doc_hidden() {
- check(
- r#"
-//- /lib.rs crate:lib deps:std
-fn f() {
- format_$0
-}
-
-//- /std.rs crate:std
-#[doc(hidden)]
-#[macro_export]
-macro_rules! format_args_nl {
- () => {}
-}
-
-pub mod prelude {
- pub mod rust_2018 {}
-}
- "#,
- expect![[r#"
- fn f() fn()
- md std
- bt u32
- "#]],
- );
- }
-
- #[test]
- fn respects_doc_hidden_in_assoc_item_list() {
- check(
- r#"
-//- /lib.rs crate:lib deps:std
-struct S;
-impl S {
- format_$0
-}
-
-//- /std.rs crate:std
-#[doc(hidden)]
-#[macro_export]
-macro_rules! format_args_nl {
- () => {}
-}
-
-pub mod prelude {
- pub mod rust_2018 {}
-}
- "#,
- expect![[r#"
- md std
- "#]],
- );
- }
-}
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index 6682bc56d1..87677e28e8 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -71,6 +71,10 @@ pub(crate) struct PathCompletionCtx {
pub(super) is_absolute_path: bool,
/// The qualifier of the current path if it exists.
pub(super) qualifier: Option<PathQualifierCtx>,
+ #[allow(dead_code)]
+ // FIXME: use this
+ /// The parent of the path we are completing.
+ pub(super) parent: Option<ast::Path>,
pub(super) kind: Option<PathKind>,
/// Whether the path segment has type args or not.
pub(super) has_type_args: bool,
@@ -949,13 +953,14 @@ impl<'a> CompletionContext<'a> {
let mut path_ctx = PathCompletionCtx {
has_call_parens: false,
+ has_macro_bang: false,
is_absolute_path: false,
qualifier: None,
+ parent: path.parent_path(),
+ kind: None,
has_type_args: false,
can_be_stmt: false,
in_loop_body: false,
- has_macro_bang: false,
- kind: None,
};
let mut pat_ctx = None;
path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax());
diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs
index 473900397a..3a0bd042da 100644
--- a/crates/ide-completion/src/lib.rs
+++ b/crates/ide-completion/src/lib.rs
@@ -144,34 +144,38 @@ pub fn completions(
config: &CompletionConfig,
position: FilePosition,
) -> Option<Completions> {
- let ctx = CompletionContext::new(db, position, config)?;
-
+ let ctx = &CompletionContext::new(db, position, config)?;
let mut acc = Completions::default();
- completions::attribute::complete_attribute(&mut acc, &ctx);
- completions::attribute::complete_derive(&mut acc, &ctx);
- completions::attribute::complete_known_attribute_input(&mut acc, &ctx);
- completions::dot::complete_dot(&mut acc, &ctx);
- completions::extern_abi::complete_extern_abi(&mut acc, &ctx);
- 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);
- completions::lifetime::complete_lifetime(&mut acc, &ctx);
- completions::mod_::complete_mod(&mut acc, &ctx);
- completions::pattern::complete_pattern(&mut acc, &ctx);
- completions::postfix::complete_postfix(&mut acc, &ctx);
- completions::qualified_path::complete_qualified_path(&mut acc, &ctx);
- completions::record::complete_record_literal(&mut acc, &ctx);
- completions::record::complete_record(&mut acc, &ctx);
- completions::snippet::complete_expr_snippet(&mut acc, &ctx);
- completions::snippet::complete_item_snippet(&mut acc, &ctx);
- completions::trait_impl::complete_trait_impl(&mut acc, &ctx);
- completions::unqualified_path::complete_unqualified_path(&mut acc, &ctx);
- completions::use_::complete_use_tree(&mut acc, &ctx);
- completions::vis::complete_vis(&mut acc, &ctx);
+
+ {
+ let acc = &mut acc;
+ completions::attribute::complete_attribute(acc, ctx);
+ completions::attribute::complete_derive(acc, ctx);
+ completions::attribute::complete_known_attribute_input(acc, ctx);
+ completions::dot::complete_dot(acc, ctx);
+ completions::expr::complete_expr_path(acc, ctx);
+ completions::extern_abi::complete_extern_abi(acc, ctx);
+ completions::flyimport::import_on_the_fly(acc, ctx);
+ completions::fn_param::complete_fn_param(acc, ctx);
+ completions::format_string::format_string(acc, ctx);
+ completions::item_list::complete_item_list(acc, ctx);
+ completions::inferred_type(acc, ctx);
+ completions::keyword::complete_expr_keyword(acc, ctx);
+ completions::lifetime::complete_label(acc, ctx);
+ completions::lifetime::complete_lifetime(acc, ctx);
+ completions::mod_::complete_mod(acc, ctx);
+ completions::pattern::complete_pattern(acc, ctx);
+ completions::postfix::complete_postfix(acc, ctx);
+ completions::qualified_path::complete_qualified_path(acc, ctx);
+ completions::record::complete_record_literal(acc, ctx);
+ completions::record::complete_record(acc, ctx);
+ completions::snippet::complete_expr_snippet(acc, ctx);
+ completions::snippet::complete_item_snippet(acc, ctx);
+ completions::trait_impl::complete_trait_impl(acc, ctx);
+ completions::r#type::complete_type_path(acc, ctx);
+ completions::use_::complete_use_tree(acc, ctx);
+ completions::vis::complete_vis(acc, ctx);
+ }
Some(acc)
}
diff --git a/crates/ide-completion/src/tests.rs b/crates/ide-completion/src/tests.rs
index 5387b455f0..8d9d1bc4b9 100644
--- a/crates/ide-completion/src/tests.rs
+++ b/crates/ide-completion/src/tests.rs
@@ -10,6 +10,7 @@
mod attribute;
mod expression;
+mod flyimport;
mod fn_param;
mod item_list;
mod item;
@@ -17,10 +18,10 @@ mod pattern;
mod predicate;
mod proc_macros;
mod record;
+mod special;
mod type_pos;
mod use_tree;
mod visibility;
-mod flyimport;
use std::mem;
diff --git a/crates/ide-completion/src/tests/expression.rs b/crates/ide-completion/src/tests/expression.rs
index a068d5bf7a..61246b963e 100644
--- a/crates/ide-completion/src/tests/expression.rs
+++ b/crates/ide-completion/src/tests/expression.rs
@@ -48,7 +48,7 @@ fn baz() {
un Union
ev TupleV(…) TupleV(u32)
bt u32
- kw crate
+ kw crate::
kw false
kw for
kw if
@@ -57,8 +57,8 @@ fn baz() {
kw match
kw mut
kw return
- kw self
- kw super
+ kw self::
+ kw super::
kw true
kw unsafe
kw while
@@ -91,7 +91,7 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
lc param1 i32
lc param2 i32
bt u32
- kw crate
+ kw crate::
kw false
kw for
kw if
@@ -99,8 +99,8 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
kw loop
kw match
kw return
- kw self
- kw super
+ kw self::
+ kw super::
kw true
kw unsafe
kw while
@@ -111,7 +111,6 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
#[test]
fn completes_all_the_things_in_fn_body() {
- cov_mark::check!(unqualified_skip_lifetime_completion);
check(
r#"
use non_existant::Unresolved;
@@ -146,7 +145,7 @@ impl Unit {
ev TupleV(…) TupleV(u32)
bt u32
kw const
- kw crate
+ kw crate::
kw enum
kw extern
kw false
@@ -160,10 +159,10 @@ impl Unit {
kw match
kw mod
kw return
- kw self
+ kw self::
kw static
kw struct
- kw super
+ kw super::
kw trait
kw true
kw type
@@ -224,7 +223,7 @@ fn complete_in_block() {
fn foo() fn()
bt u32
kw const
- kw crate
+ kw crate::
kw enum
kw extern
kw false
@@ -238,10 +237,10 @@ fn complete_in_block() {
kw match
kw mod
kw return
- kw self
+ kw self::
kw static
kw struct
- kw super
+ kw super::
kw trait
kw true
kw type
@@ -270,7 +269,7 @@ fn complete_after_if_expr() {
fn foo() fn()
bt u32
kw const
- kw crate
+ kw crate::
kw else
kw else if
kw enum
@@ -286,10 +285,10 @@ fn complete_after_if_expr() {
kw match
kw mod
kw return
- kw self
+ kw self::
kw static
kw struct
- kw super
+ kw super::
kw trait
kw true
kw type
@@ -318,7 +317,7 @@ fn complete_in_match_arm() {
expect![[r#"
fn foo() fn()
bt u32
- kw crate
+ kw crate::
kw false
kw for
kw if
@@ -326,8 +325,8 @@ fn complete_in_match_arm() {
kw loop
kw match
kw return
- kw self
- kw super
+ kw self::
+ kw super::
kw true
kw unsafe
kw while
@@ -346,7 +345,7 @@ fn completes_in_loop_ctx() {
kw break
kw const
kw continue
- kw crate
+ kw crate::
kw enum
kw extern
kw false
@@ -360,10 +359,10 @@ fn completes_in_loop_ctx() {
kw match
kw mod
kw return
- kw self
+ kw self::
kw static
kw struct
- kw super
+ kw super::
kw trait
kw true
kw type
@@ -386,7 +385,7 @@ fn completes_in_let_initializer() {
expect![[r#"
fn main() fn()
bt u32
- kw crate
+ kw crate::
kw false
kw for
kw if
@@ -394,8 +393,8 @@ fn completes_in_let_initializer() {
kw loop
kw match
kw return
- kw self
- kw super
+ kw self::
+ kw super::
kw true
kw unsafe
kw while
@@ -421,7 +420,7 @@ fn foo() {
fn foo() fn()
st Foo
bt u32
- kw crate
+ kw crate::
kw false
kw for
kw if
@@ -429,8 +428,8 @@ fn foo() {
kw loop
kw match
kw return
- kw self
- kw super
+ kw self::
+ kw super::
kw true
kw unsafe
kw while
@@ -457,7 +456,7 @@ fn foo() {
fn foo() fn()
lc bar i32
bt u32
- kw crate
+ kw crate::
kw false
kw for
kw if
@@ -465,8 +464,8 @@ fn foo() {
kw loop
kw match
kw return
- kw self
- kw super
+ kw self::
+ kw super::
kw true
kw unsafe
kw while
@@ -489,7 +488,7 @@ fn quux(x: i32) {
lc x i32
ma m!(…) macro_rules! m
bt u32
- kw crate
+ kw crate::
kw false
kw for
kw if
@@ -497,8 +496,8 @@ fn quux(x: i32) {
kw loop
kw match
kw return
- kw self
- kw super
+ kw self::
+ kw super::
kw true
kw unsafe
kw while
@@ -517,7 +516,7 @@ fn quux(x: i32) {
lc x i32
ma m!(…) macro_rules! m
bt u32
- kw crate
+ kw crate::
kw false
kw for
kw if
@@ -525,8 +524,8 @@ fn quux(x: i32) {
kw loop
kw match
kw return
- kw self
- kw super
+ kw self::
+ kw super::
kw true
kw unsafe
kw while
diff --git a/crates/ide-completion/src/tests/item.rs b/crates/ide-completion/src/tests/item.rs
index 5d324f0965..e4b70f97e3 100644
--- a/crates/ide-completion/src/tests/item.rs
+++ b/crates/ide-completion/src/tests/item.rs
@@ -27,9 +27,9 @@ impl Tra$0
tt Trait
un Union
bt u32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
)
}
@@ -50,9 +50,9 @@ impl Trait for Str$0
tt Trait
un Union
bt u32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
)
}
diff --git a/crates/ide-completion/src/tests/predicate.rs b/crates/ide-completion/src/tests/predicate.rs
index cc18bf4453..f2b9c061dc 100644
--- a/crates/ide-completion/src/tests/predicate.rs
+++ b/crates/ide-completion/src/tests/predicate.rs
@@ -26,9 +26,9 @@ struct Foo<'lt, T, const C: usize> where $0 {}
tt Trait
un Union
bt u32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -43,9 +43,9 @@ struct Foo<'lt, T, const C: usize> where T: $0 {}
ma makro!(…) macro_rules! makro
md module
tt Trait
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -62,9 +62,9 @@ struct Foo<'lt, T, const C: usize> where 'lt: $0 {}
ma makro!(…) macro_rules! makro
md module
tt Trait
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -79,9 +79,9 @@ struct Foo<'lt, T, const C: usize> where for<'a> T: $0 {}
ma makro!(…) macro_rules! makro
md module
tt Trait
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -103,9 +103,9 @@ struct Foo<'lt, T, const C: usize> where for<'a> $0 {}
tt Trait
un Union
bt u32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -129,9 +129,9 @@ impl Record {
tt Trait
un Union
bt u32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
diff --git a/crates/ide-completion/src/tests/record.rs b/crates/ide-completion/src/tests/record.rs
index bae5ddb539..a0f8b24867 100644
--- a/crates/ide-completion/src/tests/record.rs
+++ b/crates/ide-completion/src/tests/record.rs
@@ -167,7 +167,7 @@ fn main() {
tt Default
tt Sized
bt u32
- kw crate
+ kw crate::
kw false
kw for
kw if
@@ -175,8 +175,8 @@ fn main() {
kw loop
kw match
kw return
- kw self
- kw super
+ kw self::
+ kw super::
kw true
kw unsafe
kw while
diff --git a/crates/ide-completion/src/tests/special.rs b/crates/ide-completion/src/tests/special.rs
new file mode 100644
index 0000000000..79235e5ca0
--- /dev/null
+++ b/crates/ide-completion/src/tests/special.rs
@@ -0,0 +1,183 @@
+use expect_test::{expect, Expect};
+
+use crate::tests::{check_edit, completion_list_no_kw};
+
+fn check(ra_fixture: &str, expect: Expect) {
+ let actual = completion_list_no_kw(ra_fixture);
+ expect.assert_eq(&actual)
+}
+
+#[test]
+fn completes_if_prefix_is_keyword() {
+ check_edit(
+ "wherewolf",
+ r#"
+fn main() {
+ let wherewolf = 92;
+ drop(where$0)
+}
+"#,
+ r#"
+fn main() {
+ let wherewolf = 92;
+ drop(wherewolf)
+}
+"#,
+ )
+}
+
+/// Regression test for issue #6091.
+#[test]
+fn correctly_completes_module_items_prefixed_with_underscore() {
+ check_edit(
+ "_alpha",
+ r#"
+fn main() {
+ _$0
+}
+fn _alpha() {}
+"#,
+ r#"
+fn main() {
+ _alpha()$0
+}
+fn _alpha() {}
+"#,
+ )
+}
+
+#[test]
+fn completes_prelude() {
+ check(
+ r#"
+//- /main.rs crate:main deps:std
+fn foo() { let x: $0 }
+
+//- /std/lib.rs crate:std
+pub mod prelude {
+ pub mod rust_2018 {
+ pub struct Option;
+ }
+}
+"#,
+ expect![[r#"
+ md std
+ st Option
+ bt u32
+ "#]],
+ );
+}
+
+#[test]
+fn completes_prelude_macros() {
+ check(
+ r#"
+//- /main.rs crate:main deps:std
+fn f() {$0}
+
+//- /std/lib.rs crate:std
+pub mod prelude {
+ pub mod rust_2018 {
+ pub use crate::concat;
+ }
+}
+
+mod macros {
+ #[rustc_builtin_macro]
+ #[macro_export]
+ macro_rules! concat { }
+}
+"#,
+ expect![[r#"
+ fn f() fn()
+ ma concat!(…) macro_rules! concat
+ md std
+ bt u32
+ "#]],
+ );
+}
+
+#[test]
+fn completes_std_prelude_if_core_is_defined() {
+ check(
+ r#"
+//- /main.rs crate:main deps:core,std
+fn foo() { let x: $0 }
+
+//- /core/lib.rs crate:core
+pub mod prelude {
+ pub mod rust_2018 {
+ pub struct Option;
+ }
+}
+
+//- /std/lib.rs crate:std deps:core
+pub mod prelude {
+ pub mod rust_2018 {
+ pub struct String;
+ }
+}
+"#,
+ expect![[r#"
+ md core
+ md std
+ st String
+ bt u32
+ "#]],
+ );
+}
+
+#[test]
+fn respects_doc_hidden() {
+ check(
+ r#"
+//- /lib.rs crate:lib deps:std
+fn f() {
+ format_$0
+}
+
+//- /std.rs crate:std
+#[doc(hidden)]
+#[macro_export]
+macro_rules! format_args_nl {
+ () => {}
+}
+
+pub mod prelude {
+ pub mod rust_2018 {}
+}
+ "#,
+ expect![[r#"
+ fn f() fn()
+ md std
+ bt u32
+ "#]],
+ );
+}
+
+#[test]
+fn respects_doc_hidden_in_assoc_item_list() {
+ check(
+ r#"
+//- /lib.rs crate:lib deps:std
+struct S;
+impl S {
+ format_$0
+}
+
+//- /std.rs crate:std
+#[doc(hidden)]
+#[macro_export]
+macro_rules! format_args_nl {
+ () => {}
+}
+
+pub mod prelude {
+ pub mod rust_2018 {}
+}
+ "#,
+ expect![[r#"
+ md std
+ "#]],
+ );
+}
diff --git a/crates/ide-completion/src/tests/type_pos.rs b/crates/ide-completion/src/tests/type_pos.rs
index fcbb2e05a7..5224bc4b48 100644
--- a/crates/ide-completion/src/tests/type_pos.rs
+++ b/crates/ide-completion/src/tests/type_pos.rs
@@ -29,9 +29,9 @@ struct Foo<'lt, T, const C: usize> {
tp T
un Union
bt u32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
)
}
@@ -55,12 +55,12 @@ struct Foo<'lt, T, const C: usize>(f$0);
tp T
un Union
bt u32
- kw crate
+ kw crate::
kw pub
kw pub(crate)
kw pub(super)
- kw self
- kw super
+ kw self::
+ kw super::
"#]],
)
}
@@ -82,9 +82,9 @@ fn x<'lt, T, const C: usize>() -> $0
tp T
un Union
bt u32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -108,9 +108,9 @@ const FOO: $0 = Foo(2);
un Union
bt u32
it Foo<i32>
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -135,9 +135,9 @@ fn f2() {
un Union
bt u32
it i32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -164,9 +164,9 @@ fn f2() {
un Union
bt u32
it u64
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -190,9 +190,9 @@ fn f2(x: u64) -> $0 {
un Union
bt u32
it u64
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -217,9 +217,9 @@ fn f2(x: $0) {
un Union
bt u32
it i32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -252,9 +252,9 @@ fn foo<'lt, T, const C: usize>() {
un Union
bt u32
it a::Foo<a::Foo<i32>>
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -282,9 +282,9 @@ fn foo<'lt, T, const C: usize>() {
un Union
bt u32
it Foo<i32>
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
}
@@ -309,9 +309,9 @@ fn foo<'lt, T, const C: usize>() {
tp T
un Union
bt u32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
check(
@@ -359,9 +359,9 @@ fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
tp T
un Union
bt u32
- kw crate
- kw self
- kw super
+ kw crate::
+ kw self::
+ kw super::
"#]],
);
check(