ide_completion/
completions.rs

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