]> git.lizzy.rs Git - rust.git/blob - crates/ide-completion/src/render.rs
Merge remote-tracking branch 'origin/master' into sync-from-rust-2
[rust.git] / crates / ide-completion / src / render.rs
1 //! `render` module provides utilities for rendering completion suggestions
2 //! into code pieces that will be presented to user.
3
4 pub(crate) mod macro_;
5 pub(crate) mod function;
6 pub(crate) mod const_;
7 pub(crate) mod pattern;
8 pub(crate) mod type_alias;
9 pub(crate) mod variant;
10 pub(crate) mod union_literal;
11 pub(crate) mod literal;
12
13 use hir::{AsAssocItem, HasAttrs, HirDisplay, ScopeDef};
14 use ide_db::{
15     helpers::item_name, imports::import_assets::LocatedImport, RootDatabase, SnippetCap, SymbolKind,
16 };
17 use syntax::{AstNode, SmolStr, SyntaxKind, TextRange};
18
19 use crate::{
20     context::{DotAccess, PathCompletionCtx, PathKind, PatternContext},
21     item::{Builder, CompletionRelevanceTypeMatch},
22     render::{
23         function::render_fn,
24         literal::render_variant_lit,
25         macro_::{render_macro, render_macro_pat},
26     },
27     CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
28 };
29 /// Interface for data and methods required for items rendering.
30 #[derive(Debug, Clone)]
31 pub(crate) struct RenderContext<'a> {
32     completion: &'a CompletionContext<'a>,
33     is_private_editable: bool,
34     import_to_add: Option<LocatedImport>,
35 }
36
37 impl<'a> RenderContext<'a> {
38     pub(crate) fn new(completion: &'a CompletionContext<'a>) -> RenderContext<'a> {
39         RenderContext { completion, is_private_editable: false, import_to_add: None }
40     }
41
42     pub(crate) fn private_editable(mut self, private_editable: bool) -> Self {
43         self.is_private_editable = private_editable;
44         self
45     }
46
47     pub(crate) fn import_to_add(mut self, import_to_add: Option<LocatedImport>) -> Self {
48         self.import_to_add = import_to_add;
49         self
50     }
51
52     fn snippet_cap(&self) -> Option<SnippetCap> {
53         self.completion.config.snippet_cap
54     }
55
56     fn db(&self) -> &'a RootDatabase {
57         self.completion.db
58     }
59
60     fn source_range(&self) -> TextRange {
61         self.completion.source_range()
62     }
63
64     fn completion_relevance(&self) -> CompletionRelevance {
65         CompletionRelevance {
66             is_private_editable: self.is_private_editable,
67             requires_import: self.import_to_add.is_some(),
68             ..Default::default()
69         }
70     }
71
72     fn is_immediately_after_macro_bang(&self) -> bool {
73         self.completion.token.kind() == SyntaxKind::BANG
74             && self
75                 .completion
76                 .token
77                 .parent()
78                 .map_or(false, |it| it.kind() == SyntaxKind::MACRO_CALL)
79     }
80
81     fn is_deprecated(&self, def: impl HasAttrs) -> bool {
82         let attrs = def.attrs(self.db());
83         attrs.by_key("deprecated").exists()
84     }
85
86     fn is_deprecated_assoc_item(&self, as_assoc_item: impl AsAssocItem) -> bool {
87         let db = self.db();
88         let assoc = match as_assoc_item.as_assoc_item(db) {
89             Some(assoc) => assoc,
90             None => return false,
91         };
92
93         let is_assoc_deprecated = match assoc {
94             hir::AssocItem::Function(it) => self.is_deprecated(it),
95             hir::AssocItem::Const(it) => self.is_deprecated(it),
96             hir::AssocItem::TypeAlias(it) => self.is_deprecated(it),
97         };
98         is_assoc_deprecated
99             || assoc
100                 .containing_trait_or_trait_impl(db)
101                 .map(|trait_| self.is_deprecated(trait_))
102                 .unwrap_or(false)
103     }
104
105     // FIXME: remove this
106     fn docs(&self, def: impl HasAttrs) -> Option<hir::Documentation> {
107         def.docs(self.db())
108     }
109 }
110
111 pub(crate) fn render_field(
112     ctx: RenderContext<'_>,
113     dot_access: &DotAccess,
114     receiver: Option<hir::Name>,
115     field: hir::Field,
116     ty: &hir::Type,
117 ) -> CompletionItem {
118     let is_deprecated = ctx.is_deprecated(field);
119     let name = field.name(ctx.db());
120     let (name, escaped_name) = (name.to_smol_str(), name.escaped().to_smol_str());
121     let mut item = CompletionItem::new(
122         SymbolKind::Field,
123         ctx.source_range(),
124         field_with_receiver(receiver.as_ref(), &name),
125     );
126     item.set_relevance(CompletionRelevance {
127         type_match: compute_type_match(ctx.completion, ty),
128         exact_name_match: compute_exact_name_match(ctx.completion, name.as_str()),
129         ..CompletionRelevance::default()
130     });
131     item.detail(ty.display(ctx.db()).to_string())
132         .set_documentation(field.docs(ctx.db()))
133         .set_deprecated(is_deprecated)
134         .lookup_by(name.clone());
135     item.insert_text(field_with_receiver(receiver.as_ref(), &escaped_name));
136     if let Some(receiver) = &dot_access.receiver {
137         if let Some(original) = ctx.completion.sema.original_ast_node(receiver.clone()) {
138             if let Some(ref_match) = compute_ref_match(ctx.completion, ty) {
139                 item.ref_match(ref_match, original.syntax().text_range().start());
140             }
141         }
142     }
143     item.build()
144 }
145
146 fn field_with_receiver(receiver: Option<&hir::Name>, field_name: &str) -> SmolStr {
147     receiver
148         .map_or_else(|| field_name.into(), |receiver| format!("{}.{}", receiver, field_name).into())
149 }
150
151 pub(crate) fn render_tuple_field(
152     ctx: RenderContext<'_>,
153     receiver: Option<hir::Name>,
154     field: usize,
155     ty: &hir::Type,
156 ) -> CompletionItem {
157     let mut item = CompletionItem::new(
158         SymbolKind::Field,
159         ctx.source_range(),
160         field_with_receiver(receiver.as_ref(), &field.to_string()),
161     );
162     item.detail(ty.display(ctx.db()).to_string()).lookup_by(field.to_string());
163     item.build()
164 }
165
166 pub(crate) fn render_type_inference(
167     ty_string: String,
168     ctx: &CompletionContext<'_>,
169 ) -> CompletionItem {
170     let mut builder =
171         CompletionItem::new(CompletionItemKind::InferredType, ctx.source_range(), ty_string);
172     builder.set_relevance(CompletionRelevance { is_definite: true, ..Default::default() });
173     builder.build()
174 }
175
176 pub(crate) fn render_path_resolution(
177     ctx: RenderContext<'_>,
178     path_ctx: &PathCompletionCtx,
179     local_name: hir::Name,
180     resolution: ScopeDef,
181 ) -> Builder {
182     render_resolution_path(ctx, path_ctx, local_name, None, resolution)
183 }
184
185 pub(crate) fn render_pattern_resolution(
186     ctx: RenderContext<'_>,
187     pattern_ctx: &PatternContext,
188     local_name: hir::Name,
189     resolution: ScopeDef,
190 ) -> Builder {
191     render_resolution_pat(ctx, pattern_ctx, local_name, None, resolution)
192 }
193
194 pub(crate) fn render_resolution_with_import(
195     ctx: RenderContext<'_>,
196     path_ctx: &PathCompletionCtx,
197     import_edit: LocatedImport,
198 ) -> Option<Builder> {
199     let resolution = ScopeDef::from(import_edit.original_item);
200     let local_name = scope_def_to_name(resolution, &ctx, &import_edit)?;
201
202     Some(render_resolution_path(ctx, path_ctx, local_name, Some(import_edit), resolution))
203 }
204
205 pub(crate) fn render_resolution_with_import_pat(
206     ctx: RenderContext<'_>,
207     pattern_ctx: &PatternContext,
208     import_edit: LocatedImport,
209 ) -> Option<Builder> {
210     let resolution = ScopeDef::from(import_edit.original_item);
211     let local_name = scope_def_to_name(resolution, &ctx, &import_edit)?;
212     Some(render_resolution_pat(ctx, pattern_ctx, local_name, Some(import_edit), resolution))
213 }
214
215 fn scope_def_to_name(
216     resolution: ScopeDef,
217     ctx: &RenderContext<'_>,
218     import_edit: &LocatedImport,
219 ) -> Option<hir::Name> {
220     Some(match resolution {
221         ScopeDef::ModuleDef(hir::ModuleDef::Function(f)) => f.name(ctx.completion.db),
222         ScopeDef::ModuleDef(hir::ModuleDef::Const(c)) => c.name(ctx.completion.db)?,
223         ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db),
224         _ => item_name(ctx.db(), import_edit.original_item)?,
225     })
226 }
227
228 fn render_resolution_pat(
229     ctx: RenderContext<'_>,
230     pattern_ctx: &PatternContext,
231     local_name: hir::Name,
232     import_to_add: Option<LocatedImport>,
233     resolution: ScopeDef,
234 ) -> Builder {
235     let _p = profile::span("render_resolution");
236     use hir::ModuleDef::*;
237
238     match resolution {
239         ScopeDef::ModuleDef(Macro(mac)) => {
240             let ctx = ctx.import_to_add(import_to_add);
241             return render_macro_pat(ctx, pattern_ctx, local_name, mac);
242         }
243         _ => (),
244     }
245
246     render_resolution_simple_(ctx, &local_name, import_to_add, resolution)
247 }
248
249 fn render_resolution_path(
250     ctx: RenderContext<'_>,
251     path_ctx: &PathCompletionCtx,
252     local_name: hir::Name,
253     import_to_add: Option<LocatedImport>,
254     resolution: ScopeDef,
255 ) -> Builder {
256     let _p = profile::span("render_resolution");
257     use hir::ModuleDef::*;
258
259     match resolution {
260         ScopeDef::ModuleDef(Macro(mac)) => {
261             let ctx = ctx.import_to_add(import_to_add);
262             return render_macro(ctx, path_ctx, local_name, mac);
263         }
264         ScopeDef::ModuleDef(Function(func)) => {
265             let ctx = ctx.import_to_add(import_to_add);
266             return render_fn(ctx, path_ctx, Some(local_name), func);
267         }
268         ScopeDef::ModuleDef(Variant(var)) => {
269             let ctx = ctx.clone().import_to_add(import_to_add.clone());
270             if let Some(item) =
271                 render_variant_lit(ctx, path_ctx, Some(local_name.clone()), var, None)
272             {
273                 return item;
274             }
275         }
276         _ => (),
277     }
278
279     let completion = ctx.completion;
280     let cap = ctx.snippet_cap();
281     let db = completion.db;
282     let config = completion.config;
283
284     let name = local_name.to_smol_str();
285     let mut item = render_resolution_simple_(ctx, &local_name, import_to_add, resolution);
286     if local_name.escaped().is_escaped() {
287         item.insert_text(local_name.escaped().to_smol_str());
288     }
289     // Add `<>` for generic types
290     let type_path_no_ty_args = matches!(
291         path_ctx,
292         PathCompletionCtx { kind: PathKind::Type { .. }, has_type_args: false, .. }
293     ) && config.callable.is_some();
294     if type_path_no_ty_args {
295         if let Some(cap) = cap {
296             let has_non_default_type_params = match resolution {
297                 ScopeDef::ModuleDef(hir::ModuleDef::Adt(it)) => it.has_non_default_type_params(db),
298                 ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(it)) => {
299                     it.has_non_default_type_params(db)
300                 }
301                 _ => false,
302             };
303
304             if has_non_default_type_params {
305                 cov_mark::hit!(inserts_angle_brackets_for_generics);
306                 item.lookup_by(name.clone())
307                     .label(SmolStr::from_iter([&name, "<…>"]))
308                     .trigger_call_info()
309                     .insert_snippet(cap, format!("{}<$0>", local_name.escaped()));
310             }
311         }
312     }
313     if let ScopeDef::Local(local) = resolution {
314         let ty = local.ty(db);
315         if !ty.is_unknown() {
316             item.detail(ty.display(db).to_string());
317         }
318
319         item.set_relevance(CompletionRelevance {
320             type_match: compute_type_match(completion, &ty),
321             exact_name_match: compute_exact_name_match(completion, &name),
322             is_local: true,
323             ..CompletionRelevance::default()
324         });
325
326         if let Some(ref_match) = compute_ref_match(completion, &ty) {
327             item.ref_match(ref_match, path_ctx.path.syntax().text_range().start());
328         }
329     };
330     item
331 }
332
333 fn render_resolution_simple_(
334     ctx: RenderContext<'_>,
335     local_name: &hir::Name,
336     import_to_add: Option<LocatedImport>,
337     resolution: ScopeDef,
338 ) -> Builder {
339     let _p = profile::span("render_resolution");
340
341     let db = ctx.db();
342     let ctx = ctx.import_to_add(import_to_add);
343     let kind = res_to_kind(resolution);
344
345     let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.to_smol_str());
346     item.set_relevance(ctx.completion_relevance())
347         .set_documentation(scope_def_docs(db, resolution))
348         .set_deprecated(scope_def_is_deprecated(&ctx, resolution));
349
350     if let Some(import_to_add) = ctx.import_to_add {
351         item.add_import(import_to_add);
352     }
353     item
354 }
355
356 fn res_to_kind(resolution: ScopeDef) -> CompletionItemKind {
357     use hir::ModuleDef::*;
358     match resolution {
359         ScopeDef::Unknown => CompletionItemKind::UnresolvedReference,
360         ScopeDef::ModuleDef(Function(_)) => CompletionItemKind::SymbolKind(SymbolKind::Function),
361         ScopeDef::ModuleDef(Variant(_)) => CompletionItemKind::SymbolKind(SymbolKind::Variant),
362         ScopeDef::ModuleDef(Macro(_)) => CompletionItemKind::SymbolKind(SymbolKind::Macro),
363         ScopeDef::ModuleDef(Module(..)) => CompletionItemKind::SymbolKind(SymbolKind::Module),
364         ScopeDef::ModuleDef(Adt(adt)) => CompletionItemKind::SymbolKind(match adt {
365             hir::Adt::Struct(_) => SymbolKind::Struct,
366             hir::Adt::Union(_) => SymbolKind::Union,
367             hir::Adt::Enum(_) => SymbolKind::Enum,
368         }),
369         ScopeDef::ModuleDef(Const(..)) => CompletionItemKind::SymbolKind(SymbolKind::Const),
370         ScopeDef::ModuleDef(Static(..)) => CompletionItemKind::SymbolKind(SymbolKind::Static),
371         ScopeDef::ModuleDef(Trait(..)) => CompletionItemKind::SymbolKind(SymbolKind::Trait),
372         ScopeDef::ModuleDef(TypeAlias(..)) => CompletionItemKind::SymbolKind(SymbolKind::TypeAlias),
373         ScopeDef::ModuleDef(BuiltinType(..)) => CompletionItemKind::BuiltinType,
374         ScopeDef::GenericParam(param) => CompletionItemKind::SymbolKind(match param {
375             hir::GenericParam::TypeParam(_) => SymbolKind::TypeParam,
376             hir::GenericParam::ConstParam(_) => SymbolKind::ConstParam,
377             hir::GenericParam::LifetimeParam(_) => SymbolKind::LifetimeParam,
378         }),
379         ScopeDef::Local(..) => CompletionItemKind::SymbolKind(SymbolKind::Local),
380         ScopeDef::Label(..) => CompletionItemKind::SymbolKind(SymbolKind::Label),
381         ScopeDef::AdtSelfType(..) | ScopeDef::ImplSelfType(..) => {
382             CompletionItemKind::SymbolKind(SymbolKind::SelfParam)
383         }
384     }
385 }
386
387 fn scope_def_docs(db: &RootDatabase, resolution: ScopeDef) -> Option<hir::Documentation> {
388     use hir::ModuleDef::*;
389     match resolution {
390         ScopeDef::ModuleDef(Module(it)) => it.docs(db),
391         ScopeDef::ModuleDef(Adt(it)) => it.docs(db),
392         ScopeDef::ModuleDef(Variant(it)) => it.docs(db),
393         ScopeDef::ModuleDef(Const(it)) => it.docs(db),
394         ScopeDef::ModuleDef(Static(it)) => it.docs(db),
395         ScopeDef::ModuleDef(Trait(it)) => it.docs(db),
396         ScopeDef::ModuleDef(TypeAlias(it)) => it.docs(db),
397         _ => None,
398     }
399 }
400
401 fn scope_def_is_deprecated(ctx: &RenderContext<'_>, resolution: ScopeDef) -> bool {
402     match resolution {
403         ScopeDef::ModuleDef(it) => ctx.is_deprecated_assoc_item(it),
404         ScopeDef::GenericParam(it) => ctx.is_deprecated(it),
405         ScopeDef::AdtSelfType(it) => ctx.is_deprecated(it),
406         _ => false,
407     }
408 }
409
410 fn compute_type_match(
411     ctx: &CompletionContext<'_>,
412     completion_ty: &hir::Type,
413 ) -> Option<CompletionRelevanceTypeMatch> {
414     let expected_type = ctx.expected_type.as_ref()?;
415
416     // We don't ever consider unit type to be an exact type match, since
417     // nearly always this is not meaningful to the user.
418     if expected_type.is_unit() {
419         return None;
420     }
421
422     if completion_ty == expected_type {
423         Some(CompletionRelevanceTypeMatch::Exact)
424     } else if expected_type.could_unify_with(ctx.db, completion_ty) {
425         Some(CompletionRelevanceTypeMatch::CouldUnify)
426     } else {
427         None
428     }
429 }
430
431 fn compute_exact_name_match(ctx: &CompletionContext<'_>, completion_name: &str) -> bool {
432     ctx.expected_name.as_ref().map_or(false, |name| name.text() == completion_name)
433 }
434
435 fn compute_ref_match(
436     ctx: &CompletionContext<'_>,
437     completion_ty: &hir::Type,
438 ) -> Option<hir::Mutability> {
439     let expected_type = ctx.expected_type.as_ref()?;
440     if completion_ty != expected_type {
441         let expected_type_without_ref = expected_type.remove_ref()?;
442         if completion_ty.autoderef(ctx.db).any(|deref_ty| deref_ty == expected_type_without_ref) {
443             cov_mark::hit!(suggest_ref);
444             let mutability = if expected_type.is_mutable_reference() {
445                 hir::Mutability::Mut
446             } else {
447                 hir::Mutability::Shared
448             };
449             return Some(mutability);
450         };
451     }
452     None
453 }
454
455 #[cfg(test)]
456 mod tests {
457     use std::cmp;
458
459     use expect_test::{expect, Expect};
460     use ide_db::SymbolKind;
461     use itertools::Itertools;
462
463     use crate::{
464         item::CompletionRelevanceTypeMatch,
465         tests::{check_edit, do_completion, get_all_items, TEST_CONFIG},
466         CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch,
467     };
468
469     #[track_caller]
470     fn check(ra_fixture: &str, kind: impl Into<CompletionItemKind>, expect: Expect) {
471         let actual = do_completion(ra_fixture, kind.into());
472         expect.assert_debug_eq(&actual);
473     }
474
475     #[track_caller]
476     fn check_kinds(ra_fixture: &str, kinds: &[CompletionItemKind], expect: Expect) {
477         let actual: Vec<_> =
478             kinds.iter().flat_map(|&kind| do_completion(ra_fixture, kind)).collect();
479         expect.assert_debug_eq(&actual);
480     }
481
482     #[track_caller]
483     fn check_relevance_for_kinds(ra_fixture: &str, kinds: &[CompletionItemKind], expect: Expect) {
484         let mut actual = get_all_items(TEST_CONFIG, ra_fixture, None);
485         actual.retain(|it| kinds.contains(&it.kind()));
486         actual.sort_by_key(|it| cmp::Reverse(it.relevance().score()));
487         check_relevance_(actual, expect);
488     }
489
490     #[track_caller]
491     fn check_relevance(ra_fixture: &str, expect: Expect) {
492         let mut actual = get_all_items(TEST_CONFIG, ra_fixture, None);
493         actual.retain(|it| it.kind() != CompletionItemKind::Snippet);
494         actual.retain(|it| it.kind() != CompletionItemKind::Keyword);
495         actual.retain(|it| it.kind() != CompletionItemKind::BuiltinType);
496         actual.sort_by_key(|it| cmp::Reverse(it.relevance().score()));
497         check_relevance_(actual, expect);
498     }
499
500     #[track_caller]
501     fn check_relevance_(actual: Vec<CompletionItem>, expect: Expect) {
502         let actual = actual
503             .into_iter()
504             .flat_map(|it| {
505                 let mut items = vec![];
506
507                 let tag = it.kind().tag();
508                 let relevance = display_relevance(it.relevance());
509                 items.push(format!("{} {} {}\n", tag, it.label(), relevance));
510
511                 if let Some((mutability, _offset, relevance)) = it.ref_match() {
512                     let label = format!("&{}{}", mutability.as_keyword_for_ref(), it.label());
513                     let relevance = display_relevance(relevance);
514
515                     items.push(format!("{} {} {}\n", tag, label, relevance));
516                 }
517
518                 items
519             })
520             .collect::<String>();
521
522         expect.assert_eq(&actual);
523
524         fn display_relevance(relevance: CompletionRelevance) -> String {
525             let relevance_factors = vec![
526                 (relevance.type_match == Some(CompletionRelevanceTypeMatch::Exact), "type"),
527                 (
528                     relevance.type_match == Some(CompletionRelevanceTypeMatch::CouldUnify),
529                     "type_could_unify",
530                 ),
531                 (relevance.exact_name_match, "name"),
532                 (relevance.is_local, "local"),
533                 (
534                     relevance.postfix_match == Some(CompletionRelevancePostfixMatch::Exact),
535                     "snippet",
536                 ),
537                 (relevance.is_op_method, "op_method"),
538                 (relevance.requires_import, "requires_import"),
539             ]
540             .into_iter()
541             .filter_map(|(cond, desc)| if cond { Some(desc) } else { None })
542             .join("+");
543
544             format!("[{}]", relevance_factors)
545         }
546     }
547
548     #[test]
549     fn enum_detail_includes_record_fields() {
550         check(
551             r#"
552 enum Foo { Foo { x: i32, y: i32 } }
553
554 fn main() { Foo::Fo$0 }
555 "#,
556             SymbolKind::Variant,
557             expect![[r#"
558                 [
559                     CompletionItem {
560                         label: "Foo {…}",
561                         source_range: 54..56,
562                         delete: 54..56,
563                         insert: "Foo { x: ${1:()}, y: ${2:()} }$0",
564                         kind: SymbolKind(
565                             Variant,
566                         ),
567                         detail: "Foo { x: i32, y: i32 }",
568                     },
569                 ]
570             "#]],
571         );
572     }
573
574     #[test]
575     fn enum_detail_includes_tuple_fields() {
576         check(
577             r#"
578 enum Foo { Foo (i32, i32) }
579
580 fn main() { Foo::Fo$0 }
581 "#,
582             SymbolKind::Variant,
583             expect![[r#"
584                 [
585                     CompletionItem {
586                         label: "Foo(…)",
587                         source_range: 46..48,
588                         delete: 46..48,
589                         insert: "Foo(${1:()}, ${2:()})$0",
590                         kind: SymbolKind(
591                             Variant,
592                         ),
593                         detail: "Foo(i32, i32)",
594                     },
595                 ]
596             "#]],
597         );
598     }
599
600     #[test]
601     fn fn_detail_includes_args_and_return_type() {
602         check(
603             r#"
604 fn foo<T>(a: u32, b: u32, t: T) -> (u32, T) { (a, t) }
605
606 fn main() { fo$0 }
607 "#,
608             SymbolKind::Function,
609             expect![[r#"
610                 [
611                     CompletionItem {
612                         label: "foo(…)",
613                         source_range: 68..70,
614                         delete: 68..70,
615                         insert: "foo(${1:a}, ${2:b}, ${3:t})$0",
616                         kind: SymbolKind(
617                             Function,
618                         ),
619                         lookup: "foo",
620                         detail: "fn(u32, u32, T) -> (u32, T)",
621                         trigger_call_info: true,
622                     },
623                     CompletionItem {
624                         label: "main()",
625                         source_range: 68..70,
626                         delete: 68..70,
627                         insert: "main()$0",
628                         kind: SymbolKind(
629                             Function,
630                         ),
631                         lookup: "main",
632                         detail: "fn()",
633                     },
634                 ]
635             "#]],
636         );
637     }
638
639     #[test]
640     fn enum_detail_just_name_for_unit() {
641         check(
642             r#"
643 enum Foo { Foo }
644
645 fn main() { Foo::Fo$0 }
646 "#,
647             SymbolKind::Variant,
648             expect![[r#"
649                 [
650                     CompletionItem {
651                         label: "Foo",
652                         source_range: 35..37,
653                         delete: 35..37,
654                         insert: "Foo$0",
655                         kind: SymbolKind(
656                             Variant,
657                         ),
658                         detail: "Foo",
659                     },
660                 ]
661             "#]],
662         );
663     }
664
665     #[test]
666     fn lookup_enums_by_two_qualifiers() {
667         check_kinds(
668             r#"
669 mod m {
670     pub enum Spam { Foo, Bar(i32) }
671 }
672 fn main() { let _: m::Spam = S$0 }
673 "#,
674             &[
675                 CompletionItemKind::SymbolKind(SymbolKind::Function),
676                 CompletionItemKind::SymbolKind(SymbolKind::Module),
677                 CompletionItemKind::SymbolKind(SymbolKind::Variant),
678             ],
679             expect![[r#"
680                 [
681                     CompletionItem {
682                         label: "main()",
683                         source_range: 75..76,
684                         delete: 75..76,
685                         insert: "main()$0",
686                         kind: SymbolKind(
687                             Function,
688                         ),
689                         lookup: "main",
690                         detail: "fn()",
691                     },
692                     CompletionItem {
693                         label: "m",
694                         source_range: 75..76,
695                         delete: 75..76,
696                         insert: "m",
697                         kind: SymbolKind(
698                             Module,
699                         ),
700                     },
701                     CompletionItem {
702                         label: "m::Spam::Bar(…)",
703                         source_range: 75..76,
704                         delete: 75..76,
705                         insert: "m::Spam::Bar(${1:()})$0",
706                         kind: SymbolKind(
707                             Variant,
708                         ),
709                         lookup: "Spam::Bar(…)",
710                         detail: "m::Spam::Bar(i32)",
711                         relevance: CompletionRelevance {
712                             exact_name_match: false,
713                             type_match: Some(
714                                 Exact,
715                             ),
716                             is_local: false,
717                             is_item_from_trait: false,
718                             is_name_already_imported: false,
719                             requires_import: false,
720                             is_op_method: false,
721                             is_private_editable: false,
722                             postfix_match: None,
723                             is_definite: false,
724                         },
725                     },
726                     CompletionItem {
727                         label: "m::Spam::Foo",
728                         source_range: 75..76,
729                         delete: 75..76,
730                         insert: "m::Spam::Foo$0",
731                         kind: SymbolKind(
732                             Variant,
733                         ),
734                         lookup: "Spam::Foo",
735                         detail: "m::Spam::Foo",
736                         relevance: CompletionRelevance {
737                             exact_name_match: false,
738                             type_match: Some(
739                                 Exact,
740                             ),
741                             is_local: false,
742                             is_item_from_trait: false,
743                             is_name_already_imported: false,
744                             requires_import: false,
745                             is_op_method: false,
746                             is_private_editable: false,
747                             postfix_match: None,
748                             is_definite: false,
749                         },
750                     },
751                 ]
752             "#]],
753         )
754     }
755
756     #[test]
757     fn sets_deprecated_flag_in_items() {
758         check(
759             r#"
760 #[deprecated]
761 fn something_deprecated() {}
762
763 fn main() { som$0 }
764 "#,
765             SymbolKind::Function,
766             expect![[r#"
767                 [
768                     CompletionItem {
769                         label: "main()",
770                         source_range: 56..59,
771                         delete: 56..59,
772                         insert: "main()$0",
773                         kind: SymbolKind(
774                             Function,
775                         ),
776                         lookup: "main",
777                         detail: "fn()",
778                     },
779                     CompletionItem {
780                         label: "something_deprecated()",
781                         source_range: 56..59,
782                         delete: 56..59,
783                         insert: "something_deprecated()$0",
784                         kind: SymbolKind(
785                             Function,
786                         ),
787                         lookup: "something_deprecated",
788                         detail: "fn()",
789                         deprecated: true,
790                     },
791                 ]
792             "#]],
793         );
794
795         check(
796             r#"
797 struct A { #[deprecated] the_field: u32 }
798 fn foo() { A { the$0 } }
799 "#,
800             SymbolKind::Field,
801             expect![[r#"
802                 [
803                     CompletionItem {
804                         label: "the_field",
805                         source_range: 57..60,
806                         delete: 57..60,
807                         insert: "the_field",
808                         kind: SymbolKind(
809                             Field,
810                         ),
811                         detail: "u32",
812                         deprecated: true,
813                         relevance: CompletionRelevance {
814                             exact_name_match: false,
815                             type_match: Some(
816                                 CouldUnify,
817                             ),
818                             is_local: false,
819                             is_item_from_trait: false,
820                             is_name_already_imported: false,
821                             requires_import: false,
822                             is_op_method: false,
823                             is_private_editable: false,
824                             postfix_match: None,
825                             is_definite: false,
826                         },
827                     },
828                 ]
829             "#]],
830         );
831     }
832
833     #[test]
834     fn renders_docs() {
835         check_kinds(
836             r#"
837 struct S {
838     /// Field docs
839     foo:
840 }
841 impl S {
842     /// Method docs
843     fn bar(self) { self.$0 }
844 }"#,
845             &[CompletionItemKind::Method, CompletionItemKind::SymbolKind(SymbolKind::Field)],
846             expect![[r#"
847                 [
848                     CompletionItem {
849                         label: "bar()",
850                         source_range: 94..94,
851                         delete: 94..94,
852                         insert: "bar()$0",
853                         kind: Method,
854                         lookup: "bar",
855                         detail: "fn(self)",
856                         documentation: Documentation(
857                             "Method docs",
858                         ),
859                     },
860                     CompletionItem {
861                         label: "foo",
862                         source_range: 94..94,
863                         delete: 94..94,
864                         insert: "foo",
865                         kind: SymbolKind(
866                             Field,
867                         ),
868                         detail: "{unknown}",
869                         documentation: Documentation(
870                             "Field docs",
871                         ),
872                     },
873                 ]
874             "#]],
875         );
876
877         check_kinds(
878             r#"
879 use self::my$0;
880
881 /// mod docs
882 mod my { }
883
884 /// enum docs
885 enum E {
886     /// variant docs
887     V
888 }
889 use self::E::*;
890 "#,
891             &[
892                 CompletionItemKind::SymbolKind(SymbolKind::Module),
893                 CompletionItemKind::SymbolKind(SymbolKind::Variant),
894                 CompletionItemKind::SymbolKind(SymbolKind::Enum),
895             ],
896             expect![[r#"
897                 [
898                     CompletionItem {
899                         label: "my",
900                         source_range: 10..12,
901                         delete: 10..12,
902                         insert: "my",
903                         kind: SymbolKind(
904                             Module,
905                         ),
906                         documentation: Documentation(
907                             "mod docs",
908                         ),
909                     },
910                     CompletionItem {
911                         label: "V",
912                         source_range: 10..12,
913                         delete: 10..12,
914                         insert: "V$0",
915                         kind: SymbolKind(
916                             Variant,
917                         ),
918                         detail: "V",
919                         documentation: Documentation(
920                             "variant docs",
921                         ),
922                     },
923                     CompletionItem {
924                         label: "E",
925                         source_range: 10..12,
926                         delete: 10..12,
927                         insert: "E",
928                         kind: SymbolKind(
929                             Enum,
930                         ),
931                         documentation: Documentation(
932                             "enum docs",
933                         ),
934                     },
935                 ]
936             "#]],
937         )
938     }
939
940     #[test]
941     fn dont_render_attrs() {
942         check(
943             r#"
944 struct S;
945 impl S {
946     #[inline]
947     fn the_method(&self) { }
948 }
949 fn foo(s: S) { s.$0 }
950 "#,
951             CompletionItemKind::Method,
952             expect![[r#"
953                 [
954                     CompletionItem {
955                         label: "the_method()",
956                         source_range: 81..81,
957                         delete: 81..81,
958                         insert: "the_method()$0",
959                         kind: Method,
960                         lookup: "the_method",
961                         detail: "fn(&self)",
962                     },
963                 ]
964             "#]],
965         )
966     }
967
968     #[test]
969     fn no_call_parens_if_fn_ptr_needed() {
970         cov_mark::check!(no_call_parens_if_fn_ptr_needed);
971         check_edit(
972             "foo",
973             r#"
974 fn foo(foo: u8, bar: u8) {}
975 struct ManualVtable { f: fn(u8, u8) }
976
977 fn main() -> ManualVtable {
978     ManualVtable { f: f$0 }
979 }
980 "#,
981             r#"
982 fn foo(foo: u8, bar: u8) {}
983 struct ManualVtable { f: fn(u8, u8) }
984
985 fn main() -> ManualVtable {
986     ManualVtable { f: foo }
987 }
988 "#,
989         );
990         check_edit(
991             "type",
992             r#"
993 struct RawIdentTable { r#type: u32 }
994
995 fn main() -> RawIdentTable {
996     RawIdentTable { t$0: 42 }
997 }
998 "#,
999             r#"
1000 struct RawIdentTable { r#type: u32 }
1001
1002 fn main() -> RawIdentTable {
1003     RawIdentTable { r#type: 42 }
1004 }
1005 "#,
1006         );
1007     }
1008
1009     #[test]
1010     fn no_parens_in_use_item() {
1011         check_edit(
1012             "foo",
1013             r#"
1014 mod m { pub fn foo() {} }
1015 use crate::m::f$0;
1016 "#,
1017             r#"
1018 mod m { pub fn foo() {} }
1019 use crate::m::foo;
1020 "#,
1021         );
1022     }
1023
1024     #[test]
1025     fn no_parens_in_call() {
1026         check_edit(
1027             "foo",
1028             r#"
1029 fn foo(x: i32) {}
1030 fn main() { f$0(); }
1031 "#,
1032             r#"
1033 fn foo(x: i32) {}
1034 fn main() { foo(); }
1035 "#,
1036         );
1037         check_edit(
1038             "foo",
1039             r#"
1040 struct Foo;
1041 impl Foo { fn foo(&self){} }
1042 fn f(foo: &Foo) { foo.f$0(); }
1043 "#,
1044             r#"
1045 struct Foo;
1046 impl Foo { fn foo(&self){} }
1047 fn f(foo: &Foo) { foo.foo(); }
1048 "#,
1049         );
1050     }
1051
1052     #[test]
1053     fn inserts_angle_brackets_for_generics() {
1054         cov_mark::check!(inserts_angle_brackets_for_generics);
1055         check_edit(
1056             "Vec",
1057             r#"
1058 struct Vec<T> {}
1059 fn foo(xs: Ve$0)
1060 "#,
1061             r#"
1062 struct Vec<T> {}
1063 fn foo(xs: Vec<$0>)
1064 "#,
1065         );
1066         check_edit(
1067             "Vec",
1068             r#"
1069 type Vec<T> = (T,);
1070 fn foo(xs: Ve$0)
1071 "#,
1072             r#"
1073 type Vec<T> = (T,);
1074 fn foo(xs: Vec<$0>)
1075 "#,
1076         );
1077         check_edit(
1078             "Vec",
1079             r#"
1080 struct Vec<T = i128> {}
1081 fn foo(xs: Ve$0)
1082 "#,
1083             r#"
1084 struct Vec<T = i128> {}
1085 fn foo(xs: Vec)
1086 "#,
1087         );
1088         check_edit(
1089             "Vec",
1090             r#"
1091 struct Vec<T> {}
1092 fn foo(xs: Ve$0<i128>)
1093 "#,
1094             r#"
1095 struct Vec<T> {}
1096 fn foo(xs: Vec<i128>)
1097 "#,
1098         );
1099     }
1100
1101     #[test]
1102     fn active_param_relevance() {
1103         check_relevance(
1104             r#"
1105 struct S { foo: i64, bar: u32, baz: u32 }
1106 fn test(bar: u32) { }
1107 fn foo(s: S) { test(s.$0) }
1108 "#,
1109             expect![[r#"
1110                 fd bar [type+name]
1111                 fd baz [type]
1112                 fd foo []
1113             "#]],
1114         );
1115     }
1116
1117     #[test]
1118     fn record_field_relevances() {
1119         check_relevance(
1120             r#"
1121 struct A { foo: i64, bar: u32, baz: u32 }
1122 struct B { x: (), y: f32, bar: u32 }
1123 fn foo(a: A) { B { bar: a.$0 }; }
1124 "#,
1125             expect![[r#"
1126                 fd bar [type+name]
1127                 fd baz [type]
1128                 fd foo []
1129             "#]],
1130         )
1131     }
1132
1133     #[test]
1134     fn record_field_and_call_relevances() {
1135         check_relevance(
1136             r#"
1137 struct A { foo: i64, bar: u32, baz: u32 }
1138 struct B { x: (), y: f32, bar: u32 }
1139 fn f(foo: i64) {  }
1140 fn foo(a: A) { B { bar: f(a.$0) }; }
1141 "#,
1142             expect![[r#"
1143                 fd foo [type+name]
1144                 fd bar []
1145                 fd baz []
1146             "#]],
1147         );
1148         check_relevance(
1149             r#"
1150 struct A { foo: i64, bar: u32, baz: u32 }
1151 struct B { x: (), y: f32, bar: u32 }
1152 fn f(foo: i64) {  }
1153 fn foo(a: A) { f(B { bar: a.$0 }); }
1154 "#,
1155             expect![[r#"
1156                 fd bar [type+name]
1157                 fd baz [type]
1158                 fd foo []
1159             "#]],
1160         );
1161     }
1162
1163     #[test]
1164     fn prioritize_exact_ref_match() {
1165         check_relevance(
1166             r#"
1167 struct WorldSnapshot { _f: () };
1168 fn go(world: &WorldSnapshot) { go(w$0) }
1169 "#,
1170             expect![[r#"
1171                 lc world [type+name+local]
1172                 st WorldSnapshot {…} []
1173                 st &WorldSnapshot {…} [type]
1174                 st WorldSnapshot []
1175                 fn go(…) []
1176             "#]],
1177         );
1178     }
1179
1180     #[test]
1181     fn too_many_arguments() {
1182         cov_mark::check!(too_many_arguments);
1183         check_relevance(
1184             r#"
1185 struct Foo;
1186 fn f(foo: &Foo) { f(foo, w$0) }
1187 "#,
1188             expect![[r#"
1189                 lc foo [local]
1190                 st Foo []
1191                 fn f(…) []
1192             "#]],
1193         );
1194     }
1195
1196     #[test]
1197     fn score_fn_type_and_name_match() {
1198         check_relevance(
1199             r#"
1200 struct A { bar: u8 }
1201 fn baz() -> u8 { 0 }
1202 fn bar() -> u8 { 0 }
1203 fn f() { A { bar: b$0 }; }
1204 "#,
1205             expect![[r#"
1206                 fn bar() [type+name]
1207                 fn baz() [type]
1208                 st A []
1209                 fn f() []
1210             "#]],
1211         );
1212     }
1213
1214     #[test]
1215     fn score_method_type_and_name_match() {
1216         check_relevance(
1217             r#"
1218 fn baz(aaa: u32){}
1219 struct Foo;
1220 impl Foo {
1221 fn aaa(&self) -> u32 { 0 }
1222 fn bbb(&self) -> u32 { 0 }
1223 fn ccc(&self) -> u64 { 0 }
1224 }
1225 fn f() {
1226     baz(Foo.$0
1227 }
1228 "#,
1229             expect![[r#"
1230                 me aaa() [type+name]
1231                 me bbb() [type]
1232                 me ccc() []
1233             "#]],
1234         );
1235     }
1236
1237     #[test]
1238     fn score_method_name_match_only() {
1239         check_relevance(
1240             r#"
1241 fn baz(aaa: u32){}
1242 struct Foo;
1243 impl Foo {
1244 fn aaa(&self) -> u64 { 0 }
1245 }
1246 fn f() {
1247     baz(Foo.$0
1248 }
1249 "#,
1250             expect![[r#"
1251                 me aaa() [name]
1252             "#]],
1253         );
1254     }
1255
1256     #[test]
1257     fn suggest_ref_mut() {
1258         cov_mark::check!(suggest_ref);
1259         check_relevance(
1260             r#"
1261 struct S;
1262 fn foo(s: &mut S) {}
1263 fn main() {
1264     let mut s = S;
1265     foo($0);
1266 }
1267             "#,
1268             expect![[r#"
1269                 lc s [name+local]
1270                 lc &mut s [type+name+local]
1271                 st S []
1272                 st &mut S [type]
1273                 st S []
1274                 fn main() []
1275                 fn foo(…) []
1276             "#]],
1277         );
1278         check_relevance(
1279             r#"
1280 struct S;
1281 fn foo(s: &mut S) {}
1282 fn main() {
1283     let mut s = S;
1284     foo(&mut $0);
1285 }
1286             "#,
1287             expect![[r#"
1288                 lc s [type+name+local]
1289                 st S [type]
1290                 st S []
1291                 fn main() []
1292                 fn foo(…) []
1293             "#]],
1294         );
1295         check_relevance(
1296             r#"
1297 struct S;
1298 fn foo(s: &mut S) {}
1299 fn main() {
1300     let mut ssss = S;
1301     foo(&mut s$0);
1302 }
1303             "#,
1304             expect![[r#"
1305                 lc ssss [type+local]
1306                 st S [type]
1307                 st S []
1308                 fn main() []
1309                 fn foo(…) []
1310             "#]],
1311         );
1312     }
1313
1314     #[test]
1315     fn suggest_deref() {
1316         check_relevance(
1317             r#"
1318 //- minicore: deref
1319 struct S;
1320 struct T(S);
1321
1322 impl core::ops::Deref for T {
1323     type Target = S;
1324
1325     fn deref(&self) -> &Self::Target {
1326         &self.0
1327     }
1328 }
1329
1330 fn foo(s: &S) {}
1331
1332 fn main() {
1333     let t = T(S);
1334     let m = 123;
1335
1336     foo($0);
1337 }
1338             "#,
1339             expect![[r#"
1340                 lc m [local]
1341                 lc t [local]
1342                 lc &t [type+local]
1343                 st S []
1344                 st &S [type]
1345                 st T []
1346                 st S []
1347                 fn main() []
1348                 fn foo(…) []
1349                 md core []
1350                 tt Sized []
1351             "#]],
1352         )
1353     }
1354
1355     #[test]
1356     fn suggest_deref_mut() {
1357         check_relevance(
1358             r#"
1359 //- minicore: deref_mut
1360 struct S;
1361 struct T(S);
1362
1363 impl core::ops::Deref for T {
1364     type Target = S;
1365
1366     fn deref(&self) -> &Self::Target {
1367         &self.0
1368     }
1369 }
1370
1371 impl core::ops::DerefMut for T {
1372     fn deref_mut(&mut self) -> &mut Self::Target {
1373         &mut self.0
1374     }
1375 }
1376
1377 fn foo(s: &mut S) {}
1378
1379 fn main() {
1380     let t = T(S);
1381     let m = 123;
1382
1383     foo($0);
1384 }
1385             "#,
1386             expect![[r#"
1387                 lc m [local]
1388                 lc t [local]
1389                 lc &mut t [type+local]
1390                 st S []
1391                 st &mut S [type]
1392                 st T []
1393                 st S []
1394                 fn main() []
1395                 fn foo(…) []
1396                 md core []
1397                 tt Sized []
1398             "#]],
1399         )
1400     }
1401
1402     #[test]
1403     fn locals() {
1404         check_relevance(
1405             r#"
1406 fn foo(bar: u32) {
1407     let baz = 0;
1408
1409     f$0
1410 }
1411 "#,
1412             expect![[r#"
1413                 lc baz [local]
1414                 lc bar [local]
1415                 fn foo(…) []
1416             "#]],
1417         );
1418     }
1419
1420     #[test]
1421     fn enum_owned() {
1422         check_relevance(
1423             r#"
1424 enum Foo { A, B }
1425 fn foo() {
1426     bar($0);
1427 }
1428 fn bar(t: Foo) {}
1429 "#,
1430             expect![[r#"
1431                 ev Foo::A [type]
1432                 ev Foo::B [type]
1433                 en Foo []
1434                 fn bar(…) []
1435                 fn foo() []
1436             "#]],
1437         );
1438     }
1439
1440     #[test]
1441     fn enum_ref() {
1442         check_relevance(
1443             r#"
1444 enum Foo { A, B }
1445 fn foo() {
1446     bar($0);
1447 }
1448 fn bar(t: &Foo) {}
1449 "#,
1450             expect![[r#"
1451                 ev Foo::A []
1452                 ev &Foo::A [type]
1453                 ev Foo::B []
1454                 ev &Foo::B [type]
1455                 en Foo []
1456                 fn bar(…) []
1457                 fn foo() []
1458             "#]],
1459         );
1460     }
1461
1462     #[test]
1463     fn suggest_deref_fn_ret() {
1464         check_relevance(
1465             r#"
1466 //- minicore: deref
1467 struct S;
1468 struct T(S);
1469
1470 impl core::ops::Deref for T {
1471     type Target = S;
1472
1473     fn deref(&self) -> &Self::Target {
1474         &self.0
1475     }
1476 }
1477
1478 fn foo(s: &S) {}
1479 fn bar() -> T {}
1480
1481 fn main() {
1482     foo($0);
1483 }
1484 "#,
1485             expect![[r#"
1486                 st S []
1487                 st &S [type]
1488                 st T []
1489                 st S []
1490                 fn main() []
1491                 fn bar() []
1492                 fn &bar() [type]
1493                 fn foo(…) []
1494                 md core []
1495                 tt Sized []
1496             "#]],
1497         )
1498     }
1499
1500     #[test]
1501     fn op_function_relevances() {
1502         check_relevance(
1503             r#"
1504 #[lang = "sub"]
1505 trait Sub {
1506     fn sub(self, other: Self) -> Self { self }
1507 }
1508 impl Sub for u32 {}
1509 fn foo(a: u32) { a.$0 }
1510 "#,
1511             expect![[r#"
1512                 me sub(…) (as Sub) [op_method]
1513             "#]],
1514         );
1515         check_relevance(
1516             r#"
1517 struct Foo;
1518 impl Foo {
1519     fn new() -> Self {}
1520 }
1521 #[lang = "eq"]
1522 pub trait PartialEq<Rhs: ?Sized = Self> {
1523     fn eq(&self, other: &Rhs) -> bool;
1524     fn ne(&self, other: &Rhs) -> bool;
1525 }
1526
1527 impl PartialEq for Foo {}
1528 fn main() {
1529     Foo::$0
1530 }
1531 "#,
1532             expect![[r#"
1533                 fn new() []
1534                 me eq(…) (as PartialEq) [op_method]
1535                 me ne(…) (as PartialEq) [op_method]
1536             "#]],
1537         );
1538     }
1539
1540     #[test]
1541     fn struct_field_method_ref() {
1542         check_kinds(
1543             r#"
1544 struct Foo { bar: u32 }
1545 impl Foo { fn baz(&self) -> u32 { 0 } }
1546
1547 fn foo(f: Foo) { let _: &u32 = f.b$0 }
1548 "#,
1549             &[CompletionItemKind::Method, CompletionItemKind::SymbolKind(SymbolKind::Field)],
1550             expect![[r#"
1551                 [
1552                     CompletionItem {
1553                         label: "baz()",
1554                         source_range: 98..99,
1555                         delete: 98..99,
1556                         insert: "baz()$0",
1557                         kind: Method,
1558                         lookup: "baz",
1559                         detail: "fn(&self) -> u32",
1560                         ref_match: "&@96",
1561                     },
1562                     CompletionItem {
1563                         label: "bar",
1564                         source_range: 98..99,
1565                         delete: 98..99,
1566                         insert: "bar",
1567                         kind: SymbolKind(
1568                             Field,
1569                         ),
1570                         detail: "u32",
1571                         ref_match: "&@96",
1572                     },
1573                 ]
1574             "#]],
1575         );
1576     }
1577
1578     #[test]
1579     fn qualified_path_ref() {
1580         check_kinds(
1581             r#"
1582 struct S;
1583
1584 struct T;
1585 impl T {
1586     fn foo() -> S {}
1587 }
1588
1589 fn bar(s: &S) {}
1590
1591 fn main() {
1592     bar(T::$0);
1593 }
1594 "#,
1595             &[CompletionItemKind::SymbolKind(SymbolKind::Function)],
1596             expect![[r#"
1597                 [
1598                     CompletionItem {
1599                         label: "foo()",
1600                         source_range: 95..95,
1601                         delete: 95..95,
1602                         insert: "foo()$0",
1603                         kind: SymbolKind(
1604                             Function,
1605                         ),
1606                         lookup: "foo",
1607                         detail: "fn() -> S",
1608                         ref_match: "&@92",
1609                     },
1610                 ]
1611             "#]],
1612         );
1613     }
1614
1615     #[test]
1616     fn generic_enum() {
1617         check_relevance(
1618             r#"
1619 enum Foo<T> { A(T), B }
1620 // bar() should not be an exact type match
1621 // because the generic parameters are different
1622 fn bar() -> Foo<u8> { Foo::B }
1623 // FIXME baz() should be an exact type match
1624 // because the types could unify, but it currently
1625 // is not. This is due to the T here being
1626 // TyKind::Placeholder rather than TyKind::Missing.
1627 fn baz<T>() -> Foo<T> { Foo::B }
1628 fn foo() {
1629     let foo: Foo<u32> = Foo::B;
1630     let _: Foo<u32> = f$0;
1631 }
1632 "#,
1633             expect![[r#"
1634                 lc foo [type+local]
1635                 ev Foo::A(…) [type_could_unify]
1636                 ev Foo::B [type_could_unify]
1637                 fn foo() []
1638                 en Foo []
1639                 fn baz() []
1640                 fn bar() []
1641             "#]],
1642         );
1643     }
1644
1645     #[test]
1646     fn postfix_exact_match_is_high_priority() {
1647         cov_mark::check!(postfix_exact_match_is_high_priority);
1648         check_relevance_for_kinds(
1649             r#"
1650 mod ops {
1651     pub trait Not {
1652         type Output;
1653         fn not(self) -> Self::Output;
1654     }
1655
1656     impl Not for bool {
1657         type Output = bool;
1658         fn not(self) -> bool { if self { false } else { true }}
1659     }
1660 }
1661
1662 fn main() {
1663     let _: bool = (9 > 2).not$0;
1664 }
1665     "#,
1666             &[CompletionItemKind::Snippet, CompletionItemKind::Method],
1667             expect![[r#"
1668                 sn not [snippet]
1669                 me not() (use ops::Not) [type_could_unify+requires_import]
1670                 sn if []
1671                 sn while []
1672                 sn ref []
1673                 sn refm []
1674                 sn match []
1675                 sn box []
1676                 sn dbg []
1677                 sn dbgr []
1678                 sn call []
1679             "#]],
1680         );
1681     }
1682
1683     #[test]
1684     fn postfix_inexact_match_is_low_priority() {
1685         cov_mark::check!(postfix_inexact_match_is_low_priority);
1686         check_relevance_for_kinds(
1687             r#"
1688 struct S;
1689 impl S {
1690     fn f(&self) {}
1691 }
1692 fn main() {
1693     S.$0
1694 }
1695     "#,
1696             &[CompletionItemKind::Snippet, CompletionItemKind::Method],
1697             expect![[r#"
1698                 me f() []
1699                 sn ref []
1700                 sn refm []
1701                 sn match []
1702                 sn box []
1703                 sn dbg []
1704                 sn dbgr []
1705                 sn call []
1706                 sn let []
1707                 sn letm []
1708             "#]],
1709         );
1710     }
1711
1712     #[test]
1713     fn flyimport_reduced_relevance() {
1714         check_relevance(
1715             r#"
1716 mod std {
1717     pub mod io {
1718         pub trait BufRead {}
1719         pub struct BufReader;
1720         pub struct BufWriter;
1721     }
1722 }
1723 struct Buffer;
1724
1725 fn f() {
1726     Buf$0
1727 }
1728 "#,
1729             expect![[r#"
1730                 md std []
1731                 st Buffer []
1732                 fn f() []
1733                 tt BufRead (use std::io::BufRead) [requires_import]
1734                 st BufReader (use std::io::BufReader) [requires_import]
1735                 st BufWriter (use std::io::BufWriter) [requires_import]
1736             "#]],
1737         );
1738     }
1739
1740     #[test]
1741     fn completes_struct_with_raw_identifier() {
1742         check_edit(
1743             "type",
1744             r#"
1745 mod m { pub struct r#type {} }
1746 fn main() {
1747     let r#type = m::t$0;
1748 }
1749 "#,
1750             r#"
1751 mod m { pub struct r#type {} }
1752 fn main() {
1753     let r#type = m::r#type;
1754 }
1755 "#,
1756         )
1757     }
1758
1759     #[test]
1760     fn completes_fn_with_raw_identifier() {
1761         check_edit(
1762             "type",
1763             r#"
1764 mod m { pub fn r#type {} }
1765 fn main() {
1766     m::t$0
1767 }
1768 "#,
1769             r#"
1770 mod m { pub fn r#type {} }
1771 fn main() {
1772     m::r#type()$0
1773 }
1774 "#,
1775         )
1776     }
1777
1778     #[test]
1779     fn completes_macro_with_raw_identifier() {
1780         check_edit(
1781             "let!",
1782             r#"
1783 macro_rules! r#let { () => {} }
1784 fn main() {
1785     $0
1786 }
1787 "#,
1788             r#"
1789 macro_rules! r#let { () => {} }
1790 fn main() {
1791     r#let!($0)
1792 }
1793 "#,
1794         )
1795     }
1796
1797     #[test]
1798     fn completes_variant_with_raw_identifier() {
1799         check_edit(
1800             "type",
1801             r#"
1802 enum A { r#type }
1803 fn main() {
1804     let a = A::t$0
1805 }
1806 "#,
1807             r#"
1808 enum A { r#type }
1809 fn main() {
1810     let a = A::r#type$0
1811 }
1812 "#,
1813         )
1814     }
1815
1816     #[test]
1817     fn completes_field_with_raw_identifier() {
1818         check_edit(
1819             "fn",
1820             r#"
1821 mod r#type {
1822     pub struct r#struct {
1823         pub r#fn: u32
1824     }
1825 }
1826
1827 fn main() {
1828     let a = r#type::r#struct {};
1829     a.$0
1830 }
1831 "#,
1832             r#"
1833 mod r#type {
1834     pub struct r#struct {
1835         pub r#fn: u32
1836     }
1837 }
1838
1839 fn main() {
1840     let a = r#type::r#struct {};
1841     a.r#fn
1842 }
1843 "#,
1844         )
1845     }
1846
1847     #[test]
1848     fn completes_const_with_raw_identifier() {
1849         check_edit(
1850             "type",
1851             r#"
1852 struct r#struct {}
1853 impl r#struct { pub const r#type: u8 = 1; }
1854 fn main() {
1855     r#struct::t$0
1856 }
1857 "#,
1858             r#"
1859 struct r#struct {}
1860 impl r#struct { pub const r#type: u8 = 1; }
1861 fn main() {
1862     r#struct::r#type
1863 }
1864 "#,
1865         )
1866     }
1867
1868     #[test]
1869     fn completes_type_alias_with_raw_identifier() {
1870         check_edit(
1871             "type type",
1872             r#"
1873 struct r#struct {}
1874 trait r#trait { type r#type; }
1875 impl r#trait for r#struct { type t$0 }
1876 "#,
1877             r#"
1878 struct r#struct {}
1879 trait r#trait { type r#type; }
1880 impl r#trait for r#struct { type r#type = $0; }
1881 "#,
1882         )
1883     }
1884
1885     #[test]
1886     fn field_access_includes_self() {
1887         check_edit(
1888             "length",
1889             r#"
1890 struct S {
1891     length: i32
1892 }
1893
1894 impl S {
1895     fn some_fn(&self) {
1896         let l = len$0
1897     }
1898 }
1899 "#,
1900             r#"
1901 struct S {
1902     length: i32
1903 }
1904
1905 impl S {
1906     fn some_fn(&self) {
1907         let l = self.length
1908     }
1909 }
1910 "#,
1911         )
1912     }
1913 }