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