]> git.lizzy.rs Git - rust.git/blob - crates/ide-completion/src/render.rs
fix: format literal lookup
[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                         lookup: "Foo{}",
569                         detail: "Foo { x: i32, y: i32 }",
570                     },
571                 ]
572             "#]],
573         );
574     }
575
576     #[test]
577     fn enum_detail_includes_tuple_fields() {
578         check(
579             r#"
580 enum Foo { Foo (i32, i32) }
581
582 fn main() { Foo::Fo$0 }
583 "#,
584             SymbolKind::Variant,
585             expect![[r#"
586                 [
587                     CompletionItem {
588                         label: "Foo(…)",
589                         source_range: 46..48,
590                         delete: 46..48,
591                         insert: "Foo(${1:()}, ${2:()})$0",
592                         kind: SymbolKind(
593                             Variant,
594                         ),
595                         lookup: "Foo()",
596                         detail: "Foo(i32, i32)",
597                     },
598                 ]
599             "#]],
600         );
601     }
602
603     #[test]
604     fn fn_detail_includes_args_and_return_type() {
605         check(
606             r#"
607 fn foo<T>(a: u32, b: u32, t: T) -> (u32, T) { (a, t) }
608
609 fn main() { fo$0 }
610 "#,
611             SymbolKind::Function,
612             expect![[r#"
613                 [
614                     CompletionItem {
615                         label: "foo(…)",
616                         source_range: 68..70,
617                         delete: 68..70,
618                         insert: "foo(${1:a}, ${2:b}, ${3:t})$0",
619                         kind: SymbolKind(
620                             Function,
621                         ),
622                         lookup: "foo",
623                         detail: "fn(u32, u32, T) -> (u32, T)",
624                         trigger_call_info: true,
625                     },
626                     CompletionItem {
627                         label: "main()",
628                         source_range: 68..70,
629                         delete: 68..70,
630                         insert: "main()$0",
631                         kind: SymbolKind(
632                             Function,
633                         ),
634                         lookup: "main",
635                         detail: "fn()",
636                     },
637                 ]
638             "#]],
639         );
640     }
641
642     #[test]
643     fn enum_detail_just_name_for_unit() {
644         check(
645             r#"
646 enum Foo { Foo }
647
648 fn main() { Foo::Fo$0 }
649 "#,
650             SymbolKind::Variant,
651             expect![[r#"
652                 [
653                     CompletionItem {
654                         label: "Foo",
655                         source_range: 35..37,
656                         delete: 35..37,
657                         insert: "Foo$0",
658                         kind: SymbolKind(
659                             Variant,
660                         ),
661                         detail: "Foo",
662                     },
663                 ]
664             "#]],
665         );
666     }
667
668     #[test]
669     fn lookup_enums_by_two_qualifiers() {
670         check_kinds(
671             r#"
672 mod m {
673     pub enum Spam { Foo, Bar(i32) }
674 }
675 fn main() { let _: m::Spam = S$0 }
676 "#,
677             &[
678                 CompletionItemKind::SymbolKind(SymbolKind::Function),
679                 CompletionItemKind::SymbolKind(SymbolKind::Module),
680                 CompletionItemKind::SymbolKind(SymbolKind::Variant),
681             ],
682             expect![[r#"
683                 [
684                     CompletionItem {
685                         label: "main()",
686                         source_range: 75..76,
687                         delete: 75..76,
688                         insert: "main()$0",
689                         kind: SymbolKind(
690                             Function,
691                         ),
692                         lookup: "main",
693                         detail: "fn()",
694                     },
695                     CompletionItem {
696                         label: "m",
697                         source_range: 75..76,
698                         delete: 75..76,
699                         insert: "m",
700                         kind: SymbolKind(
701                             Module,
702                         ),
703                     },
704                     CompletionItem {
705                         label: "m::Spam::Bar(…)",
706                         source_range: 75..76,
707                         delete: 75..76,
708                         insert: "m::Spam::Bar(${1:()})$0",
709                         kind: SymbolKind(
710                             Variant,
711                         ),
712                         lookup: "Spam::Bar()",
713                         detail: "m::Spam::Bar(i32)",
714                         relevance: CompletionRelevance {
715                             exact_name_match: false,
716                             type_match: Some(
717                                 Exact,
718                             ),
719                             is_local: false,
720                             is_item_from_trait: false,
721                             is_name_already_imported: false,
722                             requires_import: false,
723                             is_op_method: false,
724                             is_private_editable: false,
725                             postfix_match: None,
726                             is_definite: false,
727                         },
728                     },
729                     CompletionItem {
730                         label: "m::Spam::Foo",
731                         source_range: 75..76,
732                         delete: 75..76,
733                         insert: "m::Spam::Foo$0",
734                         kind: SymbolKind(
735                             Variant,
736                         ),
737                         lookup: "Spam::Foo",
738                         detail: "m::Spam::Foo",
739                         relevance: CompletionRelevance {
740                             exact_name_match: false,
741                             type_match: Some(
742                                 Exact,
743                             ),
744                             is_local: false,
745                             is_item_from_trait: false,
746                             is_name_already_imported: false,
747                             requires_import: false,
748                             is_op_method: false,
749                             is_private_editable: false,
750                             postfix_match: None,
751                             is_definite: false,
752                         },
753                     },
754                 ]
755             "#]],
756         )
757     }
758
759     #[test]
760     fn sets_deprecated_flag_in_items() {
761         check(
762             r#"
763 #[deprecated]
764 fn something_deprecated() {}
765
766 fn main() { som$0 }
767 "#,
768             SymbolKind::Function,
769             expect![[r#"
770                 [
771                     CompletionItem {
772                         label: "main()",
773                         source_range: 56..59,
774                         delete: 56..59,
775                         insert: "main()$0",
776                         kind: SymbolKind(
777                             Function,
778                         ),
779                         lookup: "main",
780                         detail: "fn()",
781                     },
782                     CompletionItem {
783                         label: "something_deprecated()",
784                         source_range: 56..59,
785                         delete: 56..59,
786                         insert: "something_deprecated()$0",
787                         kind: SymbolKind(
788                             Function,
789                         ),
790                         lookup: "something_deprecated",
791                         detail: "fn()",
792                         deprecated: true,
793                     },
794                 ]
795             "#]],
796         );
797
798         check(
799             r#"
800 struct A { #[deprecated] the_field: u32 }
801 fn foo() { A { the$0 } }
802 "#,
803             SymbolKind::Field,
804             expect![[r#"
805                 [
806                     CompletionItem {
807                         label: "the_field",
808                         source_range: 57..60,
809                         delete: 57..60,
810                         insert: "the_field",
811                         kind: SymbolKind(
812                             Field,
813                         ),
814                         detail: "u32",
815                         deprecated: true,
816                         relevance: CompletionRelevance {
817                             exact_name_match: false,
818                             type_match: Some(
819                                 CouldUnify,
820                             ),
821                             is_local: false,
822                             is_item_from_trait: false,
823                             is_name_already_imported: false,
824                             requires_import: false,
825                             is_op_method: false,
826                             is_private_editable: false,
827                             postfix_match: None,
828                             is_definite: false,
829                         },
830                     },
831                 ]
832             "#]],
833         );
834     }
835
836     #[test]
837     fn renders_docs() {
838         check_kinds(
839             r#"
840 struct S {
841     /// Field docs
842     foo:
843 }
844 impl S {
845     /// Method docs
846     fn bar(self) { self.$0 }
847 }"#,
848             &[CompletionItemKind::Method, CompletionItemKind::SymbolKind(SymbolKind::Field)],
849             expect![[r#"
850                 [
851                     CompletionItem {
852                         label: "bar()",
853                         source_range: 94..94,
854                         delete: 94..94,
855                         insert: "bar()$0",
856                         kind: Method,
857                         lookup: "bar",
858                         detail: "fn(self)",
859                         documentation: Documentation(
860                             "Method docs",
861                         ),
862                     },
863                     CompletionItem {
864                         label: "foo",
865                         source_range: 94..94,
866                         delete: 94..94,
867                         insert: "foo",
868                         kind: SymbolKind(
869                             Field,
870                         ),
871                         detail: "{unknown}",
872                         documentation: Documentation(
873                             "Field docs",
874                         ),
875                     },
876                 ]
877             "#]],
878         );
879
880         check_kinds(
881             r#"
882 use self::my$0;
883
884 /// mod docs
885 mod my { }
886
887 /// enum docs
888 enum E {
889     /// variant docs
890     V
891 }
892 use self::E::*;
893 "#,
894             &[
895                 CompletionItemKind::SymbolKind(SymbolKind::Module),
896                 CompletionItemKind::SymbolKind(SymbolKind::Variant),
897                 CompletionItemKind::SymbolKind(SymbolKind::Enum),
898             ],
899             expect![[r#"
900                 [
901                     CompletionItem {
902                         label: "my",
903                         source_range: 10..12,
904                         delete: 10..12,
905                         insert: "my",
906                         kind: SymbolKind(
907                             Module,
908                         ),
909                         documentation: Documentation(
910                             "mod docs",
911                         ),
912                     },
913                     CompletionItem {
914                         label: "V",
915                         source_range: 10..12,
916                         delete: 10..12,
917                         insert: "V$0",
918                         kind: SymbolKind(
919                             Variant,
920                         ),
921                         detail: "V",
922                         documentation: Documentation(
923                             "variant docs",
924                         ),
925                     },
926                     CompletionItem {
927                         label: "E",
928                         source_range: 10..12,
929                         delete: 10..12,
930                         insert: "E",
931                         kind: SymbolKind(
932                             Enum,
933                         ),
934                         documentation: Documentation(
935                             "enum docs",
936                         ),
937                     },
938                 ]
939             "#]],
940         )
941     }
942
943     #[test]
944     fn dont_render_attrs() {
945         check(
946             r#"
947 struct S;
948 impl S {
949     #[inline]
950     fn the_method(&self) { }
951 }
952 fn foo(s: S) { s.$0 }
953 "#,
954             CompletionItemKind::Method,
955             expect![[r#"
956                 [
957                     CompletionItem {
958                         label: "the_method()",
959                         source_range: 81..81,
960                         delete: 81..81,
961                         insert: "the_method()$0",
962                         kind: Method,
963                         lookup: "the_method",
964                         detail: "fn(&self)",
965                     },
966                 ]
967             "#]],
968         )
969     }
970
971     #[test]
972     fn no_call_parens_if_fn_ptr_needed() {
973         cov_mark::check!(no_call_parens_if_fn_ptr_needed);
974         check_edit(
975             "foo",
976             r#"
977 fn foo(foo: u8, bar: u8) {}
978 struct ManualVtable { f: fn(u8, u8) }
979
980 fn main() -> ManualVtable {
981     ManualVtable { f: f$0 }
982 }
983 "#,
984             r#"
985 fn foo(foo: u8, bar: u8) {}
986 struct ManualVtable { f: fn(u8, u8) }
987
988 fn main() -> ManualVtable {
989     ManualVtable { f: foo }
990 }
991 "#,
992         );
993         check_edit(
994             "type",
995             r#"
996 struct RawIdentTable { r#type: u32 }
997
998 fn main() -> RawIdentTable {
999     RawIdentTable { t$0: 42 }
1000 }
1001 "#,
1002             r#"
1003 struct RawIdentTable { r#type: u32 }
1004
1005 fn main() -> RawIdentTable {
1006     RawIdentTable { r#type: 42 }
1007 }
1008 "#,
1009         );
1010     }
1011
1012     #[test]
1013     fn no_parens_in_use_item() {
1014         check_edit(
1015             "foo",
1016             r#"
1017 mod m { pub fn foo() {} }
1018 use crate::m::f$0;
1019 "#,
1020             r#"
1021 mod m { pub fn foo() {} }
1022 use crate::m::foo;
1023 "#,
1024         );
1025     }
1026
1027     #[test]
1028     fn no_parens_in_call() {
1029         check_edit(
1030             "foo",
1031             r#"
1032 fn foo(x: i32) {}
1033 fn main() { f$0(); }
1034 "#,
1035             r#"
1036 fn foo(x: i32) {}
1037 fn main() { foo(); }
1038 "#,
1039         );
1040         check_edit(
1041             "foo",
1042             r#"
1043 struct Foo;
1044 impl Foo { fn foo(&self){} }
1045 fn f(foo: &Foo) { foo.f$0(); }
1046 "#,
1047             r#"
1048 struct Foo;
1049 impl Foo { fn foo(&self){} }
1050 fn f(foo: &Foo) { foo.foo(); }
1051 "#,
1052         );
1053     }
1054
1055     #[test]
1056     fn inserts_angle_brackets_for_generics() {
1057         cov_mark::check!(inserts_angle_brackets_for_generics);
1058         check_edit(
1059             "Vec",
1060             r#"
1061 struct Vec<T> {}
1062 fn foo(xs: Ve$0)
1063 "#,
1064             r#"
1065 struct Vec<T> {}
1066 fn foo(xs: Vec<$0>)
1067 "#,
1068         );
1069         check_edit(
1070             "Vec",
1071             r#"
1072 type Vec<T> = (T,);
1073 fn foo(xs: Ve$0)
1074 "#,
1075             r#"
1076 type Vec<T> = (T,);
1077 fn foo(xs: Vec<$0>)
1078 "#,
1079         );
1080         check_edit(
1081             "Vec",
1082             r#"
1083 struct Vec<T = i128> {}
1084 fn foo(xs: Ve$0)
1085 "#,
1086             r#"
1087 struct Vec<T = i128> {}
1088 fn foo(xs: Vec)
1089 "#,
1090         );
1091         check_edit(
1092             "Vec",
1093             r#"
1094 struct Vec<T> {}
1095 fn foo(xs: Ve$0<i128>)
1096 "#,
1097             r#"
1098 struct Vec<T> {}
1099 fn foo(xs: Vec<i128>)
1100 "#,
1101         );
1102     }
1103
1104     #[test]
1105     fn active_param_relevance() {
1106         check_relevance(
1107             r#"
1108 struct S { foo: i64, bar: u32, baz: u32 }
1109 fn test(bar: u32) { }
1110 fn foo(s: S) { test(s.$0) }
1111 "#,
1112             expect![[r#"
1113                 fd bar [type+name]
1114                 fd baz [type]
1115                 fd foo []
1116             "#]],
1117         );
1118     }
1119
1120     #[test]
1121     fn record_field_relevances() {
1122         check_relevance(
1123             r#"
1124 struct A { foo: i64, bar: u32, baz: u32 }
1125 struct B { x: (), y: f32, bar: u32 }
1126 fn foo(a: A) { B { bar: a.$0 }; }
1127 "#,
1128             expect![[r#"
1129                 fd bar [type+name]
1130                 fd baz [type]
1131                 fd foo []
1132             "#]],
1133         )
1134     }
1135
1136     #[test]
1137     fn record_field_and_call_relevances() {
1138         check_relevance(
1139             r#"
1140 struct A { foo: i64, bar: u32, baz: u32 }
1141 struct B { x: (), y: f32, bar: u32 }
1142 fn f(foo: i64) {  }
1143 fn foo(a: A) { B { bar: f(a.$0) }; }
1144 "#,
1145             expect![[r#"
1146                 fd foo [type+name]
1147                 fd bar []
1148                 fd baz []
1149             "#]],
1150         );
1151         check_relevance(
1152             r#"
1153 struct A { foo: i64, bar: u32, baz: u32 }
1154 struct B { x: (), y: f32, bar: u32 }
1155 fn f(foo: i64) {  }
1156 fn foo(a: A) { f(B { bar: a.$0 }); }
1157 "#,
1158             expect![[r#"
1159                 fd bar [type+name]
1160                 fd baz [type]
1161                 fd foo []
1162             "#]],
1163         );
1164     }
1165
1166     #[test]
1167     fn prioritize_exact_ref_match() {
1168         check_relevance(
1169             r#"
1170 struct WorldSnapshot { _f: () };
1171 fn go(world: &WorldSnapshot) { go(w$0) }
1172 "#,
1173             expect![[r#"
1174                 lc world [type+name+local]
1175                 st WorldSnapshot {…} []
1176                 st &WorldSnapshot {…} [type]
1177                 st WorldSnapshot []
1178                 fn go(…) []
1179             "#]],
1180         );
1181     }
1182
1183     #[test]
1184     fn too_many_arguments() {
1185         cov_mark::check!(too_many_arguments);
1186         check_relevance(
1187             r#"
1188 struct Foo;
1189 fn f(foo: &Foo) { f(foo, w$0) }
1190 "#,
1191             expect![[r#"
1192                 lc foo [local]
1193                 st Foo []
1194                 fn f(…) []
1195             "#]],
1196         );
1197     }
1198
1199     #[test]
1200     fn score_fn_type_and_name_match() {
1201         check_relevance(
1202             r#"
1203 struct A { bar: u8 }
1204 fn baz() -> u8 { 0 }
1205 fn bar() -> u8 { 0 }
1206 fn f() { A { bar: b$0 }; }
1207 "#,
1208             expect![[r#"
1209                 fn bar() [type+name]
1210                 fn baz() [type]
1211                 st A []
1212                 fn f() []
1213             "#]],
1214         );
1215     }
1216
1217     #[test]
1218     fn score_method_type_and_name_match() {
1219         check_relevance(
1220             r#"
1221 fn baz(aaa: u32){}
1222 struct Foo;
1223 impl Foo {
1224 fn aaa(&self) -> u32 { 0 }
1225 fn bbb(&self) -> u32 { 0 }
1226 fn ccc(&self) -> u64 { 0 }
1227 }
1228 fn f() {
1229     baz(Foo.$0
1230 }
1231 "#,
1232             expect![[r#"
1233                 me aaa() [type+name]
1234                 me bbb() [type]
1235                 me ccc() []
1236             "#]],
1237         );
1238     }
1239
1240     #[test]
1241     fn score_method_name_match_only() {
1242         check_relevance(
1243             r#"
1244 fn baz(aaa: u32){}
1245 struct Foo;
1246 impl Foo {
1247 fn aaa(&self) -> u64 { 0 }
1248 }
1249 fn f() {
1250     baz(Foo.$0
1251 }
1252 "#,
1253             expect![[r#"
1254                 me aaa() [name]
1255             "#]],
1256         );
1257     }
1258
1259     #[test]
1260     fn suggest_ref_mut() {
1261         cov_mark::check!(suggest_ref);
1262         check_relevance(
1263             r#"
1264 struct S;
1265 fn foo(s: &mut S) {}
1266 fn main() {
1267     let mut s = S;
1268     foo($0);
1269 }
1270             "#,
1271             expect![[r#"
1272                 lc s [name+local]
1273                 lc &mut s [type+name+local]
1274                 st S []
1275                 st &mut S [type]
1276                 st S []
1277                 fn foo(…) []
1278                 fn main() []
1279             "#]],
1280         );
1281         check_relevance(
1282             r#"
1283 struct S;
1284 fn foo(s: &mut S) {}
1285 fn main() {
1286     let mut s = S;
1287     foo(&mut $0);
1288 }
1289             "#,
1290             expect![[r#"
1291                 lc s [type+name+local]
1292                 st S [type]
1293                 st S []
1294                 fn foo(…) []
1295                 fn main() []
1296             "#]],
1297         );
1298         check_relevance(
1299             r#"
1300 struct S;
1301 fn foo(s: &mut S) {}
1302 fn main() {
1303     let mut ssss = S;
1304     foo(&mut s$0);
1305 }
1306             "#,
1307             expect![[r#"
1308                 lc ssss [type+local]
1309                 st S [type]
1310                 st S []
1311                 fn foo(…) []
1312                 fn main() []
1313             "#]],
1314         );
1315     }
1316
1317     #[test]
1318     fn suggest_deref() {
1319         check_relevance(
1320             r#"
1321 //- minicore: deref
1322 struct S;
1323 struct T(S);
1324
1325 impl core::ops::Deref for T {
1326     type Target = S;
1327
1328     fn deref(&self) -> &Self::Target {
1329         &self.0
1330     }
1331 }
1332
1333 fn foo(s: &S) {}
1334
1335 fn main() {
1336     let t = T(S);
1337     let m = 123;
1338
1339     foo($0);
1340 }
1341             "#,
1342             expect![[r#"
1343                 lc m [local]
1344                 lc t [local]
1345                 lc &t [type+local]
1346                 st S []
1347                 st &S [type]
1348                 st S []
1349                 st T []
1350                 fn foo(…) []
1351                 fn main() []
1352                 md core []
1353             "#]],
1354         )
1355     }
1356
1357     #[test]
1358     fn suggest_deref_mut() {
1359         check_relevance(
1360             r#"
1361 //- minicore: deref_mut
1362 struct S;
1363 struct T(S);
1364
1365 impl core::ops::Deref for T {
1366     type Target = S;
1367
1368     fn deref(&self) -> &Self::Target {
1369         &self.0
1370     }
1371 }
1372
1373 impl core::ops::DerefMut for T {
1374     fn deref_mut(&mut self) -> &mut Self::Target {
1375         &mut self.0
1376     }
1377 }
1378
1379 fn foo(s: &mut S) {}
1380
1381 fn main() {
1382     let t = T(S);
1383     let m = 123;
1384
1385     foo($0);
1386 }
1387             "#,
1388             expect![[r#"
1389                 lc m [local]
1390                 lc t [local]
1391                 lc &mut t [type+local]
1392                 st S []
1393                 st &mut S [type]
1394                 st S []
1395                 st T []
1396                 fn foo(…) []
1397                 fn main() []
1398                 md core []
1399             "#]],
1400         )
1401     }
1402
1403     #[test]
1404     fn locals() {
1405         check_relevance(
1406             r#"
1407 fn foo(bar: u32) {
1408     let baz = 0;
1409
1410     f$0
1411 }
1412 "#,
1413             expect![[r#"
1414                 lc baz [local]
1415                 lc bar [local]
1416                 fn foo(…) []
1417             "#]],
1418         );
1419     }
1420
1421     #[test]
1422     fn enum_owned() {
1423         check_relevance(
1424             r#"
1425 enum Foo { A, B }
1426 fn foo() {
1427     bar($0);
1428 }
1429 fn bar(t: Foo) {}
1430 "#,
1431             expect![[r#"
1432                 ev Foo::A [type]
1433                 ev Foo::B [type]
1434                 en Foo []
1435                 fn bar(…) []
1436                 fn foo() []
1437             "#]],
1438         );
1439     }
1440
1441     #[test]
1442     fn enum_ref() {
1443         check_relevance(
1444             r#"
1445 enum Foo { A, B }
1446 fn foo() {
1447     bar($0);
1448 }
1449 fn bar(t: &Foo) {}
1450 "#,
1451             expect![[r#"
1452                 ev Foo::A []
1453                 ev &Foo::A [type]
1454                 ev Foo::B []
1455                 ev &Foo::B [type]
1456                 en Foo []
1457                 fn bar(…) []
1458                 fn foo() []
1459             "#]],
1460         );
1461     }
1462
1463     #[test]
1464     fn suggest_deref_fn_ret() {
1465         check_relevance(
1466             r#"
1467 //- minicore: deref
1468 struct S;
1469 struct T(S);
1470
1471 impl core::ops::Deref for T {
1472     type Target = S;
1473
1474     fn deref(&self) -> &Self::Target {
1475         &self.0
1476     }
1477 }
1478
1479 fn foo(s: &S) {}
1480 fn bar() -> T {}
1481
1482 fn main() {
1483     foo($0);
1484 }
1485 "#,
1486             expect![[r#"
1487                 st S []
1488                 st &S [type]
1489                 st S []
1490                 st T []
1491                 fn bar() []
1492                 fn &bar() [type]
1493                 fn foo(…) []
1494                 fn main() []
1495                 md core []
1496             "#]],
1497         )
1498     }
1499
1500     #[test]
1501     fn op_function_relevances() {
1502         check_relevance(
1503             r#"
1504 #[lang = "sub"]
1505 trait Sub {
1506     fn sub(self, other: Self) -> Self { self }
1507 }
1508 impl Sub for u32 {}
1509 fn foo(a: u32) { a.$0 }
1510 "#,
1511             expect![[r#"
1512                 me sub(…) (as Sub) [op_method]
1513             "#]],
1514         );
1515         check_relevance(
1516             r#"
1517 struct Foo;
1518 impl Foo {
1519     fn new() -> Self {}
1520 }
1521 #[lang = "eq"]
1522 pub trait PartialEq<Rhs: ?Sized = Self> {
1523     fn eq(&self, other: &Rhs) -> bool;
1524     fn ne(&self, other: &Rhs) -> bool;
1525 }
1526
1527 impl PartialEq for Foo {}
1528 fn main() {
1529     Foo::$0
1530 }
1531 "#,
1532             expect![[r#"
1533                 fn new() []
1534                 me eq(…) (as PartialEq) [op_method]
1535                 me ne(…) (as PartialEq) [op_method]
1536             "#]],
1537         );
1538     }
1539
1540     #[test]
1541     fn struct_field_method_ref() {
1542         check_kinds(
1543             r#"
1544 struct Foo { bar: u32 }
1545 impl Foo { fn baz(&self) -> u32 { 0 } }
1546
1547 fn foo(f: Foo) { let _: &u32 = f.b$0 }
1548 "#,
1549             &[CompletionItemKind::Method, CompletionItemKind::SymbolKind(SymbolKind::Field)],
1550             expect![[r#"
1551                 [
1552                     CompletionItem {
1553                         label: "baz()",
1554                         source_range: 98..99,
1555                         delete: 98..99,
1556                         insert: "baz()$0",
1557                         kind: Method,
1558                         lookup: "baz",
1559                         detail: "fn(&self) -> u32",
1560                         ref_match: "&@96",
1561                     },
1562                     CompletionItem {
1563                         label: "bar",
1564                         source_range: 98..99,
1565                         delete: 98..99,
1566                         insert: "bar",
1567                         kind: SymbolKind(
1568                             Field,
1569                         ),
1570                         detail: "u32",
1571                         ref_match: "&@96",
1572                     },
1573                 ]
1574             "#]],
1575         );
1576     }
1577
1578     #[test]
1579     fn qualified_path_ref() {
1580         check_kinds(
1581             r#"
1582 struct S;
1583
1584 struct T;
1585 impl T {
1586     fn foo() -> S {}
1587 }
1588
1589 fn bar(s: &S) {}
1590
1591 fn main() {
1592     bar(T::$0);
1593 }
1594 "#,
1595             &[CompletionItemKind::SymbolKind(SymbolKind::Function)],
1596             expect![[r#"
1597                 [
1598                     CompletionItem {
1599                         label: "foo()",
1600                         source_range: 95..95,
1601                         delete: 95..95,
1602                         insert: "foo()$0",
1603                         kind: SymbolKind(
1604                             Function,
1605                         ),
1606                         lookup: "foo",
1607                         detail: "fn() -> S",
1608                         ref_match: "&@92",
1609                     },
1610                 ]
1611             "#]],
1612         );
1613     }
1614
1615     #[test]
1616     fn generic_enum() {
1617         check_relevance(
1618             r#"
1619 enum Foo<T> { A(T), B }
1620 // bar() should not be an exact type match
1621 // because the generic parameters are different
1622 fn bar() -> Foo<u8> { Foo::B }
1623 // FIXME baz() should be an exact type match
1624 // because the types could unify, but it currently
1625 // is not. This is due to the T here being
1626 // TyKind::Placeholder rather than TyKind::Missing.
1627 fn baz<T>() -> Foo<T> { Foo::B }
1628 fn foo() {
1629     let foo: Foo<u32> = Foo::B;
1630     let _: Foo<u32> = f$0;
1631 }
1632 "#,
1633             expect![[r#"
1634                 lc foo [type+local]
1635                 ev Foo::A(…) [type_could_unify]
1636                 ev Foo::B [type_could_unify]
1637                 fn foo() []
1638                 en Foo []
1639                 fn bar() []
1640                 fn baz() []
1641             "#]],
1642         );
1643     }
1644
1645     #[test]
1646     fn postfix_exact_match_is_high_priority() {
1647         cov_mark::check!(postfix_exact_match_is_high_priority);
1648         check_relevance_for_kinds(
1649             r#"
1650 mod ops {
1651     pub trait Not {
1652         type Output;
1653         fn not(self) -> Self::Output;
1654     }
1655
1656     impl Not for bool {
1657         type Output = bool;
1658         fn not(self) -> bool { if self { false } else { true }}
1659     }
1660 }
1661
1662 fn main() {
1663     let _: bool = (9 > 2).not$0;
1664 }
1665     "#,
1666             &[CompletionItemKind::Snippet, CompletionItemKind::Method],
1667             expect![[r#"
1668                 sn not [snippet]
1669                 me not() (use ops::Not) [type_could_unify+requires_import]
1670                 sn if []
1671                 sn while []
1672                 sn ref []
1673                 sn refm []
1674                 sn match []
1675                 sn box []
1676                 sn dbg []
1677                 sn dbgr []
1678                 sn call []
1679             "#]],
1680         );
1681     }
1682
1683     #[test]
1684     fn postfix_inexact_match_is_low_priority() {
1685         cov_mark::check!(postfix_inexact_match_is_low_priority);
1686         check_relevance_for_kinds(
1687             r#"
1688 struct S;
1689 impl S {
1690     fn f(&self) {}
1691 }
1692 fn main() {
1693     S.$0
1694 }
1695     "#,
1696             &[CompletionItemKind::Snippet, CompletionItemKind::Method],
1697             expect![[r#"
1698                 me f() []
1699                 sn ref []
1700                 sn refm []
1701                 sn match []
1702                 sn box []
1703                 sn dbg []
1704                 sn dbgr []
1705                 sn call []
1706                 sn let []
1707                 sn letm []
1708             "#]],
1709         );
1710     }
1711
1712     #[test]
1713     fn flyimport_reduced_relevance() {
1714         check_relevance(
1715             r#"
1716 mod std {
1717     pub mod io {
1718         pub trait BufRead {}
1719         pub struct BufReader;
1720         pub struct BufWriter;
1721     }
1722 }
1723 struct Buffer;
1724
1725 fn f() {
1726     Buf$0
1727 }
1728 "#,
1729             expect![[r#"
1730                 st Buffer []
1731                 fn f() []
1732                 md std []
1733                 tt BufRead (use std::io::BufRead) [requires_import]
1734                 st BufReader (use std::io::BufReader) [requires_import]
1735                 st BufWriter (use std::io::BufWriter) [requires_import]
1736             "#]],
1737         );
1738     }
1739
1740     #[test]
1741     fn completes_struct_with_raw_identifier() {
1742         check_edit(
1743             "type",
1744             r#"
1745 mod m { pub struct r#type {} }
1746 fn main() {
1747     let r#type = m::t$0;
1748 }
1749 "#,
1750             r#"
1751 mod m { pub struct r#type {} }
1752 fn main() {
1753     let r#type = m::r#type;
1754 }
1755 "#,
1756         )
1757     }
1758
1759     #[test]
1760     fn completes_fn_with_raw_identifier() {
1761         check_edit(
1762             "type",
1763             r#"
1764 mod m { pub fn r#type {} }
1765 fn main() {
1766     m::t$0
1767 }
1768 "#,
1769             r#"
1770 mod m { pub fn r#type {} }
1771 fn main() {
1772     m::r#type()$0
1773 }
1774 "#,
1775         )
1776     }
1777
1778     #[test]
1779     fn completes_macro_with_raw_identifier() {
1780         check_edit(
1781             "let!",
1782             r#"
1783 macro_rules! r#let { () => {} }
1784 fn main() {
1785     $0
1786 }
1787 "#,
1788             r#"
1789 macro_rules! r#let { () => {} }
1790 fn main() {
1791     r#let!($0)
1792 }
1793 "#,
1794         )
1795     }
1796
1797     #[test]
1798     fn completes_variant_with_raw_identifier() {
1799         check_edit(
1800             "type",
1801             r#"
1802 enum A { r#type }
1803 fn main() {
1804     let a = A::t$0
1805 }
1806 "#,
1807             r#"
1808 enum A { r#type }
1809 fn main() {
1810     let a = A::r#type$0
1811 }
1812 "#,
1813         )
1814     }
1815
1816     #[test]
1817     fn completes_field_with_raw_identifier() {
1818         check_edit(
1819             "fn",
1820             r#"
1821 mod r#type {
1822     pub struct r#struct {
1823         pub r#fn: u32
1824     }
1825 }
1826
1827 fn main() {
1828     let a = r#type::r#struct {};
1829     a.$0
1830 }
1831 "#,
1832             r#"
1833 mod r#type {
1834     pub struct r#struct {
1835         pub r#fn: u32
1836     }
1837 }
1838
1839 fn main() {
1840     let a = r#type::r#struct {};
1841     a.r#fn
1842 }
1843 "#,
1844         )
1845     }
1846
1847     #[test]
1848     fn completes_const_with_raw_identifier() {
1849         check_edit(
1850             "type",
1851             r#"
1852 struct r#struct {}
1853 impl r#struct { pub const r#type: u8 = 1; }
1854 fn main() {
1855     r#struct::t$0
1856 }
1857 "#,
1858             r#"
1859 struct r#struct {}
1860 impl r#struct { pub const r#type: u8 = 1; }
1861 fn main() {
1862     r#struct::r#type
1863 }
1864 "#,
1865         )
1866     }
1867
1868     #[test]
1869     fn completes_type_alias_with_raw_identifier() {
1870         check_edit(
1871             "type type",
1872             r#"
1873 struct r#struct {}
1874 trait r#trait { type r#type; }
1875 impl r#trait for r#struct { type t$0 }
1876 "#,
1877             r#"
1878 struct r#struct {}
1879 trait r#trait { type r#type; }
1880 impl r#trait for r#struct { type r#type = $0; }
1881 "#,
1882         )
1883     }
1884
1885     #[test]
1886     fn field_access_includes_self() {
1887         check_edit(
1888             "length",
1889             r#"
1890 struct S {
1891     length: i32
1892 }
1893
1894 impl S {
1895     fn some_fn(&self) {
1896         let l = len$0
1897     }
1898 }
1899 "#,
1900             r#"
1901 struct S {
1902     length: i32
1903 }
1904
1905 impl S {
1906     fn some_fn(&self) {
1907         let l = self.length
1908     }
1909 }
1910 "#,
1911         )
1912     }
1913 }