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