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