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