about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--crates/ide_completion/src/completions.rs9
-rw-r--r--crates/ide_completion/src/completions/attribute.rs8
-rw-r--r--crates/ide_completion/src/completions/attribute/cfg.rs10
-rw-r--r--crates/ide_completion/src/completions/attribute/derive.rs6
-rw-r--r--crates/ide_completion/src/completions/attribute/lint.rs8
-rw-r--r--crates/ide_completion/src/completions/attribute/repr.rs5
-rw-r--r--crates/ide_completion/src/completions/dot.rs13
-rw-r--r--crates/ide_completion/src/completions/flyimport.rs1015
-rw-r--r--crates/ide_completion/src/completions/fn_param.rs6
-rw-r--r--crates/ide_completion/src/completions/keyword.rs300
-rw-r--r--crates/ide_completion/src/completions/mod_.rs8
-rw-r--r--crates/ide_completion/src/completions/postfix.rs24
-rw-r--r--crates/ide_completion/src/completions/qualified_path.rs7
-rw-r--r--crates/ide_completion/src/completions/record.rs16
-rw-r--r--crates/ide_completion/src/completions/snippet.rs6
-rw-r--r--crates/ide_completion/src/completions/trait_impl.rs78
-rw-r--r--crates/ide_completion/src/completions/unqualified_path.rs17
-rw-r--r--crates/ide_completion/src/context.rs1
-rw-r--r--crates/ide_completion/src/item.rs41
-rw-r--r--crates/ide_completion/src/lib.rs2
-rw-r--r--crates/ide_completion/src/render.rs169
-rw-r--r--crates/ide_completion/src/render/const_.rs10
-rw-r--r--crates/ide_completion/src/render/enum_variant.rs7
-rw-r--r--crates/ide_completion/src/render/function.rs8
-rw-r--r--crates/ide_completion/src/render/macro_.rs7
-rw-r--r--crates/ide_completion/src/render/pattern.rs8
-rw-r--r--crates/ide_completion/src/render/struct_literal.rs10
-rw-r--r--crates/ide_completion/src/render/type_alias.rs10
-rw-r--r--crates/ide_completion/src/tests.rs75
-rw-r--r--crates/ide_completion/src/tests/expression.rs219
-rw-r--r--crates/ide_completion/src/tests/flyimport.rs1014
-rw-r--r--crates/ide_completion/src/tests/record.rs1
-rw-r--r--crates/rust-analyzer/src/to_proto.rs2
-rw-r--r--crates/rust-analyzer/tests/slow-tests/tidy.rs1
34 files changed, 1558 insertions, 1563 deletions
diff --git a/crates/ide_completion/src/completions.rs b/crates/ide_completion/src/completions.rs
index 5f751d83a83..3e658c6e91d 100644
--- a/crates/ide_completion/src/completions.rs
+++ b/crates/ide_completion/src/completions.rs
@@ -21,7 +21,7 @@ use hir::known;
 use ide_db::SymbolKind;
 
 use crate::{
-    item::{Builder, CompletionKind},
+    item::Builder,
     render::{
         const_::render_const,
         enum_variant::render_variant,
@@ -76,8 +76,7 @@ impl Completions {
     }
 
     pub(crate) fn add_keyword(&mut self, ctx: &CompletionContext, keyword: &'static str) {
-        let mut item = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), keyword);
-        item.kind(CompletionItemKind::Keyword);
+        let item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), keyword);
         item.add_to(self);
     }
 
@@ -191,9 +190,7 @@ impl Completions {
     }
 
     pub(crate) fn add_static_lifetime(&mut self, ctx: &CompletionContext) {
-        let mut item =
-            CompletionItem::new(CompletionKind::Reference, ctx.source_range(), "'static");
-        item.kind(CompletionItemKind::SymbolKind(SymbolKind::LifetimeParam));
+        let item = CompletionItem::new(SymbolKind::LifetimeParam, ctx.source_range(), "'static");
         self.add(item.build());
     }
 
diff --git a/crates/ide_completion/src/completions/attribute.rs b/crates/ide_completion/src/completions/attribute.rs
index 119572923c9..2482418ae6a 100644
--- a/crates/ide_completion/src/completions/attribute.rs
+++ b/crates/ide_completion/src/completions/attribute.rs
@@ -12,7 +12,7 @@ use syntax::{algo::non_trivia_sibling, ast, AstNode, Direction, SyntaxKind, T};
 
 use crate::{
     context::CompletionContext,
-    item::{CompletionItem, CompletionItemKind, CompletionKind},
+    item::{CompletionItem, CompletionItemKind},
     Completions,
 };
 
