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