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