1 //! Completion of paths, i.e. `some::prefix::$0`.
5 use hir::{ScopeDef, Trait};
6 use rustc_hash::FxHashSet;
7 use syntax::{ast, AstNode};
10 context::{PathCompletionContext, PathKind},
11 patterns::ImmediateLocation,
12 CompletionContext, Completions,
15 pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
16 if ctx.is_path_disallowed() || ctx.has_impl_or_trait_prev_sibling() {
19 let (path, use_tree_parent, kind) = match ctx.path_context {
20 // let ... else, syntax would come in really handy here right now
21 Some(PathCompletionContext {
22 qualifier: Some(ref qualifier),
26 }) => (qualifier, use_tree_parent, kind),
30 // special case `<_>::$0` as this doesn't resolve to anything.
31 if path.qualifier().is_none() {
33 path.segment().and_then(|it| it.kind()),
34 Some(ast::PathSegmentKind::Type {
35 type_ref: Some(ast::Type::InferType(_)),
39 cov_mark::hit!(completion_type_anchor_empty);
43 .flat_map(|it| Trait::from(it).items(ctx.sema.db))
44 .for_each(|item| add_assoc_item(acc, ctx, item));
49 let resolution = match ctx.sema.resolve_path(path) {
54 let context_module = ctx.scope.module();
56 match ctx.completion_location {
57 Some(ImmediateLocation::ItemList | ImmediateLocation::Trait | ImmediateLocation::Impl) => {
58 if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
59 for (name, def) in module.scope(ctx.db, context_module) {
60 if let ScopeDef::MacroDef(macro_def) = def {
61 if macro_def.is_fn_like() {
62 acc.add_macro(ctx, Some(name.clone()), macro_def);
65 if let ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
66 acc.add_resolution(ctx, name, def);
76 Some(PathKind::Vis { .. }) => {
77 if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
78 if let Some(current_module) = ctx.scope.module() {
79 if let Some(next) = current_module
82 .take_while(|&it| it != module)
85 if let Some(name) = next.name(ctx.db) {
86 acc.add_resolution(ctx, name, ScopeDef::ModuleDef(next.into()));
93 Some(PathKind::Attr) => {
94 if let hir::PathResolution::Def(hir::ModuleDef::Module(module)) = resolution {
95 for (name, def) in module.scope(ctx.db, context_module) {
96 let add_resolution = match def {
97 ScopeDef::MacroDef(mac) => mac.is_attr(),
98 ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) => true,
102 acc.add_resolution(ctx, name, def);
108 Some(PathKind::Use) => {
109 if iter::successors(Some(path.clone()), |p| p.qualifier())
110 .all(|p| p.segment().and_then(|s| s.super_token()).is_some())
112 acc.add_keyword(ctx, "super::");
114 // only show `self` in a new use-tree when the qualifier doesn't end in self
117 path.segment().and_then(|it| it.kind()),
118 Some(ast::PathSegmentKind::SelfKw)
121 acc.add_keyword(ctx, "self");
127 if !matches!(kind, Some(PathKind::Pat)) {
128 // Add associated types on type parameters and `Self`.
129 resolution.assoc_type_shorthand_candidates(ctx.db, |_, alias| {
130 acc.add_type_alias(ctx, alias);
136 hir::PathResolution::Def(hir::ModuleDef::Module(module)) => {
137 let module_scope = module.scope(ctx.db, context_module);
138 for (name, def) in module_scope {
139 if let Some(PathKind::Use) = kind {
140 if let ScopeDef::Unknown = def {
141 if let Some(ast::NameLike::NameRef(name_ref)) = ctx.name_syntax.as_ref() {
142 if name_ref.syntax().text() == name.to_smol_str().as_str() {
143 // for `use self::foo$0`, don't suggest `foo` as a completion
144 cov_mark::hit!(dont_complete_current_use);
151 let add_resolution = match def {
152 // Don't suggest attribute macros and derives.
153 ScopeDef::MacroDef(mac) => mac.is_fn_like(),
154 // no values in type places
156 hir::ModuleDef::Function(_)
157 | hir::ModuleDef::Variant(_)
158 | hir::ModuleDef::Static(_),
160 | ScopeDef::Local(_) => !ctx.expects_type(),
161 // unless its a constant in a generic arg list position
162 ScopeDef::ModuleDef(hir::ModuleDef::Const(_)) => {
163 !ctx.expects_type() || ctx.expects_generic_arg()
169 acc.add_resolution(ctx, name, def);
173 hir::PathResolution::Def(
174 def @ (hir::ModuleDef::Adt(_)
175 | hir::ModuleDef::TypeAlias(_)
176 | hir::ModuleDef::BuiltinType(_)),
178 if let hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
179 add_enum_variants(acc, ctx, e);
182 hir::ModuleDef::Adt(adt) => adt.ty(ctx.db),
183 hir::ModuleDef::TypeAlias(a) => {
184 let ty = a.ty(ctx.db);
185 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
186 cov_mark::hit!(completes_variant_through_alias);
187 add_enum_variants(acc, ctx, e);
191 hir::ModuleDef::BuiltinType(builtin) => {
192 let module = match ctx.scope.module() {
196 cov_mark::hit!(completes_primitive_assoc_const);
197 builtin.ty(ctx.db, module)
202 // XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType.
203 // (where AssocType is defined on a trait, not an inherent impl)
205 let krate = ctx.krate;
206 if let Some(krate) = krate {
207 let traits_in_scope = ctx.scope.visible_traits();
208 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
209 add_assoc_item(acc, ctx, item);
213 // Iterate assoc types separately
214 ty.iterate_assoc_items(ctx.db, krate, |item| {
215 if let hir::AssocItem::TypeAlias(ty) = item {
216 acc.add_type_alias(ctx, ty)
222 hir::PathResolution::Def(hir::ModuleDef::Trait(t)) => {
223 // Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`.
224 for item in t.items(ctx.db) {
225 add_assoc_item(acc, ctx, item);
228 hir::PathResolution::TypeParam(_) | hir::PathResolution::SelfType(_) => {
229 if let Some(krate) = ctx.krate {
230 let ty = match resolution {
231 hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
232 hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
236 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
237 add_enum_variants(acc, ctx, e);
240 let traits_in_scope = ctx.scope.visible_traits();
241 let mut seen = FxHashSet::default();
242 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
243 // We might iterate candidates of a trait multiple times here, so deduplicate
245 if seen.insert(item) {
246 add_assoc_item(acc, ctx, item);
252 hir::PathResolution::Macro(mac) => acc.add_macro(ctx, None, mac),
257 fn add_assoc_item(acc: &mut Completions, ctx: &CompletionContext, item: hir::AssocItem) {
259 hir::AssocItem::Function(func) if !ctx.expects_type() => acc.add_function(ctx, func, None),
260 hir::AssocItem::Const(ct) if !ctx.expects_type() || ctx.expects_generic_arg() => {
261 acc.add_const(ctx, ct)
263 hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
268 fn add_enum_variants(acc: &mut Completions, ctx: &CompletionContext, e: hir::Enum) {
269 if ctx.expects_type() {
272 e.variants(ctx.db).into_iter().for_each(|variant| acc.add_enum_variant(ctx, variant, None));
277 use expect_test::{expect, Expect};
279 use crate::tests::{check_edit, completion_list_no_kw};
281 fn check(ra_fixture: &str, expect: Expect) {
282 let actual = completion_list_no_kw(ra_fixture);
283 expect.assert_eq(&actual);
287 fn associated_item_visibility() {
290 //- /lib.rs crate:lib new_source_root:library
294 pub fn public_method() { }
295 fn private_method() { }
296 pub type PublicType = u32;
297 type PrivateType = u32;
298 pub const PUBLIC_CONST: u32 = 1;
299 const PRIVATE_CONST: u32 = 1;
302 //- /main.rs crate:main deps:lib new_source_root:local
303 fn foo() { let _ = lib::S::$0 }
306 fn public_method() fn()
307 ct PUBLIC_CONST pub const PUBLIC_CONST: u32
308 ta PublicType pub type PublicType = u32
314 fn completes_union_associated_method() {
318 impl U { fn m() { } }
320 fn foo() { let _ = U::$0 }
329 fn completes_trait_associated_method_1() {
332 trait Trait { fn m(); }
334 fn foo() { let _ = Trait::$0 }
337 fn m() (as Trait) fn()
343 fn completes_trait_associated_method_2() {
346 trait Trait { fn m(); }
351 fn foo() { let _ = S::$0 }
354 fn m() (as Trait) fn()
360 fn completes_trait_associated_method_3() {
363 trait Trait { fn m(); }
368 fn foo() { let _ = <S as Trait>::$0 }
371 fn m() (as Trait) fn()
377 fn completes_ty_param_assoc_ty() {
391 fn submethod(&self) {}
394 fn foo<T: Sub>() { T::$0 }
397 ta SubTy (as Sub) type SubTy
398 ta Ty (as Super) type Ty
399 ct C2 (as Sub) const C2: ()
400 fn subfunc() (as Sub) fn()
401 me submethod(…) (as Sub) fn(&self)
402 ct CONST (as Super) const CONST: u8
403 fn func() (as Super) fn()
404 me method(…) (as Super) fn(&self)
410 fn completes_self_param_assoc_ty() {
424 fn submethod(&self) {}
428 impl<T> Super for Wrap<T> {}
429 impl<T> Sub for Wrap<T> {
431 // Should be able to assume `Self: Sub + Super`
437 ta SubTy (as Sub) type SubTy
438 ta Ty (as Super) type Ty
439 ct CONST (as Super) const CONST: u8
440 fn func() (as Super) fn()
441 me method(…) (as Super) fn(&self)
442 ct C2 (as Sub) const C2: ()
443 fn subfunc() (as Sub) fn()
444 me submethod(…) (as Sub) fn(&self)
450 fn completes_type_alias() {
454 impl S { fn foo() {} }
456 impl T { fn bar() {} }
468 fn completes_qualified_macros() {
472 macro_rules! foo { () => {} }
474 fn main() { let _ = crate::$0 }
478 ma foo!(…) #[macro_export] macro_rules! foo
484 fn does_not_complete_non_fn_macros() {
488 #[rustc_builtin_macro]
499 #[rustc_builtin_macro]
510 fn completes_reexported_items_under_correct_name() {
513 fn foo() { self::m::$0 }
516 pub use super::p::wrong_fn as right_fn;
517 pub use super::p::WRONG_CONST as RIGHT_CONST;
518 pub use super::p::WrongType as RightType;
522 const WRONG_CONST: u32 = 1;
536 fn foo() { self::m::$0 }
539 pub use super::p::wrong_fn as right_fn;
540 pub use super::p::WRONG_CONST as RIGHT_CONST;
541 pub use super::p::WrongType as RightType;
545 const WRONG_CONST: u32 = 1;
550 fn foo() { self::m::RightType }
553 pub use super::p::wrong_fn as right_fn;
554 pub use super::p::WRONG_CONST as RIGHT_CONST;
555 pub use super::p::WrongType as RightType;
559 const WRONG_CONST: u32 = 1;
567 fn completes_in_simple_macro_call() {
570 macro_rules! m { ($e:expr) => { $e } }
571 fn main() { m!(self::f$0); }
582 fn function_mod_share_name() {
585 fn foo() { self::m::$0 }
600 fn completes_hashmap_new() {
604 struct HashMap<K, V, S = RandomState> {}
606 impl<K, V> HashMap<K, V, RandomState> {
607 pub fn new() -> HashMap<K, V, RandomState> { }
614 fn new() fn() -> HashMap<K, V, RandomState>
620 fn dont_complete_attr() {
623 mod foo { pub struct Foo; }
632 fn completes_variant_through_self() {
655 fn completes_primitive_assoc_const() {
656 cov_mark::check!(completes_primitive_assoc_const);
659 //- /lib.rs crate:lib deps:core
664 //- /core.rs crate:core
667 pub const MAX: Self = 255;
673 ct MAX pub const MAX: Self
680 fn completes_variant_through_alias() {
681 cov_mark::check!(completes_variant_through_alias);
699 fn respects_doc_hidden() {
700 cov_mark::check!(qualified_path_doc_hidden);
703 //- /lib.rs crate:lib deps:dep
708 //- /dep.rs crate:dep
729 fn type_anchor_empty() {
730 cov_mark::check!(completion_type_anchor_empty);
747 fn foo() (as Foo) fn() -> Self