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