]> git.lizzy.rs Git - rust.git/blob - crates/ide_completion/src/context.rs
Merge #11204
[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::{Local, Name, ScopeDef, Semantics, SemanticsScope, Type, TypeInfo};
7 use ide_db::{
8     active_parameter::ActiveParameter,
9     base_db::{FilePosition, SourceDatabase},
10     helpers::FamousDefs,
11     RootDatabase,
12 };
13 use syntax::{
14     algo::find_node_at_offset,
15     ast::{self, HasName, NameOrNameRef},
16     match_ast, AstNode, NodeOrToken,
17     SyntaxKind::{self, *},
18     SyntaxNode, SyntaxToken, TextRange, TextSize, T,
19 };
20 use text_edit::Indel;
21
22 use crate::{
23     patterns::{
24         determine_location, determine_prev_sibling, for_is_prev2, inside_impl_trait_block,
25         is_in_loop_body, previous_token, ImmediateLocation, ImmediatePrevSibling,
26     },
27     CompletionConfig,
28 };
29
30 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
31 pub(crate) enum PatternRefutability {
32     Refutable,
33     Irrefutable,
34 }
35
36 #[derive(Copy, Clone, Debug)]
37 pub(super) enum PathKind {
38     Expr,
39     Type,
40     Attr,
41     Mac,
42     Pat,
43     Vis { has_in_token: bool },
44     Use,
45 }
46
47 #[derive(Debug)]
48 pub(crate) struct PathCompletionContext {
49     /// If this is a call with () already there
50     has_call_parens: bool,
51     /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
52     pub(super) is_trivial_path: bool,
53     /// If not a trivial path, the prefix (qualifier).
54     pub(super) qualifier: Option<ast::Path>,
55     #[allow(dead_code)]
56     /// If not a trivial path, the suffix (parent).
57     pub(super) parent: Option<ast::Path>,
58     /// Whether the qualifier comes from a use tree parent or not
59     pub(super) use_tree_parent: bool,
60     pub(super) kind: Option<PathKind>,
61     /// Whether the path segment has type args or not.
62     pub(super) has_type_args: bool,
63     /// `true` if we are a statement or a last expr in the block.
64     pub(super) can_be_stmt: bool,
65     pub(super) in_loop_body: bool,
66 }
67
68 #[derive(Debug)]
69 pub(super) struct PatternContext {
70     pub(super) refutability: PatternRefutability,
71     pub(super) is_param: Option<ParamKind>,
72     pub(super) has_type_ascription: bool,
73 }
74
75 #[derive(Debug)]
76 pub(super) enum LifetimeContext {
77     LifetimeParam(Option<ast::LifetimeParam>),
78     Lifetime,
79     LabelRef,
80     LabelDef,
81 }
82
83 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
84 pub(crate) enum ParamKind {
85     Function,
86     Closure,
87 }
88 /// `CompletionContext` is created early during completion to figure out, where
89 /// exactly is the cursor, syntax-wise.
90 #[derive(Debug)]
91 pub(crate) struct CompletionContext<'a> {
92     pub(super) sema: Semantics<'a, RootDatabase>,
93     pub(super) scope: SemanticsScope<'a>,
94     pub(super) db: &'a RootDatabase,
95     pub(super) config: &'a CompletionConfig,
96     pub(super) position: FilePosition,
97     /// The token before the cursor, in the original file.
98     pub(super) original_token: SyntaxToken,
99     /// The token before the cursor, in the macro-expanded file.
100     pub(super) token: SyntaxToken,
101     /// The crate of the current file.
102     pub(super) krate: Option<hir::Crate>,
103     pub(super) expected_name: Option<NameOrNameRef>,
104     pub(super) expected_type: Option<Type>,
105
106     /// The parent function of the cursor position if it exists.
107     pub(super) function_def: Option<ast::Fn>,
108     pub(super) attr: Option<ast::Attr>,
109     /// The parent impl of the cursor position if it exists.
110     pub(super) impl_def: Option<ast::Impl>,
111     /// The NameLike under the cursor in the original file if it exists.
112     pub(super) name_syntax: Option<ast::NameLike>,
113     pub(super) incomplete_let: bool,
114
115     pub(super) completion_location: Option<ImmediateLocation>,
116     pub(super) prev_sibling: Option<ImmediatePrevSibling>,
117     pub(super) fake_attribute_under_caret: Option<ast::Attr>,
118     pub(super) previous_token: Option<SyntaxToken>,
119
120     pub(super) lifetime_ctx: Option<LifetimeContext>,
121     pub(super) pattern_ctx: Option<PatternContext>,
122     pub(super) path_context: Option<PathCompletionContext>,
123     pub(super) locals: Vec<(Name, Local)>,
124
125     no_completion_required: bool,
126 }
127
128 impl<'a> CompletionContext<'a> {
129     /// Checks whether completions in that particular case don't make much sense.
130     /// Examples:
131     /// - `fn $0` -- we expect function name, it's unlikely that "hint" will be helpful.
132     ///   Exception for this case is `impl Trait for Foo`, where we would like to hint trait method names.
133     /// - `for _ i$0` -- obviously, it'll be "in" keyword.
134     pub(crate) fn no_completion_required(&self) -> bool {
135         self.no_completion_required
136     }
137
138     /// The range of the identifier that is being completed.
139     pub(crate) fn source_range(&self) -> TextRange {
140         // check kind of macro-expanded token, but use range of original token
141         let kind = self.token.kind();
142         if kind == IDENT || kind == LIFETIME_IDENT || kind == UNDERSCORE || kind.is_keyword() {
143             self.original_token.text_range()
144         } else if kind == CHAR {
145             // assume we are completing a lifetime but the user has only typed the '
146             cov_mark::hit!(completes_if_lifetime_without_idents);
147             TextRange::at(self.original_token.text_range().start(), TextSize::from(1))
148         } else {
149             TextRange::empty(self.position.offset)
150         }
151     }
152
153     pub(crate) fn previous_token_is(&self, kind: SyntaxKind) -> bool {
154         self.previous_token.as_ref().map_or(false, |tok| tok.kind() == kind)
155     }
156
157     pub(crate) fn famous_defs(&self) -> FamousDefs {
158         FamousDefs(&self.sema, self.krate)
159     }
160
161     pub(crate) fn dot_receiver(&self) -> Option<&ast::Expr> {
162         match &self.completion_location {
163             Some(
164                 ImmediateLocation::MethodCall { receiver, .. }
165                 | ImmediateLocation::FieldAccess { receiver, .. },
166             ) => receiver.as_ref(),
167             _ => None,
168         }
169     }
170
171     pub(crate) fn has_dot_receiver(&self) -> bool {
172         matches!(
173             &self.completion_location,
174             Some(ImmediateLocation::FieldAccess { receiver, .. } | ImmediateLocation::MethodCall { receiver,.. })
175                 if receiver.is_some()
176         )
177     }
178
179     pub(crate) fn expects_assoc_item(&self) -> bool {
180         matches!(self.completion_location, Some(ImmediateLocation::Trait | ImmediateLocation::Impl))
181     }
182
183     pub(crate) fn expects_variant(&self) -> bool {
184         matches!(self.completion_location, Some(ImmediateLocation::Variant))
185     }
186
187     pub(crate) fn expects_non_trait_assoc_item(&self) -> bool {
188         matches!(self.completion_location, Some(ImmediateLocation::Impl))
189     }
190
191     pub(crate) fn expects_item(&self) -> bool {
192         matches!(self.completion_location, Some(ImmediateLocation::ItemList))
193     }
194
195     pub(crate) fn expects_generic_arg(&self) -> bool {
196         matches!(self.completion_location, Some(ImmediateLocation::GenericArgList(_)))
197     }
198
199     pub(crate) fn has_block_expr_parent(&self) -> bool {
200         matches!(self.completion_location, Some(ImmediateLocation::StmtList))
201     }
202
203     pub(crate) fn expects_ident_pat_or_ref_expr(&self) -> bool {
204         matches!(
205             self.completion_location,
206             Some(ImmediateLocation::IdentPat | ImmediateLocation::RefExpr)
207         )
208     }
209
210     pub(crate) fn expect_field(&self) -> bool {
211         matches!(
212             self.completion_location,
213             Some(ImmediateLocation::RecordField | ImmediateLocation::TupleField)
214         )
215     }
216
217     pub(crate) fn has_impl_or_trait_prev_sibling(&self) -> bool {
218         matches!(
219             self.prev_sibling,
220             Some(ImmediatePrevSibling::ImplDefType | ImmediatePrevSibling::TraitDefName)
221         )
222     }
223
224     pub(crate) fn has_impl_prev_sibling(&self) -> bool {
225         matches!(self.prev_sibling, Some(ImmediatePrevSibling::ImplDefType))
226     }
227
228     pub(crate) fn has_visibility_prev_sibling(&self) -> bool {
229         matches!(self.prev_sibling, Some(ImmediatePrevSibling::Visibility))
230     }
231
232     pub(crate) fn after_if(&self) -> bool {
233         matches!(self.prev_sibling, Some(ImmediatePrevSibling::IfExpr))
234     }
235
236     pub(crate) fn is_path_disallowed(&self) -> bool {
237         self.previous_token_is(T![unsafe])
238             || matches!(
239                 self.prev_sibling,
240                 Some(ImmediatePrevSibling::Attribute | ImmediatePrevSibling::Visibility)
241             )
242             || matches!(
243                 self.completion_location,
244                 Some(
245                     ImmediateLocation::ModDeclaration(_)
246                         | ImmediateLocation::RecordPat(_)
247                         | ImmediateLocation::RecordExpr(_)
248                         | ImmediateLocation::Rename
249                 )
250             )
251     }
252
253     pub(crate) fn expects_expression(&self) -> bool {
254         matches!(self.path_context, Some(PathCompletionContext { kind: Some(PathKind::Expr), .. }))
255     }
256
257     pub(crate) fn expects_type(&self) -> bool {
258         matches!(self.path_context, Some(PathCompletionContext { kind: Some(PathKind::Type), .. }))
259     }
260
261     pub(crate) fn path_is_call(&self) -> bool {
262         self.path_context.as_ref().map_or(false, |it| it.has_call_parens)
263     }
264
265     pub(crate) fn is_trivial_path(&self) -> bool {
266         matches!(self.path_context, Some(PathCompletionContext { is_trivial_path: true, .. }))
267     }
268
269     pub(crate) fn is_non_trivial_path(&self) -> bool {
270         matches!(self.path_context, Some(PathCompletionContext { is_trivial_path: false, .. }))
271     }
272
273     pub(crate) fn path_qual(&self) -> Option<&ast::Path> {
274         self.path_context.as_ref().and_then(|it| it.qualifier.as_ref())
275     }
276
277     pub(crate) fn path_kind(&self) -> Option<PathKind> {
278         self.path_context.as_ref().and_then(|it| it.kind)
279     }
280
281     /// Checks if an item is visible and not `doc(hidden)` at the completion site.
282     pub(crate) fn is_visible<I>(&self, item: &I) -> bool
283     where
284         I: hir::HasVisibility + hir::HasAttrs + hir::HasCrate + Copy,
285     {
286         self.is_visible_impl(&item.visibility(self.db), &item.attrs(self.db), item.krate(self.db))
287     }
288
289     pub(crate) fn is_scope_def_hidden(&self, scope_def: ScopeDef) -> bool {
290         if let (Some(attrs), Some(krate)) = (scope_def.attrs(self.db), scope_def.krate(self.db)) {
291             return self.is_doc_hidden(&attrs, krate);
292         }
293
294         false
295     }
296
297     /// Check if an item is `#[doc(hidden)]`.
298     pub(crate) fn is_item_hidden(&self, item: &hir::ItemInNs) -> bool {
299         let attrs = item.attrs(self.db);
300         let krate = item.krate(self.db);
301         match (attrs, krate) {
302             (Some(attrs), Some(krate)) => self.is_doc_hidden(&attrs, krate),
303             _ => false,
304         }
305     }
306
307     pub(crate) fn is_immediately_after_macro_bang(&self) -> bool {
308         self.token.kind() == BANG && self.token.parent().map_or(false, |it| it.kind() == MACRO_CALL)
309     }
310
311     /// A version of [`SemanticsScope::process_all_names`] that filters out `#[doc(hidden)]` items.
312     pub(crate) fn process_all_names(&self, f: &mut dyn FnMut(Name, ScopeDef)) {
313         let _p = profile::span("CompletionContext::process_all_names");
314         self.scope.process_all_names(&mut |name, def| {
315             if self.is_scope_def_hidden(def) {
316                 return;
317             }
318
319             f(name, def);
320         })
321     }
322
323     fn is_visible_impl(
324         &self,
325         vis: &hir::Visibility,
326         attrs: &hir::Attrs,
327         defining_crate: hir::Crate,
328     ) -> bool {
329         let module = match self.scope.module() {
330             Some(it) => it,
331             None => return false,
332         };
333         if !vis.is_visible_from(self.db, module.into()) {
334             // If the definition location is editable, also show private items
335             let root_file = defining_crate.root_file(self.db);
336             let source_root_id = self.db.file_source_root(root_file);
337             let is_editable = !self.db.source_root(source_root_id).is_library;
338             return is_editable;
339         }
340
341         !self.is_doc_hidden(attrs, defining_crate)
342     }
343
344     fn is_doc_hidden(&self, attrs: &hir::Attrs, defining_crate: hir::Crate) -> bool {
345         let krate = match self.krate {
346             Some(it) => it,
347             None => return true,
348         };
349         if krate != defining_crate && attrs.has_doc_hidden() {
350             // `doc(hidden)` items are only completed within the defining crate.
351             return true;
352         }
353
354         false
355     }
356 }
357
358 // CompletionContext construction
359 impl<'a> CompletionContext<'a> {
360     pub(super) fn new(
361         db: &'a RootDatabase,
362         position @ FilePosition { file_id, offset }: FilePosition,
363         config: &'a CompletionConfig,
364     ) -> Option<CompletionContext<'a>> {
365         let _p = profile::span("CompletionContext::new");
366         let sema = Semantics::new(db);
367
368         let original_file = sema.parse(file_id);
369
370         // Insert a fake ident to get a valid parse tree. We will use this file
371         // to determine context, though the original_file will be used for
372         // actual completion.
373         let file_with_fake_ident = {
374             let parse = db.parse(file_id);
375             let edit = Indel::insert(offset, "intellijRulezz".to_string());
376             parse.reparse(&edit).tree()
377         };
378         let fake_ident_token =
379             file_with_fake_ident.syntax().token_at_offset(offset).right_biased()?;
380
381         let original_token = original_file.syntax().token_at_offset(offset).left_biased()?;
382         let token = sema.descend_into_macros_single(original_token.clone());
383         let scope = sema.scope_at_offset(&token, offset);
384         let krate = scope.krate();
385         let mut locals = vec![];
386         scope.process_all_names(&mut |name, scope| {
387             if let ScopeDef::Local(local) = scope {
388                 locals.push((name, local));
389             }
390         });
391         let mut ctx = CompletionContext {
392             sema,
393             scope,
394             db,
395             config,
396             position,
397             original_token,
398             token,
399             krate,
400             expected_name: None,
401             expected_type: None,
402             function_def: None,
403             attr: None,
404             impl_def: None,
405             name_syntax: None,
406             lifetime_ctx: None,
407             pattern_ctx: None,
408             completion_location: None,
409             prev_sibling: None,
410             fake_attribute_under_caret: None,
411             previous_token: None,
412             path_context: None,
413             locals,
414             incomplete_let: false,
415             no_completion_required: false,
416         };
417         ctx.expand_and_fill(
418             original_file.syntax().clone(),
419             file_with_fake_ident.syntax().clone(),
420             offset,
421             fake_ident_token,
422         );
423         Some(ctx)
424     }
425
426     /// Do the attribute expansion at the current cursor position for both original file and fake file
427     /// as long as possible. As soon as one of the two expansions fail we stop to stay in sync.
428     fn expand_and_fill(
429         &mut self,
430         mut original_file: SyntaxNode,
431         mut speculative_file: SyntaxNode,
432         mut offset: TextSize,
433         mut fake_ident_token: SyntaxToken,
434     ) {
435         let _p = profile::span("CompletionContext::expand_and_fill");
436         'expansion: loop {
437             let parent_item =
438                 |item: &ast::Item| item.syntax().ancestors().skip(1).find_map(ast::Item::cast);
439             let ancestor_items = iter::successors(
440                 Option::zip(
441                     find_node_at_offset::<ast::Item>(&original_file, offset),
442                     find_node_at_offset::<ast::Item>(&speculative_file, offset),
443                 ),
444                 |(a, b)| parent_item(a).zip(parent_item(b)),
445             );
446             for (actual_item, item_with_fake_ident) in ancestor_items {
447                 match (
448                     self.sema.expand_attr_macro(&actual_item),
449                     self.sema.speculative_expand_attr_macro(
450                         &actual_item,
451                         &item_with_fake_ident,
452                         fake_ident_token.clone(),
453                     ),
454                 ) {
455                     // maybe parent items have attributes
456                     (None, None) => (),
457                     // successful expansions
458                     (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => {
459                         let new_offset = fake_mapped_token.text_range().start();
460                         if new_offset > actual_expansion.text_range().end() {
461                             break 'expansion;
462                         }
463                         original_file = actual_expansion;
464                         speculative_file = fake_expansion;
465                         fake_ident_token = fake_mapped_token;
466                         offset = new_offset;
467                         continue 'expansion;
468                     }
469                     // exactly one expansion failed, inconsistent state so stop expanding completely
470                     _ => break 'expansion,
471                 }
472             }
473
474             // Expand fn-like macro calls
475             if let (Some(actual_macro_call), Some(macro_call_with_fake_ident)) = (
476                 find_node_at_offset::<ast::MacroCall>(&original_file, offset),
477                 find_node_at_offset::<ast::MacroCall>(&speculative_file, offset),
478             ) {
479                 let mac_call_path0 = actual_macro_call.path().as_ref().map(|s| s.syntax().text());
480                 let mac_call_path1 =
481                     macro_call_with_fake_ident.path().as_ref().map(|s| s.syntax().text());
482                 if mac_call_path0 != mac_call_path1 {
483                     break;
484                 }
485                 let speculative_args = match macro_call_with_fake_ident.token_tree() {
486                     Some(tt) => tt,
487                     None => break,
488                 };
489
490                 match (
491                     self.sema.expand(&actual_macro_call),
492                     self.sema.speculative_expand(
493                         &actual_macro_call,
494                         &speculative_args,
495                         fake_ident_token.clone(),
496                     ),
497                 ) {
498                     // successful expansions
499                     (Some(actual_expansion), Some((fake_expansion, fake_mapped_token))) => {
500                         let new_offset = fake_mapped_token.text_range().start();
501                         if new_offset > actual_expansion.text_range().end() {
502                             break;
503                         }
504                         original_file = actual_expansion;
505                         speculative_file = fake_expansion;
506                         fake_ident_token = fake_mapped_token;
507                         offset = new_offset;
508                         continue;
509                     }
510                     _ => break,
511                 }
512             }
513
514             break;
515         }
516
517         self.fill(&original_file, speculative_file, offset);
518     }
519
520     fn expected_type_and_name(&self) -> (Option<Type>, Option<NameOrNameRef>) {
521         let mut node = match self.token.parent() {
522             Some(it) => it,
523             None => return (None, None),
524         };
525         loop {
526             break match_ast! {
527                 match node {
528                     ast::LetStmt(it) => {
529                         cov_mark::hit!(expected_type_let_with_leading_char);
530                         cov_mark::hit!(expected_type_let_without_leading_char);
531                         let ty = it.pat()
532                             .and_then(|pat| self.sema.type_of_pat(&pat))
533                             .or_else(|| it.initializer().and_then(|it| self.sema.type_of_expr(&it)))
534                             .map(TypeInfo::original);
535                         let name = match it.pat() {
536                             Some(ast::Pat::IdentPat(ident)) => ident.name().map(NameOrNameRef::Name),
537                             Some(_) | None => None,
538                         };
539
540                         (ty, name)
541                     },
542                     ast::ArgList(_) => {
543                         cov_mark::hit!(expected_type_fn_param);
544                         ActiveParameter::at_token(
545                             &self.sema,
546                             self.token.clone(),
547                         ).map(|ap| {
548                             let name = ap.ident().map(NameOrNameRef::Name);
549                             let ty = if has_ref(&self.token) {
550                                 cov_mark::hit!(expected_type_fn_param_ref);
551                                 ap.ty.remove_ref()
552                             } else {
553                                 Some(ap.ty)
554                             };
555                             (ty, name)
556                         })
557                         .unwrap_or((None, None))
558                     },
559                     ast::RecordExprFieldList(it) => {
560                         // wouldn't try {} be nice...
561                         (|| {
562                             if self.token.kind() == T![..]
563                                 || self.token.prev_token().map(|t| t.kind()) == Some(T![..])
564                             {
565                                 cov_mark::hit!(expected_type_struct_func_update);
566                                 let record_expr = it.syntax().parent().and_then(ast::RecordExpr::cast)?;
567                                 let ty = self.sema.type_of_expr(&record_expr.into())?;
568                                 Some((
569                                     Some(ty.original),
570                                     None
571                                 ))
572                             } else {
573                                 cov_mark::hit!(expected_type_struct_field_without_leading_char);
574                                 let expr_field = self.token.prev_sibling_or_token()?
575                                     .into_node()
576                                     .and_then(ast::RecordExprField::cast)?;
577                                 let (_, _, ty) = self.sema.resolve_record_field(&expr_field)?;
578                                 Some((
579                                     Some(ty),
580                                     expr_field.field_name().map(NameOrNameRef::NameRef),
581                                 ))
582                             }
583                         })().unwrap_or((None, None))
584                     },
585                     ast::RecordExprField(it) => {
586                         if let Some(expr) = it.expr() {
587                             cov_mark::hit!(expected_type_struct_field_with_leading_char);
588                             (
589                                 self.sema.type_of_expr(&expr).map(TypeInfo::original),
590                                 it.field_name().map(NameOrNameRef::NameRef),
591                             )
592                         } else {
593                             cov_mark::hit!(expected_type_struct_field_followed_by_comma);
594                             let ty = self.sema.resolve_record_field(&it)
595                                 .map(|(_, _, ty)| ty);
596                             (
597                                 ty,
598                                 it.field_name().map(NameOrNameRef::NameRef),
599                             )
600                         }
601                     },
602                     ast::MatchExpr(it) => {
603                         cov_mark::hit!(expected_type_match_arm_without_leading_char);
604                         let ty = it.expr().and_then(|e| self.sema.type_of_expr(&e)).map(TypeInfo::original);
605                         (ty, None)
606                     },
607                     ast::IfExpr(it) => {
608                         cov_mark::hit!(expected_type_if_let_without_leading_char);
609                         let ty = it.condition()
610                             .and_then(|cond| cond.expr())
611                             .and_then(|e| self.sema.type_of_expr(&e))
612                             .map(TypeInfo::original);
613                         (ty, None)
614                     },
615                     ast::IdentPat(it) => {
616                         cov_mark::hit!(expected_type_if_let_with_leading_char);
617                         cov_mark::hit!(expected_type_match_arm_with_leading_char);
618                         let ty = self.sema.type_of_pat(&ast::Pat::from(it)).map(TypeInfo::original);
619                         (ty, None)
620                     },
621                     ast::Fn(it) => {
622                         cov_mark::hit!(expected_type_fn_ret_with_leading_char);
623                         cov_mark::hit!(expected_type_fn_ret_without_leading_char);
624                         let def = self.sema.to_def(&it);
625                         (def.map(|def| def.ret_type(self.db)), None)
626                     },
627                     ast::ClosureExpr(it) => {
628                         let ty = self.sema.type_of_expr(&it.into());
629                         ty.and_then(|ty| ty.original.as_callable(self.db))
630                             .map(|c| (Some(c.return_type()), None))
631                             .unwrap_or((None, None))
632                     },
633                     ast::ParamList(_) => (None, None),
634                     ast::Stmt(_) => (None, None),
635                     ast::Item(_) => (None, None),
636                     _ => {
637                         match node.parent() {
638                             Some(n) => {
639                                 node = n;
640                                 continue;
641                             },
642                             None => (None, None),
643                         }
644                     },
645                 }
646             };
647         }
648     }
649
650     fn fill(
651         &mut self,
652         original_file: &SyntaxNode,
653         file_with_fake_ident: SyntaxNode,
654         offset: TextSize,
655     ) {
656         let fake_ident_token = file_with_fake_ident.token_at_offset(offset).right_biased().unwrap();
657         let syntax_element = NodeOrToken::Token(fake_ident_token);
658         self.previous_token = previous_token(syntax_element.clone());
659         self.no_completion_required = {
660             let inside_impl_trait_block = inside_impl_trait_block(syntax_element.clone());
661             let fn_is_prev = self.previous_token_is(T![fn]);
662             let for_is_prev2 = for_is_prev2(syntax_element.clone());
663             (fn_is_prev && !inside_impl_trait_block) || for_is_prev2
664         };
665
666         self.attr = self
667             .sema
668             .token_ancestors_with_macros(self.token.clone())
669             .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
670             .find_map(ast::Attr::cast);
671         self.fake_attribute_under_caret = syntax_element.ancestors().find_map(ast::Attr::cast);
672
673         self.incomplete_let =
674             syntax_element.ancestors().take(6).find_map(ast::LetStmt::cast).map_or(false, |it| {
675                 it.syntax().text_range().end() == syntax_element.text_range().end()
676             });
677
678         let (expected_type, expected_name) = self.expected_type_and_name();
679         self.expected_type = expected_type;
680         self.expected_name = expected_name;
681
682         let name_like = match find_node_at_offset(&file_with_fake_ident, offset) {
683             Some(it) => it,
684             None => return,
685         };
686         self.completion_location =
687             determine_location(&self.sema, original_file, offset, &name_like);
688         self.prev_sibling = determine_prev_sibling(&name_like);
689         self.name_syntax =
690             find_node_at_offset(original_file, name_like.syntax().text_range().start());
691         self.impl_def = self
692             .sema
693             .token_ancestors_with_macros(self.token.clone())
694             .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
695             .find_map(ast::Impl::cast);
696         self.function_def = self
697             .sema
698             .token_ancestors_with_macros(self.token.clone())
699             .take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
700             .find_map(ast::Fn::cast);
701         match name_like {
702             ast::NameLike::Lifetime(lifetime) => {
703                 self.lifetime_ctx =
704                     Self::classify_lifetime(&self.sema, original_file, lifetime, offset);
705             }
706             ast::NameLike::NameRef(name_ref) => {
707                 if let Some((path_ctx, pat_ctx)) =
708                     Self::classify_name_ref(&self.sema, original_file, name_ref)
709                 {
710                     self.path_context = Some(path_ctx);
711                     self.pattern_ctx = pat_ctx;
712                 }
713             }
714             ast::NameLike::Name(name) => {
715                 self.pattern_ctx = Self::classify_name(&self.sema, name);
716             }
717         }
718     }
719
720     fn classify_lifetime(
721         sema: &Semantics<RootDatabase>,
722         original_file: &SyntaxNode,
723         lifetime: ast::Lifetime,
724         offset: TextSize,
725     ) -> Option<LifetimeContext> {
726         let parent = lifetime.syntax().parent()?;
727         if parent.kind() == ERROR {
728             return None;
729         }
730
731         Some(match_ast! {
732             match parent {
733                 ast::LifetimeParam(_) => LifetimeContext::LifetimeParam(sema.find_node_at_offset_with_macros(original_file, offset)),
734                 ast::BreakExpr(_) => LifetimeContext::LabelRef,
735                 ast::ContinueExpr(_) => LifetimeContext::LabelRef,
736                 ast::Label(_) => LifetimeContext::LabelDef,
737                 _ => LifetimeContext::Lifetime,
738             }
739         })
740     }
741
742     fn classify_name(_sema: &Semantics<RootDatabase>, name: ast::Name) -> Option<PatternContext> {
743         let bind_pat = name.syntax().parent().and_then(ast::IdentPat::cast)?;
744         let is_name_in_field_pat = bind_pat
745             .syntax()
746             .parent()
747             .and_then(ast::RecordPatField::cast)
748             .map_or(false, |pat_field| pat_field.name_ref().is_none());
749         if is_name_in_field_pat {
750             return None;
751         }
752         if !bind_pat.is_simple_ident() {
753             return None;
754         }
755         Some(pattern_context_for(bind_pat.into()))
756     }
757
758     fn classify_name_ref(
759         _sema: &Semantics<RootDatabase>,
760         original_file: &SyntaxNode,
761         name_ref: ast::NameRef,
762     ) -> Option<(PathCompletionContext, Option<PatternContext>)> {
763         let parent = name_ref.syntax().parent()?;
764         let segment = ast::PathSegment::cast(parent)?;
765         let path = segment.parent_path();
766
767         let mut path_ctx = PathCompletionContext {
768             has_call_parens: false,
769             is_trivial_path: false,
770             qualifier: None,
771             parent: None,
772             has_type_args: false,
773             can_be_stmt: false,
774             in_loop_body: false,
775             use_tree_parent: false,
776             kind: None,
777         };
778         let mut pat_ctx = None;
779         path_ctx.in_loop_body = is_in_loop_body(name_ref.syntax());
780
781         path_ctx.kind  = path.syntax().ancestors().find_map(|it| {
782             match_ast! {
783                 match it {
784                     ast::PathType(_) => Some(PathKind::Type),
785                     ast::PathExpr(it) => {
786                         path_ctx.has_call_parens = it.syntax().parent().map_or(false, |it| ast::CallExpr::can_cast(it.kind()));
787                         Some(PathKind::Expr)
788                     },
789                     ast::TupleStructPat(it) => {
790                         path_ctx.has_call_parens = true;
791                         pat_ctx = Some(pattern_context_for(it.into()));
792                         Some(PathKind::Pat)
793                     },
794                     ast::RecordPat(it) => {
795                         pat_ctx = Some(pattern_context_for(it.into()));
796                         Some(PathKind::Pat)
797                     },
798                     ast::PathPat(it) => {
799                         pat_ctx = Some(pattern_context_for(it.into()));
800                         Some(PathKind::Pat)
801                     },
802                     ast::MacroCall(it) => it.excl_token().and(Some(PathKind::Mac)),
803                     ast::Meta(_) => Some(PathKind::Attr),
804                     ast::Visibility(it) => Some(PathKind::Vis { has_in_token: it.in_token().is_some() }),
805                     ast::UseTree(_) => Some(PathKind::Use),
806                     _ => None,
807                 }
808             }
809         });
810         path_ctx.has_type_args = segment.generic_arg_list().is_some();
811
812         if let Some((path, use_tree_parent)) = path_or_use_tree_qualifier(&path) {
813             path_ctx.use_tree_parent = use_tree_parent;
814             path_ctx.qualifier = path
815                 .segment()
816                 .and_then(|it| {
817                     find_node_with_range::<ast::PathSegment>(
818                         original_file,
819                         it.syntax().text_range(),
820                     )
821                 })
822                 .map(|it| it.parent_path());
823             return Some((path_ctx, pat_ctx));
824         }
825
826         if let Some(segment) = path.segment() {
827             if segment.coloncolon_token().is_some() {
828                 return Some((path_ctx, pat_ctx));
829             }
830         }
831
832         path_ctx.is_trivial_path = true;
833
834         // Find either enclosing expr statement (thing with `;`) or a
835         // block. If block, check that we are the last expr.
836         path_ctx.can_be_stmt = name_ref
837             .syntax()
838             .ancestors()
839             .find_map(|node| {
840                 if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
841                     return Some(stmt.syntax().text_range() == name_ref.syntax().text_range());
842                 }
843                 if let Some(stmt_list) = ast::StmtList::cast(node) {
844                     return Some(
845                         stmt_list.tail_expr().map(|e| e.syntax().text_range())
846                             == Some(name_ref.syntax().text_range()),
847                     );
848                 }
849                 None
850             })
851             .unwrap_or(false);
852         Some((path_ctx, pat_ctx))
853     }
854 }
855
856 fn pattern_context_for(pat: ast::Pat) -> PatternContext {
857     let mut is_param = None;
858     let (refutability, has_type_ascription) =
859     pat
860         .syntax()
861         .ancestors()
862         .skip_while(|it| ast::Pat::can_cast(it.kind()))
863         .next()
864         .map_or((PatternRefutability::Irrefutable, false), |node| {
865             let refutability = match_ast! {
866                 match node {
867                     ast::LetStmt(let_) => return (PatternRefutability::Irrefutable, let_.ty().is_some()),
868                     ast::Param(param) => {
869                         let is_closure_param = param
870                             .syntax()
871                             .ancestors()
872                             .nth(2)
873                             .and_then(ast::ClosureExpr::cast)
874                             .is_some();
875                         is_param = Some(if is_closure_param {
876                             ParamKind::Closure
877                         } else {
878                             ParamKind::Function
879                         });
880                         return (PatternRefutability::Irrefutable, param.ty().is_some())
881                     },
882                     ast::MatchArm(_) => PatternRefutability::Refutable,
883                     ast::Condition(_) => PatternRefutability::Refutable,
884                     ast::ForExpr(_) => PatternRefutability::Irrefutable,
885                     _ => PatternRefutability::Irrefutable,
886                 }
887             };
888             (refutability, false)
889         });
890     PatternContext { refutability, is_param, has_type_ascription }
891 }
892 fn find_node_with_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> {
893     syntax.covering_element(range).ancestors().find_map(N::cast)
894 }
895
896 fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<(ast::Path, bool)> {
897     if let Some(qual) = path.qualifier() {
898         return Some((qual, false));
899     }
900     let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
901     let use_tree = use_tree_list.syntax().parent().and_then(ast::UseTree::cast)?;
902     use_tree.path().zip(Some(true))
903 }
904
905 fn has_ref(token: &SyntaxToken) -> bool {
906     let mut token = token.clone();
907     for skip in [WHITESPACE, IDENT, T![mut]] {
908         if token.kind() == skip {
909             token = match token.prev_token() {
910                 Some(it) => it,
911                 None => return false,
912             }
913         }
914     }
915     token.kind() == T![&]
916 }
917
918 #[cfg(test)]
919 mod tests {
920     use expect_test::{expect, Expect};
921     use hir::HirDisplay;
922
923     use crate::tests::{position, TEST_CONFIG};
924
925     use super::CompletionContext;
926
927     fn check_expected_type_and_name(ra_fixture: &str, expect: Expect) {
928         let (db, pos) = position(ra_fixture);
929         let config = TEST_CONFIG;
930         let completion_context = CompletionContext::new(&db, pos, &config).unwrap();
931
932         let ty = completion_context
933             .expected_type
934             .map(|t| t.display_test(&db).to_string())
935             .unwrap_or("?".to_owned());
936
937         let name = completion_context
938             .expected_name
939             .map_or_else(|| "?".to_owned(), |name| name.to_string());
940
941         expect.assert_eq(&format!("ty: {}, name: {}", ty, name));
942     }
943
944     #[test]
945     fn expected_type_let_without_leading_char() {
946         cov_mark::check!(expected_type_let_without_leading_char);
947         check_expected_type_and_name(
948             r#"
949 fn foo() {
950     let x: u32 = $0;
951 }
952 "#,
953             expect![[r#"ty: u32, name: x"#]],
954         );
955     }
956
957     #[test]
958     fn expected_type_let_with_leading_char() {
959         cov_mark::check!(expected_type_let_with_leading_char);
960         check_expected_type_and_name(
961             r#"
962 fn foo() {
963     let x: u32 = c$0;
964 }
965 "#,
966             expect![[r#"ty: u32, name: x"#]],
967         );
968     }
969
970     #[test]
971     fn expected_type_let_pat() {
972         check_expected_type_and_name(
973             r#"
974 fn foo() {
975     let x$0 = 0u32;
976 }
977 "#,
978             expect![[r#"ty: u32, name: ?"#]],
979         );
980         check_expected_type_and_name(
981             r#"
982 fn foo() {
983     let $0 = 0u32;
984 }
985 "#,
986             expect![[r#"ty: u32, name: ?"#]],
987         );
988     }
989
990     #[test]
991     fn expected_type_fn_param() {
992         cov_mark::check!(expected_type_fn_param);
993         check_expected_type_and_name(
994             r#"
995 fn foo() { bar($0); }
996 fn bar(x: u32) {}
997 "#,
998             expect![[r#"ty: u32, name: x"#]],
999         );
1000         check_expected_type_and_name(
1001             r#"
1002 fn foo() { bar(c$0); }
1003 fn bar(x: u32) {}
1004 "#,
1005             expect![[r#"ty: u32, name: x"#]],
1006         );
1007     }
1008
1009     #[test]
1010     fn expected_type_fn_param_ref() {
1011         cov_mark::check!(expected_type_fn_param_ref);
1012         check_expected_type_and_name(
1013             r#"
1014 fn foo() { bar(&$0); }
1015 fn bar(x: &u32) {}
1016 "#,
1017             expect![[r#"ty: u32, name: x"#]],
1018         );
1019         check_expected_type_and_name(
1020             r#"
1021 fn foo() { bar(&mut $0); }
1022 fn bar(x: &mut u32) {}
1023 "#,
1024             expect![[r#"ty: u32, name: x"#]],
1025         );
1026         check_expected_type_and_name(
1027             r#"
1028 fn foo() { bar(&c$0); }
1029 fn bar(x: &u32) {}
1030         "#,
1031             expect![[r#"ty: u32, name: x"#]],
1032         );
1033     }
1034
1035     #[test]
1036     fn expected_type_struct_field_without_leading_char() {
1037         cov_mark::check!(expected_type_struct_field_without_leading_char);
1038         check_expected_type_and_name(
1039             r#"
1040 struct Foo { a: u32 }
1041 fn foo() {
1042     Foo { a: $0 };
1043 }
1044 "#,
1045             expect![[r#"ty: u32, name: a"#]],
1046         )
1047     }
1048
1049     #[test]
1050     fn expected_type_struct_field_followed_by_comma() {
1051         cov_mark::check!(expected_type_struct_field_followed_by_comma);
1052         check_expected_type_and_name(
1053             r#"
1054 struct Foo { a: u32 }
1055 fn foo() {
1056     Foo { a: $0, };
1057 }
1058 "#,
1059             expect![[r#"ty: u32, name: a"#]],
1060         )
1061     }
1062
1063     #[test]
1064     fn expected_type_generic_struct_field() {
1065         check_expected_type_and_name(
1066             r#"
1067 struct Foo<T> { a: T }
1068 fn foo() -> Foo<u32> {
1069     Foo { a: $0 }
1070 }
1071 "#,
1072             expect![[r#"ty: u32, name: a"#]],
1073         )
1074     }
1075
1076     #[test]
1077     fn expected_type_struct_field_with_leading_char() {
1078         cov_mark::check!(expected_type_struct_field_with_leading_char);
1079         check_expected_type_and_name(
1080             r#"
1081 struct Foo { a: u32 }
1082 fn foo() {
1083     Foo { a: c$0 };
1084 }
1085 "#,
1086             expect![[r#"ty: u32, name: a"#]],
1087         );
1088     }
1089
1090     #[test]
1091     fn expected_type_match_arm_without_leading_char() {
1092         cov_mark::check!(expected_type_match_arm_without_leading_char);
1093         check_expected_type_and_name(
1094             r#"
1095 enum E { X }
1096 fn foo() {
1097    match E::X { $0 }
1098 }
1099 "#,
1100             expect![[r#"ty: E, name: ?"#]],
1101         );
1102     }
1103
1104     #[test]
1105     fn expected_type_match_arm_with_leading_char() {
1106         cov_mark::check!(expected_type_match_arm_with_leading_char);
1107         check_expected_type_and_name(
1108             r#"
1109 enum E { X }
1110 fn foo() {
1111    match E::X { c$0 }
1112 }
1113 "#,
1114             expect![[r#"ty: E, name: ?"#]],
1115         );
1116     }
1117
1118     #[test]
1119     fn expected_type_if_let_without_leading_char() {
1120         cov_mark::check!(expected_type_if_let_without_leading_char);
1121         check_expected_type_and_name(
1122             r#"
1123 enum Foo { Bar, Baz, Quux }
1124
1125 fn foo() {
1126     let f = Foo::Quux;
1127     if let $0 = f { }
1128 }
1129 "#,
1130             expect![[r#"ty: Foo, name: ?"#]],
1131         )
1132     }
1133
1134     #[test]
1135     fn expected_type_if_let_with_leading_char() {
1136         cov_mark::check!(expected_type_if_let_with_leading_char);
1137         check_expected_type_and_name(
1138             r#"
1139 enum Foo { Bar, Baz, Quux }
1140
1141 fn foo() {
1142     let f = Foo::Quux;
1143     if let c$0 = f { }
1144 }
1145 "#,
1146             expect![[r#"ty: Foo, name: ?"#]],
1147         )
1148     }
1149
1150     #[test]
1151     fn expected_type_fn_ret_without_leading_char() {
1152         cov_mark::check!(expected_type_fn_ret_without_leading_char);
1153         check_expected_type_and_name(
1154             r#"
1155 fn foo() -> u32 {
1156     $0
1157 }
1158 "#,
1159             expect![[r#"ty: u32, name: ?"#]],
1160         )
1161     }
1162
1163     #[test]
1164     fn expected_type_fn_ret_with_leading_char() {
1165         cov_mark::check!(expected_type_fn_ret_with_leading_char);
1166         check_expected_type_and_name(
1167             r#"
1168 fn foo() -> u32 {
1169     c$0
1170 }
1171 "#,
1172             expect![[r#"ty: u32, name: ?"#]],
1173         )
1174     }
1175
1176     #[test]
1177     fn expected_type_fn_ret_fn_ref_fully_typed() {
1178         check_expected_type_and_name(
1179             r#"
1180 fn foo() -> u32 {
1181     foo$0
1182 }
1183 "#,
1184             expect![[r#"ty: u32, name: ?"#]],
1185         )
1186     }
1187
1188     #[test]
1189     fn expected_type_closure_param_return() {
1190         // FIXME: make this work with `|| $0`
1191         check_expected_type_and_name(
1192             r#"
1193 //- minicore: fn
1194 fn foo() {
1195     bar(|| a$0);
1196 }
1197
1198 fn bar(f: impl FnOnce() -> u32) {}
1199 "#,
1200             expect![[r#"ty: u32, name: ?"#]],
1201         );
1202     }
1203
1204     #[test]
1205     fn expected_type_generic_function() {
1206         check_expected_type_and_name(
1207             r#"
1208 fn foo() {
1209     bar::<u32>($0);
1210 }
1211
1212 fn bar<T>(t: T) {}
1213 "#,
1214             expect![[r#"ty: u32, name: t"#]],
1215         );
1216     }
1217
1218     #[test]
1219     fn expected_type_generic_method() {
1220         check_expected_type_and_name(
1221             r#"
1222 fn foo() {
1223     S(1u32).bar($0);
1224 }
1225
1226 struct S<T>(T);
1227 impl<T> S<T> {
1228     fn bar(self, t: T) {}
1229 }
1230 "#,
1231             expect![[r#"ty: u32, name: t"#]],
1232         );
1233     }
1234
1235     #[test]
1236     fn expected_type_functional_update() {
1237         cov_mark::check!(expected_type_struct_func_update);
1238         check_expected_type_and_name(
1239             r#"
1240 struct Foo { field: u32 }
1241 fn foo() {
1242     Foo {
1243         ..$0
1244     }
1245 }
1246 "#,
1247             expect![[r#"ty: Foo, name: ?"#]],
1248         );
1249     }
1250
1251     #[test]
1252     fn expected_type_param_pat() {
1253         check_expected_type_and_name(
1254             r#"
1255 struct Foo { field: u32 }
1256 fn foo(a$0: Foo) {}
1257 "#,
1258             expect![[r#"ty: Foo, name: ?"#]],
1259         );
1260         check_expected_type_and_name(
1261             r#"
1262 struct Foo { field: u32 }
1263 fn foo($0: Foo) {}
1264 "#,
1265             // FIXME make this work, currently fails due to pattern recovery eating the `:`
1266             expect![[r#"ty: ?, name: ?"#]],
1267         );
1268     }
1269 }