]> git.lizzy.rs Git - rust.git/blob - crates/ide-completion/src/context.rs
More precise where keyword completions
[rust.git] / crates / ide-completion / src / context.rs
1 //! See `CompletionContext` structure.
2
3 use std::iter;
4
5 use base_db::SourceDatabaseExt;
6 use hir::{
7     HasAttrs, Local, Name, PathResolution, ScopeDef, Semantics, SemanticsScope, Type, TypeInfo,
8 };
9 use ide_db::{
10     active_parameter::ActiveParameter,
11     base_db::{FilePosition, SourceDatabase},
12     famous_defs::FamousDefs,
13     FxHashMap, FxHashSet, RootDatabase,
14 };
15 use syntax::{
16     algo::{find_node_at_offset, non_trivia_sibling},
17     ast::{self, AttrKind, HasArgList, HasName, NameOrNameRef},
18     match_ast, AstNode, AstToken, NodeOrToken,
19     SyntaxKind::{self, *},
20     SyntaxNode, SyntaxToken, TextRange, TextSize, T,
21 };
22 use text_edit::Indel;
23
24 use crate::{
25     patterns::{
26         determine_location, determine_prev_sibling, is_in_loop_body, is_in_token_of_for_loop,
27         previous_token, ImmediateLocation, ImmediatePrevSibling,
28     },
29     CompletionConfig,
30 };
31
32 const COMPLETION_MARKER: &str = "intellijRulezz";
33
34 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
35 pub(crate) enum PatternRefutability {
36     Refutable,
37     Irrefutable,
38 }
39
40 pub(crate) enum Visible {
41     Yes,
42     Editable,
43     No,
44 }
45
46 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
47 pub(super) enum PathKind {
48     Expr {
49         in_block_expr: bool,
50         in_loop_body: bool,
51     },
52     Type {
53         in_tuple_struct: bool,
54     },
55     Attr {
56         kind: AttrKind,
57         annotated_item_kind: Option<SyntaxKind>,
58     },
59     Derive,
60     /// Path in item position, that is inside an (Assoc)ItemList
61     Item {
62         kind: ItemListKind,
63     },
64     Pat,
65     Vis {
66         has_in_token: bool,
67     },
68     Use,
69 }
70
71 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
72 pub(super) enum ItemListKind {
73     SourceFile,
74     Module,
75     Impl,
76     TraitImpl,
77     Trait,
78     ExternBlock,
79 }
80
81 #[derive(Debug, Default)]
82 pub(super) struct QualifierCtx {
83     pub(super) unsafe_tok: Option<SyntaxToken>,
84     pub(super) vis_node: Option<ast::Visibility>,
85 }
86
87 impl QualifierCtx {
88     pub(super) fn none(&self) -> bool {
89         self.unsafe_tok.is_none() && self.vis_node.is_none()
90     }
91 }
92
93 #[derive(Debug)]
94 pub(crate) struct PathCompletionCtx {
95     /// If this is a call with () already there (or {} in case of record patterns)
96     pub(super) has_call_parens: bool,
97     /// If this has a macro call bang !
98     pub(super) has_macro_bang: bool,
99     /// Whether this path stars with a `::`.
100     pub(super) is_absolute_path: bool,
101     /// The qualifier of the current path if it exists.
102     pub(super) qualifier: Option<PathQualifierCtx>,
103     #[allow(dead_code)]
104     // FIXME: use this
105     /// The parent of the path we are completing.
106     pub(super) parent: Option<ast::Path>,
107     pub(super) kind: PathKind,
108     /// Whether the path segment has type args or not.
109     pub(super) has_type_args: bool,
110 }
111
112 #[derive(Debug)]
113 pub(crate) struct PathQualifierCtx {
114     pub(crate) path: ast::Path,
115     pub(crate) resolution: Option<PathResolution>,
116     /// Whether this path consists solely of `super` segments
117     pub(crate) is_super_chain: bool,
118     /// Whether the qualifier comes from a use tree parent or not
119     pub(crate) use_tree_parent: bool,
120     /// <_>
121     pub(crate) is_infer_qualifier: bool,
122 }
123
124 #[derive(Debug)]
125 pub(super) struct PatternContext {
126     pub(super) refutability: PatternRefutability,
127     pub(super) param_ctx: Option<(ast::ParamList, ast::Param, ParamKind)>,
128     pub(super) has_type_ascription: bool,
129     pub(super) parent_pat: Option<ast::Pat>,
130     pub(super) ref_token: Option<SyntaxToken>,
131     pub(super) mut_token: Option<SyntaxToken>,
132     /// The record pattern this name or ref is a field of
133     pub(super) record_pat: Option<ast::RecordPat>,
134 }
135
136 #[derive(Debug)]
137 pub(super) struct LifetimeContext {
138     pub(super) lifetime: Option<ast::Lifetime>,
139     pub(super) kind: LifetimeKind,
140 }
141
142 #[derive(Debug)]
143 pub(super) enum LifetimeKind {
144     LifetimeParam { is_decl: bool, param: ast::LifetimeParam },
145     Lifetime,
146     LabelRef,
147     LabelDef,
148 }
149
150 #[derive(Debug)]
151 pub(super) struct NameContext {
152     #[allow(dead_code)]
153     pub(super) name: Option<ast::Name>,
154     pub(super) kind: NameKind,
155 }
156
157 #[derive(Debug)]
158 #[allow(dead_code)]
159 pub(super) enum NameKind {
160     Const,
161     ConstParam,
162     Enum,
163     Function,
164     IdentPat,
165     MacroDef,
166     MacroRules,
167     /// Fake node
168     Module(ast::Module),
169     RecordField,
170     Rename,
171     SelfParam,
172     Static,
173     Struct,
174     Trait,
175     TypeAlias,
176     TypeParam,
177     Union,
178     Variant,
179 }
180
181 #[derive(Debug)]
182 pub(super) struct NameRefContext {
183     /// NameRef syntax in the original file
184     pub(super) nameref: Option<ast::NameRef>,
185     // FIXME: these fields are actually disjoint -> enum
186     pub(super) dot_access: Option<DotAccess>,
187     pub(super) path_ctx: Option<PathCompletionCtx>,
188     /// Position where we are only interested in keyword completions
189     pub(super) keyword: Option<ast::Item>,
190     /// The record expression this nameref is a field of
191     pub(super) record_expr: Option<(ast::RecordExpr, bool)>,
192 }
193
194 #[derive(Debug)]
195 pub(super) enum IdentContext {
196     Name(NameContext),
197     NameRef(NameRefContext),
198     Lifetime(LifetimeContext),
199     /// Original token, fake token
200     String {
201         original: ast::String,
202         expanded: Option<ast::String>,
203     },
204     UnexpandedAttrTT {
205         fake_attribute_under_caret: Option<ast::Attr>,
206     },
207 }
208
209 #[derive(Debug)]
210 pub(super) struct DotAccess {
211     pub(super) receiver: Option<ast::Expr>,
212     pub(super) receiver_ty: Option<TypeInfo>,
213     pub(super) kind: DotAccessKind,
214 }
215
216 #[derive(Debug)]
217 pub(super) enum DotAccessKind {
218     Field {
219         /// True if the receiver is an integer and there is no ident in the original file after it yet
220         /// like `0.$0`
221         receiver_is_ambiguous_float_literal: bool,
222     },
223     Method {
224         has_parens: bool,
225     },
226 }
227
228 #[derive(Clone, Debug, PartialEq, Eq)]
229 pub(crate) enum ParamKind {
230     Function(ast::Fn),
231     Closure(ast::ClosureExpr),
232 }
233
234 /// `CompletionContext` is created early during completion to figure out, where
235 /// exactly is the cursor, syntax-wise.
236 #[derive(Debug)]
237 pub(crate) struct CompletionContext<'a> {
238     pub(super) sema: Semantics<'a, RootDatabase>,
239     pub(super) scope: SemanticsScope<'a>,
240     pub(super) db: &'a RootDatabase,
241     pub(super) config: &'a CompletionConfig,
242     pub(super) position: FilePosition,
243
244     /// The token before the cursor, in the original file.
245     pub(super) original_token: SyntaxToken,
246     /// The token before the cursor, in the macro-expanded file.
247     pub(super) token: SyntaxToken,
248     /// The crate of the current file.
249     pub(super) krate: hir::Crate,
250     /// The module of the `scope`.
251     pub(super) module: hir::Module,
252
253     /// The expected name of what we are completing.
254     /// This is usually the parameter name of the function argument we are completing.
255     pub(super) expected_name: Option<NameOrNameRef>,
256     /// The expected type of what we are completing.
257     pub(super) expected_type: Option<Type>,
258
259     /// The parent function of the cursor position if it exists.
260     pub(super) function_def: Option<ast::Fn>,
261     /// The parent impl of the cursor position if it exists.
262     pub(super) impl_def: Option<ast::Impl>,
263     /// Are we completing inside a let statement with a missing semicolon?
264     pub(super) incomplete_let: bool,
265
266     pub(super) completion_location: Option<ImmediateLocation>,
267     pub(super) prev_sibling: Option<ImmediatePrevSibling>,
268     pub(super) previous_token: Option<SyntaxToken>,
269
270     pub(super) ident_ctx: IdentContext,
271
272     pub(super) pattern_ctx: Option<PatternContext>,
273     pub(super) qualifier_ctx: QualifierCtx,
274
275     pub(super) existing_derives: FxHashSet<hir::Macro>,
276
277     pub(super) locals: FxHashMap<Name, Local>,
278 }
279
280 impl<'a> CompletionContext<'a> {
281     /// The range of the identifier that is being completed.
282     pub(crate) fn source_range(&self) -> TextRange {
283         // check kind of macro-expanded token, but use range of original token
284         let kind = self.token.kind();
285         match kind {
286             CHAR => {
287                 // assume we are completing a lifetime but the user has only typed the '
288                 cov_mark::hit!(completes_if_lifetime_without_idents);
289                 TextRange::at(self.original_token.text_range().start(), TextSize::from(1))
290             }
291             IDENT | LIFETIME_IDENT | UNDERSCORE => self.original_token.text_range(),
292             _ if kind.is_keyword() => self.original_token.text_range(),
293             _ => TextRange::empty(self.position.offset),
294         }
295     }
296
297     pub(crate) fn previous_token_is(&self, kind: SyntaxKind) -> bool {
298         self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind)
299     }
300
301     pub(crate) fn famous_defs(&self) -> FamousDefs {
302         FamousDefs(&self.sema, self.krate)
303     }
304
305     pub(super) fn nameref_ctx(&self) -> Option<&NameRefContext> {
306         match &self.ident_ctx {
307             IdentContext::NameRef(it) => Some(it),
308             _ => None,
309         }
310     }
311
312     pub(super) fn name_ctx(&self) -> Option<&NameContext> {
313         match &self.ident_ctx {
314             IdentContext::Name(it) => Some(it),
315             _ => None,
316         }
317     }
318
319     pub(super) fn lifetime_ctx(&self) -> Option<&LifetimeContext> {
320         match &self.ident_ctx {
321             IdentContext::Lifetime(it) => Some(it),
322             _ => None,
323         }
324     }
325
326     pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
327         match self.nameref_ctx() {
328             Some(NameRefContext { dot_access: Some(DotAccess { receiver, .. }), .. }) => {
329                 receiver.as_ref()
330             }
331             _ => None,
332         }
333     }
334
335     pub(crate) fn has_dot_receiver(&self) -> bool {
336         self.dot_receiver().is_some()
337     }
338
339     // FIXME: This shouldn't exist
340     pub(crate) fn expects_generic_arg(&self) -> bool {
341         matches!(self.completion_location, Some(ImmediateLocation::GenericArgList(_)))
342     }
343
344     pub(crate) fn expects_ident_ref_expr(&self) -> bool {
345         matches!(self.completion_location, Some(ImmediateLocation::RefExpr))
346     }
347
348     pub(crate) fn after_if(&self) -> bool {
349         matches!(self.prev_sibling, Some(ImmediatePrevSibling::IfExpr))
350     }
351
352     // FIXME: This shouldn't exist
353     pub(crate) fn is_path_disallowed(&self) -> bool {
354         !self.qualifier_ctx.none()
355             || (matches!(self.name_ctx(), Some(NameContext { .. })) && self.pattern_ctx.is_none())
356             || matches!(self.pattern_ctx, Some(PatternContext { record_pat: Some(_), .. }))
357             || matches!(
358                 self.nameref_ctx(),
359                 Some(NameRefContext { record_expr: Some((_, false)), .. })
360             )
361     }
362
363     pub(crate) fn path_context(&self) -> Option<&PathCompletionCtx> {
364         self.nameref_ctx().and_then(|ctx| ctx.path_ctx.as_ref())
365     }
366
367     pub(crate) fn expects_expression(&self) -> bool {
368         matches!(self.path_context(), Some(PathCompletionCtx { kind: PathKind::Expr { .. }, .. }))
369     }
370
371     pub(crate) fn is_non_trivial_path(&self) -> bool {
372         matches!(
373             self.path_context(),
374             Some(
375                 PathCompletionCtx { is_absolute_path: true, .. }
376                     | PathCompletionCtx { qualifier: Some(_), .. }
377             )
378         )
379     }
380
381     pub(crate) fn path_qual(&self) -> Option<&ast::Path> {
382         self.path_context().and_then(|it| it.qualifier.as_ref().map(|it| &it.path))
383     }
384
385     pub(crate) fn path_kind(&self) -> Option<PathKind> {
386         self.path_context().map(|it| it.kind)
387     }
388
389     /// Checks if an item is visible and not `doc(hidden)` at the completion site.
390     pub(crate) fn is_visible<I>(&self, item: &I) -> Visible
391     where
392         I: hir::HasVisibility + hir::HasAttrs + hir::HasCrate + Copy,
393     {
394         self.is_visible_impl(&item.visibility(self.db), &item.attrs(self.db), item.krate(self.db))
395     }
396
397     pub(crate) fn is_scope_def_hidden(&self, scope_def: ScopeDef) -> bool {
398         if let (Some(attrs), Some(krate)) = (scope_def.attrs(self.db), scope_def.krate(self.db)) {
399             return self.is_doc_hidden(&attrs, krate);
400         }
401
402         false
403     }
404
405     /// Check if an item is `#[doc(hidden)]`.
406     pub(crate) fn is_item_hidden(&self, item: &hir::ItemInNs) -> bool {
407         let attrs = item.attrs(self.db);
408         let krate = item.krate(self.db);
409         match (attrs, krate) {
410             (Some(attrs), Some(krate)) => self.is_doc_hidden(&attrs, krate),
411             _ => false,
412         }
413     }
414     /// Whether the given trait is an operator trait or not.
415     pub(crate) fn is_ops_trait(&self, trait_: hir::Trait) -> bool {
416         match trait_.attrs(self.db).lang() {
417             Some(lang) => OP_TRAIT_LANG_NAMES.contains(&lang.as_str()),
418             None => false,
419         }
420     }
421
422     /// Returns the traits in scope, with the [`Drop`] trait removed.
423     pub(crate) fn traits_in_scope(&self) -> hir::VisibleTraits {
424         let mut traits_in_scope = self.scope.visible_traits();
425         if let Some(drop) = self.famous_defs().core_ops_Drop() {
426             traits_in_scope.0.remove(&drop.into());
427         }
428         traits_in_scope
429     }
430
431     /// A version of [`SemanticsScope::process_all_names`] that filters out `#[doc(hidden)]` items.
432     pub(crate) fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef)) {
433         let _p = profile::span("CompletionContext::process_all_names");
434         self.scope.process_all_names(&mut |name, def| {
435             if self.is_scope_def_hidden(def) {
436                 return;
437             }
438
439             f(name, def);
440         });
441     }
442
443     pub(crate) fn process_all_names_raw(&self, f: &mut dyn FnMut(Name, ScopeDef)) {
444         let _p = profile::span("CompletionContext::process_all_names_raw");
445         self.scope.process_all_names(&mut |name, def| f(name, def));
446     }
447
448     fn is_visible_impl(
449         &self,
450         vis: &hir::Visibility,
451         attrs: &hir::Attrs,
452         defining_crate: hir::Crate,
453     ) -> Visible {
454         if !vis.is_visible_from(self.db, self.module.into()) {
455             if !self.config.enable_private_editable {
456                 return Visible::No;
457             }
458             // If the definition location is editable, also show private items
459             let root_file = defining_crate.root_file(self.db);
460             let source_root_id = self.db.file_source_root(root_file);
461             let is_editable = !self.db.source_root(source_root_id).is_library;
462             return if is_editable { Visible::Editable } else { Visible::No };
463         }
464
465         if self.is_doc_hidden(attrs, defining_crate) {
466             Visible::No
467         } else {
468             Visible::Yes
469         }
470     }
471
472     fn is_doc_hidden(&self, attrs: &hir::Attrs, defining_crate: hir::Crate) -> bool {
473         // `doc(hidden)` items are only completed within the defining crate.
474         self.krate != defining_crate && attrs.has_doc_hidden()
475     }
476 }
477
478 // CompletionContext construction
479 impl<'a> CompletionContext<'a> {
480     pub(super) fn new(
481         db: &'a RootDatabase,
482         position @ FilePosition { file_id, offset }: FilePosition,
483         config: &'a CompletionConfig,
484     ) -> Option<CompletionContext<'a>> {
485         let _p = profile::span("CompletionContext::new");
486         let sema = Semantics::new(db);
487
488         let original_file = sema.parse(file_id);
489
490         // Insert a fake ident to get a valid parse tree. We will use this file
491         // to determine context, though the original_file will be used for
492         // actual completion.
493         let file_with_fake_ident = {
494             let parse = db.parse(file_id);
495             let edit = Indel::insert(offset, COMPLETION_MARKER.to_string());
496             parse.reparse(&edit).tree()
497         };
498         let fake_ident_token =
499             file_with_fake_ident.syntax().token_at_offset(offset).right_biased()?;
500
501         let original_token = original_file.syntax().token_at_offset(offset).left_biased()?;
502         let token = sema.descend_into_macros_single(original_token.clone());
503         let scope = sema.scope_at_offset(&token.parent()?, offset)?;
504         let krate = scope.krate();
505         let module = scope.module();
506
507         let mut locals = FxHashMap::default();
508         scope.process_all_names(&mut |name, scope| {
509             if let ScopeDef::Local(local) = scope {
510                 locals.insert(name, local);
511             }
512         });
513
514         let mut ctx = CompletionContext {
515             sema,
516             scope,
517             db,
518             config,
519             position,
520             original_token,
521             token,
522             krate,
523             module,
524             expected_name: None,
525             expected_type: None,
526             function_def: None,
527             impl_def: None,
528             incomplete_let: false,
529             completion_location: None,
530             prev_sibling: None,
531             previous_token: None,
532             // dummy value, will be overwritten
533             ident_ctx: IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: None },
534             pattern_ctx: None,
535             qualifier_ctx: Default::default(),
536             existing_derives: Default::default(),
537             locals,
538         };
539         ctx.expand_and_fill(
540             original_file.syntax().clone(),
541             file_with_fake_ident.syntax().clone(),
542             offset,
543             fake_ident_token,
544         )?;
545         Some(ctx)
546     }
547
548     /// Expand attributes and macro calls at the current cursor position for both the original file
549     /// and fake file repeatedly. As soon as one of the two expansions fail we stop so the original
550     /// and speculative states stay in sync.
551     fn expand_and_fill(
552         &mut self,
553         mut original_file: SyntaxNode,
554         mut speculative_file: SyntaxNode,
555         mut offset: TextSize,
556         mut fake_ident_token: SyntaxToken,
557     ) -> Option<()> {
558         let _p = profile::span("CompletionContext::expand_and_fill");
559         let mut derive_ctx = None;
560
561         'expansion: loop {
562             let parent_item =
563                 |item: &ast::Item| item.syntax().ancestors().skip(1).find_map(ast::Item::cast);
564             let ancestor_items = iter::successors(
565                 Option::zip(
566                     find_node_at_offset::<ast::Item>(&original_file, offset),
567                     find_node_at_offset::<ast::Item>(&speculative_file, offset),
568                 ),
569                 |(a, b)| parent_item(a).zip(parent_item(b)),
570             );
571
572             // first try to expand attributes as these are always the outermost macro calls
573             'ancestors: for (actual_item, item_with_fake_ident) in ancestor_items {
574                 match (
575                     self.sema.expand_attr_macro(&actual_item),
576                     self.sema.speculative_expand_attr_macro(
577                         &actual_item,
578                         &item_with_fake_ident,
579                         fake_ident_token.clone(),
580                     ),
581                 ) {
582                     // maybe parent items have attributes, so continue walking the ancestors
583                     (None, None) => continue 'ancestors,
584                     // successful expansions
585                     (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => {
586                         let new_offset = fake_mapped_token.text_range().start();
587                         if new_offset > actual_expansion.text_range().end() {
588                             // offset outside of bounds from the original expansion,
589                             // stop here to prevent problems from happening
590                             break 'expansion;
591                         }
592                         original_file = actual_expansion;
593                         speculative_file = fake_expansion;
594                         fake_ident_token = fake_mapped_token;
595                         offset = new_offset;
596                         continue 'expansion;
597                     }
598                     // exactly one expansion failed, inconsistent state so stop expanding completely
599                     _ => break 'expansion,
600                 }
601             }
602
603             // No attributes have been expanded, so look for macro_call! token trees or derive token trees
604             let orig_tt = match find_node_at_offset::<ast::TokenTree>(&original_file, offset) {
605                 Some(it) => it,
606                 None => break 'expansion,
607             };
608             let spec_tt = match find_node_at_offset::<ast::TokenTree>(&speculative_file, offset) {
609                 Some(it) => it,
610                 None => break 'expansion,
611             };
612
613             // Expand pseudo-derive expansion
614             if let (Some(orig_attr), Some(spec_attr)) = (
615                 orig_tt.syntax().parent().and_then(ast::Meta::cast).and_then(|it| it.parent_attr()),
616                 spec_tt.syntax().parent().and_then(ast::Meta::cast).and_then(|it| it.parent_attr()),
617             ) {
618                 if let (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) = (
619                     self.sema.expand_derive_as_pseudo_attr_macro(&orig_attr),
620                     self.sema.speculative_expand_derive_as_pseudo_attr_macro(
621                         &orig_attr,
622                         &spec_attr,
623                         fake_ident_token.clone(),
624                     ),
625                 ) {
626                     derive_ctx = Some((
627                         actual_expansion,
628                         fake_expansion,
629                         fake_mapped_token.text_range().start(),
630                         orig_attr,
631                     ));
632                 }
633                 // at this point we won't have any more successful expansions, so stop
634                 break 'expansion;
635             }
636
637             // Expand fn-like macro calls
638             if let (Some(actual_macro_call), Some(macro_call_with_fake_ident)) = (
639                 orig_tt.syntax().ancestors().find_map(ast::MacroCall::cast),
640                 spec_tt.syntax().ancestors().find_map(ast::MacroCall::cast),
641             ) {
642                 let mac_call_path0 = actual_macro_call.path().as_ref().map(|s| s.syntax().text());
643                 let mac_call_path1 =
644                     macro_call_with_fake_ident.path().as_ref().map(|s| s.syntax().text());
645
646                 // inconsistent state, stop expanding
647                 if mac_call_path0 != mac_call_path1 {
648                     break 'expansion;
649                 }
650                 let speculative_args = match macro_call_with_fake_ident.token_tree() {
651                     Some(tt) => tt,
652                     None => break 'expansion,
653                 };
654
655                 match (
656                     self.sema.expand(&actual_macro_call),
657                     self.sema.speculative_expand(
658                         &actual_macro_call,
659                         &speculative_args,
660                         fake_ident_token.clone(),
661                     ),
662                 ) {
663                     // successful expansions
664                     (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => {
665                         let new_offset = fake_mapped_token.text_range().start();
666                         if new_offset > actual_expansion.text_range().end() {
667                             // offset outside of bounds from the original expansion,
668                             // stop here to prevent problems from happening
669                             break 'expansion;
670                         }
671                         original_file = actual_expansion;
672                         speculative_file = fake_expansion;
673                         fake_ident_token = fake_mapped_token;
674                         offset = new_offset;
675                         continue 'expansion;
676                     }
677                     // at least on expansion failed, we won't have anything to expand from this point
678                     // onwards so break out
679                     _ => break 'expansion,
680                 }
681             }
682
683             // none of our states have changed so stop the loop
684             break 'expansion;
685         }
686
687         self.fill(&original_file, speculative_file, offset, derive_ctx)
688     }
689
690     /// Calculate the expected type and name of the cursor position.
691     fn expected_type_and_name(&self) -> (Option<Type>, Option<NameOrNameRef>) {
692         let mut node = match self.token.parent() {
693             Some(it) => it,
694             None => return (None, None),
695         };
696         loop {
697             break match_ast! {
698                 match node {
699                     ast::LetStmt(it) => {
700                         cov_mark::hit!(expected_type_let_with_leading_char);
701                         cov_mark::hit!(expected_type_let_without_leading_char);
702                         let ty = it.pat()
703                             .and_then(|pat| self.sema.type_of_pat(&pat))
704                             .or_else(|| it.initializer().and_then(|it| self.sema.type_of_expr(&it)))
705                             .map(TypeInfo::original);
706                         let name = match it.pat() {
707                             Some(ast::Pat::IdentPat(ident)) => ident.name().map(NameOrNameRef::Name),
708                             Some(_) | None => None,
709                         };
710
711                         (ty, name)
712                     },
713                     ast::LetExpr(it) => {
714                         cov_mark::hit!(expected_type_if_let_without_leading_char);
715                         let ty = it.pat()
716                             .and_then(|pat| self.sema.type_of_pat(&pat))
717                             .or_else(|| it.expr().and_then(|it| self.sema.type_of_expr(&it)))
718                             .map(TypeInfo::original);
719                         (ty, None)
720                     },
721                     ast::ArgList(_) => {
722                         cov_mark::hit!(expected_type_fn_param);
723                         ActiveParameter::at_token(
724                             &self.sema,
725                             self.token.clone(),
726                         ).map(|ap| {
727                             let name = ap.ident().map(NameOrNameRef::Name);
728                             let ty = if has_ref(&self.token) {
729                                 cov_mark::hit!(expected_type_fn_param_ref);
730                                 ap.ty.remove_ref()
731                             } else {
732                                 Some(ap.ty)
733                             };
734                             (ty, name)
735                         })
736                         .unwrap_or((None, None))
737                     },
738                     ast::RecordExprFieldList(it) => {
739                         // wouldn't try {} be nice...
740                         (|| {
741                             if self.token.kind() == T![..]
742                                 || self.token.prev_token().map(|t| t.kind()) == Some(T![..])
743                             {
744                                 cov_mark::hit!(expected_type_struct_func_update);
745                                 let record_expr = it.syntax().parent().and_then(ast::RecordExpr::cast)?;
746                                 let ty = self.sema.type_of_expr(&record_expr.into())?;
747                                 Some((
748                                     Some(ty.original),
749                                     None
750                                 ))
751                             } else {
752                                 cov_mark::hit!(expected_type_struct_field_without_leading_char);
753                                 let expr_field = self.token.prev_sibling_or_token()?
754                                     .into_node()
755                                     .and_then(ast::RecordExprField::cast)?;
756                                 let (_, _, ty) = self.sema.resolve_record_field(&expr_field)?;
757                                 Some((
758                                     Some(ty),
759                                     expr_field.field_name().map(NameOrNameRef::NameRef),
760                                 ))
761                             }
762                         })().unwrap_or((None, None))
763                     },
764                     ast::RecordExprField(it) => {
765                         if let Some(expr) = it.expr() {
766                             cov_mark::hit!(expected_type_struct_field_with_leading_char);
767                             (
768                                 self.sema.type_of_expr(&expr).map(TypeInfo::original),
769                                 it.field_name().map(NameOrNameRef::NameRef),
770                             )
771                         } else {
772                             cov_mark::hit!(expected_type_struct_field_followed_by_comma);
773                             let ty = self.sema.resolve_record_field(&it)
774                                 .map(|(_, _, ty)| ty);
775                             (
776                                 ty,
777                                 it.field_name().map(NameOrNameRef::NameRef),
778                             )
779                         }
780                     },
781                     // match foo { $0 }
782                     // match foo { ..., pat => $0 }
783                     ast::MatchExpr(it) => {
784                         let ty = if self.previous_token_is(T![=>]) {
785                             // match foo { ..., pat => $0 }
786                             cov_mark::hit!(expected_type_match_arm_body_without_leading_char);
787                             cov_mark::hit!(expected_type_match_arm_body_with_leading_char);
788                             self.sema.type_of_expr(&it.into())
789                         } else {
790                             // match foo { $0 }
791                             cov_mark::hit!(expected_type_match_arm_without_leading_char);
792                             it.expr().and_then(|e| self.sema.type_of_expr(&e))
793                         }.map(TypeInfo::original);
794                         (ty, None)
795                     },
796                     ast::IfExpr(it) => {
797                         let ty = it.condition()
798                             .and_then(|e| self.sema.type_of_expr(&e))
799                             .map(TypeInfo::original);
800                         (ty, None)
801                     },
802                     ast::IdentPat(it) => {
803                         cov_mark::hit!(expected_type_if_let_with_leading_char);
804                         cov_mark::hit!(expected_type_match_arm_with_leading_char);
805                         let ty = self.sema.type_of_pat(&ast::Pat::from(it)).map(TypeInfo::original);
806                         (ty, None)
807                     },
808                     ast::Fn(it) => {
809                         cov_mark::hit!(expected_type_fn_ret_with_leading_char);
810                         cov_mark::hit!(expected_type_fn_ret_without_leading_char);
811                         let def = self.sema.to_def(&it);
812                         (def.map(|def| def.ret_type(self.db)), None)
813                     },
814                     ast::ClosureExpr(it) => {
815                         let ty = self.sema.type_of_expr(&it.into());
816                         ty.and_then(|ty| ty.original.as_callable(self.db))
817                             .map(|c| (Some(c.return_type()), None))
818                             .unwrap_or((None, None))
819                     },
820                     ast::ParamList(_) => (None, None),
821                     ast::Stmt(_) => (None, None),
822                     ast::Item(_) => (None, None),
823                     _ => {
824                         match node.parent() {
825                             Some(n) => {
826                                 node = n;
827                                 continue;
828                             },
829                             None => (None, None),
830                         }
831                     },
832                 }
833             };
834         }
835     }
836
837     /// Fill the completion context, this is what does semantic reasoning about the surrounding context
838     /// of the completion location.
839     fn fill(
840         &mut self,
841         original_file: &SyntaxNode,
842         file_with_fake_ident: SyntaxNode,
843         offset: TextSize,
844         derive_ctx: Option<(SyntaxNode, SyntaxNode, TextSize, ast::Attr)>,
845     ) -> Option<()> {
846         let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased()?;
847         let syntax_element = NodeOrToken::Token(fake_ident_token);
848         if is_in_token_of_for_loop(syntax_element.clone()) {
849             // for pat $0
850             // there is nothing to complete here except `in` keyword
851             // don't bother populating the context
852             // FIXME: the completion calculations should end up good enough
853             // such that this special case becomes unnecessary
854             return None;
855         }
856
857         self.previous_token = previous_token(syntax_element.clone());
858
859         self.incomplete_let =
860             syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| {
861                 it.syntax().text_range().end() == syntax_element.text_range().end()
862             });
863
864         (self.expected_type, self.expected_name) = self.expected_type_and_name();
865
866         // Overwrite the path kind for derives
867         if let Some((original_file, file_with_fake_ident, offset, origin_attr)) = derive_ctx {
868             self.existing_derives = self
869                 .sema
870                 .resolve_derive_macro(&origin_attr)
871                 .into_iter()
872                 .flatten()
873                 .flatten()
874                 .collect();
875
876             if let Some(ast::NameLike::NameRef(name_ref)) =
877                 find_node_at_offset(&file_with_fake_ident, offset)
878             {
879                 let parent = name_ref.syntax().parent()?;
880                 let (mut nameref_ctx, _) =
881                     Self::classify_name_ref(&self.sema, &original_file, name_ref, parent);
882                 if let Some(path_ctx) = &mut nameref_ctx.path_ctx {
883                     path_ctx.kind = PathKind::Derive;
884                 }
885                 self.ident_ctx = IdentContext::NameRef(nameref_ctx);
886                 return Some(());
887             }
888             return None;
889         }
890
891         let name_like = match find_node_at_offset(&file_with_fake_ident, offset) {
892             Some(it) => it,
893             None => {
894                 if let Some(original) = ast::String::cast(self.original_token.clone()) {
895                     self.ident_ctx = IdentContext::String {
896                         original,
897                         expanded: ast::String::cast(self.token.clone()),
898                     };
899                 } else {
900                     // Fix up trailing whitespace problem
901                     // #[attr(foo = $0
902                     let token = if self.token.kind() == SyntaxKind::WHITESPACE {
903                         self.previous_token.as_ref()?
904                     } else {
905                         &self.token
906                     };
907                     let p = token.parent()?;
908                     if p.kind() == SyntaxKind::TOKEN_TREE
909                         && p.ancestors().any(|it| it.kind() == SyntaxKind::META)
910                     {
911                         self.ident_ctx = IdentContext::UnexpandedAttrTT {
912                             fake_attribute_under_caret: syntax_element
913                                 .ancestors()
914                                 .find_map(ast::Attr::cast),
915                         };
916                     } else {
917                         return None;
918                     }
919                 }
920                 return Some(());
921             }
922         };
923         self.completion_location =
924             determine_location(&self.sema, original_file, offset, &name_like);
925         self.prev_sibling = determine_prev_sibling(&name_like);
926         self.impl_def = self
927             .sema
928             .token_ancestors_with_macros(self.token.clone())
929             .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
930             .find_map(ast::Impl::cast);
931         self.function_def = self
932             .sema
933             .token_ancestors_with_macros(self.token.clone())
934             .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
935             .find_map(ast::Fn::cast);
936
937         match name_like {
938             ast::NameLike::Lifetime(lifetime) => {
939                 self.ident_ctx = IdentContext::Lifetime(Self::classify_lifetime(
940                     &self.sema,
941                     original_file,
942                     lifetime,
943                 )?);
944             }
945             ast::NameLike::NameRef(name_ref) => {
946                 let parent = name_ref.syntax().parent()?;
947                 let (nameref_ctx, pat_ctx) =
948                     Self::classify_name_ref(&self.sema, &original_file, name_ref, parent.clone());
949
950                 // Extract qualifiers
951                 if let Some(path_ctx) = &nameref_ctx.path_ctx {
952                     if path_ctx.qualifier.is_none() {
953                         let top = match path_ctx.kind {
954                             PathKind::Expr { in_block_expr: true, .. } => parent
955                                 .ancestors()
956                                 .find(|it| ast::PathExpr::can_cast(it.kind()))
957                                 .and_then(|p| {
958                                     let parent = p.parent()?;
959                                     if ast::StmtList::can_cast(parent.kind()) {
960                                         Some(p)
961                                     } else if ast::ExprStmt::can_cast(parent.kind()) {
962                                         Some(parent)
963                                     } else {
964                                         None
965                                     }
966                                 }),
967                             PathKind::Item { .. } => {
968                                 parent.ancestors().find(|it| ast::MacroCall::can_cast(it.kind()))
969                             }
970                             _ => None,
971                         };
972                         if let Some(top) = top {
973                             if let Some(NodeOrToken::Node(error_node)) =
974                                 syntax::algo::non_trivia_sibling(
975                                     top.into(),
976                                     syntax::Direction::Prev,
977                                 )
978                             {
979                                 if error_node.kind() == SyntaxKind::ERROR {
980                                     self.qualifier_ctx.unsafe_tok = error_node
981                                         .children_with_tokens()
982                                         .filter_map(NodeOrToken::into_token)
983                                         .find(|it| it.kind() == T![unsafe]);
984                                     self.qualifier_ctx.vis_node =
985                                         error_node.children().find_map(ast::Visibility::cast);
986                                 }
987                             }
988                         }
989                     }
990                 }
991                 self.ident_ctx = IdentContext::NameRef(nameref_ctx);
992                 self.pattern_ctx = pat_ctx;
993             }
994             ast::NameLike::Name(name) => {
995                 let (name_ctx, pat_ctx) = Self::classify_name(&self.sema, original_file, name)?;
996                 self.pattern_ctx = pat_ctx;
997                 self.ident_ctx = IdentContext::Name(name_ctx);
998             }
999         }
1000         Some(())
1001     }
1002
1003     fn classify_lifetime(
1004         _sema: &Semantics<RootDatabase>,
1005         original_file: &SyntaxNode,
1006         lifetime: ast::Lifetime,
1007     ) -> Option<LifetimeContext> {
1008         let parent = lifetime.syntax().parent()?;
1009         if parent.kind() == ERROR {
1010             return None;
1011         }
1012
1013         let kind = match_ast! {
1014             match parent {
1015                 ast::LifetimeParam(param) => LifetimeKind::LifetimeParam {
1016                     is_decl: param.lifetime().as_ref() == Some(&lifetime),
1017                     param
1018                 },
1019                 ast::BreakExpr(_) => LifetimeKind::LabelRef,
1020                 ast::ContinueExpr(_) => LifetimeKind::LabelRef,
1021                 ast::Label(_) => LifetimeKind::LabelDef,
1022                 _ => LifetimeKind::Lifetime,
1023             }
1024         };
1025         let lifetime = find_node_at_offset(&original_file, lifetime.syntax().text_range().start());
1026
1027         Some(LifetimeContext { lifetime, kind })
1028     }
1029
1030     fn classify_name(
1031         _sema: &Semantics<RootDatabase>,
1032         original_file: &SyntaxNode,
1033         name: ast::Name,
1034     ) -> Option<(NameContext, Option<PatternContext>)> {
1035         let parent = name.syntax().parent()?;
1036         let mut pat_ctx = None;
1037         let kind = match_ast! {
1038             match parent {
1039                 ast::Const(_) => NameKind::Const,
1040                 ast::ConstParam(_) => NameKind::ConstParam,
1041                 ast::Enum(_) => NameKind::Enum,
1042                 ast::Fn(_) => NameKind::Function,
1043                 ast::IdentPat(bind_pat) => {
1044                     pat_ctx = Some({
1045                         let mut pat_ctx = pattern_context_for(original_file, bind_pat.into());
1046                         if let Some(record_field) = ast::RecordPatField::for_field_name(&name) {
1047                             pat_ctx.record_pat = find_node_in_file_compensated(original_file, &record_field.parent_record_pat());
1048                         }
1049                         pat_ctx
1050                     });
1051
1052                     NameKind::IdentPat
1053                 },
1054                 ast::MacroDef(_) => NameKind::MacroDef,
1055                 ast::MacroRules(_) => NameKind::MacroRules,
1056                 ast::Module(module) => NameKind::Module(module),
1057                 ast::RecordField(_) => NameKind::RecordField,
1058                 ast::Rename(_) => NameKind::Rename,
1059                 ast::SelfParam(_) => NameKind::SelfParam,
1060                 ast::Static(_) => NameKind::Static,
1061                 ast::Struct(_) => NameKind::Struct,
1062                 ast::Trait(_) => NameKind::Trait,
1063                 ast::TypeAlias(_) => NameKind::TypeAlias,
1064                 ast::TypeParam(_) => NameKind::TypeParam,
1065                 ast::Union(_) => NameKind::Union,
1066                 ast::Variant(_) => NameKind::Variant,
1067                 _ => return None,
1068             }
1069         };
1070         let name = find_node_at_offset(&original_file, name.syntax().text_range().start());
1071         Some((NameContext { name, kind }, pat_ctx))
1072     }
1073
1074     fn classify_name_ref(
1075         sema: &Semantics<RootDatabase>,
1076         original_file: &SyntaxNode,
1077         name_ref: ast::NameRef,
1078         parent: SyntaxNode,
1079     ) -> (NameRefContext, Option<PatternContext>) {
1080         let nameref = find_node_at_offset(&original_file, name_ref.syntax().text_range().start());
1081
1082         let mut nameref_ctx = NameRefContext {
1083             dot_access: None,
1084             path_ctx: None,
1085             nameref,
1086             record_expr: None,
1087             keyword: None,
1088         };
1089
1090         if let Some(record_field) = ast::RecordExprField::for_field_name(&name_ref) {
1091             nameref_ctx.record_expr =
1092                 find_node_in_file_compensated(original_file, &record_field.parent_record_lit())
1093                     .zip(Some(false));
1094             return (nameref_ctx, None);
1095         }
1096         if let Some(record_field) = ast::RecordPatField::for_field_name_ref(&name_ref) {
1097             let pat_ctx =
1098                 pattern_context_for(original_file, record_field.parent_record_pat().clone().into());
1099             return (
1100                 nameref_ctx,
1101                 Some(PatternContext {
1102                     param_ctx: None,
1103                     has_type_ascription: false,
1104                     ref_token: None,
1105                     mut_token: None,
1106                     record_pat: find_node_in_file_compensated(
1107                         original_file,
1108                         &record_field.parent_record_pat(),
1109                     ),
1110                     ..pat_ctx
1111                 }),
1112             );
1113         }
1114
1115         let segment = match_ast! {
1116             match parent {
1117                 ast::PathSegment(segment) => segment,
1118                 ast::FieldExpr(field) => {
1119                     let receiver = find_in_original_file(field.expr(), original_file);
1120                     let receiver_is_ambiguous_float_literal = match &receiver {
1121                         Some(ast::Expr::Literal(l)) => matches! {
1122                             l.kind(),
1123                             ast::LiteralKind::FloatNumber { .. } if l.syntax().last_token().map_or(false, |it| it.text().ends_with('.'))
1124                         },
1125                         _ => false,
1126                     };
1127                     nameref_ctx.dot_access = Some(DotAccess {
1128                         receiver_ty: receiver.as_ref().and_then(|it| sema.type_of_expr(it)),
1129                         kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal },
1130                         receiver
1131                     });
1132                     return (nameref_ctx, None);
1133                 },
1134                 ast::MethodCallExpr(method) => {
1135                     let receiver = find_in_original_file(method.receiver(), original_file);
1136                     nameref_ctx.dot_access = Some(DotAccess {
1137                         receiver_ty: receiver.as_ref().and_then(|it| sema.type_of_expr(it)),
1138                         kind: DotAccessKind::Method { has_parens: method.arg_list().map_or(false, |it| it.l_paren_token().is_some()) },
1139                         receiver
1140                     });
1141                     return (nameref_ctx, None);
1142                 },
1143                 _ => return (nameref_ctx, None),
1144             }
1145         };
1146
1147         let path = segment.parent_path();
1148         let mut path_ctx = PathCompletionCtx {
1149             has_call_parens: false,
1150             has_macro_bang: false,
1151             is_absolute_path: false,
1152             qualifier: None,
1153             parent: path.parent_path(),
1154             kind: PathKind::Item { kind: ItemListKind::SourceFile },
1155             has_type_args: false,
1156         };
1157         let mut pat_ctx = None;
1158
1159         let is_in_block = |it: &SyntaxNode| {
1160             it.parent()
1161                 .map(|node| {
1162                     ast::ExprStmt::can_cast(node.kind()) || ast::StmtList::can_cast(node.kind())
1163                 })
1164                 .unwrap_or(false)
1165         };
1166         let mut fill_record_expr = |syn: &SyntaxNode| {
1167             if let Some(record_expr) = syn.ancestors().nth(2).and_then(ast::RecordExpr::cast) {
1168                 nameref_ctx.record_expr =
1169                     find_node_in_file_compensated(original_file, &record_expr).zip(Some(true));
1170             }
1171         };
1172
1173         // We do not want to generate path completions when we are sandwiched between an item decl signature and its body.
1174         // ex. trait Foo $0 {}
1175         // in these cases parser recovery usually kicks in for our inserted identifier, causing it
1176         // to either be parsed as an ExprStmt or a MacroCall, depending on whether it is in a block
1177         // expression or an item list.
1178         // The following code checks if the body is missing, if it is we either cut off the body
1179         // from the item or it was missing in the first place
1180         let inbetween_body_and_decl_check = |node: SyntaxNode| {
1181             if let Some(NodeOrToken::Node(n)) =
1182                 syntax::algo::non_trivia_sibling(node.into(), syntax::Direction::Prev)
1183             {
1184                 if let Some(item) = ast::Item::cast(n) {
1185                     let is_inbetween = match &item {
1186                         ast::Item::Const(it) => it.body().is_none(),
1187                         ast::Item::Enum(it) => it.variant_list().is_none(),
1188                         ast::Item::ExternBlock(it) => it.extern_item_list().is_none(),
1189                         ast::Item::Fn(it) => it.body().is_none(),
1190                         ast::Item::Impl(it) => it.assoc_item_list().is_none(),
1191                         ast::Item::Module(it) => it.item_list().is_none(),
1192                         ast::Item::Static(it) => it.body().is_none(),
1193                         ast::Item::Struct(it) => it.field_list().is_none(),
1194                         ast::Item::Trait(it) => it.assoc_item_list().is_none(),
1195                         ast::Item::TypeAlias(it) => it.ty().is_none(),
1196                         ast::Item::Union(it) => it.record_field_list().is_none(),
1197                         _ => false,
1198                     };
1199                     if is_inbetween {
1200                         return Some(item);
1201                     }
1202                 }
1203             }
1204             None
1205         };
1206
1207         let kind = path.syntax().ancestors().find_map(|it| {
1208             // using Option<Option<PathKind>> as extra controlflow
1209             let kind = match_ast! {
1210                 match it {
1211                     ast::PathType(it) => Some(PathKind::Type {
1212                         in_tuple_struct: it.syntax().parent().map_or(false, |it| ast::TupleField::can_cast(it.kind()))
1213                     }),
1214                     ast::PathExpr(it) => {
1215                         if let Some(p) = it.syntax().parent() {
1216                             if ast::ExprStmt::can_cast(p.kind()) {
1217                                 if let Some(kind) = inbetween_body_and_decl_check(p) {
1218                                     nameref_ctx.keyword = Some(kind);
1219                                     return Some(None);
1220                                 }
1221                             }
1222                         }
1223
1224                         fill_record_expr(it.syntax());
1225
1226                         path_ctx.has_call_parens = it.syntax().parent().map_or(false, |it| ast::CallExpr::can_cast(it.kind()));
1227                         let in_block_expr = is_in_block(it.syntax());
1228                         let in_loop_body = is_in_loop_body(it.syntax());
1229                         Some(PathKind::Expr { in_block_expr, in_loop_body })
1230                     },
1231                     ast::TupleStructPat(it) => {
1232                         path_ctx.has_call_parens = true;
1233                         pat_ctx = Some(pattern_context_for(original_file, it.into()));
1234                         Some(PathKind::Pat)
1235                     },
1236                     ast::RecordPat(it) => {
1237                         path_ctx.has_call_parens = true;
1238                         pat_ctx = Some(pattern_context_for(original_file, it.into()));
1239                         Some(PathKind::Pat)
1240                     },
1241                     ast::PathPat(it) => {
1242                         pat_ctx = Some(pattern_context_for(original_file, it.into()));
1243                         Some(PathKind::Pat)
1244                     },
1245                     ast::MacroCall(it) => {
1246                         if let Some(kind) = inbetween_body_and_decl_check(it.syntax().clone()) {
1247                             nameref_ctx.keyword = Some(kind);
1248                             return Some(None);
1249                         }
1250
1251                         path_ctx.has_macro_bang = it.excl_token().is_some();
1252                         let parent = it.syntax().parent();
1253                         match parent.as_ref().map(|it| it.kind()) {
1254                             Some(SyntaxKind::MACRO_PAT) => Some(PathKind::Pat),
1255                             Some(SyntaxKind::MACRO_TYPE) => Some(PathKind::Type { in_tuple_struct: false }),
1256                             Some(SyntaxKind::ITEM_LIST) => Some(PathKind::Item { kind: ItemListKind::Module }),
1257                             Some(SyntaxKind::ASSOC_ITEM_LIST) => Some(PathKind::Item { kind: match parent.and_then(|it| it.parent()) {
1258                                 Some(it) => match_ast! {
1259                                     match it {
1260                                         ast::Trait(_) => ItemListKind::Trait,
1261                                         ast::Impl(it) => if it.trait_().is_some() {
1262                                             ItemListKind::TraitImpl
1263                                         } else {
1264                                             ItemListKind::Impl
1265                                         },
1266                                         _ => return Some(None)
1267                                     }
1268                                 },
1269                                 None => return Some(None),
1270                             } }),
1271                             Some(SyntaxKind::EXTERN_ITEM_LIST) => Some(PathKind::Item { kind: ItemListKind::ExternBlock }),
1272                             Some(SyntaxKind::SOURCE_FILE) => Some(PathKind::Item { kind: ItemListKind::SourceFile }),
1273                             _ => {
1274                                return Some(parent.and_then(ast::MacroExpr::cast).map(|it| {
1275                                     let in_loop_body = is_in_loop_body(it.syntax());
1276                                     let in_block_expr = is_in_block(it.syntax());
1277                                     fill_record_expr(it.syntax());
1278                                     PathKind::Expr { in_block_expr, in_loop_body }
1279                                 }));
1280                             },
1281                         }
1282                     },
1283                     ast::Meta(meta) => (|| {
1284                         let attr = meta.parent_attr()?;
1285                         let kind = attr.kind();
1286                         let attached = attr.syntax().parent()?;
1287                         let is_trailing_outer_attr = kind != AttrKind::Inner
1288                             && non_trivia_sibling(attr.syntax().clone().into(), syntax::Direction::Next).is_none();
1289                         let annotated_item_kind = if is_trailing_outer_attr {
1290                             None
1291                         } else {
1292                             Some(attached.kind())
1293                         };
1294                         Some(PathKind::Attr {
1295                             kind,
1296                             annotated_item_kind,
1297                         })
1298                     })(),
1299                     ast::Visibility(it) => Some(PathKind::Vis { has_in_token: it.in_token().is_some() }),
1300                     ast::UseTree(_) => Some(PathKind::Use),
1301                     ast::ItemList(_) => Some(PathKind::Item { kind: ItemListKind::Module }),
1302                     ast::AssocItemList(it) => Some(PathKind::Item { kind: {
1303                         match_ast! {
1304                             match (it.syntax().parent()?) {
1305                                 ast::Trait(_) => ItemListKind::Trait,
1306                                 ast::Impl(it) => if it.trait_().is_some() {
1307                                     ItemListKind::TraitImpl
1308                                 } else {
1309                                     ItemListKind::Impl
1310                                 },
1311                                 _ => return None
1312                             }
1313                         }
1314                     }}),
1315                     ast::ExternItemList(_) => Some(PathKind::Item { kind: ItemListKind::ExternBlock }),
1316                     ast::SourceFile(_) => Some(PathKind::Item { kind: ItemListKind::SourceFile }),
1317                     _ => return None,
1318                 }
1319             };
1320             Some(kind)
1321         }).flatten();
1322         match kind {
1323             Some(kind) => path_ctx.kind = kind,
1324             None => return (nameref_ctx, pat_ctx),
1325         }
1326         path_ctx.has_type_args = segment.generic_arg_list().is_some();
1327
1328         if let Some((path, use_tree_parent)) = path_or_use_tree_qualifier(&path) {
1329             if !use_tree_parent {
1330                 path_ctx.is_absolute_path =
1331                     path.top_path().segment().map_or(false, |it| it.coloncolon_token().is_some());
1332             }
1333
1334             let path = path
1335                 .segment()
1336                 .and_then(|it| find_node_in_file(original_file, &it))
1337                 .map(|it| it.parent_path());
1338             path_ctx.qualifier = path.map(|path| {
1339                 let res = sema.resolve_path(&path);
1340                 let is_super_chain = iter::successors(Some(path.clone()), |p| p.qualifier())
1341                     .all(|p| p.segment().and_then(|s| s.super_token()).is_some());
1342
1343                 // `<_>::$0`
1344                 let is_infer_qualifier = path.qualifier().is_none()
1345                     && matches!(
1346                         path.segment().and_then(|it| it.kind()),
1347                         Some(ast::PathSegmentKind::Type {
1348                             type_ref: Some(ast::Type::InferType(_)),
1349                             trait_ref: None,
1350                         })
1351                     );
1352
1353                 PathQualifierCtx {
1354                     path,
1355                     resolution: res,
1356                     is_super_chain,
1357                     use_tree_parent,
1358                     is_infer_qualifier,
1359                 }
1360             });
1361         } else if let Some(segment) = path.segment() {
1362             if segment.coloncolon_token().is_some() {
1363                 path_ctx.is_absolute_path = true;
1364             }
1365         }
1366         nameref_ctx.path_ctx = Some(path_ctx);
1367         (nameref_ctx, pat_ctx)
1368     }
1369 }
1370
1371 fn pattern_context_for(original_file: &SyntaxNode, pat: ast::Pat) -> PatternContext {
1372     let mut is_param = None;
1373     let (refutability, has_type_ascription) =
1374     pat
1375         .syntax()
1376         .ancestors()
1377         .skip_while(|it| ast::Pat::can_cast(it.kind()))
1378         .next()
1379         .map_or((PatternRefutability::Irrefutable, false), |node| {
1380             let refutability = match_ast! {
1381                 match node {
1382                     ast::LetStmt(let_) => return (PatternRefutability::Irrefutable, let_.ty().is_some()),
1383                     ast::Param(param) => {
1384                         let has_type_ascription = param.ty().is_some();
1385                         is_param = (|| {
1386                             let fake_param_list = param.syntax().parent().and_then(ast::ParamList::cast)?;
1387                             let param_list = find_node_in_file_compensated(original_file, &fake_param_list)?;
1388                             let param_list_owner = param_list.syntax().parent()?;
1389                             let kind = match_ast! {
1390                                 match param_list_owner {
1391                                     ast::ClosureExpr(closure) => ParamKind::Closure(closure),
1392                                     ast::Fn(fn_) => ParamKind::Function(fn_),
1393                                     _ => return None,
1394                                 }
1395                             };
1396                             Some((param_list, param, kind))
1397                         })();
1398                         return (PatternRefutability::Irrefutable, has_type_ascription)
1399                     },
1400                     ast::MatchArm(_) => PatternRefutability::Refutable,
1401                     ast::LetExpr(_) => PatternRefutability::Refutable,
1402                     ast::ForExpr(_) => PatternRefutability::Irrefutable,
1403                     _ => PatternRefutability::Irrefutable,
1404                 }
1405             };
1406             (refutability, false)
1407         });
1408     let (ref_token, mut_token) = match &pat {
1409         ast::Pat::IdentPat(it) => (it.ref_token(), it.mut_token()),
1410         _ => (None, None),
1411     };
1412     PatternContext {
1413         refutability,
1414         param_ctx: is_param,
1415         has_type_ascription,
1416         parent_pat: pat.syntax().parent().and_then(ast::Pat::cast),
1417         mut_token,
1418         ref_token,
1419         record_pat: None,
1420     }
1421 }
1422
1423 fn find_in_original_file<N: AstNode>(x: Option<N>, original_file: &SyntaxNode) -> Option<N> {
1424     fn find_node_with_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> {
1425         let range = syntax.text_range().intersect(range)?;
1426         syntax.covering_element(range).ancestors().find_map(N::cast)
1427     }
1428     x.map(|e| e.syntax().text_range()).and_then(|r| find_node_with_range(original_file, r))
1429 }
1430
1431 /// Attempts to find `node` inside `syntax` via `node`'s text range.
1432 fn find_node_in_file<N: AstNode>(syntax: &SyntaxNode, node: &N) -> Option<N> {
1433     let syntax_range = syntax.text_range();
1434     let range = node.syntax().text_range();
1435     let intersection = range.intersect(syntax_range)?;
1436     syntax.covering_element(intersection).ancestors().find_map(N::cast)
1437 }
1438
1439 /// Attempts to find `node` inside `syntax` via `node`'s text range while compensating
1440 /// for the offset introduced by the fake ident.
1441 /// This is wrong if `node` comes before the insertion point! Use `find_node_in_file` instead.
1442 fn find_node_in_file_compensated<N: AstNode>(syntax: &SyntaxNode, node: &N) -> Option<N> {
1443     let syntax_range = syntax.text_range();
1444     let range = node.syntax().text_range();
1445     let end = range.end().checked_sub(TextSize::try_from(COMPLETION_MARKER.len()).ok()?)?;
1446     if end < range.start() {
1447         return None;
1448     }
1449     let range = TextRange::new(range.start(), end);
1450     // our inserted ident could cause `range` to be go outside of the original syntax, so cap it
1451     let intersection = range.intersect(syntax_range)?;
1452     syntax.covering_element(intersection).ancestors().find_map(N::cast)
1453 }
1454
1455 fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
1456     if let Some(qual) = path.qualifier() {
1457         return Some((qual, false));
1458     }
1459     let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
1460     let use_tree = use_tree_list.syntax().parent().and_then(ast::UseTree::cast)?;
1461     Some((use_tree.path()?, true))
1462 }
1463
1464 fn has_ref(token: &SyntaxToken) -> bool {
1465     let mut token = token.clone();
1466     for skip in [IDENT, WHITESPACE, T![mut]] {
1467         if token.kind() == skip {
1468             token = match token.prev_token() {
1469                 Some(it) => it,
1470                 None => return false,
1471             }
1472         }
1473     }
1474     token.kind() == T![&]
1475 }
1476
1477 const OP_TRAIT_LANG_NAMES: &[&str] = &[
1478     "add_assign",
1479     "add",
1480     "bitand_assign",
1481     "bitand",
1482     "bitor_assign",
1483     "bitor",
1484     "bitxor_assign",
1485     "bitxor",
1486     "deref_mut",
1487     "deref",
1488     "div_assign",
1489     "div",
1490     "eq",
1491     "fn_mut",
1492     "fn_once",
1493     "fn",
1494     "index_mut",
1495     "index",
1496     "mul_assign",
1497     "mul",
1498     "neg",
1499     "not",
1500     "partial_ord",
1501     "rem_assign",
1502     "rem",
1503     "shl_assign",
1504     "shl",
1505     "shr_assign",
1506     "shr",
1507     "sub",
1508 ];
1509
1510 #[cfg(test)]
1511 mod tests {
1512     use expect_test::{expect, Expect};
1513     use hir::HirDisplay;
1514
1515     use crate::tests::{position, TEST_CONFIG};
1516
1517     use super::CompletionContext;
1518
1519     fn check_expected_type_and_name(ra_fixture: &str, expect: Expect) {
1520         let (db, pos) = position(ra_fixture);
1521         let config = TEST_CONFIG;
1522         let completion_context = CompletionContext::new(&db, pos, &config).unwrap();
1523
1524         let ty = completion_context
1525             .expected_type
1526             .map(|t| t.display_test(&db).to_string())
1527             .unwrap_or("?".to_owned());
1528
1529         let name = completion_context
1530             .expected_name
1531             .map_or_else(|| "?".to_owned(), |name| name.to_string());
1532
1533         expect.assert_eq(&format!("ty: {}, name: {}", ty, name));
1534     }
1535
1536     #[test]
1537     fn expected_type_let_without_leading_char() {
1538         cov_mark::check!(expected_type_let_without_leading_char);
1539         check_expected_type_and_name(
1540             r#"
1541 fn foo() {
1542     let x: u32 = $0;
1543 }
1544 "#,
1545             expect![[r#"ty: u32, name: x"#]],
1546         );
1547     }
1548
1549     #[test]
1550     fn expected_type_let_with_leading_char() {
1551         cov_mark::check!(expected_type_let_with_leading_char);
1552         check_expected_type_and_name(
1553             r#"
1554 fn foo() {
1555     let x: u32 = c$0;
1556 }
1557 "#,
1558             expect![[r#"ty: u32, name: x"#]],
1559         );
1560     }
1561
1562     #[test]
1563     fn expected_type_let_pat() {
1564         check_expected_type_and_name(
1565             r#"
1566 fn foo() {
1567     let x$0 = 0u32;
1568 }
1569 "#,
1570             expect![[r#"ty: u32, name: ?"#]],
1571         );
1572         check_expected_type_and_name(
1573             r#"
1574 fn foo() {
1575     let $0 = 0u32;
1576 }
1577 "#,
1578             expect![[r#"ty: u32, name: ?"#]],
1579         );
1580     }
1581
1582     #[test]
1583     fn expected_type_fn_param() {
1584         cov_mark::check!(expected_type_fn_param);
1585         check_expected_type_and_name(
1586             r#"
1587 fn foo() { bar($0); }
1588 fn bar(x: u32) {}
1589 "#,
1590             expect![[r#"ty: u32, name: x"#]],
1591         );
1592         check_expected_type_and_name(
1593             r#"
1594 fn foo() { bar(c$0); }
1595 fn bar(x: u32) {}
1596 "#,
1597             expect![[r#"ty: u32, name: x"#]],
1598         );
1599     }
1600
1601     #[test]
1602     fn expected_type_fn_param_ref() {
1603         cov_mark::check!(expected_type_fn_param_ref);
1604         check_expected_type_and_name(
1605             r#"
1606 fn foo() { bar(&$0); }
1607 fn bar(x: &u32) {}
1608 "#,
1609             expect![[r#"ty: u32, name: x"#]],
1610         );
1611         check_expected_type_and_name(
1612             r#"
1613 fn foo() { bar(&mut $0); }
1614 fn bar(x: &mut u32) {}
1615 "#,
1616             expect![[r#"ty: u32, name: x"#]],
1617         );
1618         check_expected_type_and_name(
1619             r#"
1620 fn foo() { bar(& c$0); }
1621 fn bar(x: &u32) {}
1622         "#,
1623             expect![[r#"ty: u32, name: x"#]],
1624         );
1625         check_expected_type_and_name(
1626             r#"
1627 fn foo() { bar(&mut c$0); }
1628 fn bar(x: &mut u32) {}
1629 "#,
1630             expect![[r#"ty: u32, name: x"#]],
1631         );
1632         check_expected_type_and_name(
1633             r#"
1634 fn foo() { bar(&c$0); }
1635 fn bar(x: &u32) {}
1636         "#,
1637             expect![[r#"ty: u32, name: x"#]],
1638         );
1639     }
1640
1641     #[test]
1642     fn expected_type_struct_field_without_leading_char() {
1643         cov_mark::check!(expected_type_struct_field_without_leading_char);
1644         check_expected_type_and_name(
1645             r#"
1646 struct Foo { a: u32 }
1647 fn foo() {
1648     Foo { a: $0 };
1649 }
1650 "#,
1651             expect![[r#"ty: u32, name: a"#]],
1652         )
1653     }
1654
1655     #[test]
1656     fn expected_type_struct_field_followed_by_comma() {
1657         cov_mark::check!(expected_type_struct_field_followed_by_comma);
1658         check_expected_type_and_name(
1659             r#"
1660 struct Foo { a: u32 }
1661 fn foo() {
1662     Foo { a: $0, };
1663 }
1664 "#,
1665             expect![[r#"ty: u32, name: a"#]],
1666         )
1667     }
1668
1669     #[test]
1670     fn expected_type_generic_struct_field() {
1671         check_expected_type_and_name(
1672             r#"
1673 struct Foo<T> { a: T }
1674 fn foo() -> Foo<u32> {
1675     Foo { a: $0 }
1676 }
1677 "#,
1678             expect![[r#"ty: u32, name: a"#]],
1679         )
1680     }
1681
1682     #[test]
1683     fn expected_type_struct_field_with_leading_char() {
1684         cov_mark::check!(expected_type_struct_field_with_leading_char);
1685         check_expected_type_and_name(
1686             r#"
1687 struct Foo { a: u32 }
1688 fn foo() {
1689     Foo { a: c$0 };
1690 }
1691 "#,
1692             expect![[r#"ty: u32, name: a"#]],
1693         );
1694     }
1695
1696     #[test]
1697     fn expected_type_match_arm_without_leading_char() {
1698         cov_mark::check!(expected_type_match_arm_without_leading_char);
1699         check_expected_type_and_name(
1700             r#"
1701 enum E { X }
1702 fn foo() {
1703    match E::X { $0 }
1704 }
1705 "#,
1706             expect![[r#"ty: E, name: ?"#]],
1707         );
1708     }
1709
1710     #[test]
1711     fn expected_type_match_arm_with_leading_char() {
1712         cov_mark::check!(expected_type_match_arm_with_leading_char);
1713         check_expected_type_and_name(
1714             r#"
1715 enum E { X }
1716 fn foo() {
1717    match E::X { c$0 }
1718 }
1719 "#,
1720             expect![[r#"ty: E, name: ?"#]],
1721         );
1722     }
1723
1724     #[test]
1725     fn expected_type_match_arm_body_without_leading_char() {
1726         cov_mark::check!(expected_type_match_arm_body_without_leading_char);
1727         check_expected_type_and_name(
1728             r#"
1729 struct Foo;
1730 enum E { X }
1731 fn foo() -> Foo {
1732    match E::X { E::X => $0 }
1733 }
1734 "#,
1735             expect![[r#"ty: Foo, name: ?"#]],
1736         );
1737     }
1738
1739     #[test]
1740     fn expected_type_match_body_arm_with_leading_char() {
1741         cov_mark::check!(expected_type_match_arm_body_with_leading_char);
1742         check_expected_type_and_name(
1743             r#"
1744 struct Foo;
1745 enum E { X }
1746 fn foo() -> Foo {
1747    match E::X { E::X => c$0 }
1748 }
1749 "#,
1750             expect![[r#"ty: Foo, name: ?"#]],
1751         );
1752     }
1753
1754     #[test]
1755     fn expected_type_if_let_without_leading_char() {
1756         cov_mark::check!(expected_type_if_let_without_leading_char);
1757         check_expected_type_and_name(
1758             r#"
1759 enum Foo { Bar, Baz, Quux }
1760
1761 fn foo() {
1762     let f = Foo::Quux;
1763     if let $0 = f { }
1764 }
1765 "#,
1766             expect![[r#"ty: Foo, name: ?"#]],
1767         )
1768     }
1769
1770     #[test]
1771     fn expected_type_if_let_with_leading_char() {
1772         cov_mark::check!(expected_type_if_let_with_leading_char);
1773         check_expected_type_and_name(
1774             r#"
1775 enum Foo { Bar, Baz, Quux }
1776
1777 fn foo() {
1778     let f = Foo::Quux;
1779     if let c$0 = f { }
1780 }
1781 "#,
1782             expect![[r#"ty: Foo, name: ?"#]],
1783         )
1784     }
1785
1786     #[test]
1787     fn expected_type_fn_ret_without_leading_char() {
1788         cov_mark::check!(expected_type_fn_ret_without_leading_char);
1789         check_expected_type_and_name(
1790             r#"
1791 fn foo() -> u32 {
1792     $0
1793 }
1794 "#,
1795             expect![[r#"ty: u32, name: ?"#]],
1796         )
1797     }
1798
1799     #[test]
1800     fn expected_type_fn_ret_with_leading_char() {
1801         cov_mark::check!(expected_type_fn_ret_with_leading_char);
1802         check_expected_type_and_name(
1803             r#"
1804 fn foo() -> u32 {
1805     c$0
1806 }
1807 "#,
1808             expect![[r#"ty: u32, name: ?"#]],
1809         )
1810     }
1811
1812     #[test]
1813     fn expected_type_fn_ret_fn_ref_fully_typed() {
1814         check_expected_type_and_name(
1815             r#"
1816 fn foo() -> u32 {
1817     foo$0
1818 }
1819 "#,
1820             expect![[r#"ty: u32, name: ?"#]],
1821         )
1822     }
1823
1824     #[test]
1825     fn expected_type_closure_param_return() {
1826         // FIXME: make this work with `|| $0`
1827         check_expected_type_and_name(
1828             r#"
1829 //- minicore: fn
1830 fn foo() {
1831     bar(|| a$0);
1832 }
1833
1834 fn bar(f: impl FnOnce() -> u32) {}
1835 "#,
1836             expect![[r#"ty: u32, name: ?"#]],
1837         );
1838     }
1839
1840     #[test]
1841     fn expected_type_generic_function() {
1842         check_expected_type_and_name(
1843             r#"
1844 fn foo() {
1845     bar::<u32>($0);
1846 }
1847
1848 fn bar<T>(t: T) {}
1849 "#,
1850             expect![[r#"ty: u32, name: t"#]],
1851         );
1852     }
1853
1854     #[test]
1855     fn expected_type_generic_method() {
1856         check_expected_type_and_name(
1857             r#"
1858 fn foo() {
1859     S(1u32).bar($0);
1860 }
1861
1862 struct S<T>(T);
1863 impl<T> S<T> {
1864     fn bar(self, t: T) {}
1865 }
1866 "#,
1867             expect![[r#"ty: u32, name: t"#]],
1868         );
1869     }
1870
1871     #[test]
1872     fn expected_type_functional_update() {
1873         cov_mark::check!(expected_type_struct_func_update);
1874         check_expected_type_and_name(
1875             r#"
1876 struct Foo { field: u32 }
1877 fn foo() {
1878     Foo {
1879         ..$0
1880     }
1881 }
1882 "#,
1883             expect![[r#"ty: Foo, name: ?"#]],
1884         );
1885     }
1886
1887     #[test]
1888     fn expected_type_param_pat() {
1889         check_expected_type_and_name(
1890             r#"
1891 struct Foo { field: u32 }
1892 fn foo(a$0: Foo) {}
1893 "#,
1894             expect![[r#"ty: Foo, name: ?"#]],
1895         );
1896         check_expected_type_and_name(
1897             r#"
1898 struct Foo { field: u32 }
1899 fn foo($0: Foo) {}
1900 "#,
1901             // FIXME make this work, currently fails due to pattern recovery eating the `:`
1902             expect![[r#"ty: ?, name: ?"#]],
1903         );
1904     }
1905 }