@@ -69,11 +69,10 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib
 
     let add_completion = |attr_completion: &AttrCompletion| {
         let mut item = CompletionItem::new(
-            CompletionKind::Attribute,
+            CompletionItemKind::Attribute,
             ctx.source_range(),
             attr_completion.label,
         );
-        item.kind(CompletionItemKind::Attribute);
 
         if let Some(lookup) = attr_completion.lookup {
             item.lookup_by(lookup);
@@ -103,11 +102,10 @@ fn complete_new_attribute(acc: &mut Completions, ctx: &CompletionContext, attrib
         if let hir::ScopeDef::MacroDef(mac) = scope_def {
             if mac.kind() == hir::MacroKind::Attr {
                 let mut item = CompletionItem::new(
-                    CompletionKind::Attribute,
+                    CompletionItemKind::Attribute,
                     ctx.source_range(),
                     name.to_string(),
                 );
-                item.kind(CompletionItemKind::Attribute);
                 if let Some(docs) = mac.docs(ctx.sema.db) {
                     item.documentation(docs);
                 }
diff --git a/crates/ide_completion/src/completions/attribute/cfg.rs b/crates/ide_completion/src/completions/attribute/cfg.rs
index 171babc698e..c83e1718ece 100644
--- a/crates/ide_completion/src/completions/attribute/cfg.rs
+++ b/crates/ide_completion/src/completions/attribute/cfg.rs
@@ -5,16 +5,14 @@ use std::iter;
 use syntax::SyntaxKind;
 
 use crate::{
-    completions::Completions, context::CompletionContext, item::CompletionKind, CompletionItem,
-    CompletionItemKind,
+    completions::Completions, context::CompletionContext, CompletionItem, CompletionItemKind,
 };
 
 pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) {
     let add_completion = |item: &str| {
         let mut completion =
-            CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), item);
+            CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), item);
         completion.insert_text(format!(r#""{}""#, item));
-        completion.kind(CompletionItemKind::Attribute);
         acc.add(completion.build());
     };
 
@@ -35,7 +33,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) {
             if let Some(krate) = ctx.krate {
                 krate.potential_cfg(ctx.db).get_cfg_values(&name).iter().for_each(|s| {
                     let mut item = CompletionItem::new(
-                        CompletionKind::Attribute,
+                        CompletionItemKind::Attribute,
                         ctx.source_range(),
                         s.as_str(),
                     );
@@ -49,7 +47,7 @@ pub(crate) fn complete_cfg(acc: &mut Completions, ctx: &CompletionContext) {
             if let Some(krate) = ctx.krate {
                 krate.potential_cfg(ctx.db).get_cfg_keys().iter().for_each(|s| {
                     let item = CompletionItem::new(
-                        CompletionKind::Attribute,
+                        CompletionItemKind::Attribute,
                         ctx.source_range(),
                         s.as_str(),
                     );
diff --git a/crates/ide_completion/src/completions/attribute/derive.rs b/crates/ide_completion/src/completions/attribute/derive.rs
index e460a91102c..7f050f25c9b 100644
--- a/crates/ide_completion/src/completions/attribute/derive.rs
+++ b/crates/ide_completion/src/completions/attribute/derive.rs
@@ -7,7 +7,7 @@ use syntax::ast;
 
 use crate::{
     context::CompletionContext,
-    item::{CompletionItem, CompletionItemKind, CompletionKind},
+    item::{CompletionItem, CompletionItemKind},
     Completions,
 };
 
@@ -56,8 +56,8 @@ pub(super) fn complete_derive(
             _ => (&*name, None),
         };
 
-        let mut item = CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label);
-        item.kind(CompletionItemKind::Attribute);
+        let mut item =
+            CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), label);
         if let Some(docs) = mac.docs(ctx.db) {
             item.documentation(docs);
         }
diff --git a/crates/ide_completion/src/completions/attribute/lint.rs b/crates/ide_completion/src/completions/attribute/lint.rs
index 18942f8beb3..05a29dd0ae2 100644
--- a/crates/ide_completion/src/completions/attribute/lint.rs
+++ b/crates/ide_completion/src/completions/attribute/lint.rs
@@ -4,7 +4,7 @@ use syntax::{ast, T};
 
 use crate::{
     context::CompletionContext,
-    item::{CompletionItem, CompletionItemKind, CompletionKind},
+    item::{CompletionItem, CompletionItemKind},
     Completions,
 };
 
@@ -58,9 +58,9 @@ pub(super) fn complete_lint(
             Some(qual) if !is_qualified => format!("{}::{}", qual, name),
             _ => name.to_owned(),
         };
-        let mut item = CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label);
-        item.kind(CompletionItemKind::Attribute)
-            .documentation(hir::Documentation::new(description.to_owned()));
+        let mut item =
+            CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), label);
+        item.documentation(hir::Documentation::new(description.to_owned()));
         item.add_to(acc)
     }
 }
diff --git a/crates/ide_completion/src/completions/attribute/repr.rs b/crates/ide_completion/src/completions/attribute/repr.rs
index 9a12b8571c7..c240912f023 100644
--- a/crates/ide_completion/src/completions/attribute/repr.rs
+++ b/crates/ide_completion/src/completions/attribute/repr.rs
@@ -4,7 +4,7 @@ use syntax::ast;
 
 use crate::{
     context::CompletionContext,
-    item::{CompletionItem, CompletionItemKind, CompletionKind},
+    item::{CompletionItem, CompletionItemKind},
     Completions,
 };
 
@@ -30,8 +30,7 @@ pub(super) fn complete_repr(acc: &mut Completions, ctx: &CompletionContext, inpu
             }
 
             let mut item =
-                CompletionItem::new(CompletionKind::Attribute, ctx.source_range(), label);
-            item.kind(CompletionItemKind::Attribute);
+                CompletionItem::new(CompletionItemKind::Attribute, ctx.source_range(), label);
             if let Some(lookup) = lookup {
                 item.lookup_by(lookup);
             }
diff --git a/crates/ide_completion/src/completions/dot.rs b/crates/ide_completion/src/completions/dot.rs
index 213cb701704..ce964e986b0 100644
--- a/crates/ide_completion/src/completions/dot.rs
+++ b/crates/ide_completion/src/completions/dot.rs
@@ -99,13 +99,10 @@ fn complete_methods(
 mod tests {
     use expect_test::{expect, Expect};
 
-    use crate::{
-        tests::{check_edit, filtered_completion_list},
-        CompletionKind,
-    };
+    use crate::tests::{check_edit, completion_list_no_kw};
 
     fn check(ra_fixture: &str, expect: Expect) {
-        let actual = filtered_completion_list(ra_fixture, CompletionKind::Reference);
+        let actual = completion_list_no_kw(ra_fixture);
         expect.assert_eq(&actual);
     }
 
@@ -166,7 +163,7 @@ impl A {
 struct A { the_field: u32 }
 fn foo(a: A) { a.$0() }
 "#,
-            expect![[""]],
+            expect![[r#""#]],
         );
     }
 
@@ -405,7 +402,7 @@ fn foo(a: A) {
    a.$0
 }
 "#,
-            expect![[""]],
+            expect![[r#""#]],
         );
     }
 
@@ -654,6 +651,7 @@ impl Foo { fn foo(&self) { $0 } }"#,
                 lc self       &Foo
                 sp Self
                 st Foo
+                bt u32
                 fd self.field i32
                 me self.foo() fn(&self)
             "#]],
@@ -667,6 +665,7 @@ impl Foo { fn foo(&mut self) { $0 } }"#,
                 lc self       &mut Foo
                 sp Self
                 st Foo
+                bt u32
                 fd self.0     i32
                 me self.foo() fn(&mut self)
             "#]],
diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs
index d7c8c54315c..486cbff6859 100644
--- a/crates/ide_completion/src/completions/flyimport.rs
+++ b/crates/ide_completion/src/completions/flyimport.rs
@@ -219,1018 +219,3 @@ fn compute_fuzzy_completion_order_key(
         None => usize::MAX,
     }
 }
-
-#[cfg(test)]
-mod tests {
-    use expect_test::{expect, Expect};
-
-    use crate::{
-        item::CompletionKind,
-        tests::{check_edit, check_edit_with_config, filtered_completion_list, TEST_CONFIG},
-    };
-
-    fn check(ra_fixture: &str, expect: Expect) {
-        let actual = filtered_completion_list(ra_fixture, CompletionKind::Magic);
-        expect.assert_eq(&actual);
-    }
-
-    #[test]
-    fn function_fuzzy_completion() {
-        check_edit(
-            "stdin",
-            r#"
-//- /lib.rs crate:dep
-pub mod io {
-    pub fn stdin() {}
-};
-
-//- /main.rs crate:main deps:dep
-fn main() {
-    stdi$0
-}
-"#,
-            r#"
-use dep::io::stdin;
-
-fn main() {
-    stdin()$0
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn macro_fuzzy_completion() {
-        check_edit(
-            "macro_with_curlies!",
-            r#"
-//- /lib.rs crate:dep
-/// Please call me as macro_with_curlies! {}
-#[macro_export]
-macro_rules! macro_with_curlies {
-    () => {}
-}
-
-//- /main.rs crate:main deps:dep
-fn main() {
-    curli$0
-}
-"#,
-            r#"
-use dep::macro_with_curlies;
-
-fn main() {
-    macro_with_curlies! {$0}
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn struct_fuzzy_completion() {
-        check_edit(
-            "ThirdStruct",
-            r#"
-//- /lib.rs crate:dep
-pub struct FirstStruct;
-pub mod some_module {
-    pub struct SecondStruct;
-    pub struct ThirdStruct;
-}
-
-//- /main.rs crate:main deps:dep
-use dep::{FirstStruct, some_module::SecondStruct};
-
-fn main() {
-    this$0
-}
-"#,
-            r#"
-use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}};
-
-fn main() {
-    ThirdStruct
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn short_paths_are_ignored() {
-        cov_mark::check!(ignore_short_input_for_path);
-
-        check(
-            r#"
-//- /lib.rs crate:dep
-pub struct FirstStruct;
-pub mod some_module {
-    pub struct SecondStruct;
-    pub struct ThirdStruct;
-}
-
-//- /main.rs crate:main deps:dep
-use dep::{FirstStruct, some_module::SecondStruct};
-
-fn main() {
-    t$0
-}
-"#,
-            expect![[r#""#]],
-        );
-    }
-
-    #[test]
-    fn fuzzy_completions_come_in_specific_order() {
-        cov_mark::check!(certain_fuzzy_order_test);
-        check(
-            r#"
-//- /lib.rs crate:dep
-pub struct FirstStruct;
-pub mod some_module {
-    // already imported, omitted
-    pub struct SecondStruct;
-    // does not contain all letters from the query, omitted
-    pub struct UnrelatedOne;
-    // contains all letters from the query, but not in sequence, displayed last
-    pub struct ThiiiiiirdStruct;
-    // contains all letters from the query, but not in the beginning, displayed second
-    pub struct AfterThirdStruct;
-    // contains all letters from the query in the begginning, displayed first
-    pub struct ThirdStruct;
-}
-
-//- /main.rs crate:main deps:dep
-use dep::{FirstStruct, some_module::SecondStruct};
-
-fn main() {
-    hir$0
-}
-"#,
-            expect![[r#"
-                st ThirdStruct (use dep::some_module::ThirdStruct)
-                st AfterThirdStruct (use dep::some_module::AfterThirdStruct)
-                st ThiiiiiirdStruct (use dep::some_module::ThiiiiiirdStruct)
-            "#]],
-        );
-    }
-
-    #[test]
-    fn trait_function_fuzzy_completion() {
-        let fixture = r#"
-        //- /lib.rs crate:dep
-        pub mod test_mod {
-            pub trait TestTrait {
-                const SPECIAL_CONST: u8;
-                type HumbleType;
-                fn weird_function();
-                fn random_method(&self);
-            }
-            pub struct TestStruct {}
-            impl TestTrait for TestStruct {
-                const SPECIAL_CONST: u8 = 42;
-                type HumbleType = ();
-                fn weird_function() {}
-                fn random_method(&self) {}
-            }
-        }
-
-        //- /main.rs crate:main deps:dep
-        fn main() {
-            dep::test_mod::TestStruct::wei$0
-        }
-        "#;
-
-        check(
-            fixture,
-            expect![[r#"
-                fn weird_function() (use dep::test_mod::TestTrait) fn()
-            "#]],
-        );
-
-        check_edit(
-            "weird_function",
-            fixture,
-            r#"
-use dep::test_mod::TestTrait;
-
-fn main() {
-    dep::test_mod::TestStruct::weird_function()$0
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn trait_const_fuzzy_completion() {
-        let fixture = r#"
-        //- /lib.rs crate:dep
-        pub mod test_mod {
-            pub trait TestTrait {
-                const SPECIAL_CONST: u8;
-                type HumbleType;
-                fn weird_function();
-                fn random_method(&self);
-            }
-            pub struct TestStruct {}
-            impl TestTrait for TestStruct {
-                const SPECIAL_CONST: u8 = 42;
-                type HumbleType = ();
-                fn weird_function() {}
-                fn random_method(&self) {}
-            }
-        }
-
-        //- /main.rs crate:main deps:dep
-        fn main() {
-            dep::test_mod::TestStruct::spe$0
-        }
-        "#;
-
-        check(
-            fixture,
-            expect![[r#"
-            ct SPECIAL_CONST (use dep::test_mod::TestTrait)
-        "#]],
-        );
-
-        check_edit(
-            "SPECIAL_CONST",
-            fixture,
-            r#"
-use dep::test_mod::TestTrait;
-
-fn main() {
-    dep::test_mod::TestStruct::SPECIAL_CONST
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn trait_method_fuzzy_completion() {
-        let fixture = r#"
-        //- /lib.rs crate:dep
-        pub mod test_mod {
-            pub trait TestTrait {
-                const SPECIAL_CONST: u8;
-                type HumbleType;
-                fn weird_function();
-                fn random_method(&self);
-            }
-            pub struct TestStruct {}
-            impl TestTrait for TestStruct {
-                const SPECIAL_CONST: u8 = 42;
-                type HumbleType = ();
-                fn weird_function() {}
-                fn random_method(&self) {}
-            }
-        }
-
-        //- /main.rs crate:main deps:dep
-        fn main() {
-            let test_struct = dep::test_mod::TestStruct {};
-            test_struct.ran$0
-        }
-        "#;
-
-        check(
-            fixture,
-            expect![[r#"
-                me random_method() (use dep::test_mod::TestTrait) fn(&self)
-            "#]],
-        );
-
-        check_edit(
-            "random_method",
-            fixture,
-            r#"
-use dep::test_mod::TestTrait;
-
-fn main() {
-    let test_struct = dep::test_mod::TestStruct {};
-    test_struct.random_method()$0
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn no_trait_type_fuzzy_completion() {
-        check(
-            r#"
-//- /lib.rs crate:dep
-pub mod test_mod {
-    pub trait TestTrait {
-        const SPECIAL_CONST: u8;
-        type HumbleType;
-        fn weird_function();
-        fn random_method(&self);
-    }
-    pub struct TestStruct {}
-    impl TestTrait for TestStruct {
-        const SPECIAL_CONST: u8 = 42;
-        type HumbleType = ();
-        fn weird_function() {}
-        fn random_method(&self) {}
-    }
-}
-
-//- /main.rs crate:main deps:dep
-fn main() {
-    dep::test_mod::TestStruct::hum$0
-}
-"#,
-            expect![[r#""#]],
-        );
-    }
-
-    #[test]
-    fn does_not_propose_names_in_scope() {
-        check(
-            r#"
-//- /lib.rs crate:dep
-pub mod test_mod {
-    pub trait TestTrait {
-        const SPECIAL_CONST: u8;
-        type HumbleType;
-        fn weird_function();
-        fn random_method(&self);
-    }
-    pub struct TestStruct {}
-    impl TestTrait for TestStruct {
-        const SPECIAL_CONST: u8 = 42;
-        type HumbleType = ();
-        fn weird_function() {}
-        fn random_method(&self) {}
-    }
-}
-
-//- /main.rs crate:main deps:dep
-use dep::test_mod::TestStruct;
-fn main() {
-    TestSt$0
-}
-"#,
-            expect![[r#""#]],
-        );
-    }
-
-    #[test]
-    fn does_not_propose_traits_in_scope() {
-        check(
-            r#"
-//- /lib.rs crate:dep
-pub mod test_mod {
-    pub trait TestTrait {
-        const SPECIAL_CONST: u8;
-        type HumbleType;
-        fn weird_function();
-        fn random_method(&self);
-    }
-    pub struct TestStruct {}
-    impl TestTrait for TestStruct {
-        const SPECIAL_CONST: u8 = 42;
-        type HumbleType = ();
-        fn weird_function() {}
-        fn random_method(&self) {}
-    }
-}
-
-//- /main.rs crate:main deps:dep
-use dep::test_mod::{TestStruct, TestTrait};
-fn main() {
-    dep::test_mod::TestStruct::hum$0
-}
-"#,
-            expect![[r#""#]],
-        );
-    }
-
-    #[test]
-    fn blanket_trait_impl_import() {
-        check_edit(
-            "another_function",
-            r#"
-//- /lib.rs crate:dep
-pub mod test_mod {
-    pub struct TestStruct {}
-    pub trait TestTrait {
-        fn another_function();
-    }
-    impl<T> TestTrait for T {
-        fn another_function() {}
-    }
-}
-
-//- /main.rs crate:main deps:dep
-fn main() {
-    dep::test_mod::TestStruct::ano$0
-}
-"#,
-            r#"
-use dep::test_mod::TestTrait;
-
-fn main() {
-    dep::test_mod::TestStruct::another_function()$0
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn zero_input_deprecated_assoc_item_completion() {
-        check(
-            r#"
-//- /lib.rs crate:dep
-pub mod test_mod {
-    #[deprecated]
-    pub trait TestTrait {
-        const SPECIAL_CONST: u8;
-        type HumbleType;
-        fn weird_function();
-        fn random_method(&self);
-    }
-    pub struct TestStruct {}
-    impl TestTrait for TestStruct {
-        const SPECIAL_CONST: u8 = 42;
-        type HumbleType = ();
-        fn weird_function() {}
-        fn random_method(&self) {}
-    }
-}
-
-//- /main.rs crate:main deps:dep
-fn main() {
-    let test_struct = dep::test_mod::TestStruct {};
-    test_struct.$0
-}
-        "#,
-            expect![[r#"
-                me random_method() (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
-            "#]],
-        );
-
-        check(
-            r#"
-//- /lib.rs crate:dep
-pub mod test_mod {
-    #[deprecated]
-    pub trait TestTrait {
-        const SPECIAL_CONST: u8;
-        type HumbleType;
-        fn weird_function();
-        fn random_method(&self);
-    }
-    pub struct TestStruct {}
-    impl TestTrait for TestStruct {
-        const SPECIAL_CONST: u8 = 42;
-        type HumbleType = ();
-        fn weird_function() {}
-        fn random_method(&self) {}
-    }
-}
-
-//- /main.rs crate:main deps:dep
-fn main() {
-    dep::test_mod::TestStruct::$0
-}
-"#,
-            expect![[r#"
-                fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED
-                ct SPECIAL_CONST (use dep::test_mod::TestTrait) DEPRECATED
-            "#]],
-        );
-    }
-
-    #[test]
-    fn no_completions_in_use_statements() {
-        check(
-            r#"
-//- /lib.rs crate:dep
-pub mod io {
-    pub fn stdin() {}
-};
-
-//- /main.rs crate:main deps:dep
-use stdi$0
-
-fn main() {}
-"#,
-            expect![[]],
-        );
-    }
-
-    #[test]
-    fn prefix_config_usage() {
-        let fixture = r#"
-mod foo {
-    pub mod bar {
-        pub struct Item;
-    }
-}
-
-use crate::foo::bar;
-
-fn main() {
-    Ite$0
-}"#;
-        let mut config = TEST_CONFIG;
-
-        config.insert_use.prefix_kind = hir::PrefixKind::ByCrate;
-        check_edit_with_config(
-            config.clone(),
-            "Item",
-            fixture,
-            r#"
-mod foo {
-    pub mod bar {
-        pub struct Item;
-    }
-}
-
-use crate::foo::bar::{self, Item};
-
-fn main() {
-    Item
-}"#,
-        );
-
-        config.insert_use.prefix_kind = hir::PrefixKind::BySelf;
-        check_edit_with_config(
-            config.clone(),
-            "Item",
-            fixture,
-            r#"
-mod foo {
-    pub mod bar {
-        pub struct Item;
-    }
-}
-
-use crate::foo::bar;
-
-use self::foo::bar::Item;
-
-fn main() {
-    Item
-}"#,
-        );
-
-        config.insert_use.prefix_kind = hir::PrefixKind::Plain;
-        check_edit_with_config(
-            config,
-            "Item",
-            fixture,
-            r#"
-mod foo {
-    pub mod bar {
-        pub struct Item;
-    }
-}
-
-use foo::bar::Item;
-
-use crate::foo::bar;
-
-fn main() {
-    Item
-}"#,
-        );
-    }
-
-    #[test]
-    fn unresolved_qualifier() {
-        let fixture = r#"
-mod foo {
-    pub mod bar {
-        pub mod baz {
-            pub struct Item;
-        }
-    }
-}
-
-fn main() {
-    bar::baz::Ite$0
-}"#;
-
-        check(
-            fixture,
-            expect![[r#"
-        st Item (use foo::bar::baz::Item)
-        "#]],
-        );
-
-        check_edit(
-            "Item",
-            fixture,
-            r#"
-        use foo::bar;
-
-        mod foo {
-            pub mod bar {
-                pub mod baz {
-                    pub struct Item;
-                }
-            }
-        }
-
-        fn main() {
-            bar::baz::Item
-        }"#,
-        );
-    }
-
-    #[test]
-    fn unresolved_assoc_item_container() {
-        let fixture = r#"
-mod foo {
-    pub struct Item;
-
-    impl Item {
-        pub const TEST_ASSOC: usize = 3;
-    }
-}
-
-fn main() {
-    Item::TEST_A$0
-}"#;
-
-        check(
-            fixture,
-            expect![[r#"
-        ct TEST_ASSOC (use foo::Item)
-        "#]],
-        );
-
-        check_edit(
-            "TEST_ASSOC",
-            fixture,
-            r#"
-use foo::Item;
-
-mod foo {
-    pub struct Item;
-
-    impl Item {
-        pub const TEST_ASSOC: usize = 3;
-    }
-}
-
-fn main() {
-    Item::TEST_ASSOC
-}"#,
-        );
-    }
-
-    #[test]
-    fn unresolved_assoc_item_container_with_path() {
-        let fixture = r#"
-mod foo {
-    pub mod bar {
-        pub struct Item;
-
-        impl Item {
-            pub const TEST_ASSOC: usize = 3;
-        }
-    }
-}
-
-fn main() {
-    bar::Item::TEST_A$0
-}"#;
-
-        check(
-            fixture,
-            expect![[r#"
-        ct TEST_ASSOC (use foo::bar::Item)
-    "#]],
-        );
-
-        check_edit(
-            "TEST_ASSOC",
-            fixture,
-            r#"
-use foo::bar;
-
-mod foo {
-    pub mod bar {
-        pub struct Item;
-
-        impl Item {
-            pub const TEST_ASSOC: usize = 3;
-        }
-    }
-}
-
-fn main() {
-    bar::Item::TEST_ASSOC
-}"#,
-        );
-    }
-
-    #[test]
-    fn fuzzy_unresolved_path() {
-        check(
-            r#"
-mod foo {
-    pub mod bar {
-        pub struct Item;
-
-        impl Item {
-            pub const TEST_ASSOC: usize = 3;
-        }
-    }
-}
-
-fn main() {
-    bar::ASS$0
-}"#,
-            expect![[]],
-        )
-    }
-
-    #[test]
-    fn unqualified_assoc_items_are_omitted() {
-        check(
-            r#"
-mod something {
-    pub trait BaseTrait {
-        fn test_function() -> i32;
-    }
-
-    pub struct Item1;
-    pub struct Item2;
-
-    impl BaseTrait for Item1 {
-        fn test_function() -> i32 {
-            1
-        }
-    }
-
-    impl BaseTrait for Item2 {
-        fn test_function() -> i32 {
-            2
-        }
-    }
-}
-
-fn main() {
-    test_f$0
-}"#,
-            expect![[]],
-        )
-    }
-
-    #[test]
-    fn case_matters() {
-        check(
-            r#"
-mod foo {
-    pub const TEST_CONST: usize = 3;
-    pub fn test_function() -> i32 {
-        4
-    }
-}
-
-fn main() {
-    TE$0
-}"#,
-            expect![[r#"
-        ct TEST_CONST (use foo::TEST_CONST)
-    "#]],
-        );
-
-        check(
-            r#"
-mod foo {
-    pub const TEST_CONST: usize = 3;
-    pub fn test_function() -> i32 {
-        4
-    }
-}
-
-fn main() {
-    te$0
-}"#,
-            expect![[r#"
-        ct TEST_CONST (use foo::TEST_CONST)
-        fn test_function() (use foo::test_function) fn() -> i32
-    "#]],
-        );
-
-        check(
-            r#"
-mod foo {
-    pub const TEST_CONST: usize = 3;
-    pub fn test_function() -> i32 {
-        4
-    }
-}
-
-fn main() {
-    Te$0
-}"#,
-            expect![[]],
-        );
-    }
-
-    #[test]
-    fn no_fuzzy_during_fields_of_record_lit_syntax() {
-        check(
-            r#"
-mod m {
-    pub fn some_fn() -> i32 {
-        42
-    }
-}
-struct Foo {
-    some_field: i32,
-}
-fn main() {
-    let _ = Foo { so$0 };
-}
-"#,
-            expect![[]],
-        );
-    }
-
-    #[test]
-    fn fuzzy_after_fields_of_record_lit_syntax() {
-        check(
-            r#"
-mod m {
-    pub fn some_fn() -> i32 {
-        42
-    }
-}
-struct Foo {
-    some_field: i32,
-}
-fn main() {
-    let _ = Foo { some_field: so$0 };
-}
-"#,
-            expect![[r#"
-                fn some_fn() (use m::some_fn) fn() -> i32
-            "#]],
-        );
-    }
-
-    #[test]
-    fn no_flyimports_in_traits_and_impl_declarations() {
-        check(
-            r#"
-mod m {
-    pub fn some_fn() -> i32 {
-        42
-    }
-}
-trait Foo {
-    som$0
-}
-"#,
-            expect![[r#""#]],
-        );
-
-        check(
-            r#"
-mod m {
-    pub fn some_fn() -> i32 {
-        42
-    }
-}
-struct Foo;
-impl Foo {
-    som$0
-}
-"#,
-            expect![[r#""#]],
-        );
-
-        check(
-            r#"
-mod m {
-    pub fn some_fn() -> i32 {
-        42
-    }
-}
-struct Foo;
-trait Bar {}
-impl Bar for Foo {
-    som$0
-}
-"#,
-            expect![[r#""#]],
-        );
-    }
-
-    #[test]
-    fn no_inherent_candidates_proposed() {
-        check(
-            r#"
-mod baz {
-    pub trait DefDatabase {
-        fn method1(&self);
-    }
-    pub trait HirDatabase: DefDatabase {
-        fn method2(&self);
-    }
-}
-
-mod bar {
-    fn test(db: &dyn crate::baz::HirDatabase) {
-        db.metho$0
-    }
-}
-            "#,
-            expect![[r#""#]],
-        );
-    }
-
-    #[test]
-    fn respects_doc_hidden() {
-        check(
-            r#"
-//- /lib.rs crate:lib deps:dep
-fn f() {
-    ().fro$0
-}
-
-//- /dep.rs crate:dep
-#[doc(hidden)]
-pub trait Private {
-    fn frob(&self) {}
-}
-
-impl<T> Private for T {}
-            "#,
-            expect![[r#""#]],
-        );
-        check(
-            r#"
-//- /lib.rs crate:lib deps:dep
-fn f() {
-    ().fro$0
-}
-
-//- /dep.rs crate:dep
-pub trait Private {
-    #[doc(hidden)]
-    fn frob(&self) {}
-}
-
-impl<T> Private for T {}
-            "#,
-            expect![[r#""#]],
-        );
-    }
-
-    #[test]
-    fn regression_9760() {
-        check(
-            r#"
-struct Struct;
-fn main() {}
-
-mod mud {
-    fn func() {
-        let struct_instance = Stru$0
-    }
-}
-"#,
-            expect![[r#"
-                st Struct (use crate::Struct)
-            "#]],
-        );
-    }
-
-    #[test]
-    fn flyimport_pattern() {
-        check(
-            r#"
-mod module {
-    pub struct Struct;
-}
-fn function() {
-    let Str$0
-}
-"#,
-            expect![[r#"
-                st Struct (use module::Struct)
-            "#]],
-        );
-    }
-
-    #[test]
-    fn flyimport_rename() {
-        check(
-            r#"
-mod module {
-    pub struct Struct;
-}
-use self as Str$0;
-    "#,
-            expect![[r#""#]],
-        );
-    }
-}
diff --git a/crates/ide_completion/src/completions/fn_param.rs b/crates/ide_completion/src/completions/fn_param.rs
index a9f1944e283..e910c1daaad 100644
--- a/crates/ide_completion/src/completions/fn_param.rs
+++ b/crates/ide_completion/src/completions/fn_param.rs
@@ -8,7 +8,7 @@ use syntax::{
 
 use crate::{
     context::{ParamKind, PatternContext},
-    CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions,
+    CompletionContext, CompletionItem, CompletionItemKind, Completions,
 };
 
 /// Complete repeated parameters, both name and type. For example, if all
@@ -75,7 +75,7 @@ fn add_new_item_to_acc(
     label: String,
     lookup: String,
 ) {
-    let mut item = CompletionItem::new(CompletionKind::Magic, ctx.source_range(), label);
-    item.kind(CompletionItemKind::Binding).lookup_by(lookup);
+    let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), label);
+    item.lookup_by(lookup);
     item.add_to(acc)
 }
diff --git a/crates/ide_completion/src/completions/keyword.rs b/crates/ide_completion/src/completions/keyword.rs
index 31aabd98d3e..afb8df29116 100644
--- a/crates/ide_completion/src/completions/keyword.rs
+++ b/crates/ide_completion/src/completions/keyword.rs
@@ -6,7 +6,7 @@ use syntax::{SyntaxKind, T};
 
 use crate::{
     context::PathCompletionContext, patterns::ImmediateLocation, CompletionContext, CompletionItem,
-    CompletionItemKind, CompletionKind, Completions,
+    CompletionItemKind, Completions,
 };
 
 pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionContext) {
@@ -158,8 +158,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
 }
 
 fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet: &str) {
-    let mut item = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), kw);
-    item.kind(CompletionItemKind::Keyword);
+    let mut item = CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), kw);
 
     match ctx.config.snippet_cap {
         Some(cap) => {
@@ -181,115 +180,15 @@ fn add_keyword(ctx: &CompletionContext, acc: &mut Completions, kw: &str, snippet
 mod tests {
     use expect_test::{expect, Expect};
 
-    use crate::{
-        tests::{check_edit, filtered_completion_list},
-        CompletionKind,
-    };
+    use crate::tests::{check_edit, completion_list};
 
     fn check(ra_fixture: &str, expect: Expect) {
-        let actual = filtered_completion_list(ra_fixture, CompletionKind::Keyword);
+        let actual = completion_list(ra_fixture);
         expect.assert_eq(&actual)
     }
 
     #[test]
-    fn test_keywords_in_function() {
-        check(
-            r"fn quux() { $0 }",
-            expect![[r#"
-                kw unsafe
-                kw fn
-                kw const
-                kw type
-                kw impl
-                kw extern
-                kw use
-                kw trait
-                kw static
-                kw mod
-                kw match
-                kw while
-                kw while let
-                kw loop
-                kw if
-                kw if let
-                kw for
-                kw true
-                kw false
-                kw let
-                kw return
-                kw self
-                kw super
-                kw crate
-            "#]],
-        );
-    }
-
-    #[test]
-    fn test_keywords_inside_block() {
-        check(
-            r"fn quux() { if true { $0 } }",
-            expect![[r#"
-                kw unsafe
-                kw fn
-                kw const
-                kw type
-                kw impl
-                kw extern
-                kw use
-                kw trait
-                kw static
-                kw mod
-                kw match
-                kw while
-                kw while let
-                kw loop
-                kw if
-                kw if let
-                kw for
-                kw true
-                kw false
-                kw let
-                kw return
-                kw self
-                kw super
-                kw crate
-            "#]],
-        );
-    }
-
-    #[test]
-    fn test_keywords_after_if() {
-        check(
-            r#"fn quux() { if true { () } $0 }"#,
-            expect![[r#"
-                kw unsafe
-                kw fn
-                kw const
-                kw type
-                kw impl
-                kw extern
-                kw use
-                kw trait
-                kw static
-                kw mod
-                kw match
-                kw while
-                kw while let
-                kw loop
-                kw if
-                kw if let
-                kw for
-                kw true
-                kw false
-                kw let
-                kw else
-                kw else if
-                kw return
-                kw self
-                kw super
-                kw crate
-            "#]],
-        );
+    fn test_else_edit_after_if() {
         check_edit(
             "else",
             r#"fn quux() { if true { () } $0 }"#,
@@ -300,68 +199,6 @@ mod tests {
     }
 
     #[test]
-    fn test_keywords_in_match_arm() {
-        check(
-            r#"
-fn quux() -> i32 {
-    match () { () => $0 }
-}
-"#,
-            expect![[r#"
-                kw unsafe
-                kw match
-                kw while
-                kw while let
-                kw loop
-                kw if
-                kw if let
-                kw for
-                kw true
-                kw false
-                kw return
-                kw self
-                kw super
-                kw crate
-            "#]],
-        );
-    }
-
-    #[test]
-    fn test_keywords_in_loop() {
-        check(
-            r"fn my() { loop { $0 } }",
-            expect![[r#"
-                kw unsafe
-                kw fn
-                kw const
-                kw type
-                kw impl
-                kw extern
-                kw use
-                kw trait
-                kw static
-                kw mod
-                kw match
-                kw while
-                kw while let
-                kw loop
-                kw if
-                kw if let
-                kw for
-                kw true
-                kw false
-                kw let
-                kw continue
-                kw break
-                kw return
-                kw self
-                kw super
-                kw crate
-            "#]],
-        );
-    }
-
-    #[test]
     fn test_keywords_after_unsafe_in_block_expr() {
         check(
             r"fn my_fn() { unsafe $0 }",
@@ -369,39 +206,13 @@ fn quux() -> i32 {
                 kw fn
                 kw trait
                 kw impl
+                sn pd
+                sn ppd
             "#]],
         );
     }
 
     #[test]
-    fn no_keyword_completion_in_comments() {
-        cov_mark::check!(no_keyword_completion_in_comments);
-        check(
-            r#"
-fn test() {
-    let x = 2; // A comment$0
-}
-"#,
-            expect![[""]],
-        );
-        check(
-            r#"
-/*
-Some multi-line comment$0
-*/
-"#,
-            expect![[""]],
-        );
-        check(
-            r#"
-/// Some doc comment
-/// let test$0 = 1
-"#,
-            expect![[""]],
-        );
-    }
-
-    #[test]
     fn test_completion_await_impls_future() {
         check(
             r#"
@@ -413,6 +224,18 @@ fn foo(a: A) { a.$0 }
 "#,
             expect![[r#"
                 kw await expr.await
+                sn ref   &expr
+                sn refm  &mut expr
+                sn match match expr {}
+                sn box   Box::new(expr)
+                sn ok    Ok(expr)
+                sn err   Err(expr)
+                sn some  Some(expr)
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn call  function(expr)
+                sn let   let
+                sn letm  let mut
             "#]],
         );
 
@@ -427,84 +250,23 @@ fn foo() {
 "#,
             expect![[r#"
                 kw await expr.await
+                sn ref   &expr
+                sn refm  &mut expr
+                sn match match expr {}
+                sn box   Box::new(expr)
+                sn ok    Ok(expr)
+                sn err   Err(expr)
+                sn some  Some(expr)
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn call  function(expr)
+                sn let   let
+                sn letm  let mut
             "#]],
         )
     }
 
     #[test]
-    fn after_let() {
-        check(
-            r#"fn main() { let _ = $0 }"#,
-            expect![[r#"
-                kw unsafe
-                kw match
-                kw while
-                kw while let
-                kw loop
-                kw if
-                kw if let
-                kw for
-                kw true
-                kw false
-                kw return
-                kw self
-                kw super
-                kw crate
-            "#]],
-        )
-    }
-
-    #[test]
-    fn skip_struct_initializer() {
-        cov_mark::check!(no_keyword_completion_in_record_lit);
-        check(
-            r#"
-struct Foo {
-    pub f: i32,
-}
-fn foo() {
-    Foo {
-        $0
-    }
-}
-"#,
-            expect![[r#""#]],
-        );
-    }
-
-    #[test]
-    fn struct_initializer_field_expr() {
-        check(
-            r#"
-struct Foo {
-    pub f: i32,
-}
-fn foo() {
-    Foo {
-        f: $0
-    }
-}
-"#,
-            expect![[r#"
-                kw unsafe
-                kw match
-                kw while
-                kw while let
-                kw loop
-                kw if
-                kw if let
-                kw for
-                kw true
-                kw false
-                kw return
-                kw self
-                kw super
-                kw crate
-            "#]],
-        );
-    }
-
-    #[test]
     fn let_semi() {
         cov_mark::check!(let_semi);
         check_edit(
diff --git a/crates/ide_completion/src/completions/mod_.rs b/crates/ide_completion/src/completions/mod_.rs
index 1c864c0e708..28be83f196a 100644
--- a/crates/ide_completion/src/completions/mod_.rs
+++ b/crates/ide_completion/src/completions/mod_.rs
@@ -11,7 +11,7 @@ use rustc_hash::FxHashSet;
 
 use crate::{patterns::ImmediateLocation, CompletionItem};
 
-use crate::{context::CompletionContext, item::CompletionKind, Completions};
+use crate::{context::CompletionContext, Completions};
 
 /// Complete mod declaration, i.e. `mod $0 ;`
 pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
@@ -80,8 +80,7 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op
             if mod_under_caret.semicolon_token().is_none() {
                 label.push(';');
             }
-            let mut item = CompletionItem::new(CompletionKind::Magic, ctx.source_range(), &label);
-            item.kind(SymbolKind::Module);
+            let item = CompletionItem::new(SymbolKind::Module, ctx.source_range(), &label);
             item.add_to(acc)
         });
 
@@ -141,9 +140,10 @@ fn module_chain_to_containing_module_file(
 
 #[cfg(test)]
 mod tests {
-    use crate::tests::completion_list;
     use expect_test::{expect, Expect};
 
+    use crate::tests::completion_list;
+
     fn check(ra_fixture: &str, expect: Expect) {
         let actual = completion_list(ra_fixture);
         expect.assert_eq(&actual);
diff --git a/crates/ide_completion/src/completions/postfix.rs b/crates/ide_completion/src/completions/postfix.rs
index 4ace346768a..4ee257ab43a 100644
--- a/crates/ide_completion/src/completions/postfix.rs
+++ b/crates/ide_completion/src/completions/postfix.rs
@@ -15,11 +15,9 @@ use syntax::{
 use text_edit::TextEdit;
 
 use crate::{
-    completions::postfix::format_like::add_format_like_completions,
-    context::CompletionContext,
-    item::{Builder, CompletionKind},
-    patterns::ImmediateLocation,
-    CompletionItem, CompletionItemKind, CompletionRelevance, Completions, SnippetScope,
+    completions::postfix::format_like::add_format_like_completions, context::CompletionContext,
+    item::Builder, patterns::ImmediateLocation, CompletionItem, CompletionItemKind,
+    CompletionRelevance, Completions, SnippetScope,
 };
 
 pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
@@ -45,8 +43,9 @@ pub(crate) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) {
 
     // Suggest .await syntax for types that implement Future trait
     if receiver_ty.impls_future(ctx.db) {
-        let mut item = CompletionItem::new(CompletionKind::Keyword, ctx.source_range(), "await");
-        item.kind(CompletionItemKind::Keyword).detail("expr.await");
+        let mut item =
+            CompletionItem::new(CompletionItemKind::Keyword, ctx.source_range(), "await");
+        item.detail("expr.await");
         item.add_to(acc);
     }
 
@@ -224,8 +223,9 @@ fn build_postfix_snippet_builder<'ctx>(
     ) -> impl Fn(&str, &str, &str) -> Builder + 'ctx {
         move |label, detail, snippet| {
             let edit = TextEdit::replace(delete_range, snippet.to_string());
-            let mut item = CompletionItem::new(CompletionKind::Postfix, ctx.source_range(), label);
-            item.detail(detail).kind(CompletionItemKind::Snippet).snippet_edit(cap, edit);
+            let mut item =
+                CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), label);
+            item.detail(detail).snippet_edit(cap, edit);
             if ctx.original_token.text() == label {
                 let relevance =
                     CompletionRelevance { exact_postfix_snippet_match: true, ..Default::default() };
@@ -270,12 +270,12 @@ mod tests {
     use expect_test::{expect, Expect};
 
     use crate::{
-        tests::{check_edit, check_edit_with_config, filtered_completion_list, TEST_CONFIG},
-        CompletionConfig, CompletionKind, Snippet,
+        tests::{check_edit, check_edit_with_config, completion_list, TEST_CONFIG},
+        CompletionConfig, Snippet,
     };
 
     fn check(ra_fixture: &str, expect: Expect) {
-        let actual = filtered_completion_list(ra_fixture, CompletionKind::Postfix);
+        let actual = completion_list(ra_fixture);
         expect.assert_eq(&actual)
     }
 
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs
index f61baf184bb..e9d39edc43a 100644
--- a/crates/ide_completion/src/completions/qualified_path.rs
+++ b/crates/ide_completion/src/completions/qualified_path.rs
@@ -250,13 +250,10 @@ fn add_enum_variants(acc: &mut Completions, ctx: &CompletionContext, e: hir::Enu
 mod tests {
     use expect_test::{expect, Expect};
 
-    use crate::{
-        tests::{check_edit, filtered_completion_list},
-        CompletionKind,
-    };
+    use crate::tests::{check_edit, completion_list_no_kw};
 
     fn check(ra_fixture: &str, expect: Expect) {
-        let actual = filtered_completion_list(ra_fixture, CompletionKind::Reference);
+        let actual = completion_list_no_kw(ra_fixture);
         expect.assert_eq(&actual);
     }
 
diff --git a/crates/ide_completion/src/completions/record.rs b/crates/ide_completion/src/completions/record.rs
index 80132c2566a..f0c81f66bc8 100644
--- a/crates/ide_completion/src/completions/record.rs
+++ b/crates/ide_completion/src/completions/record.rs
@@ -3,8 +3,7 @@ use ide_db::{helpers::FamousDefs, SymbolKind};
 use syntax::{ast::Expr, T};
 
 use crate::{
-    item::CompletionKind, patterns::ImmediateLocation, CompletionContext, CompletionItem,
-    CompletionItemKind, Completions,
+    patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind, Completions,
 };
 
 pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
@@ -22,20 +21,17 @@ pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) ->
             let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);
             if impl_default_trait && !missing_fields.is_empty() && ctx.path_qual().is_none() {
                 let completion_text = "..Default::default()";
-                let mut item = CompletionItem::new(
-                    CompletionKind::Snippet,
-                    ctx.source_range(),
-                    completion_text,
-                );
+                let mut item =
+                    CompletionItem::new(SymbolKind::Field, ctx.source_range(), completion_text);
                 let completion_text =
                     completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text);
-                item.insert_text(completion_text).kind(SymbolKind::Field);
+                item.insert_text(completion_text);
                 item.add_to(acc);
             }
             if ctx.previous_token_is(T![.]) {
                 let mut item =
-                    CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), "..");
-                item.insert_text(".").kind(CompletionItemKind::Snippet);
+                    CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), "..");
+                item.insert_text(".");
                 item.add_to(acc);
                 return None;
             }
diff --git a/crates/ide_completion/src/completions/snippet.rs b/crates/ide_completion/src/completions/snippet.rs
index a0e5f56129e..1840e780edf 100644
--- a/crates/ide_completion/src/completions/snippet.rs
+++ b/crates/ide_completion/src/completions/snippet.rs
@@ -6,12 +6,12 @@ use syntax::T;
 
 use crate::{
     context::PathCompletionContext, item::Builder, CompletionContext, CompletionItem,
-    CompletionItemKind, CompletionKind, Completions, SnippetScope,
+    CompletionItemKind, Completions, SnippetScope,
 };
 
 fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder {
-    let mut item = CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), label);
-    item.insert_snippet(cap, snippet).kind(CompletionItemKind::Snippet);
+    let mut item = CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), label);
+    item.insert_snippet(cap, snippet);
     item
 }
 
diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs
index 31accd035f7..fc6ef5839c8 100644
--- a/crates/ide_completion/src/completions/trait_impl.rs
+++ b/crates/ide_completion/src/completions/trait_impl.rs
@@ -40,7 +40,7 @@ use syntax::{
 };
 use text_edit::TextEdit;
 
-use crate::{CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions};
+use crate::{CompletionContext, CompletionItem, CompletionItemKind, Completions};
 
 #[derive(Debug, PartialEq, Eq)]
 enum ImplCompletionKind {
@@ -141,14 +141,14 @@ fn add_function_impl(
         format!("fn {}(..)", fn_name)
     };
 
-    let mut item = CompletionItem::new(CompletionKind::Magic, ctx.source_range(), label);
-    item.lookup_by(fn_name).set_documentation(func.docs(ctx.db));
-
     let completion_kind = if func.self_param(ctx.db).is_some() {
         CompletionItemKind::Method
     } else {
         CompletionItemKind::SymbolKind(SymbolKind::Function)
     };
+    let mut item = CompletionItem::new(completion_kind, ctx.source_range(), label);
+    item.lookup_by(fn_name).set_documentation(func.docs(ctx.db));
+
     let range = replacement_range(ctx, fn_def_node);
 
     if let Some(source) = func.source(ctx.db) {
@@ -170,7 +170,6 @@ fn add_function_impl(
                     item.text_edit(TextEdit::replace(range, header));
                 }
             };
-            item.kind(completion_kind);
             item.add_to(acc);
         }
     }
@@ -211,10 +210,9 @@ fn add_type_alias_impl(
     let snippet = format!("type {} = ", alias_name);
 
     let range = replacement_range(ctx, type_def_node);
-    let mut item = CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone());
+    let mut item = CompletionItem::new(SymbolKind::TypeAlias, ctx.source_range(), snippet.clone());
     item.text_edit(TextEdit::replace(range, snippet))
         .lookup_by(alias_name)
-        .kind(SymbolKind::TypeAlias)
         .set_documentation(type_alias.docs(ctx.db));
     item.add_to(acc);
 }
@@ -241,10 +239,9 @@ fn add_const_impl(
 
                 let range = replacement_range(ctx, const_def_node);
                 let mut item =
-                    CompletionItem::new(CompletionKind::Magic, ctx.source_range(), snippet.clone());
+                    CompletionItem::new(SymbolKind::Const, ctx.source_range(), snippet.clone());
                 item.text_edit(TextEdit::replace(range, snippet))
                     .lookup_by(const_name)
-                    .kind(SymbolKind::Const)
                     .set_documentation(const_.docs(ctx.db));
                 item.add_to(acc);
             }
@@ -290,13 +287,10 @@ fn replacement_range(ctx: &CompletionContext, item: &SyntaxNode) -> TextRange {
 mod tests {
     use expect_test::{expect, Expect};
 
-    use crate::{
-        tests::{check_edit, filtered_completion_list},
-        CompletionKind,
-    };
+    use crate::tests::{check_edit, completion_list_no_kw};
 
     fn check(ra_fixture: &str, expect: Expect) {
-        let actual = filtered_completion_list(ra_fixture, CompletionKind::Magic);
+        let actual = completion_list_no_kw(ra_fixture);
         expect.assert_eq(&actual)
     }
 
@@ -313,7 +307,12 @@ impl Test for T {
     }
 }
 ",
-            expect![[""]],
+            expect![[r#"
+                sp Self
+                tt Test
+                st T
+                bt u32
+            "#]],
         );
 
         check(
@@ -356,7 +355,7 @@ impl Test for T {
     }
 }
 ",
-            expect![[""]],
+            expect![[r#""#]],
         );
 
         check(
@@ -368,7 +367,10 @@ impl Test for T {
     fn test(t$0)
 }
 ",
-            expect![[""]],
+            expect![[r#"
+                sp Self
+                st T
+            "#]],
         );
 
         check(
@@ -380,7 +382,10 @@ impl Test for T {
     fn test(f: fn $0)
 }
 ",
-            expect![[""]],
+            expect![[r#"
+                sp Self
+                st T
+            "#]],
         );
     }
 
@@ -395,7 +400,7 @@ impl Test for T {
     const TEST: fn $0
 }
 ",
-            expect![[""]],
+            expect![[r#""#]],
         );
 
         check(
@@ -407,7 +412,12 @@ impl Test for T {
     const TEST: T$0
 }
 ",
-            expect![[""]],
+            expect![[r#"
+                sp Self
+                tt Test
+                st T
+                bt u32
+            "#]],
         );
 
         check(
@@ -419,7 +429,12 @@ impl Test for T {
     const TEST: u32 = f$0
 }
 ",
-            expect![[""]],
+            expect![[r#"
+                sp Self
+                tt Test
+                st T
+                bt u32
+            "#]],
         );
 
         check(
@@ -433,7 +448,12 @@ impl Test for T {
     };
 }
 ",
-            expect![[""]],
+            expect![[r#"
+                sp Self
+                tt Test
+                st T
+                bt u32
+            "#]],
         );
 
         check(
@@ -476,7 +496,12 @@ impl Test for T {
     type Test = T$0;
 }
 ",
-            expect![[""]],
+            expect![[r#"
+                sp Self
+                tt Test
+                st T
+                bt u32
+            "#]],
         );
 
         check(
@@ -488,7 +513,12 @@ impl Test for T {
     type Test = fn $0;
 }
 ",
-            expect![[""]],
+            expect![[r#"
+                sp Self
+                tt Test
+                st T
+                bt u32
+            "#]],
         );
     }
 
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs
index afacf7fe03c..825fae587b1 100644
--- a/crates/ide_completion/src/completions/unqualified_path.rs
+++ b/crates/ide_completion/src/completions/unqualified_path.rs
@@ -117,24 +117,15 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC
 mod tests {
     use expect_test::{expect, Expect};
 
-    use crate::{
-        tests::{check_edit, filtered_completion_list_with_config, TEST_CONFIG},
-        CompletionConfig, CompletionKind,
-    };
+    use crate::tests::{check_edit, completion_list_no_kw};
 
     fn check(ra_fixture: &str, expect: Expect) {
-        check_with_config(TEST_CONFIG, ra_fixture, expect);
-    }
-
-    fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
-        let actual =
-            filtered_completion_list_with_config(config, ra_fixture, CompletionKind::Reference);
+        let actual = completion_list_no_kw(ra_fixture);
         expect.assert_eq(&actual)
     }
 
     #[test]
     fn completes_if_prefix_is_keyword() {
-        cov_mark::check!(completes_if_prefix_is_keyword);
         check_edit(
             "wherewolf",
             r#"
@@ -188,6 +179,7 @@ pub mod prelude {
 "#,
             expect![[r#"
                 md std
+                bt u32
                 st Option
             "#]],
         );
@@ -217,6 +209,7 @@ mod macros {
                 fn f()        fn()
                 ma concat!(…) #[macro_export] macro_rules! concat
                 md std
+                bt u32
             "##]],
         );
     }
@@ -245,6 +238,7 @@ pub mod prelude {
             expect![[r#"
                 md std
                 md core
+                bt u32
                 st String
             "#]],
         );
@@ -273,6 +267,7 @@ pub mod prelude {
             expect![[r#"
                 fn f() fn()
                 md std
+                bt u32
             "#]],
         );
     }
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs
index 4e3abff3b3f..0cb484d5075 100644
--- a/crates/ide_completion/src/context.rs
+++ b/crates/ide_completion/src/context.rs
@@ -134,7 +134,6 @@ impl<'a> CompletionContext<'a> {
         // check kind of macro-expanded token, but use range of original token
         let kind = self.token.kind();
         if kind == IDENT || kind == LIFETIME_IDENT || kind == UNDERSCORE || kind.is_keyword() {
-            cov_mark::hit!(completes_if_prefix_is_keyword);
             self.original_token.text_range()
         } else if kind == CHAR {
             // assume we are completing a lifetime but the user has only typed the '
diff --git a/crates/ide_completion/src/item.rs b/crates/ide_completion/src/item.rs
index a9eec472caf..3f0accfbe17 100644
--- a/crates/ide_completion/src/item.rs
+++ b/crates/ide_completion/src/item.rs
@@ -21,10 +21,6 @@ use text_edit::TextEdit;
 /// `CompletionItem`, use `new` method and the `Builder` struct.
 #[derive(Clone)]
 pub struct CompletionItem {
-    /// Used only internally in tests, to check only specific kind of
-    /// completion (postfix, keyword, reference, etc).
-    #[allow(unused)]
-    pub(crate) completion_kind: CompletionKind,
     /// Label in the completion pop up which identifies completion.
     label: String,
     /// Range of identifier that is being completed.
@@ -43,7 +39,7 @@ pub struct CompletionItem {
     is_snippet: bool,
 
     /// What item (struct, function, etc) are we completing.
-    kind: Option<CompletionItemKind>,
+    kind: CompletionItemKind,
 
     /// Lookup is used to check if completion item indeed can complete current
     /// ident.
@@ -92,9 +88,7 @@ impl fmt::Debug for CompletionItem {
         } else {
             s.field("text_edit", &self.text_edit);
         }
-        if let Some(kind) = self.kind().as_ref() {
-            s.field("kind", kind);
-        }
+        s.field("kind", &self.kind());
         if self.lookup() != self.label() {
             s.field("lookup", &self.lookup());
         }
@@ -270,32 +264,15 @@ impl CompletionItemKind {
     }
 }
 
-// FIXME remove this?
-/// Like [`CompletionItemKind`] but solely used for filtering test results.
-#[derive(Debug, PartialEq, Eq, Copy, Clone)]
-pub(crate) enum CompletionKind {
-    /// Parser-based keyword completion.
-    Keyword,
-    /// Your usual "complete all valid identifiers".
-    Reference,
-    /// "Secret sauce" completions.
-    Magic,
-    Snippet,
-    Postfix,
-    BuiltinType,
-    Attribute,
-}
-
 impl CompletionItem {
     pub(crate) fn new(
-        completion_kind: CompletionKind,
+        kind: impl Into<CompletionItemKind>,
         source_range: TextRange,
         label: impl Into<String>,
     ) -> Builder {
         let label = label.into();
         Builder {
             source_range,
-            completion_kind,
             label,
             insert_text: None,
             is_snippet: false,
@@ -303,7 +280,7 @@ impl CompletionItem {
             detail: None,
             documentation: None,
             lookup: None,
-            kind: None,
+            kind: kind.into(),
             text_edit: None,
             deprecated: false,
             trigger_call_info: None,
@@ -342,7 +319,7 @@ impl CompletionItem {
         self.lookup.as_deref().unwrap_or(&self.label)
     }
 
-    pub fn kind(&self) -> Option<CompletionItemKind> {
+    pub fn kind(&self) -> CompletionItemKind {
         self.kind
     }
 
@@ -401,7 +378,6 @@ impl ImportEdit {
 #[derive(Clone)]
 pub(crate) struct Builder {
     source_range: TextRange,
-    completion_kind: CompletionKind,
     imports_to_add: SmallVec<[ImportEdit; 1]>,
     trait_name: Option<String>,
     label: String,
@@ -410,7 +386,7 @@ pub(crate) struct Builder {
     detail: Option<String>,
     documentation: Option<Documentation>,
     lookup: Option<String>,
-    kind: Option<CompletionItemKind>,
+    kind: CompletionItemKind,
     text_edit: Option<TextEdit>,
     deprecated: bool,
     trigger_call_info: Option<bool>,
@@ -454,7 +430,6 @@ impl Builder {
             documentation: self.documentation,
             lookup,
             kind: self.kind,
-            completion_kind: self.completion_kind,
             deprecated: self.deprecated,
             trigger_call_info: self.trigger_call_info.unwrap_or(false),
             relevance: self.relevance,
@@ -487,10 +462,6 @@ impl Builder {
         self.is_snippet = true;
         self.insert_text(snippet)
     }
-    pub(crate) fn kind(&mut self, kind: impl Into<CompletionItemKind>) -> &mut Builder {
-        self.kind = Some(kind.into());
-        self
-    }
     pub(crate) fn text_edit(&mut self, edit: TextEdit) -> &mut Builder {
         self.text_edit = Some(edit);
         self
diff --git a/crates/ide_completion/src/lib.rs b/crates/ide_completion/src/lib.rs
index 6680e66c606..d555eff878c 100644
--- a/crates/ide_completion/src/lib.rs
+++ b/crates/ide_completion/src/lib.rs
@@ -24,7 +24,7 @@ use ide_db::{
 use syntax::algo;
 use text_edit::TextEdit;
 
-use crate::{completions::Completions, context::CompletionContext, item::CompletionKind};
+use crate::{completions::Completions, context::CompletionContext};
 
 pub use crate::{
     config::CompletionConfig,
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs
index 58443f566ef..4180d704a30 100644
--- a/crates/ide_completion/src/render.rs
+++ b/crates/ide_completion/src/render.rs
@@ -22,7 +22,7 @@ use crate::{
     context::{PathCompletionContext, PathKind},
     item::{CompletionRelevanceTypeMatch, ImportEdit},
     render::{enum_variant::render_variant, function::render_fn, macro_::render_macro},
-    CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance,
+    CompletionContext, CompletionItem, CompletionItemKind, CompletionRelevance,
 };
 /// Interface for data and methods required for items rendering.
 #[derive(Debug)]
@@ -85,7 +85,7 @@ pub(crate) fn render_field(
     let is_deprecated = ctx.is_deprecated(field);
     let name = field.name(ctx.db()).to_string();
     let mut item = CompletionItem::new(
-        CompletionKind::Reference,
+        SymbolKind::Field,
         ctx.source_range(),
         receiver.map_or_else(|| name.clone(), |receiver| format!("{}.{}", receiver, name)),
     );
@@ -94,8 +94,7 @@ pub(crate) fn render_field(
         exact_name_match: compute_exact_name_match(ctx.completion, name.as_str()),
         ..CompletionRelevance::default()
     });
-    item.kind(SymbolKind::Field)
-        .detail(ty.display(ctx.db()).to_string())
+    item.detail(ty.display(ctx.db()).to_string())
         .set_documentation(field.docs(ctx.db()))
         .set_deprecated(is_deprecated)
         .lookup_by(name.as_str());
@@ -118,13 +117,11 @@ pub(crate) fn render_tuple_field(
     ty: &hir::Type,
 ) -> CompletionItem {
     let mut item = CompletionItem::new(
-        CompletionKind::Reference,
+        SymbolKind::Field,
         ctx.source_range(),
         receiver.map_or_else(|| field.to_string(), |receiver| format!("{}.{}", receiver, field)),
     );
-    item.kind(SymbolKind::Field)
-        .detail(ty.display(ctx.db()).to_string())
-        .lookup_by(field.to_string());
+    item.detail(ty.display(ctx.db()).to_string()).lookup_by(field.to_string());
     item.build()
 }
 
@@ -147,10 +144,7 @@ pub(crate) fn render_resolution_with_import(
         hir::ScopeDef::ModuleDef(hir::ModuleDef::TypeAlias(t)) => t.name(ctx.completion.db),
         _ => item_name(ctx.db(), import_edit.import.original_item)?,
     };
-    render_resolution_(ctx, local_name, Some(import_edit), &resolution).map(|mut item| {
-        item.completion_kind = CompletionKind::Magic;
-        item
-    })
+    render_resolution_(ctx, local_name, Some(import_edit), &resolution)
 }
 
 fn render_resolution_(
@@ -162,11 +156,6 @@ fn render_resolution_(
     let _p = profile::span("render_resolution");
     use hir::ModuleDef::*;
 
-    let completion_kind = match resolution {
-        hir::ScopeDef::ModuleDef(BuiltinType(..)) => CompletionKind::BuiltinType,
-        _ => CompletionKind::Reference,
-    };
-
     let kind = match resolution {
         hir::ScopeDef::ModuleDef(Function(func)) => {
             return render_fn(ctx, import_to_add, Some(local_name), *func);
@@ -208,11 +197,10 @@ fn render_resolution_(
         }
         hir::ScopeDef::Unknown => {
             let mut item = CompletionItem::new(
-                CompletionKind::Reference,
+                CompletionItemKind::UnresolvedReference,
                 ctx.source_range(),
                 local_name.to_string(),
             );
-            item.kind(CompletionItemKind::UnresolvedReference);
             if let Some(import_to_add) = import_to_add {
                 item.add_import(import_to_add);
             }
@@ -221,7 +209,7 @@ fn render_resolution_(
     };
 
     let local_name = local_name.to_string();
-    let mut item = CompletionItem::new(completion_kind, ctx.source_range(), local_name.clone());
+    let mut item = CompletionItem::new(kind, ctx.source_range(), local_name.clone());
     if let hir::ScopeDef::Local(local) = resolution {
         let ty = local.ty(ctx.db());
         if !ty.is_unknown() {
@@ -260,8 +248,7 @@ fn render_resolution_(
             }
         }
     }
-    item.kind(kind)
-        .set_documentation(scope_def_docs(ctx.db(), resolution))
+    item.set_documentation(scope_def_docs(ctx.db(), resolution))
         .set_deprecated(scope_def_is_deprecated(&ctx, resolution));
 
     if let Some(import_to_add) = import_to_add {
@@ -344,37 +331,54 @@ mod tests {
     use std::cmp;
 
     use expect_test::{expect, Expect};
+    use ide_db::SymbolKind;
     use itertools::Itertools;
 
     use crate::{
         item::CompletionRelevanceTypeMatch,
         tests::{check_edit, do_completion, get_all_items, TEST_CONFIG},
-        CompletionKind, CompletionRelevance,
+        CompletionItem, CompletionItemKind, CompletionRelevance,
     };
 
     #[track_caller]
-    fn check(ra_fixture: &str, expect: Expect) {
-        let actual = do_completion(ra_fixture, CompletionKind::Reference);
+    fn check(ra_fixture: &str, kind: impl Into<CompletionItemKind>, expect: Expect) {
+        let actual = do_completion(ra_fixture, kind.into());
         expect.assert_debug_eq(&actual);
     }
 
     #[track_caller]
-    fn check_relevance(ra_fixture: &str, expect: Expect) {
-        check_relevance_for_kinds(&[CompletionKind::Reference], ra_fixture, expect)
+    fn check_kinds(ra_fixture: &str, kinds: &[CompletionItemKind], expect: Expect) {
+        let actual: Vec<_> =
+            kinds.iter().flat_map(|&kind| do_completion(ra_fixture, kind)).collect();
+        expect.assert_debug_eq(&actual);
+    }
+
+    #[track_caller]
+    fn check_relevance_for_kinds(ra_fixture: &str, kinds: &[CompletionItemKind], expect: Expect) {
+        let mut actual = get_all_items(TEST_CONFIG, ra_fixture);
+        actual.retain(|it| kinds.contains(&it.kind()));
+        actual.sort_by_key(|it| cmp::Reverse(it.relevance().score()));
+        check_relevance_(actual, expect);
     }
 
     #[track_caller]
-    fn check_relevance_for_kinds(kinds: &[CompletionKind], ra_fixture: &str, expect: Expect) {
+    fn check_relevance(ra_fixture: &str, expect: Expect) {
         let mut actual = get_all_items(TEST_CONFIG, ra_fixture);
-        actual.retain(|it| kinds.contains(&it.completion_kind));
+        actual.retain(|it| it.kind() != CompletionItemKind::Snippet);
+        actual.retain(|it| it.kind() != CompletionItemKind::Keyword);
+        actual.retain(|it| it.kind() != CompletionItemKind::BuiltinType);
         actual.sort_by_key(|it| cmp::Reverse(it.relevance().score()));
+        check_relevance_(actual, expect);
+    }
 
+    #[track_caller]
+    fn check_relevance_(actual: Vec<CompletionItem>, expect: Expect) {
         let actual = actual
             .into_iter()
             .flat_map(|it| {
                 let mut items = vec![];
 
-                let tag = it.kind().unwrap().tag();
+                let tag = it.kind().tag();
                 let relevance = display_relevance(it.relevance());
                 items.push(format!("{} {} {}\n", tag, it.label(), relevance));
 
@@ -418,6 +422,7 @@ enum Foo { Foo { x: i32, y: i32 } }
 
 fn main() { Foo::Fo$0 }
 "#,
+            SymbolKind::Variant,
             expect![[r#"
                 [
                     CompletionItem {
@@ -443,6 +448,7 @@ enum Foo { Foo (i32, i32) }
 
 fn main() { Foo::Fo$0 }
 "#,
+            SymbolKind::Variant,
             expect![[r#"
                 [
                     CompletionItem {
@@ -470,6 +476,7 @@ fn foo<T>(a: u32, b: u32, t: T) -> (u32, T) { (a, t) }
 
 fn main() { fo$0 }
 "#,
+            SymbolKind::Function,
             expect![[r#"
                 [
                     CompletionItem {
@@ -508,6 +515,7 @@ enum Foo { Foo }
 
 fn main() { Foo::Fo$0 }
 "#,
+            SymbolKind::Variant,
             expect![[r#"
                 [
                     CompletionItem {
@@ -527,16 +535,41 @@ fn main() { Foo::Fo$0 }
 
     #[test]
     fn lookup_enums_by_two_qualifiers() {
-        check(
+        check_kinds(
             r#"
 mod m {
     pub enum Spam { Foo, Bar(i32) }
 }
 fn main() { let _: m::Spam = S$0 }
 "#,
+            &[
+                CompletionItemKind::SymbolKind(SymbolKind::Function),
+                CompletionItemKind::SymbolKind(SymbolKind::Module),
+                CompletionItemKind::SymbolKind(SymbolKind::Variant),
+            ],
             expect![[r#"
                 [
                     CompletionItem {
+                        label: "main()",
+                        source_range: 75..76,
+                        delete: 75..76,
+                        insert: "main()$0",
+                        kind: SymbolKind(
+                            Function,
+                        ),
+                        lookup: "main",
+                        detail: "fn()",
+                    },
+                    CompletionItem {
+                        label: "m",
+                        source_range: 75..76,
+                        delete: 75..76,
+                        insert: "m",
+                        kind: SymbolKind(
+                            Module,
+                        ),
+                    },
+                    CompletionItem {
                         label: "Spam::Bar(…)",
                         source_range: 75..76,
                         delete: 75..76,
@@ -557,15 +590,6 @@ fn main() { let _: m::Spam = S$0 }
                         trigger_call_info: true,
                     },
                     CompletionItem {
-                        label: "m",
-                        source_range: 75..76,
-                        delete: 75..76,
-                        insert: "m",
-                        kind: SymbolKind(
-                            Module,
-                        ),
-                    },
-                    CompletionItem {
                         label: "m::Spam::Foo",
                         source_range: 75..76,
                         delete: 75..76,
@@ -584,17 +608,6 @@ fn main() { let _: m::Spam = S$0 }
                             exact_postfix_snippet_match: false,
                         },
                     },
-                    CompletionItem {
-                        label: "main()",
-                        source_range: 75..76,
-                        delete: 75..76,
-                        insert: "main()$0",
-                        kind: SymbolKind(
-                            Function,
-                        ),
-                        lookup: "main",
-                        detail: "fn()",
-                    },
                 ]
             "#]],
         )
@@ -611,6 +624,7 @@ fn something_else_deprecated() {}
 
 fn main() { som$0 }
 "#,
+            SymbolKind::Function,
             expect![[r#"
                 [
                     CompletionItem {
@@ -657,6 +671,7 @@ fn main() { som$0 }
 struct A { #[deprecated] the_field: u32 }
 fn foo() { A { the$0 } }
 "#,
+            SymbolKind::Field,
             expect![[r#"
                 [
                     CompletionItem {
@@ -685,7 +700,7 @@ fn foo() { A { the$0 } }
 
     #[test]
     fn renders_docs() {
-        check(
+        check_kinds(
             r#"
 struct S {
     /// Field docs
@@ -695,6 +710,7 @@ impl S {
     /// Method docs
     fn bar(self) { self.$0 }
 }"#,
+            &[CompletionItemKind::Method, CompletionItemKind::SymbolKind(SymbolKind::Field)],
             expect![[r#"
                 [
                     CompletionItem {
@@ -726,7 +742,7 @@ impl S {
             "#]],
         );
 
-        check(
+        check_kinds(
             r#"
 use self::my$0;
 
@@ -740,18 +756,23 @@ enum E {
 }
 use self::E::*;
 "#,
+            &[
+                CompletionItemKind::SymbolKind(SymbolKind::Module),
+                CompletionItemKind::SymbolKind(SymbolKind::Variant),
+                CompletionItemKind::SymbolKind(SymbolKind::Enum),
+            ],
             expect![[r#"
                 [
                     CompletionItem {
-                        label: "E",
+                        label: "my",
                         source_range: 10..12,
                         delete: 10..12,
-                        insert: "E",
+                        insert: "my",
                         kind: SymbolKind(
-                            Enum,
+                            Module,
                         ),
                         documentation: Documentation(
-                            "enum docs",
+                            "mod docs",
                         ),
                     },
                     CompletionItem {
@@ -768,15 +789,15 @@ use self::E::*;
                         ),
                     },
                     CompletionItem {
-                        label: "my",
+                        label: "E",
                         source_range: 10..12,
                         delete: 10..12,
-                        insert: "my",
+                        insert: "E",
                         kind: SymbolKind(
-                            Module,
+                            Enum,
                         ),
                         documentation: Documentation(
-                            "mod docs",
+                            "enum docs",
                         ),
                     },
                 ]
@@ -795,6 +816,7 @@ impl S {
 }
 fn foo(s: S) { s.$0 }
 "#,
+            CompletionItemKind::Method,
             expect![[r#"
                 [
                     CompletionItem {
@@ -1318,19 +1340,29 @@ fn main() {
 
     #[test]
     fn struct_field_method_ref() {
-        check(
+        check_kinds(
             r#"
 struct Foo { bar: u32 }
 impl Foo { fn baz(&self) -> u32 { 0 } }
 
 fn foo(f: Foo) { let _: &u32 = f.b$0 }
 "#,
+            &[CompletionItemKind::Method, CompletionItemKind::SymbolKind(SymbolKind::Field)],
             // FIXME
             // Ideally we'd also suggest &f.bar and &f.baz() as exact
             // type matches. See #8058.
             expect![[r#"
                 [
                     CompletionItem {
+                        label: "baz()",
+                        source_range: 98..99,
+                        delete: 98..99,
+                        insert: "baz()$0",
+                        kind: Method,
+                        lookup: "baz",
+                        detail: "fn(&self) -> u32",
+                    },
+                    CompletionItem {
                         label: "bar",
                         source_range: 98..99,
                         delete: 98..99,
@@ -1340,15 +1372,6 @@ fn foo(f: Foo) { let _: &u32 = f.b$0 }
                         ),
                         detail: "u32",
                     },
-                    CompletionItem {
-                        label: "baz()",
-                        source_range: 98..99,
-                        delete: 98..99,
-                        insert: "baz()$0",
-                        kind: Method,
-                        lookup: "baz",
-                        detail: "fn(&self) -> u32",
-                    },
                 ]
             "#]],
         );
@@ -1387,7 +1410,6 @@ fn foo() {
     #[test]
     fn postfix_completion_relevance() {
         check_relevance_for_kinds(
-            &[CompletionKind::Postfix, CompletionKind::Magic],
             r#"
 mod ops {
     pub trait Not {
@@ -1404,7 +1426,8 @@ mod ops {
 fn main() {
     let _: bool = (9 > 2).not$0;
 }
-"#,
+    "#,
+            &[CompletionItemKind::Snippet, CompletionItemKind::Method],
             expect![[r#"
                 sn not [snippet]
                 me not() (use ops::Not) [type_could_unify]
diff --git a/crates/ide_completion/src/render/const_.rs b/crates/ide_completion/src/render/const_.rs
index 166ae3c16bc..241e0043c9c 100644
--- a/crates/ide_completion/src/render/const_.rs
+++ b/crates/ide_completion/src/render/const_.rs
@@ -7,10 +7,7 @@ use syntax::{
     display::const_label,
 };
 
-use crate::{
-    item::{CompletionItem, CompletionKind},
-    render::RenderContext,
-};
+use crate::{item::CompletionItem, render::RenderContext};
 
 pub(crate) fn render_const(ctx: RenderContext<'_>, const_: hir::Const) -> Option<CompletionItem> {
     ConstRender::new(ctx, const_)?.render()
@@ -34,9 +31,8 @@ impl<'a> ConstRender<'a> {
         let detail = self.detail();
 
         let mut item =
-            CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), name.clone());
-        item.kind(SymbolKind::Const)
-            .set_documentation(self.ctx.docs(self.const_))
+            CompletionItem::new(SymbolKind::Const, self.ctx.source_range(), name.clone());
+        item.set_documentation(self.ctx.docs(self.const_))
             .set_deprecated(
                 self.ctx.is_deprecated(self.const_)
                     || self.ctx.is_deprecated_assoc_item(self.const_),
diff --git a/crates/ide_completion/src/render/enum_variant.rs b/crates/ide_completion/src/render/enum_variant.rs
index 95768713cf5..728e0e2a174 100644
--- a/crates/ide_completion/src/render/enum_variant.rs
+++ b/crates/ide_completion/src/render/enum_variant.rs
@@ -7,7 +7,7 @@ use ide_db::SymbolKind;
 use itertools::Itertools;
 
 use crate::{
-    item::{CompletionItem, CompletionKind, ImportEdit},
+    item::{CompletionItem, ImportEdit},
     render::{builder_ext::Params, compute_ref_match, compute_type_match, RenderContext},
     CompletionRelevance,
 };
@@ -61,12 +61,11 @@ impl<'a> EnumRender<'a> {
     }
     fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem {
         let mut item = CompletionItem::new(
-            CompletionKind::Reference,
+            SymbolKind::Variant,
             self.ctx.source_range(),
             self.qualified_name.to_string(),
         );
-        item.kind(SymbolKind::Variant)
-            .set_documentation(self.variant.docs(self.ctx.db()))
+        item.set_documentation(self.variant.docs(self.ctx.db()))
             .set_deprecated(self.ctx.is_deprecated(self.variant))
             .detail(self.detail());
 
diff --git a/crates/ide_completion/src/render/function.rs b/crates/ide_completion/src/render/function.rs
index 769a0ed21f5..7515bb6d47d 100644
--- a/crates/ide_completion/src/render/function.rs
+++ b/crates/ide_completion/src/render/function.rs
@@ -7,7 +7,7 @@ use itertools::Itertools;
 use syntax::ast;
 
 use crate::{
-    item::{CompletionItem, CompletionItemKind, CompletionKind, CompletionRelevance, ImportEdit},
+    item::{CompletionItem, CompletionItemKind, CompletionRelevance, ImportEdit},
     render::{
         builder_ext::Params, compute_exact_name_match, compute_ref_match, compute_type_match,
         RenderContext,
@@ -79,10 +79,8 @@ impl<'a> FunctionRender<'a> {
             Some(receiver) => format!("{}.{}", receiver, &self.name),
             None => self.name.clone(),
         };
-        let mut item =
-            CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), call.clone());
-        item.kind(self.kind())
-            .set_documentation(self.ctx.docs(self.func))
+        let mut item = CompletionItem::new(self.kind(), self.ctx.source_range(), call.clone());
+        item.set_documentation(self.ctx.docs(self.func))
             .set_deprecated(
                 self.ctx.is_deprecated(self.func) || self.ctx.is_deprecated_assoc_item(self.func),
             )
diff --git a/crates/ide_completion/src/render/macro_.rs b/crates/ide_completion/src/render/macro_.rs
index 196b667baac..b1ddfab0cbb 100644
--- a/crates/ide_completion/src/render/macro_.rs
+++ b/crates/ide_completion/src/render/macro_.rs
@@ -6,7 +6,7 @@ use syntax::display::macro_label;
 
 use crate::{
     context::CallKind,
-    item::{CompletionItem, CompletionKind, ImportEdit},
+    item::{CompletionItem, ImportEdit},
     render::RenderContext,
 };
 
@@ -47,9 +47,8 @@ impl<'a> MacroRender<'a> {
         } else {
             Some(self.ctx.source_range())
         }?;
-        let mut item = CompletionItem::new(CompletionKind::Reference, source_range, &self.label());
-        item.kind(SymbolKind::Macro)
-            .set_documentation(self.docs.clone())
+        let mut item = CompletionItem::new(SymbolKind::Macro, source_range, &self.label());
+        item.set_documentation(self.docs.clone())
             .set_deprecated(self.ctx.is_deprecated(self.macro_))
             .set_detail(self.detail());
 
diff --git a/crates/ide_completion/src/render/pattern.rs b/crates/ide_completion/src/render/pattern.rs
index 521296fd9b7..b7032806204 100644
--- a/crates/ide_completion/src/render/pattern.rs
+++ b/crates/ide_completion/src/render/pattern.rs
@@ -6,7 +6,6 @@ use itertools::Itertools;
 
 use crate::{
     context::{ParamKind, PatternContext},
-    item::CompletionKind,
     render::RenderContext,
     CompletionItem, CompletionItemKind,
 };
@@ -58,11 +57,8 @@ fn build_completion(
     pat: String,
     def: impl HasAttrs + Copy,
 ) -> CompletionItem {
-    let mut item = CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), name);
-    item.kind(CompletionItemKind::Binding)
-        .set_documentation(ctx.docs(def))
-        .set_deprecated(ctx.is_deprecated(def))
-        .detail(&pat);
+    let mut item = CompletionItem::new(CompletionItemKind::Binding, ctx.source_range(), name);
+    item.set_documentation(ctx.docs(def)).set_deprecated(ctx.is_deprecated(def)).detail(&pat);
     match ctx.snippet_cap() {
         Some(snippet_cap) => item.insert_snippet(snippet_cap, pat),
         None => item.insert_text(pat),
diff --git a/crates/ide_completion/src/render/struct_literal.rs b/crates/ide_completion/src/render/struct_literal.rs
index 810b51effd3..4eb4f6b9f12 100644
--- a/crates/ide_completion/src/render/struct_literal.rs
+++ b/crates/ide_completion/src/render/struct_literal.rs
@@ -4,7 +4,7 @@ use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind};
 use ide_db::helpers::SnippetCap;
 use itertools::Itertools;
 
-use crate::{item::CompletionKind, render::RenderContext, CompletionItem, CompletionItemKind};
+use crate::{render::RenderContext, CompletionItem, CompletionItemKind};
 
 pub(crate) fn render_struct_literal(
     ctx: RenderContext<'_>,
@@ -33,11 +33,9 @@ fn build_completion(
     literal: String,
     def: impl HasAttrs + Copy,
 ) -> CompletionItem {
-    let mut item = CompletionItem::new(CompletionKind::Snippet, ctx.source_range(), name + " {…}");
-    item.kind(CompletionItemKind::Snippet)
-        .set_documentation(ctx.docs(def))
-        .set_deprecated(ctx.is_deprecated(def))
-        .detail(&literal);
+    let mut item =
+        CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), name + " {…}");
+    item.set_documentation(ctx.docs(def)).set_deprecated(ctx.is_deprecated(def)).detail(&literal);
     match ctx.snippet_cap() {
         Some(snippet_cap) => item.insert_snippet(snippet_cap, literal),
         None => item.insert_text(literal),
diff --git a/crates/ide_completion/src/render/type_alias.rs b/crates/ide_completion/src/render/type_alias.rs
index c1e61826430..7b6d2fa5c3a 100644
--- a/crates/ide_completion/src/render/type_alias.rs
+++ b/crates/ide_completion/src/render/type_alias.rs
@@ -7,10 +7,7 @@ use syntax::{
     display::type_label,
 };
 
-use crate::{
-    item::{CompletionItem, CompletionKind},
-    render::RenderContext,
-};
+use crate::{item::CompletionItem, render::RenderContext};
 
 pub(crate) fn render_type_alias(
     ctx: RenderContext<'_>,
@@ -50,9 +47,8 @@ impl<'a> TypeAliasRender<'a> {
         let detail = self.detail();
 
         let mut item =
-            CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), name.clone());
-        item.kind(SymbolKind::TypeAlias)
-            .set_documentation(self.ctx.docs(self.type_alias))
+            CompletionItem::new(SymbolKind::TypeAlias, self.ctx.source_range(), name.clone());
+        item.set_documentation(self.ctx.docs(self.type_alias))
             .set_deprecated(
                 self.ctx.is_deprecated(self.type_alias)
                     || self.ctx.is_deprecated_assoc_item(self.type_alias),
diff --git a/crates/ide_completion/src/tests.rs b/crates/ide_completion/src/tests.rs
index 4028fc2242f..f063a9638ca 100644
--- a/crates/ide_completion/src/tests.rs
+++ b/crates/ide_completion/src/tests.rs
@@ -20,6 +20,7 @@ mod record;
 mod type_pos;
 mod use_tree;
 mod visibility;
+mod flyimport;
 
 use std::mem;
 
@@ -37,7 +38,7 @@ use stdx::{format_to, trim_indent};
 use syntax::{AstNode, NodeOrToken, SyntaxElement};
 use test_utils::assert_eq_text;
 
-use crate::{item::CompletionKind, CompletionConfig, CompletionItem};
+use crate::{CompletionConfig, CompletionItem, CompletionItemKind};
 
 /// Lots of basic item definitions
 const BASE_ITEMS_FIXTURE: &str = r#"
@@ -77,18 +78,28 @@ pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig {
 };
 
 pub(crate) fn completion_list(ra_fixture: &str) -> String {
-    completion_list_with_config(TEST_CONFIG, ra_fixture)
+    completion_list_with_config(TEST_CONFIG, ra_fixture, true)
 }
 
-fn completion_list_with_config(config: CompletionConfig, ra_fixture: &str) -> String {
+pub(crate) fn completion_list_no_kw(ra_fixture: &str) -> String {
+    completion_list_with_config(TEST_CONFIG, ra_fixture, false)
+}
+
+fn completion_list_with_config(
+    config: CompletionConfig,
+    ra_fixture: &str,
+    include_keywords: bool,
+) -> String {
     // filter out all but one builtintype completion for smaller test outputs
     let items = get_all_items(config, ra_fixture);
     let mut bt_seen = false;
     let items = items
         .into_iter()
         .filter(|it| {
-            it.completion_kind != CompletionKind::BuiltinType || !mem::replace(&mut bt_seen, true)
+            it.kind() != CompletionItemKind::BuiltinType || !mem::replace(&mut bt_seen, true)
         })
+        .filter(|it| include_keywords || it.kind() != CompletionItemKind::Keyword)
+        .filter(|it| include_keywords || it.kind() != CompletionItemKind::Snippet)
         .collect();
     render_completion_list(items)
 }
@@ -104,36 +115,22 @@ pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) {
     (database, FilePosition { file_id, offset })
 }
 
-pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> {
+pub(crate) fn do_completion(code: &str, kind: CompletionItemKind) -> Vec<CompletionItem> {
     do_completion_with_config(TEST_CONFIG, code, kind)
 }
 
 pub(crate) fn do_completion_with_config(
     config: CompletionConfig,
     code: &str,
-    kind: CompletionKind,
+    kind: CompletionItemKind,
 ) -> Vec<CompletionItem> {
     get_all_items(config, code)
         .into_iter()
-        .filter(|c| c.completion_kind == kind)
+        .filter(|c| c.kind() == kind)
         .sorted_by(|l, r| l.label().cmp(r.label()))
         .collect()
 }
 
-pub(crate) fn filtered_completion_list(code: &str, kind: CompletionKind) -> String {
-    filtered_completion_list_with_config(TEST_CONFIG, code, kind)
-}
-
-pub(crate) fn filtered_completion_list_with_config(
-    config: CompletionConfig,
-    code: &str,
-    kind: CompletionKind,
-) -> String {
-    let kind_completions: Vec<CompletionItem> =
-        get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect();
-    render_completion_list(kind_completions)
-}
-
 fn render_completion_list(completions: Vec<CompletionItem>) -> String {
     fn monospace_width(s: &str) -> usize {
         s.chars().count()
@@ -143,7 +140,7 @@ fn render_completion_list(completions: Vec<CompletionItem>) -> String {
     completions
         .into_iter()
         .map(|it| {
-            let tag = it.kind().unwrap().tag();
+            let tag = it.kind().tag();
             let var_name = format!("{} {}", tag, it.label());
             let mut buf = var_name;
             if let Some(detail) = it.detail() {
@@ -254,3 +251,37 @@ fn foo() {
 "#,
     );
 }
+
+#[test]
+fn no_completions_in_comments() {
+    cov_mark::check!(no_keyword_completion_in_comments);
+    assert_eq!(
+        completion_list(
+            r#"
+fn test() {
+let x = 2; // A comment$0
+}
+"#,
+        ),
+        String::new(),
+    );
+    assert_eq!(
+        completion_list(
+            r#"
+/*
+Some multi-line comment$0
+*/
+"#,
+        ),
+        String::new(),
+    );
+    assert_eq!(
+        completion_list(
+            r#"
+/// Some doc comment
+/// let test$0 = 1
+"#,
+        ),
+        String::new(),
+    );
+}
diff --git a/crates/ide_completion/src/tests/expression.rs b/crates/ide_completion/src/tests/expression.rs
index 9a42dd7b275..a6348087344 100644
--- a/crates/ide_completion/src/tests/expression.rs
+++ b/crates/ide_completion/src/tests/expression.rs
@@ -110,7 +110,7 @@ fn func(param0 @ (param1, param2): (i32, i32)) {
 }
 
 #[test]
-fn completes_all_the_things() {
+fn completes_all_the_things_in_fn_body() {
     cov_mark::check!(unqualified_skip_lifetime_completion);
     check(
         r#"
@@ -207,6 +207,223 @@ impl Unit {
 }
 
 #[test]
+fn complete_in_block() {
+    check_empty(
+        r#"
+    fn foo() {
+        if true {
+            $0
+        }
+    }
+"#,
+        expect![[r#"
+            kw unsafe
+            kw fn
+            kw const
+            kw type
+            kw impl
+            kw extern
+            kw use
+            kw trait
+            kw static
+            kw mod
+            kw match
+            kw while
+            kw while let
+            kw loop
+            kw if
+            kw if let
+            kw for
+            kw true
+            kw false
+            kw let
+            kw return
+            sn pd
+            sn ppd
+            kw self
+            kw super
+            kw crate
+            fn foo()     fn()
+            bt u32
+        "#]],
+    )
+}
+
+#[test]
+fn complete_after_if_expr() {
+    check_empty(
+        r#"
+    fn foo() {
+        if true {}
+        $0
+    }
+"#,
+        expect![[r#"
+            kw unsafe
+            kw fn
+            kw const
+            kw type
+            kw impl
+            kw extern
+            kw use
+            kw trait
+            kw static
+            kw mod
+            kw match
+            kw while
+            kw while let
+            kw loop
+            kw if
+            kw if let
+            kw for
+            kw true
+            kw false
+            kw let
+            kw else
+            kw else if
+            kw return
+            sn pd
+            sn ppd
+            kw self
+            kw super
+            kw crate
+            fn foo()     fn()
+            bt u32
+        "#]],
+    )
+}
+
+#[test]
+fn complete_in_match_arm() {
+    check_empty(
+        r#"
+    fn foo() {
+        match () {
+            () => $0
+        }
+    }
+"#,
+        expect![[r#"
+            kw unsafe
+            kw match
+            kw while
+            kw while let
+            kw loop
+            kw if
+            kw if let
+            kw for
+            kw true
+            kw false
+            kw return
+            kw self
+            kw super
+            kw crate
+            fn foo()     fn()
+            bt u32
+        "#]],
+    )
+}
+
+#[test]
+fn completes_in_loop_ctx() {
+    check_empty(
+        r"fn my() { loop { $0 } }",
+        expect![[r#"
+            kw unsafe
+            kw fn
+            kw const
+            kw type
+            kw impl
+            kw extern
+            kw use
+            kw trait
+            kw static
+            kw mod
+            kw match
+            kw while
+            kw while let
+            kw loop
+            kw if
+            kw if let
+            kw for
+            kw true
+            kw false
+            kw let
+            kw continue
+            kw break
+            kw return
+            sn pd
+            sn ppd
+            kw self
+            kw super
+            kw crate
+            fn my()      fn()
+            bt u32
+        "#]],
+    );
+}
+
+#[test]
+fn completes_in_let_initializer() {
+    check_empty(
+        r#"fn main() { let _ = $0 }"#,
+        expect![[r#"
+            kw unsafe
+            kw match
+            kw while
+            kw while let
+            kw loop
+            kw if
+            kw if let
+            kw for
+            kw true
+            kw false
+            kw return
+            kw self
+            kw super
+            kw crate
+            fn main()    fn()
+            bt u32
+        "#]],
+    )
+}
+
+#[test]
+fn struct_initializer_field_expr() {
+    check_empty(
+        r#"
+struct Foo {
+    pub f: i32,
+}
+fn foo() {
+    Foo {
+        f: $0
+    }
+}
+"#,
+        expect![[r#"
+            kw unsafe
+            kw match
+            kw while
+            kw while let
+            kw loop
+            kw if
+            kw if let
+            kw for
+            kw true
+            kw false
+            kw return
+            kw self
+            kw super
+            kw crate
+            st Foo
+            fn foo()     fn()
+            bt u32
+        "#]],
+    );
+}
+
+#[test]
 fn shadowing_shows_single_completion() {
     cov_mark::check!(shadowing_shows_single_completion);
 
diff --git a/crates/ide_completion/src/tests/flyimport.rs b/crates/ide_completion/src/tests/flyimport.rs
new file mode 100644
index 00000000000..201443e10c2
--- /dev/null
+++ b/crates/ide_completion/src/tests/flyimport.rs
@@ -0,0 +1,1014 @@
+use expect_test::{expect, Expect};
+
+use crate::tests::{check_edit, check_edit_with_config, TEST_CONFIG};
+
+fn check(ra_fixture: &str, expect: Expect) {
+    let config = TEST_CONFIG;
+    let (db, position) = crate::tests::position(ra_fixture);
+    let ctx = crate::context::CompletionContext::new(&db, position, &config).unwrap();
+
+    let mut acc = crate::completions::Completions::default();
+    crate::completions::flyimport::import_on_the_fly(&mut acc, &ctx);
+
+    expect.assert_eq(&super::render_completion_list(Vec::from(acc)));
+}
+
+#[test]
+fn function_fuzzy_completion() {
+    check_edit(
+        "stdin",
+        r#"
+//- /lib.rs crate:dep
+pub mod io {
+    pub fn stdin() {}
+};
+
+//- /main.rs crate:main deps:dep
+fn main() {
+    stdi$0
+}
+"#,
+        r#"
+use dep::io::stdin;
+
+fn main() {
+    stdin()$0
+}
+"#,
+    );
+}
+
+#[test]
+fn macro_fuzzy_completion() {
+    check_edit(
+        "macro_with_curlies!",
+        r#"
+//- /lib.rs crate:dep
+/// Please call me as macro_with_curlies! {}
+#[macro_export]
+macro_rules! macro_with_curlies {
+    () => {}
+}
+
+//- /main.rs crate:main deps:dep
+fn main() {
+    curli$0
+}
+"#,
+        r#"
+use dep::macro_with_curlies;
+
+fn main() {
+    macro_with_curlies! {$0}
+}
+"#,
+    );
+}
+
+#[test]
+fn struct_fuzzy_completion() {
+    check_edit(
+        "ThirdStruct",
+        r#"
+//- /lib.rs crate:dep
+pub struct FirstStruct;
+pub mod some_module {
+    pub struct SecondStruct;
+    pub struct ThirdStruct;
+}
+
+//- /main.rs crate:main deps:dep
+use dep::{FirstStruct, some_module::SecondStruct};
+
+fn main() {
+    this$0
+}
+"#,
+        r#"
+use dep::{FirstStruct, some_module::{SecondStruct, ThirdStruct}};
+
+fn main() {
+    ThirdStruct
+}
+"#,
+    );
+}
+
+#[test]
+fn short_paths_are_ignored() {
+    cov_mark::check!(ignore_short_input_for_path);
+
+    check(
+        r#"
+//- /lib.rs crate:dep
+pub struct FirstStruct;
+pub mod some_module {
+    pub struct SecondStruct;
+    pub struct ThirdStruct;
+}
+
+//- /main.rs crate:main deps:dep
+use dep::{FirstStruct, some_module::SecondStruct};
+
+fn main() {
+    t$0
+}
+"#,
+        expect![[r#""#]],
+    );
+}
+
+#[test]
+fn fuzzy_completions_come_in_specific_order() {
+    cov_mark::check!(certain_fuzzy_order_test);
+    check(
+        r#"
+//- /lib.rs crate:dep
+pub struct FirstStruct;
+pub mod some_module {
+    // already imported, omitted
+    pub struct SecondStruct;
+    // does not contain all letters from the query, omitted
+    pub struct UnrelatedOne;
+    // contains all letters from the query, but not in sequence, displayed last
+    pub struct ThiiiiiirdStruct;
+    // contains all letters from the query, but not in the beginning, displayed second
+    pub struct AfterThirdStruct;
+    // contains all letters from the query in the begginning, displayed first
+    pub struct ThirdStruct;
+}
+
+//- /main.rs crate:main deps:dep
+use dep::{FirstStruct, some_module::SecondStruct};
+
+fn main() {
+    hir$0
+}
+"#,
+        expect![[r#"
+                st ThirdStruct (use dep::some_module::ThirdStruct)
+                st AfterThirdStruct (use dep::some_module::AfterThirdStruct)
+                st ThiiiiiirdStruct (use dep::some_module::ThiiiiiirdStruct)
+            "#]],
+    );
+}
+
+#[test]
+fn trait_function_fuzzy_completion() {
+    let fixture = r#"
+        //- /lib.rs crate:dep
+        pub mod test_mod {
+            pub trait TestTrait {
+                const SPECIAL_CONST: u8;
+                type HumbleType;
+                fn weird_function();
+                fn random_method(&self);
+            }
+            pub struct TestStruct {}
+            impl TestTrait for TestStruct {
+                const SPECIAL_CONST: u8 = 42;
+                type HumbleType = ();
+                fn weird_function() {}
+                fn random_method(&self) {}
+            }
+        }
+
+        //- /main.rs crate:main deps:dep
+        fn main() {
+            dep::test_mod::TestStruct::wei$0
+        }
+        "#;
+
+    check(
+        fixture,
+        expect![[r#"
+                fn weird_function() (use dep::test_mod::TestTrait) fn()
+            "#]],
+    );
+
+    check_edit(
+        "weird_function",
+        fixture,
+        r#"
+use dep::test_mod::TestTrait;
+
+fn main() {
+    dep::test_mod::TestStruct::weird_function()$0
+}
+"#,
+    );
+}
+
+#[test]
+fn trait_const_fuzzy_completion() {
+    let fixture = r#"
+        //- /lib.rs crate:dep
+        pub mod test_mod {
+            pub trait TestTrait {
+                const SPECIAL_CONST: u8;
+                type HumbleType;
+                fn weird_function();
+                fn random_method(&self);
+            }
+            pub struct TestStruct {}
+            impl TestTrait for TestStruct {
+                const SPECIAL_CONST: u8 = 42;
+                type HumbleType = ();
+                fn weird_function() {}
+                fn random_method(&self) {}
+            }
+        }
+
+        //- /main.rs crate:main deps:dep
+        fn main() {
+            dep::test_mod::TestStruct::spe$0
+        }
+        "#;
+
+    check(
+        fixture,
+        expect![[r#"
+            ct SPECIAL_CONST (use dep::test_mod::TestTrait)
+        "#]],
+    );
+
+    check_edit(
+        "SPECIAL_CONST",
+        fixture,
+        r#"
+use dep::test_mod::TestTrait;
+
+fn main() {
+    dep::test_mod::TestStruct::SPECIAL_CONST
+}
+"#,
+    );
+}
+
+#[test]
+fn trait_method_fuzzy_completion() {
+    let fixture = r#"
+        //- /lib.rs crate:dep
+        pub mod test_mod {
+            pub trait TestTrait {
+                const SPECIAL_CONST: u8;
+                type HumbleType;
+                fn weird_function();
+                fn random_method(&self);
+            }
+            pub struct TestStruct {}
+            impl TestTrait for TestStruct {
+                const SPECIAL_CONST: u8 = 42;
+                type HumbleType = ();
+                fn weird_function() {}
+                fn random_method(&self) {}
+            }
+        }
+
+        //- /main.rs crate:main deps:dep
+        fn main() {
+            let test_struct = dep::test_mod::TestStruct {};
+            test_struct.ran$0
+        }
+        "#;
+
+    check(
+        fixture,
+        expect![[r#"
+                me random_method() (use dep::test_mod::TestTrait) fn(&self)
+            "#]],
+    );
+
+    check_edit(
+        "random_method",
+        fixture,
+        r#"
+use dep::test_mod::TestTrait;
+
+fn main() {
+    let test_struct = dep::test_mod::TestStruct {};
+    test_struct.random_method()$0
+}
+"#,
+    );
+}
+
+#[test]
+fn no_trait_type_fuzzy_completion() {
+    check(
+        r#"
+//- /lib.rs crate:dep
+pub mod test_mod {
+    pub trait TestTrait {
+        const SPECIAL_CONST: u8;
+        type HumbleType;
+        fn weird_function();
+        fn random_method(&self);
+    }
+    pub struct TestStruct {}
+    impl TestTrait for TestStruct {
+        const SPECIAL_CONST: u8 = 42;
+        type HumbleType = ();
+        fn weird_function() {}
+        fn random_method(&self) {}
+    }
+}
+
+//- /main.rs crate:main deps:dep
+fn main() {
+    dep::test_mod::TestStruct::hum$0
+}
+"#,
+        expect![[r#""#]],
+    );
+}
+
+#[test]
+fn does_not_propose_names_in_scope() {
+    check(
+        r#"
+//- /lib.rs crate:dep
+pub mod test_mod {
+    pub trait TestTrait {
+        const SPECIAL_CONST: u8;
+        type HumbleType;
+        fn weird_function();
+        fn random_method(&self);
+    }
+    pub struct TestStruct {}
+    impl TestTrait for TestStruct {
+        const SPECIAL_CONST: u8 = 42;
+        type HumbleType = ();
+        fn weird_function() {}
+        fn random_method(&self) {}
+    }
+}
+
+//- /main.rs crate:main deps:dep
+use dep::test_mod::TestStruct;
+fn main() {
+    TestSt$0
+}
+"#,
+        expect![[r#""#]],
+    );
+}
+
+#[test]
+fn does_not_propose_traits_in_scope() {
+    check(
+        r#"
+//- /lib.rs crate:dep
+pub mod test_mod {
+    pub trait TestTrait {
+        const SPECIAL_CONST: u8;
+        type HumbleType;
+        fn weird_function();
+        fn random_method(&self);
+    }
+    pub struct TestStruct {}
+    impl TestTrait for TestStruct {
+        const SPECIAL_CONST: u8 = 42;
+        type HumbleType = ();
+        fn weird_function() {}
+        fn random_method(&self) {}
+    }
+}
+
+//- /main.rs crate:main deps:dep
+use dep::test_mod::{TestStruct, TestTrait};
+fn main() {
+    dep::test_mod::TestStruct::hum$0
+}
+"#,
+        expect![[r#""#]],
+    );
+}
+
+#[test]
+fn blanket_trait_impl_import() {
+    check_edit(
+        "another_function",
+        r#"
+//- /lib.rs crate:dep
+pub mod test_mod {
+    pub struct TestStruct {}
+    pub trait TestTrait {
+        fn another_function();
+    }
+    impl<T> TestTrait for T {
+        fn another_function() {}
+    }
+}
+
+//- /main.rs crate:main deps:dep
+fn main() {
+    dep::test_mod::TestStruct::ano$0
+}
+"#,
+        r#"
+use dep::test_mod::TestTrait;
+
+fn main() {
+    dep::test_mod::TestStruct::another_function()$0
+}
+"#,
+    );
+}
+
+#[test]
+fn zero_input_deprecated_assoc_item_completion() {
+    check(
+        r#"
+//- /lib.rs crate:dep
+pub mod test_mod {
+    #[deprecated]
+    pub trait TestTrait {
+        const SPECIAL_CONST: u8;
+        type HumbleType;
+        fn weird_function();
+        fn random_method(&self);
+    }
+    pub struct TestStruct {}
+    impl TestTrait for TestStruct {
+        const SPECIAL_CONST: u8 = 42;
+        type HumbleType = ();
+        fn weird_function() {}
+        fn random_method(&self) {}
+    }
+}
+
+//- /main.rs crate:main deps:dep
+fn main() {
+    let test_struct = dep::test_mod::TestStruct {};
+    test_struct.$0
+}
+        "#,
+        expect![[r#"
+                me random_method() (use dep::test_mod::TestTrait) fn(&self) DEPRECATED
+            "#]],
+    );
+
+    check(
+        r#"
+//- /lib.rs crate:dep
+pub mod test_mod {
+    #[deprecated]
+    pub trait TestTrait {
+        const SPECIAL_CONST: u8;
+        type HumbleType;
+        fn weird_function();
+        fn random_method(&self);
+    }
+    pub struct TestStruct {}
+    impl TestTrait for TestStruct {
+        const SPECIAL_CONST: u8 = 42;
+        type HumbleType = ();
+        fn weird_function() {}
+        fn random_method(&self) {}
+    }
+}
+
+//- /main.rs crate:main deps:dep
+fn main() {
+    dep::test_mod::TestStruct::$0
+}
+"#,
+        expect![[r#"
+                fn weird_function() (use dep::test_mod::TestTrait) fn() DEPRECATED
+                ct SPECIAL_CONST (use dep::test_mod::TestTrait) DEPRECATED
+            "#]],
+    );
+}
+
+#[test]
+fn no_completions_in_use_statements() {
+    check(
+        r#"
+//- /lib.rs crate:dep
+pub mod io {
+    pub fn stdin() {}
+};
+
+//- /main.rs crate:main deps:dep
+use stdi$0
+
+fn main() {}
+"#,
+        expect![[]],
+    );
+}
+
+#[test]
+fn prefix_config_usage() {
+    let fixture = r#"
+mod foo {
+    pub mod bar {
+        pub struct Item;
+    }
+}
+
+use crate::foo::bar;
+
+fn main() {
+    Ite$0
+}"#;
+    let mut config = TEST_CONFIG;
+
+    config.insert_use.prefix_kind = hir::PrefixKind::ByCrate;
+    check_edit_with_config(
+        config.clone(),
+        "Item",
+        fixture,
+        r#"
+mod foo {
+    pub mod bar {
+        pub struct Item;
+    }
+}
+
+use crate::foo::bar::{self, Item};
+
+fn main() {
+    Item
+}"#,
+    );
+
+    config.insert_use.prefix_kind = hir::PrefixKind::BySelf;
+    check_edit_with_config(
+        config.clone(),
+        "Item",
+        fixture,
+        r#"
+mod foo {
+    pub mod bar {
+        pub struct Item;
+    }
+}
+
+use crate::foo::bar;
+
+use self::foo::bar::Item;
+
+fn main() {
+    Item
+}"#,
+    );
+
+    config.insert_use.prefix_kind = hir::PrefixKind::Plain;
+    check_edit_with_config(
+        config,
+        "Item",
+        fixture,
+        r#"
+mod foo {
+    pub mod bar {
+        pub struct Item;
+    }
+}
+
+use foo::bar::Item;
+
+use crate::foo::bar;
+
+fn main() {
+    Item
+}"#,
+    );
+}
+
+#[test]
+fn unresolved_qualifier() {
+    let fixture = r#"
+mod foo {
+    pub mod bar {
+        pub mod baz {
+            pub struct Item;
+        }
+    }
+}
+
+fn main() {
+    bar::baz::Ite$0
+}"#;
+
+    check(
+        fixture,
+        expect![[r#"
+        st Item (use foo::bar::baz::Item)
+        "#]],
+    );
+
+    check_edit(
+        "Item",
+        fixture,
+        r#"
+        use foo::bar;
+
+        mod foo {
+            pub mod bar {
+                pub mod baz {
+                    pub struct Item;
+                }
+            }
+        }
+
+        fn main() {
+            bar::baz::Item
+        }"#,
+    );
+}
+
+#[test]
+fn unresolved_assoc_item_container() {
+    let fixture = r#"
+mod foo {
+    pub struct Item;
+
+    impl Item {
+        pub const TEST_ASSOC: usize = 3;
+    }
+}
+
+fn main() {
+    Item::TEST_A$0
+}"#;
+
+    check(
+        fixture,
+        expect![[r#"
+        ct TEST_ASSOC (use foo::Item)
+        "#]],
+    );
+
+    check_edit(
+        "TEST_ASSOC",
+        fixture,
+        r#"
+use foo::Item;
+
+mod foo {
+    pub struct Item;
+
+    impl Item {
+        pub const TEST_ASSOC: usize = 3;
+    }
+}
+
+fn main() {
+    Item::TEST_ASSOC
+}"#,
+    );
+}
+
+#[test]
+fn unresolved_assoc_item_container_with_path() {
+    let fixture = r#"
+mod foo {
+    pub mod bar {
+        pub struct Item;
+
+        impl Item {
+            pub const TEST_ASSOC: usize = 3;
+        }
+    }
+}
+
+fn main() {
+    bar::Item::TEST_A$0
+}"#;
+
+    check(
+        fixture,
+        expect![[r#"
+        ct TEST_ASSOC (use foo::bar::Item)
+    "#]],
+    );
+
+    check_edit(
+        "TEST_ASSOC",
+        fixture,
+        r#"
+use foo::bar;
+
+mod foo {
+    pub mod bar {
+        pub struct Item;
+
+        impl Item {
+            pub const TEST_ASSOC: usize = 3;
+        }
+    }
+}
+
+fn main() {
+    bar::Item::TEST_ASSOC
+}"#,
+    );
+}
+
+#[test]
+fn fuzzy_unresolved_path() {
+    check(
+        r#"
+mod foo {
+    pub mod bar {
+        pub struct Item;
+
+        impl Item {
+            pub const TEST_ASSOC: usize = 3;
+        }
+    }
+}
+
+fn main() {
+    bar::ASS$0
+}"#,
+        expect![[]],
+    )
+}
+
+#[test]
+fn unqualified_assoc_items_are_omitted() {
+    check(
+        r#"
+mod something {
+    pub trait BaseTrait {
+        fn test_function() -> i32;
+    }
+
+    pub struct Item1;
+    pub struct Item2;
+
+    impl BaseTrait for Item1 {
+        fn test_function() -> i32 {
+            1
+        }
+    }
+
+    impl BaseTrait for Item2 {
+        fn test_function() -> i32 {
+            2
+        }
+    }
+}
+
+fn main() {
+    test_f$0
+}"#,
+        expect![[]],
+    )
+}
+
+#[test]
+fn case_matters() {
+    check(
+        r#"
+mod foo {
+    pub const TEST_CONST: usize = 3;
+    pub fn test_function() -> i32 {
+        4
+    }
+}
+
+fn main() {
+    TE$0
+}"#,
+        expect![[r#"
+        ct TEST_CONST (use foo::TEST_CONST)
+    "#]],
+    );
+
+    check(
+        r#"
+mod foo {
+    pub const TEST_CONST: usize = 3;
+    pub fn test_function() -> i32 {
+        4
+    }
+}
+
+fn main() {
+    te$0
+}"#,
+        expect![[r#"
+        ct TEST_CONST (use foo::TEST_CONST)
+        fn test_function() (use foo::test_function) fn() -> i32
+    "#]],
+    );
+
+    check(
+        r#"
+mod foo {
+    pub const TEST_CONST: usize = 3;
+    pub fn test_function() -> i32 {
+        4
+    }
+}
+
+fn main() {
+    Te$0
+}"#,
+        expect![[]],
+    );
+}
+
+#[test]
+fn no_fuzzy_during_fields_of_record_lit_syntax() {
+    check(
+        r#"
+mod m {
+    pub fn some_fn() -> i32 {
+        42
+    }
+}
+struct Foo {
+    some_field: i32,
+}
+fn main() {
+    let _ = Foo { so$0 };
+}
+"#,
+        expect![[]],
+    );
+}
+
+#[test]
+fn fuzzy_after_fields_of_record_lit_syntax() {
+    check(
+        r#"
+mod m {
+    pub fn some_fn() -> i32 {
+        42
+    }
+}
+struct Foo {
+    some_field: i32,
+}
+fn main() {
+    let _ = Foo { some_field: so$0 };
+}
+"#,
+        expect![[r#"
+                fn some_fn() (use m::some_fn) fn() -> i32
+            "#]],
+    );
+}
+
+#[test]
+fn no_flyimports_in_traits_and_impl_declarations() {
+    check(
+        r#"
+mod m {
+    pub fn some_fn() -> i32 {
+        42
+    }
+}
+trait Foo {
+    som$0
+}
+"#,
+        expect![[r#""#]],
+    );
+
+    check(
+        r#"
+mod m {
+    pub fn some_fn() -> i32 {
+        42
+    }
+}
+struct Foo;
+impl Foo {
+    som$0
+}
+"#,
+        expect![[r#""#]],
+    );
+
+    check(
+        r#"
+mod m {
+    pub fn some_fn() -> i32 {
+        42
+    }
+}
+struct Foo;
+trait Bar {}
+impl Bar for Foo {
+    som$0
+}
+"#,
+        expect![[r#""#]],
+    );
+}
+
+#[test]
+fn no_inherent_candidates_proposed() {
+    check(
+        r#"
+mod baz {
+    pub trait DefDatabase {
+        fn method1(&self);
+    }
+    pub trait HirDatabase: DefDatabase {
+        fn method2(&self);
+    }
+}
+
+mod bar {
+    fn test(db: &dyn crate::baz::HirDatabase) {
+        db.metho$0
+    }
+}
+            "#,
+        expect![[r#""#]],
+    );
+}
+
+#[test]
+fn respects_doc_hidden() {
+    check(
+        r#"
+//- /lib.rs crate:lib deps:dep
+fn f() {
+    ().fro$0
+}
+
+//- /dep.rs crate:dep
+#[doc(hidden)]
+pub trait Private {
+    fn frob(&self) {}
+}
+
+impl<T> Private for T {}
+            "#,
+        expect![[r#""#]],
+    );
+    check(
+        r#"
+//- /lib.rs crate:lib deps:dep
+fn f() {
+    ().fro$0
+}
+
+//- /dep.rs crate:dep
+pub trait Private {
+    #[doc(hidden)]
+    fn frob(&self) {}
+}
+
+impl<T> Private for T {}
+            "#,
+        expect![[r#""#]],
+    );
+}
+
+#[test]
+fn regression_9760() {
+    check(
+        r#"
+struct Struct;
+fn main() {}
+
+mod mud {
+    fn func() {
+        let struct_instance = Stru$0
+    }
+}
+"#,
+        expect![[r#"
+                st Struct (use crate::Struct)
+            "#]],
+    );
+}
+
+#[test]
+fn flyimport_pattern() {
+    check(
+        r#"
+mod module {
+    pub struct Struct;
+}
+fn function() {
+    let Str$0
+}
+"#,
+        expect![[r#"
+                st Struct (use module::Struct)
+            "#]],
+    );
+}
+
+#[test]
+fn flyimport_rename() {
+    check(
+        r#"
+mod module {
+    pub struct Struct;
+}
+use self as Str$0;
+    "#,
+        expect![[r#""#]],
+    );
+}
diff --git a/crates/ide_completion/src/tests/record.rs b/crates/ide_completion/src/tests/record.rs
index 30b1f2c1c97..e09e99aad5e 100644
--- a/crates/ide_completion/src/tests/record.rs
+++ b/crates/ide_completion/src/tests/record.rs
@@ -9,6 +9,7 @@ fn check(ra_fixture: &str, expect: Expect) {
 
 #[test]
 fn without_default_impl() {
+    cov_mark::check!(no_keyword_completion_in_record_lit);
     check(
         r#"
 struct Struct { foo: u32, bar: usize }
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index b17711d6a64..473b7a870f4 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -248,7 +248,7 @@ fn completion_item(
         label: item.label().to_string(),
         detail: item.detail().map(|it| it.to_string()),
         filter_text: Some(item.lookup().to_string()),
-        kind: item.kind().map(completion_item_kind),
+        kind: Some(completion_item_kind(item.kind())),
         text_edit: Some(text_edit),
         additional_text_edits: Some(additional_text_edits),
         documentation: item.documentation().map(documentation),
diff --git a/crates/rust-analyzer/tests/slow-tests/tidy.rs b/crates/rust-analyzer/tests/slow-tests/tidy.rs
index 9be9f3afeaf..5debb9fb3d1 100644
--- a/crates/rust-analyzer/tests/slow-tests/tidy.rs
+++ b/crates/rust-analyzer/tests/slow-tests/tidy.rs
@@ -313,6 +313,7 @@ fn check_dbg(path: &Path, text: &str) {
         "handlers/remove_dbg.rs",
         // We have .dbg postfix
         "ide_completion/src/completions/postfix.rs",
+        "ide_completion/src/completions/keyword.rs",
         "ide_completion/src/tests/proc_macros.rs",
         // The documentation in string literals may contain anything for its own purposes
         "ide_completion/src/lib.rs",