1 //! Completion of names from the current scope, e.g. locals and imported items.
4 use syntax::{ast, AstNode};
6 use crate::{patterns::ImmediateLocation, CompletionContext, Completions};
8 pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionContext) {
9 if ctx.is_path_disallowed() || !ctx.is_trivial_path() || ctx.has_impl_or_trait_prev_sibling() {
13 if ctx.expects_item() || ctx.expects_assoc_item() {
14 // only show macros in {Assoc}ItemList
15 ctx.scope.process_all_names(&mut |name, res| {
16 if let hir::ScopeDef::MacroDef(mac) = res {
18 acc.add_macro(ctx, Some(name.clone()), mac);
21 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
22 acc.add_resolution(ctx, name, &res);
28 if ctx.in_use_tree() {
29 // only show modules in a fresh UseTree
30 cov_mark::hit!(only_completes_modules_in_import);
31 ctx.scope.process_all_names(&mut |name, res| {
32 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = res {
33 acc.add_resolution(ctx, name, &res);
39 if !ctx.expects_type() {
40 if let Some(hir::Adt::Enum(e)) =
41 ctx.expected_type.as_ref().and_then(|ty| ty.strip_references().as_adt())
43 super::enum_variants_with_paths(acc, ctx, e, |acc, ctx, variant, path| {
44 acc.add_qualified_enum_variant(ctx, variant, path)
49 if let Some(ImmediateLocation::GenericArgList(arg_list)) = &ctx.completion_location {
50 if let Some(path_seg) = arg_list.syntax().parent().and_then(ast::PathSegment::cast) {
51 if let Some(hir::PathResolution::Def(hir::ModuleDef::Trait(trait_))) =
52 ctx.sema.resolve_path(&path_seg.parent_path())
54 trait_.items(ctx.sema.db).into_iter().for_each(|it| {
55 if let hir::AssocItem::TypeAlias(alias) = it {
56 acc.add_type_alias_with_eq(ctx, alias)
63 ctx.scope.process_all_names(&mut |name, res| {
64 if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) | ScopeDef::Label(_) =
67 cov_mark::hit!(skip_lifetime_completion);
70 let add_resolution = match res {
71 ScopeDef::ImplSelfType(_) => {
72 !ctx.previous_token_is(syntax::T![impl]) && !ctx.previous_token_is(syntax::T![for])
74 // Don't suggest attribute macros and derives.
75 ScopeDef::MacroDef(mac) => mac.is_fn_like(),
76 // no values in type places
78 hir::ModuleDef::Function(_)
79 | hir::ModuleDef::Variant(_)
80 | hir::ModuleDef::Static(_),
82 | ScopeDef::Local(_) => !ctx.expects_type(),
83 // unless its a constant in a generic arg list position
84 ScopeDef::ModuleDef(hir::ModuleDef::Const(_))
85 | ScopeDef::GenericParam(hir::GenericParam::ConstParam(_)) => {
86 !ctx.expects_type() || ctx.expects_generic_arg()
91 acc.add_resolution(ctx, name, &res);
98 use expect_test::{expect, Expect};
101 tests::{check_edit, filtered_completion_list_with_config, TEST_CONFIG},
102 CompletionConfig, CompletionKind,
105 fn check(ra_fixture: &str, expect: Expect) {
106 check_with_config(TEST_CONFIG, ra_fixture, expect);
109 fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
111 filtered_completion_list_with_config(config, ra_fixture, CompletionKind::Reference);
112 expect.assert_eq(&actual)
116 fn dont_complete_values_in_type_pos() {
138 fn completes_bindings_from_let() {
156 fn completes_bindings_from_if_let() {
160 if let Some(x) = foo() {
163 if let Some(a) = bar() {
178 fn completes_bindings_from_for() {
182 for x in &[1, 2, 3] { $0 }
193 fn completes_if_prefix_is_keyword() {
194 cov_mark::check!(completes_if_prefix_is_keyword);
213 fn completes_generic_params() {
215 r#"fn quux<T>() { $0 }"#,
222 r#"fn quux<const C: usize>() { $0 }"#,
231 fn does_not_complete_lifetimes() {
232 cov_mark::check!(skip_lifetime_completion);
234 r#"fn quux<'a>() { $0 }"#,
242 fn completes_generic_params_in_struct() {
244 r#"struct S<T> { x: $0}"#,
254 fn completes_self_in_enum() {
256 r#"enum X { Y($0) }"#,
265 fn completes_module_items() {
280 /// Regression test for issue #6091.
282 fn correctly_completes_module_items_prefixed_with_underscore() {
301 fn completes_module_items_in_nested_modules() {
318 fn completes_return_type() {
331 fn dont_show_both_completions_for_shadowing() {
342 // FIXME: should be only one bar here
352 fn completes_self_in_methods() {
354 r#"impl S { fn foo(&self) { $0 } }"#,
363 fn completes_prelude() {
366 //- /main.rs crate:main deps:std
367 fn foo() { let x: $0 }
369 //- /std/lib.rs crate:std
384 fn completes_prelude_macros() {
387 //- /main.rs crate:main deps:std
390 //- /std/lib.rs crate:std
393 pub use crate::concat;
398 #[rustc_builtin_macro]
400 macro_rules! concat { }
405 ma concat!(…) #[macro_export] macro_rules! concat
412 fn does_not_complete_non_fn_macros() {
415 #[rustc_builtin_macro]
426 #[rustc_builtin_macro]
438 fn completes_std_prelude_if_core_is_defined() {
441 //- /main.rs crate:main deps:core,std
442 fn foo() { let x: $0 }
444 //- /core/lib.rs crate:core
451 //- /std/lib.rs crate:std deps:core
467 fn completes_macros_as_value() {
470 macro_rules! foo { () => {} }
474 macro_rules! bar { () => {} }
478 macro_rules! nope { () => {} }
481 macro_rules! baz { () => {} }
484 fn main() { let v = $0 }
488 ma baz!(…) #[macro_export] macro_rules! baz
491 ma bar!(…) macro_rules! bar
492 ma foo!(…) macro_rules! foo
498 fn completes_both_macro_and_value() {
501 macro_rules! foo { () => {} }
506 ma foo!(…) macro_rules! foo
512 fn completes_macros_as_type() {
515 macro_rules! foo { () => {} }
516 fn main() { let x: $0 }
519 ma foo!(…) macro_rules! foo
525 fn completes_macros_as_stmt() {
528 macro_rules! foo { () => {} }
533 ma foo!(…) macro_rules! foo
539 fn completes_local_item() {
555 fn completes_in_simple_macro_1() {
558 macro_rules! m { ($e:expr) => { $e } }
568 ma m!(…) macro_rules! m
574 fn completes_in_simple_macro_2() {
577 macro_rules! m { ($e:expr) => { $e } }
587 ma m!(…) macro_rules! m
593 fn completes_in_simple_macro_without_closing_parens() {
596 macro_rules! m { ($e:expr) => { $e } }
606 ma m!(…) macro_rules! m
612 fn completes_unresolved_uses() {
627 fn completes_enum_variant_basic_expr() {
630 enum Foo { Bar, Baz, Quux }
631 fn main() { let foo: Foo = Q$0 }
644 fn completes_enum_variant_from_module() {
647 mod m { pub enum E { V } }
648 fn f() -> m::E { V$0 }
659 fn dont_complete_attr() {
671 fn completes_types_and_const_in_arg_list() {
681 const CONST: () = ();
683 fn foo<T: Foo<$0>, const CONST_PARAM: usize>(_: T) {}