]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/completions/qualified_path.rs
Move ws insert rendering for macro expansion into ide_db
[rust.git] / crates / ide_completion / src / completions / qualified_path.rs
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
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 @ (hir::ModuleDef::Adt(_)
156             | hir::ModuleDef::TypeAlias(_)
157             | hir::ModuleDef::BuiltinType(_)),
158         ) => {
159             if let hir::ModuleDef::Adt(hir::Adt::Enum(e)) = def {
160                 add_enum_variants(acc, ctx, e);
161             }
162             let ty = match def {
163                 hir::ModuleDef::Adt(adt) => adt.ty(ctx.db),
164                 hir::ModuleDef::TypeAlias(a) => {
165                     let ty = a.ty(ctx.db);
166                     if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
167                         cov_mark::hit!(completes_variant_through_alias);
168                         add_enum_variants(acc, ctx, e);
169                     }
170                     ty
171                 }
172                 hir::ModuleDef::BuiltinType(builtin) => {
173                     let module = match ctx.scope.module() {
174                         Some(it) => it,
175                         None => return,
176                     };
177                     cov_mark::hit!(completes_primitive_assoc_const);
178                     builtin.ty(ctx.db, module)
179                 }
180                 _ => unreachable!(),
181             };
182
183             // XXX: For parity with Rust bug #22519, this does not complete Ty::AssocType.
184             // (where AssocType is defined on a trait, not an inherent impl)
185
186             let krate = ctx.krate;
187             if let Some(krate) = krate {
188                 let traits_in_scope = ctx.scope.visible_traits();
189                 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
190                     add_assoc_item(acc, ctx, item);
191                     None::<()>
192                 });
193
194                 // Iterate assoc types separately
195                 ty.iterate_assoc_items(ctx.db, krate, |item| {
196                     if let hir::AssocItem::TypeAlias(ty) = item {
197                         acc.add_type_alias(ctx, ty)
198                     }
199                     None::<()>
200                 });
201             }
202         }
203         hir::PathResolution::Def(hir::ModuleDef::Trait(t)) => {
204             // Handles `Trait::assoc` as well as `<Ty as Trait>::assoc`.
205             for item in t.items(ctx.db) {
206                 add_assoc_item(acc, ctx, item);
207             }
208         }
209         hir::PathResolution::TypeParam(_) | hir::PathResolution::SelfType(_) => {
210             if let Some(krate) = ctx.krate {
211                 let ty = match resolution {
212                     hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
213                     hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
214                     _ => return,
215                 };
216
217                 if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
218                     add_enum_variants(acc, ctx, e);
219                 }
220
221                 let traits_in_scope = ctx.scope.visible_traits();
222                 let mut seen = FxHashSet::default();
223                 ty.iterate_path_candidates(ctx.db, krate, &traits_in_scope, None, |_ty, item| {
224                     // We might iterate candidates of a trait multiple times here, so deduplicate
225                     // them.
226                     if seen.insert(item) {
227                         add_assoc_item(acc, ctx, item);
228                     }
229                     None::<()>
230                 });
231             }
232         }
233         hir::PathResolution::Macro(mac) => acc.add_macro(ctx, None, mac),
234         _ => {}
235     }
236 }
237
238 fn add_assoc_item(acc: &mut Completions, ctx: &CompletionContext, item: hir::AssocItem) {
239     match item {
240         hir::AssocItem::Function(func) if !ctx.expects_type() => acc.add_function(ctx, func, None),
241         hir::AssocItem::Const(ct) if !ctx.expects_type() || ctx.expects_generic_arg() => {
242             acc.add_const(ctx, ct)
243         }
244         hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty),
245         _ => (),
246     }
247 }
248
249 fn add_enum_variants(acc: &mut Completions, ctx: &CompletionContext, e: hir::Enum) {
250     if ctx.expects_type() {
251         return;
252     }
253     e.variants(ctx.db).into_iter().for_each(|variant| acc.add_enum_variant(ctx, variant, None));
254 }
255
256 #[cfg(test)]
257 mod tests {
258     use expect_test::{expect, Expect};
259
260     use crate::tests::{check_edit, completion_list_no_kw};
261
262     fn check(ra_fixture: &str, expect: Expect) {
263         let actual = completion_list_no_kw(ra_fixture);
264         expect.assert_eq(&actual);
265     }
266
267     #[test]
268     fn associated_item_visibility() {
269         check(
270             r#"
271 //- /lib.rs crate:lib new_source_root:library
272 pub struct S;
273
274 impl S {
275     pub fn public_method() { }
276     fn private_method() { }
277     pub type PublicType = u32;
278     type PrivateType = u32;
279     pub const PUBLIC_CONST: u32 = 1;
280     const PRIVATE_CONST: u32 = 1;
281 }
282
283 //- /main.rs crate:main deps:lib new_source_root:local
284 fn foo() { let _ = lib::S::$0 }
285 "#,
286             expect![[r#"
287                 fn public_method() fn()
288                 ct PUBLIC_CONST    pub const PUBLIC_CONST: u32;
289                 ta PublicType      pub type PublicType;
290             "#]],
291         );
292     }
293
294     #[test]
295     fn completes_union_associated_method() {
296         check(
297             r#"
298 union U {};
299 impl U { fn m() { } }
300
301 fn foo() { let _ = U::$0 }
302 "#,
303             expect![[r#"
304                 fn m() fn()
305             "#]],
306         );
307     }
308
309     #[test]
310     fn completes_trait_associated_method_1() {
311         check(
312             r#"
313 trait Trait { fn m(); }
314
315 fn foo() { let _ = Trait::$0 }
316 "#,
317             expect![[r#"
318                 fn m() (as Trait) fn()
319             "#]],
320         );
321     }
322
323     #[test]
324     fn completes_trait_associated_method_2() {
325         check(
326             r#"
327 trait Trait { fn m(); }
328
329 struct S;
330 impl Trait for S {}
331
332 fn foo() { let _ = S::$0 }
333 "#,
334             expect![[r#"
335                 fn m() (as Trait) fn()
336             "#]],
337         );
338     }
339
340     #[test]
341     fn completes_trait_associated_method_3() {
342         check(
343             r#"
344 trait Trait { fn m(); }
345
346 struct S;
347 impl Trait for S {}
348
349 fn foo() { let _ = <S as Trait>::$0 }
350 "#,
351             expect![[r#"
352                 fn m() (as Trait) fn()
353             "#]],
354         );
355     }
356
357     #[test]
358     fn completes_ty_param_assoc_ty() {
359         check(
360             r#"
361 trait Super {
362     type Ty;
363     const CONST: u8;
364     fn func() {}
365     fn method(&self) {}
366 }
367
368 trait Sub: Super {
369     type SubTy;
370     const C2: ();
371     fn subfunc() {}
372     fn submethod(&self) {}
373 }
374
375 fn foo<T: Sub>() { T::$0 }
376 "#,
377             expect![[r#"
378                 ta SubTy (as Sub)        type SubTy;
379                 ta Ty (as Super)         type Ty;
380                 ct C2 (as Sub)           const C2: ();
381                 fn subfunc() (as Sub)    fn()
382                 me submethod(…) (as Sub) fn(&self)
383                 ct CONST (as Super)      const CONST: u8;
384                 fn func() (as Super)     fn()
385                 me method(…) (as Super)  fn(&self)
386             "#]],
387         );
388     }
389
390     #[test]
391     fn completes_self_param_assoc_ty() {
392         check(
393             r#"
394 trait Super {
395     type Ty;
396     const CONST: u8 = 0;
397     fn func() {}
398     fn method(&self) {}
399 }
400
401 trait Sub: Super {
402     type SubTy;
403     const C2: () = ();
404     fn subfunc() {}
405     fn submethod(&self) {}
406 }
407
408 struct Wrap<T>(T);
409 impl<T> Super for Wrap<T> {}
410 impl<T> Sub for Wrap<T> {
411     fn subfunc() {
412         // Should be able to assume `Self: Sub + Super`
413         Self::$0
414     }
415 }
416 "#,
417             expect![[r#"
418                 ta SubTy (as Sub)        type SubTy;
419                 ta Ty (as Super)         type Ty;
420                 ct CONST (as Super)      const CONST: u8;
421                 fn func() (as Super)     fn()
422                 me method(…) (as Super)  fn(&self)
423                 ct C2 (as Sub)           const C2: ();
424                 fn subfunc() (as Sub)    fn()
425                 me submethod(…) (as Sub) fn(&self)
426             "#]],
427         );
428     }
429
430     #[test]
431     fn completes_type_alias() {
432         check(
433             r#"
434 struct S;
435 impl S { fn foo() {} }
436 type T = S;
437 impl T { fn bar() {} }
438
439 fn main() { T::$0; }
440 "#,
441             expect![[r#"
442                 fn foo() fn()
443                 fn bar() fn()
444             "#]],
445         );
446     }
447
448     #[test]
449     fn completes_qualified_macros() {
450         check(
451             r#"
452 #[macro_export]
453 macro_rules! foo { () => {} }
454
455 fn main() { let _ = crate::$0 }
456 "#,
457             expect![[r##"
458                 fn main()  fn()
459                 ma foo!(…) #[macro_export] macro_rules! foo
460             "##]],
461         );
462     }
463
464     #[test]
465     fn does_not_complete_non_fn_macros() {
466         check(
467             r#"
468 mod m {
469     #[rustc_builtin_macro]
470     pub macro Clone {}
471 }
472
473 fn f() {m::$0}
474 "#,
475             expect![[r#""#]],
476         );
477         check(
478             r#"
479 mod m {
480     #[rustc_builtin_macro]
481     pub macro bench {}
482 }
483
484 fn f() {m::$0}
485 "#,
486             expect![[r#""#]],
487         );
488     }
489
490     #[test]
491     fn completes_reexported_items_under_correct_name() {
492         check(
493             r#"
494 fn foo() { self::m::$0 }
495
496 mod m {
497     pub use super::p::wrong_fn as right_fn;
498     pub use super::p::WRONG_CONST as RIGHT_CONST;
499     pub use super::p::WrongType as RightType;
500 }
501 mod p {
502     fn wrong_fn() {}
503     const WRONG_CONST: u32 = 1;
504     struct WrongType {};
505 }
506 "#,
507             expect![[r#"
508                 ct RIGHT_CONST
509                 fn right_fn()  fn()
510                 st RightType
511             "#]],
512         );
513
514         check_edit(
515             "RightType",
516             r#"
517 fn foo() { self::m::$0 }
518
519 mod m {
520     pub use super::p::wrong_fn as right_fn;
521     pub use super::p::WRONG_CONST as RIGHT_CONST;
522     pub use super::p::WrongType as RightType;
523 }
524 mod p {
525     fn wrong_fn() {}
526     const WRONG_CONST: u32 = 1;
527     struct WrongType {};
528 }
529 "#,
530             r#"
531 fn foo() { self::m::RightType }
532
533 mod m {
534     pub use super::p::wrong_fn as right_fn;
535     pub use super::p::WRONG_CONST as RIGHT_CONST;
536     pub use super::p::WrongType as RightType;
537 }
538 mod p {
539     fn wrong_fn() {}
540     const WRONG_CONST: u32 = 1;
541     struct WrongType {};
542 }
543 "#,
544         );
545     }
546
547     #[test]
548     fn completes_in_simple_macro_call() {
549         check(
550             r#"
551 macro_rules! m { ($e:expr) => { $e } }
552 fn main() { m!(self::f$0); }
553 fn foo() {}
554 "#,
555             expect![[r#"
556                 fn main() fn()
557                 fn foo()  fn()
558             "#]],
559         );
560     }
561
562     #[test]
563     fn function_mod_share_name() {
564         check(
565             r#"
566 fn foo() { self::m::$0 }
567
568 mod m {
569     pub mod z {}
570     pub fn z() {}
571 }
572 "#,
573             expect![[r#"
574                 md z
575                 fn z() fn()
576             "#]],
577         );
578     }
579
580     #[test]
581     fn completes_hashmap_new() {
582         check(
583             r#"
584 struct RandomState;
585 struct HashMap<K, V, S = RandomState> {}
586
587 impl<K, V> HashMap<K, V, RandomState> {
588     pub fn new() -> HashMap<K, V, RandomState> { }
589 }
590 fn foo() {
591     HashMap::$0
592 }
593 "#,
594             expect![[r#"
595                 fn new() fn() -> HashMap<K, V, RandomState>
596             "#]],
597         );
598     }
599
600     #[test]
601     fn dont_complete_attr() {
602         check(
603             r#"
604 mod foo { pub struct Foo; }
605 #[foo::$0]
606 fn f() {}
607 "#,
608             expect![[""]],
609         );
610     }
611
612     #[test]
613     fn completes_variant_through_self() {
614         check(
615             r#"
616 enum Foo {
617     Bar,
618     Baz,
619 }
620
621 impl Foo {
622     fn foo(self) {
623         Self::$0
624     }
625 }
626 "#,
627             expect![[r#"
628                 ev Bar    ()
629                 ev Baz    ()
630                 me foo(…) fn(self)
631             "#]],
632         );
633     }
634
635     #[test]
636     fn completes_primitive_assoc_const() {
637         cov_mark::check!(completes_primitive_assoc_const);
638         check(
639             r#"
640 //- /lib.rs crate:lib deps:core
641 fn f() {
642     u8::$0
643 }
644
645 //- /core.rs crate:core
646 #[lang = "u8"]
647 impl u8 {
648     pub const MAX: Self = 255;
649
650     pub fn func(self) {}
651 }
652 "#,
653             expect![[r#"
654                 ct MAX     pub const MAX: Self;
655                 me func(…) fn(self)
656             "#]],
657         );
658     }
659
660     #[test]
661     fn completes_variant_through_alias() {
662         cov_mark::check!(completes_variant_through_alias);
663         check(
664             r#"
665 enum Foo {
666     Bar
667 }
668 type Foo2 = Foo;
669 fn main() {
670     Foo2::$0
671 }
672 "#,
673             expect![[r#"
674                 ev Bar ()
675             "#]],
676         );
677     }
678
679     #[test]
680     fn respects_doc_hidden() {
681         cov_mark::check!(qualified_path_doc_hidden);
682         check(
683             r#"
684 //- /lib.rs crate:lib deps:dep
685 fn f() {
686     dep::$0
687 }
688
689 //- /dep.rs crate:dep
690 #[doc(hidden)]
691 #[macro_export]
692 macro_rules! m {
693     () => {}
694 }
695
696 #[doc(hidden)]
697 pub fn f() {}
698
699 #[doc(hidden)]
700 pub struct S;
701
702 #[doc(hidden)]
703 pub mod m {}
704             "#,
705             expect![[r#""#]],
706         )
707     }
708 }