1 //! Completion of paths, i.e. `some::prefix::$0`.
2
3 use std::iter;
4
5 use rustc_hash::FxHashSet;
6 use syntax::{ast, AstNode};
7
8 use crate::{
9 context::PathCompletionContext, patterns::ImmediateLocation, CompletionContext, Completions,
10 };
11
complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext)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() {
14 return;
15 }
16 let (path, use_tree_parent) = match &ctx.path_context {
17 Some(PathCompletionContext { qualifier: Some(qualifier), use_tree_parent, .. }) => {
18 (qualifier, *use_tree_parent)
19 }
20 _ => return,
21 };
22
23 let resolution = match ctx.sema.resolve_path(path) {
24 Some(res) => res,
25 None => return,
26 };
27
28 let context_module = ctx.scope.module();
29
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);
37 }
38 }
39 if let hir::ScopeDef::ModuleDef(hir::ModuleDef::Module(_)) = def {
40 acc.add_resolution(ctx, name, &def);
41 }
42 }
43 }
44 return;
45 }
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
50 .path_to_root(ctx.db)
51 .into_iter()
52 .take_while(|&it| it != resolved)
53 .next()
54 {
55 if let Some(name) = next.name(ctx.db) {
56 acc.add_resolution(ctx, name, &hir::ScopeDef::ModuleDef(next.into()));
57 }
58 }
59 }
60 }
61 return;
62 }
63 _ => (),
64 }
65
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())
69 {
70 acc.add_keyword(ctx, "super::");
71 }
72 // only show `self` in a new use-tree when the qualifier doesn't end in self
73 if use_tree_parent
74 && !matches!(
75 path.segment().and_then(|it| it.kind()),
76 Some(ast::PathSegmentKind::SelfKw)
77 )
78 {
79 acc.add_keyword(ctx, "self");
80 }
81 }
82
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);
86 None::<()>
87 });
88
89 match resolution {
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(ast::NameLike::NameRef(name_ref)) = ctx.name_syntax.as_ref() {
96 if name_ref.syntax().text() == name.to_smol_str().as_str() {
97 // for `use self::foo$0`, don't suggest `foo` as a completion
98 cov_mark::hit!(dont_complete_current_use);
99 continue;
100 }
101 }
102 }
103 }
104
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(_),
113 )
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()
118 }
119 _ => true,
120 };
121
122 if add_resolution {
123 acc.add_resolution(ctx, name, &def);
124 }
125 }
126 }
127 hir::PathResolution::Def(
128 def
129 @
130 (hir::ModuleDef::Adt(_)
131 | hir::ModuleDef::TypeAlias(_)
132 | hir::ModuleDef::BuiltinType(_)),
133 ) => {
134 if let hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
135 add_enum_variants(acc, ctx, e);
136 }
137 let ty = match def {
138 hir::ModuleDef::Adt(adt) => adt.ty(ctx.db),
139 hir::ModuleDef::TypeAlias(a) => {
140 let ty = a.ty(ctx.db);
141 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
142 cov_mark::hit!(completes_variant_through_alias);
143 add_enum_variants(acc, ctx, e);
144 }
145 ty
146 }
147 hir::ModuleDef::BuiltinType(builtin) => {
148 let module = match ctx.scope.module() {
149 Some(it) => it,
150 None => return,
151 };
152 cov_mark::hit!(completes_primitive_assoc_const);
153 builtin.ty(ctx.db, module)
154 }
155 _ => unreachable!(),
156 };
157
158 // XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType.
159 // (where AssocType is defined on a trait, not an inherent impl)
160
161 let krate = ctx.krate;
162 if let Some(krate) = krate {
163 let traits_in_scope = ctx.scope.traits_in_scope();
164 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
165 add_assoc_item(acc, ctx, item);
166 None::<()>
167 });
168
169 // Iterate assoc types separately
170 ty.iterate_assoc_items(ctx.db, krate, |item| {
171 if let hir::AssocItem::TypeAlias(ty) = item {
172 acc.add_type_alias(ctx, ty)
173 }
174 None::<()>
175 });
176 }
177 }
178 hir::PathResolution::Def(hir::ModuleDef::Trait(t)) => {
179 // Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`.
180 for item in t.items(ctx.db) {
181 add_assoc_item(acc, ctx, item);
182 }
183 }
184 hir::PathResolution::TypeParam(_) | hir::PathResolution::SelfType(_) => {
185 if let Some(krate) = ctx.krate {
186 let ty = match resolution {
187 hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
188 hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
189 _ => return,
190 };
191
192 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
193 add_enum_variants(acc, ctx, e);
194 }
195
196 let traits_in_scope = ctx.scope.traits_in_scope();
197 let mut seen = FxHashSet::default();
198 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
199 // We might iterate candidates of a trait multiple times here, so deduplicate
200 // them.
201 if seen.insert(item) {
202 add_assoc_item(acc, ctx, item);
203 }
204 None::<()>
205 });
206 }
207 }
208 hir::PathResolution::Macro(mac) => acc.add_macro(ctx, None, mac),
209 _ => {}
210 }
211 }
212
add_assoc_item(acc: &mut Completions, ctx: &CompletionContext, item: hir::AssocItem)213 fn add_assoc_item(acc: &mut Completions, ctx: &CompletionContext, item: hir::AssocItem) {
214 match item {
215 hir::AssocItem::Function(func) if !ctx.expects_type() => acc.add_function(ctx, func, None),
216 hir::AssocItem::Const(ct) if !ctx.expects_type() || ctx.expects_generic_arg() => {
217 acc.add_const(ctx, ct)
218 }
219 hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
220 _ => (),
221 }
222 }
223
add_enum_variants(acc: &mut Completions, ctx: &CompletionContext, e: hir::Enum)224 fn add_enum_variants(acc: &mut Completions, ctx: &CompletionContext, e: hir::Enum) {
225 if ctx.expects_type() {
226 return;
227 }
228 e.variants(ctx.db).into_iter().for_each(|variant| acc.add_enum_variant(ctx, variant, None));
229 }
230
231 #[cfg(test)]
232 mod tests {
233 use expect_test::{expect, Expect};
234
235 use crate::tests::{check_edit, completion_list_no_kw};
236
check(ra_fixture: &str, expect: Expect)237 fn check(ra_fixture: &str, expect: Expect) {
238 let actual = completion_list_no_kw(ra_fixture);
239 expect.assert_eq(&actual);
240 }
241
242 #[test]
associated_item_visibility()243 fn associated_item_visibility() {
244 check(
245 r#"
246 //- /lib.rs crate:lib new_source_root:library
247 pub struct S;
248
249 impl S {
250 pub fn public_method() { }
251 fn private_method() { }
252 pub type PublicType = u32;
253 type PrivateType = u32;
254 pub const PUBLIC_CONST: u32 = 1;
255 const PRIVATE_CONST: u32 = 1;
256 }
257
258 //- /main.rs crate:main deps:lib new_source_root:local
259 fn foo() { let _ = lib::S::$0 }
260 "#,
261 expect![[r#"
262 fn public_method() fn()
263 ct PUBLIC_CONST pub const PUBLIC_CONST: u32 = 1;
264 ta PublicType pub type PublicType = u32;
265 "#]],
266 );
267 }
268
269 #[test]
completes_union_associated_method()270 fn completes_union_associated_method() {
271 check(
272 r#"
273 union U {};
274 impl U { fn m() { } }
275
276 fn foo() { let _ = U::$0 }
277 "#,
278 expect![[r#"
279 fn m() fn()
280 "#]],
281 );
282 }
283
284 #[test]
completes_trait_associated_method_1()285 fn completes_trait_associated_method_1() {
286 check(
287 r#"
288 trait Trait { fn m(); }
289
290 fn foo() { let _ = Trait::$0 }
291 "#,
292 expect![[r#"
293 fn m() (as Trait) fn()
294 "#]],
295 );
296 }
297
298 #[test]
completes_trait_associated_method_2()299 fn completes_trait_associated_method_2() {
300 check(
301 r#"
302 trait Trait { fn m(); }
303
304 struct S;
305 impl Trait for S {}
306
307 fn foo() { let _ = S::$0 }
308 "#,
309 expect![[r#"
310 fn m() (as Trait) fn()
311 "#]],
312 );
313 }
314
315 #[test]
completes_trait_associated_method_3()316 fn completes_trait_associated_method_3() {
317 check(
318 r#"
319 trait Trait { fn m(); }
320
321 struct S;
322 impl Trait for S {}
323
324 fn foo() { let _ = <S as Trait>::$0 }
325 "#,
326 expect![[r#"
327 fn m() (as Trait) fn()
328 "#]],
329 );
330 }
331
332 #[test]
completes_ty_param_assoc_ty()333 fn completes_ty_param_assoc_ty() {
334 check(
335 r#"
336 trait Super {
337 type Ty;
338 const CONST: u8;
339 fn func() {}
340 fn method(&self) {}
341 }
342
343 trait Sub: Super {
344 type SubTy;
345 const C2: ();
346 fn subfunc() {}
347 fn submethod(&self) {}
348 }
349
350 fn foo<T: Sub>() { T::$0 }
351 "#,
352 expect![[r#"
353 ta SubTy (as Sub) type SubTy;
354 ta Ty (as Super) type Ty;
355 ct C2 (as Sub) const C2: ();
356 fn subfunc() (as Sub) fn()
357 me submethod(…) (as Sub) fn(&self)
358 ct CONST (as Super) const CONST: u8;
359 fn func() (as Super) fn()
360 me method(…) (as Super) fn(&self)
361 "#]],
362 );
363 }
364
365 #[test]
completes_self_param_assoc_ty()366 fn completes_self_param_assoc_ty() {
367 check(
368 r#"
369 trait Super {
370 type Ty;
371 const CONST: u8 = 0;
372 fn func() {}
373 fn method(&self) {}
374 }
375
376 trait Sub: Super {
377 type SubTy;
378 const C2: () = ();
379 fn subfunc() {}
380 fn submethod(&self) {}
381 }
382
383 struct Wrap<T>(T);
384 impl<T> Super for Wrap<T> {}
385 impl<T> Sub for Wrap<T> {
386 fn subfunc() {
387 // Should be able to assume `Self: Sub + Super`
388 Self::$0
389 }
390 }
391 "#,
392 expect![[r#"
393 ta SubTy (as Sub) type SubTy;
394 ta Ty (as Super) type Ty;
395 ct CONST (as Super) const CONST: u8 = 0;
396 fn func() (as Super) fn()
397 me method(…) (as Super) fn(&self)
398 ct C2 (as Sub) const C2: () = ();
399 fn subfunc() (as Sub) fn()
400 me submethod(…) (as Sub) fn(&self)
401 "#]],
402 );
403 }
404
405 #[test]
completes_type_alias()406 fn completes_type_alias() {
407 check(
408 r#"
409 struct S;
410 impl S { fn foo() {} }
411 type T = S;
412 impl T { fn bar() {} }
413
414 fn main() { T::$0; }
415 "#,
416 expect![[r#"
417 fn foo() fn()
418 fn bar() fn()
419 "#]],
420 );
421 }
422
423 #[test]
completes_qualified_macros()424 fn completes_qualified_macros() {
425 check(
426 r#"
427 #[macro_export]
428 macro_rules! foo { () => {} }
429
430 fn main() { let _ = crate::$0 }
431 "#,
432 expect![[r##"
433 fn main() fn()
434 ma foo!(…) #[macro_export] macro_rules! foo
435 "##]],
436 );
437 }
438
439 #[test]
does_not_complete_non_fn_macros()440 fn does_not_complete_non_fn_macros() {
441 check(
442 r#"
443 mod m {
444 #[rustc_builtin_macro]
445 pub macro Clone {}
446 }
447
448 fn f() {m::$0}
449 "#,
450 expect![[r#""#]],
451 );
452 check(
453 r#"
454 mod m {
455 #[rustc_builtin_macro]
456 pub macro bench {}
457 }
458
459 fn f() {m::$0}
460 "#,
461 expect![[r#""#]],
462 );
463 }
464
465 #[test]
completes_reexported_items_under_correct_name()466 fn completes_reexported_items_under_correct_name() {
467 check(
468 r#"
469 fn foo() { self::m::$0 }
470
471 mod m {
472 pub use super::p::wrong_fn as right_fn;
473 pub use super::p::WRONG_CONST as RIGHT_CONST;
474 pub use super::p::WrongType as RightType;
475 }
476 mod p {
477 fn wrong_fn() {}
478 const WRONG_CONST: u32 = 1;
479 struct WrongType {};
480 }
481 "#,
482 expect![[r#"
483 ct RIGHT_CONST
484 fn right_fn() fn()
485 st RightType
486 "#]],
487 );
488
489 check_edit(
490 "RightType",
491 r#"
492 fn foo() { self::m::$0 }
493
494 mod m {
495 pub use super::p::wrong_fn as right_fn;
496 pub use super::p::WRONG_CONST as RIGHT_CONST;
497 pub use super::p::WrongType as RightType;
498 }
499 mod p {
500 fn wrong_fn() {}
501 const WRONG_CONST: u32 = 1;
502 struct WrongType {};
503 }
504 "#,
505 r#"
506 fn foo() { self::m::RightType }
507
508 mod m {
509 pub use super::p::wrong_fn as right_fn;
510 pub use super::p::WRONG_CONST as RIGHT_CONST;
511 pub use super::p::WrongType as RightType;
512 }
513 mod p {
514 fn wrong_fn() {}
515 const WRONG_CONST: u32 = 1;
516 struct WrongType {};
517 }
518 "#,
519 );
520 }
521
522 #[test]
completes_in_simple_macro_call()523 fn completes_in_simple_macro_call() {
524 check(
525 r#"
526 macro_rules! m { ($e:expr) => { $e } }
527 fn main() { m!(self::f$0); }
528 fn foo() {}
529 "#,
530 expect![[r#"
531 fn main() fn()
532 fn foo() fn()
533 "#]],
534 );
535 }
536
537 #[test]
function_mod_share_name()538 fn function_mod_share_name() {
539 check(
540 r#"
541 fn foo() { self::m::$0 }
542
543 mod m {
544 pub mod z {}
545 pub fn z() {}
546 }
547 "#,
548 expect![[r#"
549 md z
550 fn z() fn()
551 "#]],
552 );
553 }
554
555 #[test]
completes_hashmap_new()556 fn completes_hashmap_new() {
557 check(
558 r#"
559 struct RandomState;
560 struct HashMap<K, V, S = RandomState> {}
561
562 impl<K, V> HashMap<K, V, RandomState> {
563 pub fn new() -> HashMap<K, V, RandomState> { }
564 }
565 fn foo() {
566 HashMap::$0
567 }
568 "#,
569 expect![[r#"
570 fn new() fn() -> HashMap<K, V, RandomState>
571 "#]],
572 );
573 }
574
575 #[test]
dont_complete_attr()576 fn dont_complete_attr() {
577 check(
578 r#"
579 mod foo { pub struct Foo; }
580 #[foo::$0]
581 fn f() {}
582 "#,
583 expect![[""]],
584 );
585 }
586
587 #[test]
completes_variant_through_self()588 fn completes_variant_through_self() {
589 check(
590 r#"
591 enum Foo {
592 Bar,
593 Baz,
594 }
595
596 impl Foo {
597 fn foo(self) {
598 Self::$0
599 }
600 }
601 "#,
602 expect![[r#"
603 ev Bar ()
604 ev Baz ()
605 me foo(…) fn(self)
606 "#]],
607 );
608 }
609
610 #[test]
completes_primitive_assoc_const()611 fn completes_primitive_assoc_const() {
612 cov_mark::check!(completes_primitive_assoc_const);
613 check(
614 r#"
615 //- /lib.rs crate:lib deps:core
616 fn f() {
617 u8::$0
618 }
619
620 //- /core.rs crate:core
621 #[lang = "u8"]
622 impl u8 {
623 pub const MAX: Self = 255;
624
625 pub fn func(self) {}
626 }
627 "#,
628 expect![[r#"
629 ct MAX pub const MAX: Self = 255;
630 me func(…) fn(self)
631 "#]],
632 );
633 }
634
635 #[test]
completes_variant_through_alias()636 fn completes_variant_through_alias() {
637 cov_mark::check!(completes_variant_through_alias);
638 check(
639 r#"
640 enum Foo {
641 Bar
642 }
643 type Foo2 = Foo;
644 fn main() {
645 Foo2::$0
646 }
647 "#,
648 expect![[r#"
649 ev Bar ()
650 "#]],
651 );
652 }
653
654 #[test]
respects_doc_hidden()655 fn respects_doc_hidden() {
656 cov_mark::check!(qualified_path_doc_hidden);
657 check(
658 r#"
659 //- /lib.rs crate:lib deps:dep
660 fn f() {
661 dep::$0
662 }
663
664 //- /dep.rs crate:dep
665 #[doc(hidden)]
666 #[macro_export]
667 macro_rules! m {
668 () => {}
669 }
670
671 #[doc(hidden)]
672 pub fn f() {}
673
674 #[doc(hidden)]
675 pub struct S;
676
677 #[doc(hidden)]
678 pub mod m {}
679 "#,
680 expect![[r#""#]],
681 )
682 }
683 }
684