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