• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! This module defines an accumulator for completions which are going to be presented to user.
2 
3 pub(crate) mod attribute;
4 pub(crate) mod dot;
5 pub(crate) mod expr;
6 pub(crate) mod extern_abi;
7 pub(crate) mod field;
8 pub(crate) mod flyimport;
9 pub(crate) mod fn_param;
10 pub(crate) mod format_string;
11 pub(crate) mod item_list;
12 pub(crate) mod keyword;
13 pub(crate) mod lifetime;
14 pub(crate) mod mod_;
15 pub(crate) mod pattern;
16 pub(crate) mod postfix;
17 pub(crate) mod record;
18 pub(crate) mod snippet;
19 pub(crate) mod r#type;
20 pub(crate) mod use_;
21 pub(crate) mod vis;
22 pub(crate) mod env_vars;
23 
24 use std::iter;
25 
26 use hir::{known, HasAttrs, ScopeDef, Variant};
27 use ide_db::{imports::import_assets::LocatedImport, RootDatabase, SymbolKind};
28 use syntax::ast;
29 
30 use crate::{
31     context::{
32         DotAccess, ItemListKind, NameContext, NameKind, NameRefContext, NameRefKind,
33         PathCompletionCtx, PathKind, PatternContext, TypeLocation, Visible,
34     },
35     item::Builder,
36     render::{
37         const_::render_const,
38         function::{render_fn, render_method},
39         literal::{render_struct_literal, render_variant_lit},
40         macro_::render_macro,
41         pattern::{render_struct_pat, render_variant_pat},
42         render_field, render_path_resolution, render_pattern_resolution, render_tuple_field,
43         type_alias::{render_type_alias, render_type_alias_with_eq},
44         union_literal::render_union_literal,
45         RenderContext,
46     },
47     CompletionContext, CompletionItem, CompletionItemKind,
48 };
49 
50 /// Represents an in-progress set of completions being built.
51 #[derive(Debug, Default)]
52 pub struct Completions {
53     buf: Vec<CompletionItem>,
54 }
55 
56 impl From<Completions> for Vec<CompletionItem> {
from(val: Completions) -> Self57     fn from(val: Completions) -> Self {
58         val.buf
59     }
60 }
61 
62 impl Builder {
63     /// Convenience method, which allows to add a freshly created completion into accumulator
64     /// without binding it to the variable.
add_to(self, acc: &mut Completions, db: &RootDatabase)65     pub(crate) fn add_to(self, acc: &mut Completions, db: &RootDatabase) {
66         acc.add(self.build(db))
67     }
68 }
69 
70 impl Completions {
add(&mut self, item: CompletionItem)71     fn add(&mut self, item: CompletionItem) {
72         self.buf.push(item)
73     }
74 
add_opt(&mut self, item: Option<CompletionItem>)75     fn add_opt(&mut self, item: Option<CompletionItem>) {
76         if let Some(item) = item {
77             self.buf.push(item)
78         }
79     }
80 
add_keyword(&mut self, ctx: &CompletionContext<'_>, keyword: &'static str)81     pub(crate) fn add_keyword(&mut self, ctx: &CompletionContext<'_>, keyword: &'static str) {
82         let item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), keyword);
83         item.add_to(self, ctx.db);
84     }
85 
add_nameref_keywords_with_colon(&mut self, ctx: &CompletionContext<'_>)86     pub(crate) fn add_nameref_keywords_with_colon(&mut self, ctx: &CompletionContext<'_>) {
87         ["self::", "crate::"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
88 
89         if ctx.depth_from_crate_root > 0 {
90             self.add_keyword(ctx, "super::");
91         }
92     }
93 
add_nameref_keywords(&mut self, ctx: &CompletionContext<'_>)94     pub(crate) fn add_nameref_keywords(&mut self, ctx: &CompletionContext<'_>) {
95         ["self", "crate"].into_iter().for_each(|kw| self.add_keyword(ctx, kw));
96 
97         if ctx.depth_from_crate_root > 0 {
98             self.add_keyword(ctx, "super");
99         }
100     }
101 
add_super_keyword( &mut self, ctx: &CompletionContext<'_>, super_chain_len: Option<usize>, )102     pub(crate) fn add_super_keyword(
103         &mut self,
104         ctx: &CompletionContext<'_>,
105         super_chain_len: Option<usize>,
106     ) {
107         if let Some(len) = super_chain_len {
108             if len > 0 && len < ctx.depth_from_crate_root {
109                 self.add_keyword(ctx, "super::");
110             }
111         }
112     }
113 
add_keyword_snippet_expr( &mut self, ctx: &CompletionContext<'_>, incomplete_let: bool, kw: &str, snippet: &str, )114     pub(crate) fn add_keyword_snippet_expr(
115         &mut self,
116         ctx: &CompletionContext<'_>,
117         incomplete_let: bool,
118         kw: &str,
119         snippet: &str,
120     ) {
121         let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
122 
123         match ctx.config.snippet_cap {
124             Some(cap) => {
125                 if incomplete_let && snippet.ends_with('}') {
126                     // complete block expression snippets with a trailing semicolon, if inside an incomplete let
127                     cov_mark::hit!(let_semi);
128                     item.insert_snippet(cap, format!("{snippet};"));
129                 } else {
130                     item.insert_snippet(cap, snippet);
131                 }
132             }
133             None => {
134                 item.insert_text(if snippet.contains('$') { kw } else { snippet });
135             }
136         };
137         item.add_to(self, ctx.db);
138     }
139 
add_keyword_snippet( &mut self, ctx: &CompletionContext<'_>, kw: &str, snippet: &str, )140     pub(crate) fn add_keyword_snippet(
141         &mut self,
142         ctx: &CompletionContext<'_>,
143         kw: &str,
144         snippet: &str,
145     ) {
146         let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
147 
148         match ctx.config.snippet_cap {
149             Some(cap) => item.insert_snippet(cap, snippet),
150             None => item.insert_text(if snippet.contains('$') { kw } else { snippet }),
151         };
152         item.add_to(self, ctx.db);
153     }
154 
add_crate_roots( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, )155     pub(crate) fn add_crate_roots(
156         &mut self,
157         ctx: &CompletionContext<'_>,
158         path_ctx: &PathCompletionCtx,
159     ) {
160         ctx.process_all_names(&mut |name, res, doc_aliases| match res {
161             ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root() => {
162                 self.add_module(ctx, path_ctx, m, name, doc_aliases);
163             }
164             _ => (),
165         });
166     }
167 
add_path_resolution( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, local_name: hir::Name, resolution: hir::ScopeDef, doc_aliases: Vec<syntax::SmolStr>, )168     pub(crate) fn add_path_resolution(
169         &mut self,
170         ctx: &CompletionContext<'_>,
171         path_ctx: &PathCompletionCtx,
172         local_name: hir::Name,
173         resolution: hir::ScopeDef,
174         doc_aliases: Vec<syntax::SmolStr>,
175     ) {
176         if !ctx.check_stability(resolution.attrs(ctx.db).as_deref()) {
177             return;
178         }
179         let is_private_editable = match ctx.def_is_visible(&resolution) {
180             Visible::Yes => false,
181             Visible::Editable => true,
182             Visible::No => return,
183         };
184         self.add(
185             render_path_resolution(
186                 RenderContext::new(ctx)
187                     .private_editable(is_private_editable)
188                     .doc_aliases(doc_aliases),
189                 path_ctx,
190                 local_name,
191                 resolution,
192             )
193             .build(ctx.db),
194         );
195     }
196 
add_pattern_resolution( &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, local_name: hir::Name, resolution: hir::ScopeDef, )197     pub(crate) fn add_pattern_resolution(
198         &mut self,
199         ctx: &CompletionContext<'_>,
200         pattern_ctx: &PatternContext,
201         local_name: hir::Name,
202         resolution: hir::ScopeDef,
203     ) {
204         if !ctx.check_stability(resolution.attrs(ctx.db).as_deref()) {
205             return;
206         }
207         let is_private_editable = match ctx.def_is_visible(&resolution) {
208             Visible::Yes => false,
209             Visible::Editable => true,
210             Visible::No => return,
211         };
212         self.add(
213             render_pattern_resolution(
214                 RenderContext::new(ctx).private_editable(is_private_editable),
215                 pattern_ctx,
216                 local_name,
217                 resolution,
218             )
219             .build(ctx.db),
220         );
221     }
222 
add_enum_variants( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, e: hir::Enum, )223     pub(crate) fn add_enum_variants(
224         &mut self,
225         ctx: &CompletionContext<'_>,
226         path_ctx: &PathCompletionCtx,
227         e: hir::Enum,
228     ) {
229         if !ctx.check_stability(Some(&e.attrs(ctx.db))) {
230             return;
231         }
232         e.variants(ctx.db)
233             .into_iter()
234             .for_each(|variant| self.add_enum_variant(ctx, path_ctx, variant, None));
235     }
236 
add_module( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, module: hir::Module, local_name: hir::Name, doc_aliases: Vec<syntax::SmolStr>, )237     pub(crate) fn add_module(
238         &mut self,
239         ctx: &CompletionContext<'_>,
240         path_ctx: &PathCompletionCtx,
241         module: hir::Module,
242         local_name: hir::Name,
243         doc_aliases: Vec<syntax::SmolStr>,
244     ) {
245         if !ctx.check_stability(Some(&module.attrs(ctx.db))) {
246             return;
247         }
248         self.add_path_resolution(
249             ctx,
250             path_ctx,
251             local_name,
252             hir::ScopeDef::ModuleDef(module.into()),
253             doc_aliases,
254         );
255     }
256 
add_macro( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, mac: hir::Macro, local_name: hir::Name, )257     pub(crate) fn add_macro(
258         &mut self,
259         ctx: &CompletionContext<'_>,
260         path_ctx: &PathCompletionCtx,
261         mac: hir::Macro,
262         local_name: hir::Name,
263     ) {
264         if !ctx.check_stability(Some(&mac.attrs(ctx.db))) {
265             return;
266         }
267         let is_private_editable = match ctx.is_visible(&mac) {
268             Visible::Yes => false,
269             Visible::Editable => true,
270             Visible::No => return,
271         };
272         self.add(
273             render_macro(
274                 RenderContext::new(ctx).private_editable(is_private_editable),
275                 path_ctx,
276                 local_name,
277                 mac,
278             )
279             .build(ctx.db),
280         );
281     }
282 
add_function( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, func: hir::Function, local_name: Option<hir::Name>, )283     pub(crate) fn add_function(
284         &mut self,
285         ctx: &CompletionContext<'_>,
286         path_ctx: &PathCompletionCtx,
287         func: hir::Function,
288         local_name: Option<hir::Name>,
289     ) {
290         if !ctx.check_stability(Some(&func.attrs(ctx.db))) {
291             return;
292         }
293         let is_private_editable = match ctx.is_visible(&func) {
294             Visible::Yes => false,
295             Visible::Editable => true,
296             Visible::No => return,
297         };
298         let doc_aliases = ctx.doc_aliases(&func);
299         self.add(
300             render_fn(
301                 RenderContext::new(ctx)
302                     .private_editable(is_private_editable)
303                     .doc_aliases(doc_aliases),
304                 path_ctx,
305                 local_name,
306                 func,
307             )
308             .build(ctx.db),
309         );
310     }
311 
add_method( &mut self, ctx: &CompletionContext<'_>, dot_access: &DotAccess, func: hir::Function, receiver: Option<hir::Name>, local_name: Option<hir::Name>, )312     pub(crate) fn add_method(
313         &mut self,
314         ctx: &CompletionContext<'_>,
315         dot_access: &DotAccess,
316         func: hir::Function,
317         receiver: Option<hir::Name>,
318         local_name: Option<hir::Name>,
319     ) {
320         if !ctx.check_stability(Some(&func.attrs(ctx.db))) {
321             return;
322         }
323         let is_private_editable = match ctx.is_visible(&func) {
324             Visible::Yes => false,
325             Visible::Editable => true,
326             Visible::No => return,
327         };
328         let doc_aliases = ctx.doc_aliases(&func);
329         self.add(
330             render_method(
331                 RenderContext::new(ctx)
332                     .private_editable(is_private_editable)
333                     .doc_aliases(doc_aliases),
334                 dot_access,
335                 receiver,
336                 local_name,
337                 func,
338             )
339             .build(ctx.db),
340         );
341     }
342 
add_method_with_import( &mut self, ctx: &CompletionContext<'_>, dot_access: &DotAccess, func: hir::Function, import: LocatedImport, )343     pub(crate) fn add_method_with_import(
344         &mut self,
345         ctx: &CompletionContext<'_>,
346         dot_access: &DotAccess,
347         func: hir::Function,
348         import: LocatedImport,
349     ) {
350         if !ctx.check_stability(Some(&func.attrs(ctx.db))) {
351             return;
352         }
353         let is_private_editable = match ctx.is_visible(&func) {
354             Visible::Yes => false,
355             Visible::Editable => true,
356             Visible::No => return,
357         };
358         let doc_aliases = ctx.doc_aliases(&func);
359         self.add(
360             render_method(
361                 RenderContext::new(ctx)
362                     .private_editable(is_private_editable)
363                     .doc_aliases(doc_aliases)
364                     .import_to_add(Some(import)),
365                 dot_access,
366                 None,
367                 None,
368                 func,
369             )
370             .build(ctx.db),
371         );
372     }
373 
add_const(&mut self, ctx: &CompletionContext<'_>, konst: hir::Const)374     pub(crate) fn add_const(&mut self, ctx: &CompletionContext<'_>, konst: hir::Const) {
375         if !ctx.check_stability(Some(&konst.attrs(ctx.db))) {
376             return;
377         }
378         let is_private_editable = match ctx.is_visible(&konst) {
379             Visible::Yes => false,
380             Visible::Editable => true,
381             Visible::No => return,
382         };
383         self.add_opt(render_const(
384             RenderContext::new(ctx).private_editable(is_private_editable),
385             konst,
386         ));
387     }
388 
add_type_alias( &mut self, ctx: &CompletionContext<'_>, type_alias: hir::TypeAlias, )389     pub(crate) fn add_type_alias(
390         &mut self,
391         ctx: &CompletionContext<'_>,
392         type_alias: hir::TypeAlias,
393     ) {
394         if !ctx.check_stability(Some(&type_alias.attrs(ctx.db))) {
395             return;
396         }
397         let is_private_editable = match ctx.is_visible(&type_alias) {
398             Visible::Yes => false,
399             Visible::Editable => true,
400             Visible::No => return,
401         };
402         self.add_opt(render_type_alias(
403             RenderContext::new(ctx).private_editable(is_private_editable),
404             type_alias,
405         ));
406     }
407 
add_type_alias_with_eq( &mut self, ctx: &CompletionContext<'_>, type_alias: hir::TypeAlias, )408     pub(crate) fn add_type_alias_with_eq(
409         &mut self,
410         ctx: &CompletionContext<'_>,
411         type_alias: hir::TypeAlias,
412     ) {
413         if !ctx.check_stability(Some(&type_alias.attrs(ctx.db))) {
414             return;
415         }
416         self.add_opt(render_type_alias_with_eq(RenderContext::new(ctx), type_alias));
417     }
418 
add_qualified_enum_variant( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, variant: hir::Variant, path: hir::ModPath, )419     pub(crate) fn add_qualified_enum_variant(
420         &mut self,
421         ctx: &CompletionContext<'_>,
422         path_ctx: &PathCompletionCtx,
423         variant: hir::Variant,
424         path: hir::ModPath,
425     ) {
426         if !ctx.check_stability(Some(&variant.attrs(ctx.db))) {
427             return;
428         }
429         if let Some(builder) =
430             render_variant_lit(RenderContext::new(ctx), path_ctx, None, variant, Some(path))
431         {
432             self.add(builder.build(ctx.db));
433         }
434     }
435 
add_enum_variant( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, variant: hir::Variant, local_name: Option<hir::Name>, )436     pub(crate) fn add_enum_variant(
437         &mut self,
438         ctx: &CompletionContext<'_>,
439         path_ctx: &PathCompletionCtx,
440         variant: hir::Variant,
441         local_name: Option<hir::Name>,
442     ) {
443         if !ctx.check_stability(Some(&variant.attrs(ctx.db))) {
444             return;
445         }
446         if let PathCompletionCtx { kind: PathKind::Pat { pat_ctx }, .. } = path_ctx {
447             cov_mark::hit!(enum_variant_pattern_path);
448             self.add_variant_pat(ctx, pat_ctx, Some(path_ctx), variant, local_name);
449             return;
450         }
451 
452         if let Some(builder) =
453             render_variant_lit(RenderContext::new(ctx), path_ctx, local_name, variant, None)
454         {
455             self.add(builder.build(ctx.db));
456         }
457     }
458 
add_field( &mut self, ctx: &CompletionContext<'_>, dot_access: &DotAccess, receiver: Option<hir::Name>, field: hir::Field, ty: &hir::Type, )459     pub(crate) fn add_field(
460         &mut self,
461         ctx: &CompletionContext<'_>,
462         dot_access: &DotAccess,
463         receiver: Option<hir::Name>,
464         field: hir::Field,
465         ty: &hir::Type,
466     ) {
467         if !ctx.check_stability(Some(&field.attrs(ctx.db))) {
468             return;
469         }
470         let is_private_editable = match ctx.is_visible(&field) {
471             Visible::Yes => false,
472             Visible::Editable => true,
473             Visible::No => return,
474         };
475         let doc_aliases = ctx.doc_aliases(&field);
476         let item = render_field(
477             RenderContext::new(ctx).private_editable(is_private_editable).doc_aliases(doc_aliases),
478             dot_access,
479             receiver,
480             field,
481             ty,
482         );
483         self.add(item);
484     }
485 
add_struct_literal( &mut self, ctx: &CompletionContext<'_>, path_ctx: &PathCompletionCtx, strukt: hir::Struct, path: Option<hir::ModPath>, local_name: Option<hir::Name>, )486     pub(crate) fn add_struct_literal(
487         &mut self,
488         ctx: &CompletionContext<'_>,
489         path_ctx: &PathCompletionCtx,
490         strukt: hir::Struct,
491         path: Option<hir::ModPath>,
492         local_name: Option<hir::Name>,
493     ) {
494         if !ctx.check_stability(Some(&strukt.attrs(ctx.db))) {
495             return;
496         }
497         if let Some(builder) =
498             render_struct_literal(RenderContext::new(ctx), path_ctx, strukt, path, local_name)
499         {
500             self.add(builder.build(ctx.db));
501         }
502     }
503 
add_union_literal( &mut self, ctx: &CompletionContext<'_>, un: hir::Union, path: Option<hir::ModPath>, local_name: Option<hir::Name>, )504     pub(crate) fn add_union_literal(
505         &mut self,
506         ctx: &CompletionContext<'_>,
507         un: hir::Union,
508         path: Option<hir::ModPath>,
509         local_name: Option<hir::Name>,
510     ) {
511         if !ctx.check_stability(Some(&un.attrs(ctx.db))) {
512             return;
513         }
514         let item = render_union_literal(RenderContext::new(ctx), un, path, local_name);
515         self.add_opt(item);
516     }
517 
add_tuple_field( &mut self, ctx: &CompletionContext<'_>, receiver: Option<hir::Name>, field: usize, ty: &hir::Type, )518     pub(crate) fn add_tuple_field(
519         &mut self,
520         ctx: &CompletionContext<'_>,
521         receiver: Option<hir::Name>,
522         field: usize,
523         ty: &hir::Type,
524     ) {
525         // Only used for (unnamed) tuples, whose all fields *are* stable. No need to check
526         // stability here.
527         let item = render_tuple_field(RenderContext::new(ctx), receiver, field, ty);
528         self.add(item);
529     }
530 
add_lifetime(&mut self, ctx: &CompletionContext<'_>, name: hir::Name)531     pub(crate) fn add_lifetime(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) {
532         CompletionItem::new(SymbolKind::LifetimeParam, ctx.source_range(), name.to_smol_str())
533             .add_to(self, ctx.db)
534     }
535 
add_label(&mut self, ctx: &CompletionContext<'_>, name: hir::Name)536     pub(crate) fn add_label(&mut self, ctx: &CompletionContext<'_>, name: hir::Name) {
537         CompletionItem::new(SymbolKind::Label, ctx.source_range(), name.to_smol_str())
538             .add_to(self, ctx.db)
539     }
540 
add_variant_pat( &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, path_ctx: Option<&PathCompletionCtx>, variant: hir::Variant, local_name: Option<hir::Name>, )541     pub(crate) fn add_variant_pat(
542         &mut self,
543         ctx: &CompletionContext<'_>,
544         pattern_ctx: &PatternContext,
545         path_ctx: Option<&PathCompletionCtx>,
546         variant: hir::Variant,
547         local_name: Option<hir::Name>,
548     ) {
549         if !ctx.check_stability(Some(&variant.attrs(ctx.db))) {
550             return;
551         }
552         self.add_opt(render_variant_pat(
553             RenderContext::new(ctx),
554             pattern_ctx,
555             path_ctx,
556             variant,
557             local_name,
558             None,
559         ));
560     }
561 
add_qualified_variant_pat( &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, variant: hir::Variant, path: hir::ModPath, )562     pub(crate) fn add_qualified_variant_pat(
563         &mut self,
564         ctx: &CompletionContext<'_>,
565         pattern_ctx: &PatternContext,
566         variant: hir::Variant,
567         path: hir::ModPath,
568     ) {
569         if !ctx.check_stability(Some(&variant.attrs(ctx.db))) {
570             return;
571         }
572         let path = Some(&path);
573         self.add_opt(render_variant_pat(
574             RenderContext::new(ctx),
575             pattern_ctx,
576             None,
577             variant,
578             None,
579             path,
580         ));
581     }
582 
add_struct_pat( &mut self, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, strukt: hir::Struct, local_name: Option<hir::Name>, )583     pub(crate) fn add_struct_pat(
584         &mut self,
585         ctx: &CompletionContext<'_>,
586         pattern_ctx: &PatternContext,
587         strukt: hir::Struct,
588         local_name: Option<hir::Name>,
589     ) {
590         if !ctx.check_stability(Some(&strukt.attrs(ctx.db))) {
591             return;
592         }
593         self.add_opt(render_struct_pat(RenderContext::new(ctx), pattern_ctx, strukt, local_name));
594     }
595 }
596 
597 /// Calls the callback for each variant of the provided enum with the path to the variant.
598 /// Skips variants that are visible with single segment paths.
enum_variants_with_paths( acc: &mut Completions, ctx: &CompletionContext<'_>, enum_: hir::Enum, impl_: &Option<ast::Impl>, cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath), )599 fn enum_variants_with_paths(
600     acc: &mut Completions,
601     ctx: &CompletionContext<'_>,
602     enum_: hir::Enum,
603     impl_: &Option<ast::Impl>,
604     cb: impl Fn(&mut Completions, &CompletionContext<'_>, hir::Variant, hir::ModPath),
605 ) {
606     let mut process_variant = |variant: Variant| {
607         let self_path = hir::ModPath::from_segments(
608             hir::PathKind::Plain,
609             iter::once(known::SELF_TYPE).chain(iter::once(variant.name(ctx.db))),
610         );
611 
612         cb(acc, ctx, variant, self_path);
613     };
614 
615     let variants = enum_.variants(ctx.db);
616 
617     if let Some(impl_) = impl_.as_ref().and_then(|impl_| ctx.sema.to_def(impl_)) {
618         if impl_.self_ty(ctx.db).as_adt() == Some(hir::Adt::Enum(enum_)) {
619             variants.iter().for_each(|variant| process_variant(*variant));
620         }
621     }
622 
623     for variant in variants {
624         if let Some(path) = ctx.module.find_use_path(
625             ctx.db,
626             hir::ModuleDef::from(variant),
627             ctx.config.prefer_no_std,
628         ) {
629             // Variants with trivial paths are already added by the existing completion logic,
630             // so we should avoid adding these twice
631             if path.segments().len() > 1 {
632                 cb(acc, ctx, variant, path);
633             }
634         }
635     }
636 }
637 
638 pub(super) fn complete_name(
639     acc: &mut Completions,
640     ctx: &CompletionContext<'_>,
641     NameContext { name, kind }: &NameContext,
642 ) {
643     match kind {
644         NameKind::Const => {
645             item_list::trait_impl::complete_trait_impl_const(acc, ctx, name);
646         }
647         NameKind::Function => {
648             item_list::trait_impl::complete_trait_impl_fn(acc, ctx, name);
649         }
650         NameKind::IdentPat(pattern_ctx) => {
651             if ctx.token.kind() != syntax::T![_] {
652                 complete_patterns(acc, ctx, pattern_ctx)
653             }
654         }
655         NameKind::Module(mod_under_caret) => {
656             mod_::complete_mod(acc, ctx, mod_under_caret);
657         }
658         NameKind::TypeAlias => {
659             item_list::trait_impl::complete_trait_impl_type_alias(acc, ctx, name);
660         }
661         NameKind::RecordField => {
662             field::complete_field_list_record_variant(acc, ctx);
663         }
664         NameKind::ConstParam
665         | NameKind::Enum
666         | NameKind::MacroDef
667         | NameKind::MacroRules
668         | NameKind::Rename
669         | NameKind::SelfParam
670         | NameKind::Static
671         | NameKind::Struct
672         | NameKind::Trait
673         | NameKind::TypeParam
674         | NameKind::Union
675         | NameKind::Variant => (),
676     }
677 }
678 
679 pub(super) fn complete_name_ref(
680     acc: &mut Completions,
681     ctx: &CompletionContext<'_>,
682     NameRefContext { nameref, kind }: &NameRefContext,
683 ) {
684     match kind {
685         NameRefKind::Path(path_ctx) => {
686             flyimport::import_on_the_fly_path(acc, ctx, path_ctx);
687 
688             match &path_ctx.kind {
689                 PathKind::Expr { expr_ctx } => {
690                     expr::complete_expr_path(acc, ctx, path_ctx, expr_ctx);
691 
692                     dot::complete_undotted_self(acc, ctx, path_ctx, expr_ctx);
693                     item_list::complete_item_list_in_expr(acc, ctx, path_ctx, expr_ctx);
694                     snippet::complete_expr_snippet(acc, ctx, path_ctx, expr_ctx);
695                 }
696                 PathKind::Type { location } => {
697                     r#type::complete_type_path(acc, ctx, path_ctx, location);
698 
699                     match location {
700                         TypeLocation::TupleField => {
701                             field::complete_field_list_tuple_variant(acc, ctx, path_ctx);
702                         }
703                         TypeLocation::TypeAscription(ascription) => {
704                             r#type::complete_ascribed_type(acc, ctx, path_ctx, ascription);
705                         }
706                         TypeLocation::GenericArgList(_)
707                         | TypeLocation::TypeBound
708                         | TypeLocation::ImplTarget
709                         | TypeLocation::ImplTrait
710                         | TypeLocation::Other => (),
711                     }
712                 }
713                 PathKind::Attr { attr_ctx } => {
714                     attribute::complete_attribute_path(acc, ctx, path_ctx, attr_ctx);
715                 }
716                 PathKind::Derive { existing_derives } => {
717                     attribute::complete_derive_path(acc, ctx, path_ctx, existing_derives);
718                 }
719                 PathKind::Item { kind } => {
720                     item_list::complete_item_list(acc, ctx, path_ctx, kind);
721 
722                     snippet::complete_item_snippet(acc, ctx, path_ctx, kind);
723                     if let ItemListKind::TraitImpl(impl_) = kind {
724                         item_list::trait_impl::complete_trait_impl_item_by_name(
725                             acc, ctx, path_ctx, nameref, impl_,
726                         );
727                     }
728                 }
729                 PathKind::Pat { .. } => {
730                     pattern::complete_pattern_path(acc, ctx, path_ctx);
731                 }
732                 PathKind::Vis { has_in_token } => {
733                     vis::complete_vis_path(acc, ctx, path_ctx, has_in_token);
734                 }
735                 PathKind::Use => {
736                     use_::complete_use_path(acc, ctx, path_ctx, nameref);
737                 }
738             }
739         }
740         NameRefKind::DotAccess(dot_access) => {
741             flyimport::import_on_the_fly_dot(acc, ctx, dot_access);
742             dot::complete_dot(acc, ctx, dot_access);
743             postfix::complete_postfix(acc, ctx, dot_access);
744         }
745         NameRefKind::Keyword(item) => {
746             keyword::complete_for_and_where(acc, ctx, item);
747         }
748         NameRefKind::RecordExpr { dot_prefix, expr } => {
749             record::complete_record_expr_fields(acc, ctx, expr, dot_prefix);
750         }
751         NameRefKind::Pattern(pattern_ctx) => complete_patterns(acc, ctx, pattern_ctx),
752     }
753 }
754 
complete_patterns( acc: &mut Completions, ctx: &CompletionContext<'_>, pattern_ctx: &PatternContext, )755 fn complete_patterns(
756     acc: &mut Completions,
757     ctx: &CompletionContext<'_>,
758     pattern_ctx: &PatternContext,
759 ) {
760     flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx);
761     fn_param::complete_fn_param(acc, ctx, pattern_ctx);
762     pattern::complete_pattern(acc, ctx, pattern_ctx);
763     record::complete_record_pattern_fields(acc, ctx, pattern_ctx);
764 }
765