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