1 //! Completion of paths, i.e. `some::prefix::$0`.
3 use hir::HasVisibility;
4 use rustc_hash::FxHashSet;
7 use crate::{CompletionContext, Completions};
9 pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
10 if ctx.is_path_disallowed() {
13 let path = match ctx.path_qual() {
18 let resolution = match ctx.sema.resolve_path(path) {
23 let context_module = ctx.scope.module();
25 if ctx.expects_item() || ctx.expects_assoc_item() {
26 if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
27 let module_scope = module.scope(ctx.db, context_module);
28 for (name, def) in module_scope {
29 if let hir::ScopeDef::MacroDef(macro_def) = def {
30 if macro_def.is_fn_like() {
31 acc.add_macro(ctx, Some(name.clone()), macro_def);
34 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
35 acc.add_resolution(ctx, name, &def);
42 // Add associated types on type parameters and `Self`.
43 resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| {
44 acc.add_type_alias(ctx, alias);
49 hir::PathResolution::Def(hir::ModuleDef::Module(module)) => {
50 let module_scope = module.scope(ctx.db, context_module);
51 for (name, def) in module_scope {
52 if ctx.in_use_tree() {
53 if let hir::ScopeDef::Unknown = def {
54 if let Some(name_ref) = ctx.name_ref_syntax.as_ref() {
55 if name_ref.syntax().text() == name.to_string().as_str() {
56 // for `use self::foo$0`, don't suggest `foo` as a completion
57 cov_mark::hit!(dont_complete_current_use);
64 let add_resolution = match def {
65 // Don't suggest attribute macros and derives.
66 hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(),
67 // no values in type places
68 hir::ScopeDef::ModuleDef(
69 hir::ModuleDef::Function(_)
70 | hir::ModuleDef::Variant(_)
71 | hir::ModuleDef::Static(_),
73 | hir::ScopeDef::Local(_) => !ctx.expects_type(),
74 // unless its a constant in a generic arg list position
75 hir::ScopeDef::ModuleDef(hir::ModuleDef::Const(_)) => {
76 !ctx.expects_type() || ctx.expects_generic_arg()
82 acc.add_resolution(ctx, name, &def);
86 hir::PathResolution::Def(
89 (hir::ModuleDef::Adt(_)
90 | hir::ModuleDef::TypeAlias(_)
91 | hir::ModuleDef::BuiltinType(_)),
93 if let hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
94 add_enum_variants(acc, ctx, e);
97 hir::ModuleDef::Adt(adt) => adt.ty(ctx.db),
98 hir::ModuleDef::TypeAlias(a) => {
99 let ty = a.ty(ctx.db);
100 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
101 cov_mark::hit!(completes_variant_through_alias);
102 add_enum_variants(acc, ctx, e);
106 hir::ModuleDef::BuiltinType(builtin) => {
107 let module = match ctx.scope.module() {
111 cov_mark::hit!(completes_primitive_assoc_const);
112 builtin.ty(ctx.db, module)
117 // XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType.
118 // (where AssocType is defined on a trait, not an inherent impl)
120 let krate = ctx.krate;
121 if let Some(krate) = krate {
122 let traits_in_scope = ctx.scope.traits_in_scope();
123 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
124 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
127 add_assoc_item(acc, ctx, item);
131 // Iterate assoc types separately
132 ty.iterate_assoc_items(ctx.db, krate, |item| {
133 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
136 if let hir::AssocItem::TypeAlias(ty) = item {
137 acc.add_type_alias(ctx, ty)
143 hir::PathResolution::Def(hir::ModuleDef::Trait(t)) => {
144 // Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`.
145 for item in t.items(ctx.db) {
146 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
149 add_assoc_item(acc, ctx, item);
152 hir::PathResolution::TypeParam(_) | hir::PathResolution::SelfType(_) => {
153 if let Some(krate) = ctx.krate {
154 let ty = match resolution {
155 hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
156 hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
160 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
161 add_enum_variants(acc, ctx, e);
164 let traits_in_scope = ctx.scope.traits_in_scope();
165 let mut seen = FxHashSet::default();
166 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
167 if context_module.map_or(false, |m| !item.is_visible_from(ctx.db, m)) {
171 // We might iterate candidates of a trait multiple times here, so deduplicate
173 if seen.insert(item) {
174 add_assoc_item(acc, ctx, item);
184 fn add_assoc_item(acc: &mut Completions, ctx: &CompletionContext, item: hir::AssocItem) {
186 hir::AssocItem::Function(func) if !ctx.expects_type() => acc.add_function(ctx, func, None),
187 hir::AssocItem::Const(ct) if !ctx.expects_type() || ctx.expects_generic_arg() => {
188 acc.add_const(ctx, ct)
190 hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
195 fn add_enum_variants(acc: &mut Completions, ctx: &CompletionContext, e: hir::Enum) {
196 if ctx.expects_type() {
199 e.variants(ctx.db).into_iter().for_each(|variant| acc.add_enum_variant(ctx, variant, None));
204 use expect_test::{expect, Expect};
207 tests::{check_edit, filtered_completion_list},
211 fn check(ra_fixture: &str, expect: Expect) {
212 let actual = filtered_completion_list(ra_fixture, CompletionKind::Reference);
213 expect.assert_eq(&actual);
216 fn check_builtin(ra_fixture: &str, expect: Expect) {
217 let actual = filtered_completion_list(ra_fixture, CompletionKind::BuiltinType);
218 expect.assert_eq(&actual);
222 fn dont_complete_primitive_in_use() {
223 check_builtin(r#"use self::$0;"#, expect![[""]]);
227 fn dont_complete_primitive_in_module_scope() {
228 check_builtin(r#"fn foo() { self::$0 }"#, expect![[""]]);
232 fn completes_enum_variant() {
235 enum E { Foo, Bar(i32) }
236 fn foo() { let _ = E::$0 }
246 fn completes_struct_associated_items() {
259 fn foo() { let _ = S::$0 }
264 ct C const C: i32 = 42;
271 fn associated_item_visibility() {
278 pub(crate) fn public_method() { }
279 fn private_method() { }
280 pub(crate) type PublicType = u32;
281 type PrivateType = u32;
282 pub(crate) const PUBLIC_CONST: u32 = 1;
283 const PRIVATE_CONST: u32 = 1;
287 fn foo() { let _ = S::$0 }
290 fn public_method() fn()
291 ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1;
292 ta PublicType pub(crate) type PublicType = u32;
298 fn completes_enum_associated_method() {
302 impl E { fn m() { } }
304 fn foo() { let _ = E::$0 }
313 fn completes_union_associated_method() {
317 impl U { fn m() { } }
319 fn foo() { let _ = U::$0 }
328 fn completes_trait_associated_method_1() {
331 trait Trait { fn m(); }
333 fn foo() { let _ = Trait::$0 }
342 fn completes_trait_associated_method_2() {
345 trait Trait { fn m(); }
350 fn foo() { let _ = S::$0 }
359 fn completes_trait_associated_method_3() {
362 trait Trait { fn m(); }
367 fn foo() { let _ = <S as Trait>::$0 }
376 fn completes_ty_param_assoc_ty() {
390 fn submethod(&self) {}
393 fn foo<T: Sub>() { T::$0 }
400 me submethod(…) fn(&self)
401 ct CONST const CONST: u8;
403 me method(…) fn(&self)
409 fn completes_self_param_assoc_ty() {
423 fn submethod(&self) {}
427 impl<T> Super for Wrap<T> {}
428 impl<T> Sub for Wrap<T> {
430 // Should be able to assume `Self: Sub + Super`
438 ct CONST const CONST: u8 = 0;
440 me method(…) fn(&self)
441 ct C2 const C2: () = ();
443 me submethod(…) fn(&self)
449 fn completes_type_alias() {
453 impl S { fn foo() {} }
455 impl T { fn bar() {} }
467 fn completes_qualified_macros() {
471 macro_rules! foo { () => {} }
473 fn main() { let _ = crate::$0 }
477 ma foo!(…) #[macro_export] macro_rules! foo
483 fn does_not_complete_non_fn_macros() {
487 #[rustc_builtin_macro]
498 #[rustc_builtin_macro]
509 fn completes_reexported_items_under_correct_name() {
512 fn foo() { self::m::$0 }
515 pub use super::p::wrong_fn as right_fn;
516 pub use super::p::WRONG_CONST as RIGHT_CONST;
517 pub use super::p::WrongType as RightType;
521 const WRONG_CONST: u32 = 1;
535 fn foo() { self::m::$0 }
538 pub use super::p::wrong_fn as right_fn;
539 pub use super::p::WRONG_CONST as RIGHT_CONST;
540 pub use super::p::WrongType as RightType;
544 const WRONG_CONST: u32 = 1;
549 fn foo() { self::m::RightType }
552 pub use super::p::wrong_fn as right_fn;
553 pub use super::p::WRONG_CONST as RIGHT_CONST;
554 pub use super::p::WrongType as RightType;
558 const WRONG_CONST: u32 = 1;
566 fn completes_in_simple_macro_call() {
569 macro_rules! m { ($e:expr) => { $e } }
570 fn main() { m!(self::f$0); }
581 fn function_mod_share_name() {
584 fn foo() { self::m::$0 }
599 fn completes_hashmap_new() {
603 struct HashMap<K, V, S = RandomState> {}
605 impl<K, V> HashMap<K, V, RandomState> {
606 pub fn new() -> HashMap<K, V, RandomState> { }
613 fn new() fn() -> HashMap<K, V, RandomState>
619 fn dont_complete_attr() {
622 mod foo { pub struct Foo; }
631 fn completes_variant_through_self() {
654 fn completes_primitive_assoc_const() {
655 cov_mark::check!(completes_primitive_assoc_const);
658 //- /lib.rs crate:lib deps:core
663 //- /core.rs crate:core
666 pub const MAX: Self = 255;
672 ct MAX pub const MAX: Self = 255;
679 fn completes_variant_through_alias() {
680 cov_mark::check!(completes_variant_through_alias);