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