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