1 //! Completion of paths, i.e. `some::prefix::$0`.
5 use rustc_hash::FxHashSet;
6 use syntax::{ast, AstNode};
9 context::PathCompletionContext, patterns::ImmediateLocation, CompletionContext, Completions,
12 pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
13 if ctx.is_path_disallowed() || ctx.has_impl_or_trait_prev_sibling() {
16 let (path, use_tree_parent) = match &ctx.path_context {
17 Some(PathCompletionContext { qualifier: Some(qualifier), use_tree_parent, .. }) => {
18 (qualifier, *use_tree_parent)
23 let resolution = match ctx.sema.resolve_path(path) {
28 let context_module = ctx.scope.module();
30 match ctx.completion_location {
31 Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
32 if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
33 for (name, def) in module.scope(ctx.db, context_module) {
34 if let hir::ScopeDef::MacroDef(macro_def) = def {
35 if macro_def.is_fn_like() {
36 acc.add_macro(ctx, Some(name.clone()), macro_def);
39 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
40 acc.add_resolution(ctx, name, &def);
46 Some(ImmediateLocation::Visibility(_)) => {
47 if let hir::PathResolution::Def(hir::ModuleDef::Module(resolved)) = resolution {
48 if let Some(current_module) = ctx.scope.module() {
49 if let Some(next) = current_module
52 .take_while(|&it| it != resolved)
55 if let Some(name) = next.name(ctx.db) {
56 acc.add_resolution(ctx, name, &hir::ScopeDef::ModuleDef(next.into()));
66 if ctx.in_use_tree() {
67 if iter::successors(Some(path.clone()), |p| p.qualifier())
68 .all(|p| p.segment().and_then(|s| s.super_token()).is_some())
70 acc.add_keyword(ctx, "super::");
72 // only show `self` in a new use-tree when the qualifier doesn't end in self
75 path.segment().and_then(|it| it.kind()),
76 Some(ast::PathSegmentKind::SelfKw)
79 acc.add_keyword(ctx, "self");
83 // Add associated types on type parameters and `Self`.
84 resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| {
85 acc.add_type_alias(ctx, alias);
90 hir::PathResolution::Def(hir::ModuleDef::Module(module)) => {
91 let module_scope = module.scope(ctx.db, context_module);
92 for (name, def) in module_scope {
93 if ctx.in_use_tree() {
94 if let hir::ScopeDef::Unknown = def {
95 if let Some(name_ref) = ctx.name_ref_syntax.as_ref() {
96 if name_ref.syntax().text() == name.to_string().as_str() {
97 // for `use self::foo$0`, don't suggest `foo` as a completion
98 cov_mark::hit!(dont_complete_current_use);
105 let add_resolution = match def {
106 // Don't suggest attribute macros and derives.
107 hir::ScopeDef::MacroDef(mac) => mac.is_fn_like(),
108 // no values in type places
109 hir::ScopeDef::ModuleDef(
110 hir::ModuleDef::Function(_)
111 | hir::ModuleDef::Variant(_)
112 | hir::ModuleDef::Static(_),
114 | hir::ScopeDef::Local(_) => !ctx.expects_type(),
115 // unless its a constant in a generic arg list position
116 hir::ScopeDef::ModuleDef(hir::ModuleDef::Const(_)) => {
117 !ctx.expects_type() || ctx.expects_generic_arg()
122 // FIXME: respect #[doc(hidden)] (see `CompletionContext::is_visible`)
124 acc.add_resolution(ctx, name, &def);
128 hir::PathResolution::Def(
131 (hir::ModuleDef::Adt(_)
132 | hir::ModuleDef::TypeAlias(_)
133 | hir::ModuleDef::BuiltinType(_)),
135 if let hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
136 add_enum_variants(acc, ctx, e);
139 hir::ModuleDef::Adt(adt) => adt.ty(ctx.db),
140 hir::ModuleDef::TypeAlias(a) => {
141 let ty = a.ty(ctx.db);
142 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
143 cov_mark::hit!(completes_variant_through_alias);
144 add_enum_variants(acc, ctx, e);
148 hir::ModuleDef::BuiltinType(builtin) => {
149 let module = match ctx.scope.module() {
153 cov_mark::hit!(completes_primitive_assoc_const);
154 builtin.ty(ctx.db, module)
159 // XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType.
160 // (where AssocType is defined on a trait, not an inherent impl)
162 let krate = ctx.krate;
163 if let Some(krate) = krate {
164 let traits_in_scope = ctx.scope.traits_in_scope();
165 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
166 if !ctx.is_visible(&item) {
169 add_assoc_item(acc, ctx, item);
173 // Iterate assoc types separately
174 ty.iterate_assoc_items(ctx.db, krate, |item| {
175 if !ctx.is_visible(&item) {
178 if let hir::AssocItem::TypeAlias(ty) = item {
179 acc.add_type_alias(ctx, ty)
185 hir::PathResolution::Def(hir::ModuleDef::Trait(t)) => {
186 // Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`.
187 for item in t.items(ctx.db) {
188 if !ctx.is_visible(&item) {
191 add_assoc_item(acc, ctx, item);
194 hir::PathResolution::TypeParam(_) | hir::PathResolution::SelfType(_) => {
195 if let Some(krate) = ctx.krate {
196 let ty = match resolution {
197 hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
198 hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
202 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
203 add_enum_variants(acc, ctx, e);
206 let traits_in_scope = ctx.scope.traits_in_scope();
207 let mut seen = FxHashSet::default();
208 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
209 if !ctx.is_visible(&item) {
213 // We might iterate candidates of a trait multiple times here, so deduplicate
215 if seen.insert(item) {
216 add_assoc_item(acc, ctx, item);
226 fn add_assoc_item(acc: &mut Completions, ctx: &CompletionContext, item: hir::AssocItem) {
228 hir::AssocItem::Function(func) if !ctx.expects_type() => acc.add_function(ctx, func, None),
229 hir::AssocItem::Const(ct) if !ctx.expects_type() || ctx.expects_generic_arg() => {
230 acc.add_const(ctx, ct)
232 hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
237 fn add_enum_variants(acc: &mut Completions, ctx: &CompletionContext, e: hir::Enum) {
238 if ctx.expects_type() {
241 e.variants(ctx.db).into_iter().for_each(|variant| acc.add_enum_variant(ctx, variant, None));
246 use expect_test::{expect, Expect};
249 tests::{check_edit, filtered_completion_list},
253 fn check(ra_fixture: &str, expect: Expect) {
254 let actual = filtered_completion_list(ra_fixture, CompletionKind::Reference);
255 expect.assert_eq(&actual);
259 fn associated_item_visibility() {
262 //- /lib.rs crate:lib new_source_root:library
266 pub fn public_method() { }
267 fn private_method() { }
268 pub type PublicType = u32;
269 type PrivateType = u32;
270 pub const PUBLIC_CONST: u32 = 1;
271 const PRIVATE_CONST: u32 = 1;
274 //- /main.rs crate:main deps:lib new_source_root:local
275 fn foo() { let _ = lib::S::$0 }
278 fn public_method() fn()
279 ct PUBLIC_CONST pub const PUBLIC_CONST: u32 = 1;
280 ta PublicType pub type PublicType = u32;
286 fn completes_union_associated_method() {
290 impl U { fn m() { } }
292 fn foo() { let _ = U::$0 }
301 fn completes_trait_associated_method_1() {
304 trait Trait { fn m(); }
306 fn foo() { let _ = Trait::$0 }
309 fn m() (as Trait) fn()
315 fn completes_trait_associated_method_2() {
318 trait Trait { fn m(); }
323 fn foo() { let _ = S::$0 }
326 fn m() (as Trait) fn()
332 fn completes_trait_associated_method_3() {
335 trait Trait { fn m(); }
340 fn foo() { let _ = <S as Trait>::$0 }
343 fn m() (as Trait) fn()
349 fn completes_ty_param_assoc_ty() {
363 fn submethod(&self) {}
366 fn foo<T: Sub>() { T::$0 }
369 ta SubTy (as Sub) type SubTy;
370 ta Ty (as Super) type Ty;
371 ct C2 (as Sub) const C2: ();
372 fn subfunc() (as Sub) fn()
373 me submethod(…) (as Sub) fn(&self)
374 ct CONST (as Super) const CONST: u8;
375 fn func() (as Super) fn()
376 me method(…) (as Super) fn(&self)
382 fn completes_self_param_assoc_ty() {
396 fn submethod(&self) {}
400 impl<T> Super for Wrap<T> {}
401 impl<T> Sub for Wrap<T> {
403 // Should be able to assume `Self: Sub + Super`
409 ta SubTy (as Sub) type SubTy;
410 ta Ty (as Super) type Ty;
411 ct CONST (as Super) const CONST: u8 = 0;
412 fn func() (as Super) fn()
413 me method(…) (as Super) fn(&self)
414 ct C2 (as Sub) const C2: () = ();
415 fn subfunc() (as Sub) fn()
416 me submethod(…) (as Sub) fn(&self)
422 fn completes_type_alias() {
426 impl S { fn foo() {} }
428 impl T { fn bar() {} }
440 fn completes_qualified_macros() {
444 macro_rules! foo { () => {} }
446 fn main() { let _ = crate::$0 }
450 ma foo!(…) #[macro_export] macro_rules! foo
456 fn does_not_complete_non_fn_macros() {
460 #[rustc_builtin_macro]
471 #[rustc_builtin_macro]
482 fn completes_reexported_items_under_correct_name() {
485 fn foo() { self::m::$0 }
488 pub use super::p::wrong_fn as right_fn;
489 pub use super::p::WRONG_CONST as RIGHT_CONST;
490 pub use super::p::WrongType as RightType;
494 const WRONG_CONST: u32 = 1;
508 fn foo() { self::m::$0 }
511 pub use super::p::wrong_fn as right_fn;
512 pub use super::p::WRONG_CONST as RIGHT_CONST;
513 pub use super::p::WrongType as RightType;
517 const WRONG_CONST: u32 = 1;
522 fn foo() { self::m::RightType }
525 pub use super::p::wrong_fn as right_fn;
526 pub use super::p::WRONG_CONST as RIGHT_CONST;
527 pub use super::p::WrongType as RightType;
531 const WRONG_CONST: u32 = 1;
539 fn completes_in_simple_macro_call() {
542 macro_rules! m { ($e:expr) => { $e } }
543 fn main() { m!(self::f$0); }
554 fn function_mod_share_name() {
557 fn foo() { self::m::$0 }
572 fn completes_hashmap_new() {
576 struct HashMap<K, V, S = RandomState> {}
578 impl<K, V> HashMap<K, V, RandomState> {
579 pub fn new() -> HashMap<K, V, RandomState> { }
586 fn new() fn() -> HashMap<K, V, RandomState>
592 fn dont_complete_attr() {
595 mod foo { pub struct Foo; }
604 fn completes_variant_through_self() {
627 fn completes_primitive_assoc_const() {
628 cov_mark::check!(completes_primitive_assoc_const);
631 //- /lib.rs crate:lib deps:core
636 //- /core.rs crate:core
639 pub const MAX: Self = 255;
645 ct MAX pub const MAX: Self = 255;
652 fn completes_variant_through_alias() {
653 cov_mark::check!(completes_variant_through_alias);