1 //! Completion of paths, i.e. `some::prefix::$0`.
3 use hir::{Adt, HasVisibility, PathResolution, ScopeDef};
4 use rustc_hash::FxHashSet;
7 use crate::{CompletionContext, Completions};
9 pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
10 let path = match &ctx.path_qual {
11 Some(path) => path.clone(),
15 if ctx.attribute_under_caret.is_some() || ctx.mod_declaration_under_caret.is_some() {
19 let context_module = ctx.scope.module();
21 let resolution = match ctx.sema.resolve_path(&path) {
26 // Add associated types on type parameters and `Self`.
27 resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| {
28 acc.add_type_alias(ctx, alias);
33 PathResolution::Def(hir::ModuleDef::Module(module)) => {
34 let module_scope = module.scope(ctx.db, context_module);
35 for (name, def) in module_scope {
36 if ctx.use_item_syntax.is_some() {
37 if let ScopeDef::Unknown = def {
38 if let Some(name_ref) = ctx.name_ref_syntax.as_ref() {
39 if name_ref.syntax().text() == name.to_string().as_str() {
40 // for `use self::foo$0`, don't suggest `foo` as a completion
41 cov_mark::hit!(dont_complete_current_use);
48 acc.add_resolution(ctx, name.to_string(), &def);
51 PathResolution::Def(def @ hir::ModuleDef::Adt(_))
52 | PathResolution::Def(def @ hir::ModuleDef::TypeAlias(_))
53 | PathResolution::Def(def @ hir::ModuleDef::BuiltinType(_)) => {
54 if let hir::ModuleDef::Adt(Adt::Enum(e)) = def {
55 add_enum_variants(ctx, acc, e);
58 hir::ModuleDef::Adt(adt) => adt.ty(ctx.db),
59 hir::ModuleDef::TypeAlias(a) => {
60 let ty = a.ty(ctx.db);
61 if let Some(Adt::Enum(e)) = ty.as_adt() {
62 cov_mark::hit!(completes_variant_through_alias);
63 add_enum_variants(ctx, acc, e);
67 hir::ModuleDef::BuiltinType(builtin) => {
68 let module = match ctx.scope.module() {
72 cov_mark::hit!(completes_primitive_assoc_const);
73 builtin.ty(ctx.db, module)
78 // XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType.
79 // (where AssocType is defined on a trait, not an inherent impl)
81 let krate = ctx.krate;
82 if let Some(krate) = krate {
83 let traits_in_scope = ctx.scope.traits_in_scope();
84 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
85 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
89 hir::AssocItem::Function(func) => acc.add_function(ctx, func, None),
90 hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
91 hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
96 // Iterate assoc types separately
97 ty.iterate_assoc_items(ctx.db, krate, |item| {
98 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
101 if let hir::AssocItem::TypeAlias(ty) = item {
102 acc.add_type_alias(ctx, ty)
108 PathResolution::Def(hir::ModuleDef::Trait(t)) => {
109 // Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`.
110 for item in t.items(ctx.db) {
111 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
115 hir::AssocItem::Function(func) => acc.add_function(ctx, func, None),
116 hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
117 hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
121 PathResolution::TypeParam(_) | PathResolution::SelfType(_) => {
122 if let Some(krate) = ctx.krate {
123 let ty = match resolution {
124 PathResolution::TypeParam(param) => param.ty(ctx.db),
125 PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
129 if let Some(Adt::Enum(e)) = ty.as_adt() {
130 add_enum_variants(ctx, acc, e);
133 let traits_in_scope = ctx.scope.traits_in_scope();
134 let mut seen = FxHashSet::default();
135 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
136 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
140 // We might iterate candidates of a trait multiple times here, so deduplicate
142 if seen.insert(item) {
144 hir::AssocItem::Function(func) => acc.add_function(ctx, func, None),
145 hir::AssocItem::Const(ct) => acc.add_const(ctx, ct),
146 hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
157 fn add_enum_variants(ctx: &CompletionContext, acc: &mut Completions, e: hir::Enum) {
158 for variant in e.variants(ctx.db) {
159 acc.add_enum_variant(ctx, variant, None);
165 use expect_test::{expect, Expect};
168 test_utils::{check_edit, completion_list},
172 fn check(ra_fixture: &str, expect: Expect) {
173 let actual = completion_list(ra_fixture, CompletionKind::Reference);
174 expect.assert_eq(&actual);
177 fn check_builtin(ra_fixture: &str, expect: Expect) {
178 let actual = completion_list(ra_fixture, CompletionKind::BuiltinType);
179 expect.assert_eq(&actual);
183 fn dont_complete_current_use() {
184 cov_mark::check!(dont_complete_current_use);
185 check(r#"use self::foo$0;"#, expect![[""]]);
189 fn dont_complete_current_use_in_braces_with_glob() {
192 mod foo { pub struct S; }
193 use self::{foo::*, bar$0};
203 fn dont_complete_primitive_in_use() {
204 check_builtin(r#"use self::$0;"#, expect![[""]]);
208 fn dont_complete_primitive_in_module_scope() {
209 check_builtin(r#"fn foo() { self::$0 }"#, expect![[""]]);
213 fn completes_primitives() {
215 r#"fn main() { let _: $0 = 92; }"#,
239 fn completes_mod_with_same_name_as_function() {
244 mod my { pub struct Bar; }
254 fn filters_visibility() {
262 pub use Bar as PublicBar;
273 fn completes_use_item_starting_with_self() {
278 mod m { pub struct Bar; }
287 fn completes_use_item_starting_with_crate() {
304 fn completes_nested_use_tree() {
321 fn completes_deeply_nested_use_tree() {
332 use crate::{bar::{baz::Sp$0}};
341 fn completes_enum_variant() {
344 enum E { Foo, Bar(i32) }
345 fn foo() { let _ = E::$0 }
355 fn completes_struct_associated_items() {
368 fn foo() { let _ = S::$0 }
373 ct C const C: i32 = 42;
380 fn associated_item_visibility() {
387 pub(crate) fn public_method() { }
388 fn private_method() { }
389 pub(crate) type PublicType = u32;
390 type PrivateType = u32;
391 pub(crate) const PUBLIC_CONST: u32 = 1;
392 const PRIVATE_CONST: u32 = 1;
396 fn foo() { let _ = S::$0 }
399 fn public_method() fn()
400 ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1;
401 ta PublicType pub(crate) type PublicType = u32;
407 fn completes_enum_associated_method() {
411 impl E { fn m() { } }
413 fn foo() { let _ = E::$0 }
422 fn completes_union_associated_method() {
426 impl U { fn m() { } }
428 fn foo() { let _ = U::$0 }
437 fn completes_use_paths_across_crates() {
440 //- /main.rs crate:main deps:foo
443 //- /foo/lib.rs crate:foo
444 pub mod bar { pub struct S; }
453 fn completes_trait_associated_method_1() {
456 trait Trait { fn m(); }
458 fn foo() { let _ = Trait::$0 }
467 fn completes_trait_associated_method_2() {
470 trait Trait { fn m(); }
475 fn foo() { let _ = S::$0 }
484 fn completes_trait_associated_method_3() {
487 trait Trait { fn m(); }
492 fn foo() { let _ = <S as Trait>::$0 }
501 fn completes_ty_param_assoc_ty() {
515 fn submethod(&self) {}
518 fn foo<T: Sub>() { T::$0 }
525 me submethod(…) fn(&self)
526 ct CONST const CONST: u8;
528 me method(…) fn(&self)
534 fn completes_self_param_assoc_ty() {
548 fn submethod(&self) {}
552 impl<T> Super for Wrap<T> {}
553 impl<T> Sub for Wrap<T> {
555 // Should be able to assume `Self: Sub + Super`
563 ct CONST const CONST: u8 = 0;
565 me method(…) fn(&self)
566 ct C2 const C2: () = ();
568 me submethod(…) fn(&self)
574 fn completes_type_alias() {
578 impl S { fn foo() {} }
580 impl T { fn bar() {} }
592 fn completes_qualified_macros() {
596 macro_rules! foo { () => {} }
598 fn main() { let _ = crate::$0 }
602 ma foo!(…) #[macro_export] macro_rules! foo
608 fn test_super_super_completion() {
615 mod c { use super::super::$0 }
627 fn completes_reexported_items_under_correct_name() {
630 fn foo() { self::m::$0 }
633 pub use super::p::wrong_fn as right_fn;
634 pub use super::p::WRONG_CONST as RIGHT_CONST;
635 pub use super::p::WrongType as RightType;
639 const WRONG_CONST: u32 = 1;
653 fn foo() { self::m::$0 }
656 pub use super::p::wrong_fn as right_fn;
657 pub use super::p::WRONG_CONST as RIGHT_CONST;
658 pub use super::p::WrongType as RightType;
662 const WRONG_CONST: u32 = 1;
667 fn foo() { self::m::RightType }
670 pub use super::p::wrong_fn as right_fn;
671 pub use super::p::WRONG_CONST as RIGHT_CONST;
672 pub use super::p::WrongType as RightType;
676 const WRONG_CONST: u32 = 1;
684 fn completes_in_simple_macro_call() {
687 macro_rules! m { ($e:expr) => { $e } }
688 fn main() { m!(self::f$0); }
699 fn function_mod_share_name() {
702 fn foo() { self::m::$0 }
717 fn completes_hashmap_new() {
721 struct HashMap<K, V, S = RandomState> {}
723 impl<K, V> HashMap<K, V, RandomState> {
724 pub fn new() -> HashMap<K, V, RandomState> { }
731 fn new() fn() -> HashMap<K, V, RandomState>
737 fn dont_complete_attr() {
740 mod foo { pub struct Foo; }
749 fn completes_variant_through_self() {
772 fn completes_primitive_assoc_const() {
773 cov_mark::check!(completes_primitive_assoc_const);
776 //- /lib.rs crate:lib deps:core
781 //- /core.rs crate:core
784 pub const MAX: Self = 255;
790 ct MAX pub const MAX: Self = 255;
797 fn completes_variant_through_alias() {
798 cov_mark::check!(completes_variant_through_alias);