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