]> git.lizzy.rs Git - rust.git/commitdiff
Merge #6921
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>
Sun, 20 Dec 2020 11:47:01 +0000 (11:47 +0000)
committerGitHub <noreply@github.com>
Sun, 20 Dec 2020 11:47:01 +0000 (11:47 +0000)
6921: Higher-ranked trait bounds for where clauses r=flodiebold a=Veykril

There is a slight problem with this which is also noted in a FIXME now but `LifetimeParameters` of these ForLifetime where clauses allocate the lifetimes in the corresponding arena as if they were lifetimes of the item itself and not just the clause they belong to. I wasn't entirely sure what I could do about this but given nothing really uses lifetimes like that currently I figured it might be fine? Open to suggestions for that problem.

Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
85 files changed:
Cargo.lock
crates/assists/src/handlers/extract_struct_from_enum_variant.rs
crates/assists/src/handlers/fill_match_arms.rs
crates/assists/src/handlers/fix_visibility.rs
crates/assists/src/handlers/generate_function.rs
crates/completion/src/completions.rs
crates/completion/src/completions/attribute.rs
crates/completion/src/completions/dot.rs
crates/completion/src/completions/keyword.rs
crates/completion/src/completions/mod_.rs
crates/completion/src/completions/pattern.rs
crates/completion/src/completions/postfix.rs
crates/completion/src/completions/qualified_path.rs
crates/completion/src/completions/record.rs
crates/completion/src/completions/snippet.rs
crates/completion/src/completions/trait_impl.rs
crates/completion/src/completions/unqualified_path.rs
crates/completion/src/render.rs
crates/completion/src/render/enum_variant.rs
crates/completion/src/render/macro_.rs
crates/completion/src/test_utils.rs
crates/hir/src/attrs.rs
crates/hir/src/code_model.rs
crates/hir/src/from_id.rs
crates/hir/src/has_source.rs
crates/hir/src/lib.rs
crates/hir/src/semantics.rs
crates/hir/src/source_analyzer.rs
crates/hir_def/src/adt.rs
crates/hir_def/src/attr.rs
crates/hir_def/src/body.rs
crates/hir_def/src/body/lower.rs
crates/hir_def/src/data.rs
crates/hir_def/src/item_tree.rs
crates/hir_def/src/item_tree/lower.rs
crates/hir_def/src/lib.rs
crates/hir_def/src/nameres/collector.rs
crates/hir_def/src/nameres/tests.rs
crates/hir_def/src/nameres/tests/diagnostics.rs
crates/hir_def/src/nameres/tests/macros.rs
crates/hir_def/src/path.rs
crates/hir_expand/src/name.rs
crates/ide/src/call_hierarchy.rs
crates/ide/src/diagnostics/fixes.rs
crates/ide/src/display.rs
crates/ide/src/display/navigation_target.rs
crates/ide/src/doc_links.rs
crates/ide/src/file_structure.rs
crates/ide/src/goto_definition.rs
crates/ide/src/hover.rs
crates/ide/src/lib.rs
crates/ide/src/parent_module.rs
crates/ide/src/references.rs
crates/ide/src/references/rename.rs
crates/ide/src/runnables.rs
crates/ide/src/syntax_highlighting.rs
crates/ide/src/syntax_highlighting/format.rs
crates/ide/src/syntax_highlighting/injection.rs
crates/ide/src/syntax_highlighting/tags.rs
crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
crates/ide/src/syntax_highlighting/test_data/highlighting.html
crates/ide_db/src/defs.rs
crates/ide_db/src/helpers/insert_use.rs
crates/ide_db/src/helpers/insert_use/tests.rs
crates/ide_db/src/search.rs
crates/ide_db/src/symbol_index.rs
crates/mbe/src/mbe_expander/transcriber.rs
crates/mbe/src/parser.rs
crates/mbe/src/syntax_bridge.rs
crates/mbe/src/tests.rs
crates/parser/src/grammar.rs
crates/parser/src/lib.rs
crates/project_model/src/cargo_workspace.rs
crates/rust-analyzer/Cargo.toml
crates/rust-analyzer/src/caps.rs
crates/rust-analyzer/src/handlers.rs
crates/rust-analyzer/src/to_proto.rs
crates/syntax/src/ast/make.rs
crates/syntax/src/lib.rs
editors/code/package-lock.json
editors/code/package.json
editors/code/src/main.ts

index 4476d188bc3bf06f91dc0079f12bf4b656fbaba9..1051c4ec63ec9888520914f2792740c378139f49 100644 (file)
@@ -26,9 +26,9 @@ dependencies = [
 
 [[package]]
 name = "anyhow"
-version = "1.0.35"
+version = "1.0.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2c0df63cb2955042487fad3aefd2c6e3ae7389ac5dc1beb28921de0b69f779d4"
+checksum = "68803225a7b13e47191bab76f2687382b60d259e8cf37f6e1893658b84bb9479"
 
 [[package]]
 name = "anymap"
@@ -685,9 +685,9 @@ dependencies = [
 
 [[package]]
 name = "indexmap"
-version = "1.6.0"
+version = "1.6.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
+checksum = "4fb1fa934250de4de8aef298d81c729a7d33d8c239daa3a7575e6b92bfc7313b"
 dependencies = [
  "autocfg",
  "hashbrown",
@@ -844,9 +844,9 @@ dependencies = [
 
 [[package]]
 name = "lsp-types"
-version = "0.85.0"
+version = "0.86.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "857650f3e83fb62f89d15410414e0ed7d0735445020da398d37f65d20a5423b9"
+checksum = "f2a5c40d566f2704dac30859bca152217583fc94fd5b178d8baba915e1abd382"
 dependencies = [
  "base64",
  "bitflags",
@@ -1105,9 +1105,9 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
 
 [[package]]
 name = "perf-event"
-version = "0.4.5"
+version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "273069d0b956939ba75e8b5663328b9b7f0dc2e262b3306c6be66c4d87e2240a"
+checksum = "b7a1c2678a77d65edf773bd900f5b87f0944ac3421949842a2c6a4efe42d6c66"
 dependencies = [
  "libc",
  "perf-event-open-sys",
@@ -1990,18 +1990,18 @@ dependencies = [
 
 [[package]]
 name = "xshell"
-version = "0.1.7"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed0728d188f2ae530490b7d92435728aba53c6aed06d07e1951da9bd4c1d0798"
+checksum = "ed373ede30cea03e8c0af22f48ee1ba80efbf06fec8b4746977e6ee703878de0"
 dependencies = [
  "xshell-macros",
 ]
 
 [[package]]
 name = "xshell-macros"
-version = "0.1.7"
+version = "0.1.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "367f903cc3f8bc4f4b2400d47dfa6c9e3e121ffb51a30cf0fb67a72c0a0f9617"
+checksum = "7f6af9f8119104697b0105989a73c578ce33f922d9d6f3dae0e8ae3d538db321"
 
 [[package]]
 name = "xtask"
index 2e56bd7ffc057df7a26e9396ad9a974008d51366..030b9cd0c7d9f7992db9641e852afae002bbe520 100644 (file)
@@ -1,7 +1,7 @@
 use std::iter;
 
 use either::Either;
-use hir::{AsName, EnumVariant, Module, ModuleDef, Name};
+use hir::{AsName, Module, ModuleDef, Name, Variant};
 use ide_db::helpers::{
     insert_use::{insert_use, ImportScope},
     mod_path_to_ast,
@@ -53,7 +53,7 @@ pub(crate) fn extract_struct_from_enum_variant(
             let variant_hir_name = variant_hir.name(ctx.db());
             let enum_module_def = ModuleDef::from(enum_hir);
             let usages =
-                Definition::ModuleDef(ModuleDef::EnumVariant(variant_hir)).usages(&ctx.sema).all();
+                Definition::ModuleDef(ModuleDef::Variant(variant_hir)).usages(&ctx.sema).all();
 
             let mut visited_modules_set = FxHashSet::default();
             let current_module = enum_hir.module(ctx.db());
@@ -109,7 +109,7 @@ fn extract_field_list_if_applicable(
     }
 }
 
-fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &EnumVariant) -> bool {
+fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Variant) -> bool {
     variant
         .parent_enum(db)
         .module(db)
@@ -119,7 +119,7 @@ fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &En
             // only check type-namespace
             hir::ScopeDef::ModuleDef(def) => matches!(def,
                 ModuleDef::Module(_) | ModuleDef::Adt(_) |
-                ModuleDef::EnumVariant(_) | ModuleDef::Trait(_) |
+                ModuleDef::Variant(_) | ModuleDef::Trait(_) |
                 ModuleDef::TypeAlias(_) | ModuleDef::BuiltinType(_)
             ),
             _ => false,
index ef12ef0cf1adc44d1322219457fc89146e5aa010..cb60a3128288be989b11ffd267bf9f18faf7534d 100644 (file)
@@ -192,7 +192,7 @@ fn resolve_tuple_of_enum_def(
         .collect()
 }
 
-fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> Option<ast::Pat> {
+fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::Variant) -> Option<ast::Pat> {
     let path = mod_path_to_ast(&module.find_use_path(db, ModuleDef::from(var))?);
 
     // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though
index c867207877bc0a396ab2a96f0ab615a4b567db9b..8558a8ff01ce0c282caf96d284b905eea2c0aeb3 100644 (file)
@@ -201,7 +201,7 @@ fn offset_target_and_file_id<S, Ast>(
             (vis_offset(syntax), in_file_source.value.visibility(), syntax.text_range(), file_id)
         }
         // Enum variants can't be private, we can't modify builtin types
-        hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None,
+        hir::ModuleDef::Variant(_) | hir::ModuleDef::BuiltinType(_) => return None,
     };
 
     Some((offset, current_visibility, target, target_file, target_name))
index 758188a42956aa7133706a7e84f893156699b6df..f4cf155b6306ab9e04bf7ac40bb16ed9fdcc3239 100644 (file)
@@ -145,7 +145,7 @@ fn render(self) -> FunctionTemplate {
             self.type_params,
             self.params,
             fn_body,
-            Some(make::ret_type(make::ty("()"))),
+            Some(make::ret_type(make::ty_unit())),
         );
         let leading_ws;
         let trailing_ws;
index 9b7d6c5809131b2819176037086402d516113267..1ef6b5f48f1dd9bb5353ac01a1927191b7f3a2a4 100644 (file)
@@ -19,7 +19,7 @@
 use crate::{
     item::Builder,
     render::{
-        const_::render_const, enum_variant::render_enum_variant, function::render_fn,
+        const_::render_const, enum_variant::render_variant, function::render_fn,
         macro_::render_macro, render_field, render_resolution, render_tuple_field,
         type_alias::render_type_alias, RenderContext,
     },
@@ -120,20 +120,20 @@ pub(crate) fn add_type_alias(&mut self, ctx: &CompletionContext, type_alias: hir
     pub(crate) fn add_qualified_enum_variant(
         &mut self,
         ctx: &CompletionContext,
-        variant: hir::EnumVariant,
+        variant: hir::Variant,
         path: ModPath,
     ) {
-        let item = render_enum_variant(RenderContext::new(ctx), None, None, variant, Some(path));
+        let item = render_variant(RenderContext::new(ctx), None, None, variant, Some(path));
         self.add(item);
     }
 
     pub(crate) fn add_enum_variant(
         &mut self,
         ctx: &CompletionContext,
-        variant: hir::EnumVariant,
+        variant: hir::Variant,
         local_name: Option<String>,
     ) {
-        let item = render_enum_variant(RenderContext::new(ctx), None, local_name, variant, None);
+        let item = render_variant(RenderContext::new(ctx), None, local_name, variant, None);
         self.add(item);
     }
 }
index acce2e7e7a5d09c935f45426e130f52bab7c0c37..19ce2482fd4babf364e2dcdd42754a7e445a0b76 100644 (file)
@@ -428,8 +428,8 @@ struct Test {}
                 at Hash
                 at PartialEq
                 at PartialEq, Eq
-                at PartialEq, Eq, PartialOrd, Ord
                 at PartialEq, PartialOrd
+                at PartialEq, Eq, PartialOrd, Ord
             "#]],
         );
     }
@@ -457,10 +457,10 @@ struct Test {}
                 at Clone, Copy
                 at Debug
                 at Default
-                at Eq
-                at Eq, PartialOrd, Ord
                 at Hash
+                at Eq
                 at PartialOrd
+                at Eq, PartialOrd, Ord
             "#]],
         )
     }
@@ -472,14 +472,14 @@ fn test_attribute_completion() {
             expect![[r#"
                 at allow(…)
                 at automatically_derived
-                at cfg(…)
                 at cfg_attr(…)
+                at cfg(…)
                 at cold
                 at deny(…)
                 at deprecated = "…"
                 at derive(…)
-                at doc = "…"
                 at export_name = "…"
+                at doc = "…"
                 at forbid(…)
                 at ignore = "…"
                 at inline(…)
@@ -518,15 +518,15 @@ fn test_inner_attribute_completion() {
             expect![[r#"
                 at allow(…)
                 at automatically_derived
-                at cfg(…)
                 at cfg_attr(…)
+                at cfg(…)
                 at cold
                 at crate_name = ""
                 at deny(…)
                 at deprecated = "…"
                 at derive(…)
-                at doc = "…"
                 at export_name = "…"
+                at doc = "…"
                 at feature(…)
                 at forbid(…)
                 at global_allocator
@@ -538,8 +538,8 @@ fn test_inner_attribute_completion() {
                 at macro_export
                 at macro_use
                 at must_use = "…"
-                at no_implicit_prelude
                 at no_link
+                at no_implicit_prelude
                 at no_main
                 at no_mangle
                 at no_std
index c9875045ad4676367058f49684b62c807005ebff..551ef17716d1fc4799c8ca4fdc03c302c0eca03d 100644 (file)
@@ -82,8 +82,8 @@ fn bar(&self) {}
 fn foo(s: S) { s.<|> }
 "#,
             expect![[r#"
-                me bar() fn bar(&self)
                 fd foo   u32
+                me bar() fn bar(&self)
             "#]],
         );
     }
@@ -98,8 +98,8 @@ fn foo(self) { self.<|> }
 }
 "#,
             expect![[r#"
-                me foo()     fn foo(self)
                 fd the_field (u32,)
+                me foo()     fn foo(self)
             "#]],
         )
     }
@@ -114,8 +114,8 @@ fn foo(&self) { self.<|> }
 }
 "#,
             expect![[r#"
-                me foo()     fn foo(&self)
                 fd the_field (u32, i32)
+                me foo()     fn foo(&self)
             "#]],
         )
     }
@@ -147,8 +147,8 @@ pub struct A {
 fn foo(a: inner::A) { a.<|> }
 "#,
             expect![[r#"
-                fd crate_field u32
                 fd pub_field   u32
+                fd crate_field u32
                 fd super_field u32
             "#]],
         );
index 720349b9ded6b70967e99992ee85d6d3d50fb741..1859dec70861f19bca786ced4cdf6c76b70b6596 100644 (file)
@@ -223,21 +223,21 @@ fn test_keywords_at_source_file_level() {
         check(
             r"m<|>",
             expect![[r#"
-                kw const
-                kw enum
-                kw extern
                 kw fn
+                kw use
                 kw impl
-                kw mod
-                kw pub
-                kw pub(crate)
-                kw static
-                kw struct
                 kw trait
-                kw type
+                kw enum
+                kw struct
                 kw union
+                kw mod
+                kw const
+                kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
+                kw pub(crate)
+                kw pub
             "#]],
         );
     }
@@ -247,23 +247,23 @@ fn test_keywords_in_function() {
         check(
             r"fn quux() { <|> }",
             expect![[r#"
-                kw const
-                kw extern
                 kw fn
+                kw use
+                kw impl
+                kw trait
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw impl
                 kw let
-                kw loop
-                kw match
                 kw mod
-                kw return
-                kw static
-                kw trait
+                kw const
                 kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
-                kw while
+                kw return
             "#]],
         );
     }
@@ -273,23 +273,23 @@ fn test_keywords_inside_block() {
         check(
             r"fn quux() { if true { <|> } }",
             expect![[r#"
-                kw const
-                kw extern
                 kw fn
+                kw use
+                kw impl
+                kw trait
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw impl
                 kw let
-                kw loop
-                kw match
                 kw mod
-                kw return
-                kw static
-                kw trait
+                kw const
                 kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
-                kw while
+                kw return
             "#]],
         );
     }
@@ -299,25 +299,25 @@ fn test_keywords_after_if() {
         check(
             r#"fn quux() { if true { () } <|> }"#,
             expect![[r#"
-                kw const
-                kw else
-                kw else if
-                kw extern
                 kw fn
+                kw use
+                kw impl
+                kw trait
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw impl
                 kw let
-                kw loop
-                kw match
+                kw else
+                kw else if
                 kw mod
-                kw return
-                kw static
-                kw trait
+                kw const
                 kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
-                kw while
+                kw return
             "#]],
         );
         check_edit(
@@ -336,13 +336,13 @@ fn quux() -> i32 {
 }
 "#,
             expect![[r#"
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw loop
-                kw match
-                kw return
                 kw unsafe
-                kw while
+                kw return
             "#]],
         );
     }
@@ -352,8 +352,8 @@ fn test_keywords_in_trait_def() {
         check(
             r"trait My { <|> }",
             expect![[r#"
-                kw const
                 kw fn
+                kw const
                 kw type
                 kw unsafe
             "#]],
@@ -365,12 +365,12 @@ fn test_keywords_in_impl_def() {
         check(
             r"impl My { <|> }",
             expect![[r#"
-                kw const
                 kw fn
-                kw pub
-                kw pub(crate)
+                kw const
                 kw type
                 kw unsafe
+                kw pub(crate)
+                kw pub
             "#]],
         );
     }
@@ -380,25 +380,25 @@ fn test_keywords_in_loop() {
         check(
             r"fn my() { loop { <|> } }",
             expect![[r#"
-                kw break
-                kw const
-                kw continue
-                kw extern
                 kw fn
+                kw use
+                kw impl
+                kw trait
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw impl
                 kw let
-                kw loop
-                kw match
                 kw mod
-                kw return
-                kw static
-                kw trait
+                kw const
                 kw type
+                kw static
+                kw extern
                 kw unsafe
-                kw use
-                kw while
+                kw continue
+                kw break
+                kw return
             "#]],
         );
     }
@@ -409,8 +409,8 @@ fn test_keywords_after_unsafe_in_item_list() {
             r"unsafe <|>",
             expect![[r#"
                 kw fn
-                kw impl
                 kw trait
+                kw impl
             "#]],
         );
     }
@@ -421,8 +421,8 @@ fn test_keywords_after_unsafe_in_block_expr() {
             r"fn my_fn() { unsafe <|> }",
             expect![[r#"
                 kw fn
-                kw impl
                 kw trait
+                kw impl
             "#]],
         );
     }
@@ -542,12 +542,12 @@ fn after_let() {
         check(
             r#"fn main() { let _ = <|> }"#,
             expect![[r#"
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw loop
-                kw match
                 kw return
-                kw while
             "#]],
         )
     }
@@ -562,8 +562,8 @@ struct Foo {
 }
 "#,
             expect![[r#"
-                kw pub
                 kw pub(crate)
+                kw pub
             "#]],
         )
     }
@@ -600,12 +600,12 @@ fn foo() {
 }
 "#,
             expect![[r#"
+                kw match
+                kw while
+                kw loop
                 kw if
                 kw if let
-                kw loop
-                kw match
                 kw return
-                kw while
             "#]],
         );
     }
index c96f84171bc74d98f6f622ae853ceede8c48a741..f77864b7752fc922adc684b94586733d32f78872 100644 (file)
@@ -170,8 +170,8 @@ fn bar() {}
             fn ignored_bar() {}
         "#,
             expect![[r#"
-                md bar;
                 md foo;
+                md bar;
             "#]],
         );
     }
@@ -207,8 +207,8 @@ fn bar() {}
             fn ignored_bar() {}
         "#,
             expect![[r#"
-                md bar;
                 md foo;
+                md bar;
             "#]],
         );
     }
index 4f63ff0ef67f22e73a908aee2bf01e5f6826e89b..4d56731ec619c833aee9d74d949a5de6ef9ed57b 100644 (file)
@@ -23,7 +23,7 @@ pub(crate) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) {
                         def,
                         hir::ModuleDef::Adt(hir::Adt::Enum(..))
                             | hir::ModuleDef::Adt(hir::Adt::Struct(..))
-                            | hir::ModuleDef::EnumVariant(..)
+                            | hir::ModuleDef::Variant(..)
                             | hir::ModuleDef::Const(..)
                             | hir::ModuleDef::Module(..)
                     )
@@ -66,10 +66,10 @@ fn foo() {
 }
 "#,
             expect![[r#"
-                st Bar
                 en E
-                ev X   ()
                 ct Z
+                st Bar
+                ev X   ()
                 md m
             "#]],
         );
index c8ba63cd3befb08142c8a7592e5d6ab5c9fd1f36..d6db82a93bbc49fa5529dd7be59dc32ec87f0850 100644 (file)
@@ -315,20 +315,20 @@ fn main() {
 }
 "#,
             expect![[r#"
-                sn box   Box::new(expr)
-                sn call  function(expr)
-                sn dbg   dbg!(expr)
-                sn dbgr  dbg!(&expr)
                 sn if    if expr {}
-                sn let   let
-                sn letm  let mut
-                sn match match expr {}
+                sn while while expr {}
                 sn not   !expr
-                sn ok    Ok(expr)
                 sn ref   &expr
                 sn refm  &mut expr
+                sn match match expr {}
+                sn box   Box::new(expr)
+                sn ok    Ok(expr)
                 sn some  Some(expr)
-                sn while while expr {}
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn call  function(expr)
+                sn let   let
+                sn letm  let mut
             "#]],
         );
     }
@@ -347,18 +347,18 @@ fn main() {
 }
 "#,
             expect![[r#"
-                sn box   Box::new(expr)
-                sn call  function(expr)
-                sn dbg   dbg!(expr)
-                sn dbgr  dbg!(&expr)
                 sn if    if expr {}
-                sn match match expr {}
+                sn while while expr {}
                 sn not   !expr
-                sn ok    Ok(expr)
                 sn ref   &expr
                 sn refm  &mut expr
+                sn match match expr {}
+                sn box   Box::new(expr)
+                sn ok    Ok(expr)
                 sn some  Some(expr)
-                sn while while expr {}
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn call  function(expr)
             "#]],
         );
     }
@@ -373,17 +373,17 @@ fn main() {
 }
 "#,
             expect![[r#"
+                sn ref   &expr
+                sn refm  &mut expr
+                sn match match expr {}
                 sn box   Box::new(expr)
-                sn call  function(expr)
+                sn ok    Ok(expr)
+                sn some  Some(expr)
                 sn dbg   dbg!(expr)
                 sn dbgr  dbg!(&expr)
+                sn call  function(expr)
                 sn let   let
                 sn letm  let mut
-                sn match match expr {}
-                sn ok    Ok(expr)
-                sn ref   &expr
-                sn refm  &mut expr
-                sn some  Some(expr)
             "#]],
         )
     }
@@ -398,20 +398,20 @@ fn main() {
 }
 "#,
             expect![[r#"
-                sn box   Box::new(expr)
-                sn call  function(expr)
-                sn dbg   dbg!(expr)
-                sn dbgr  dbg!(&expr)
                 sn if    if expr {}
-                sn let   let
-                sn letm  let mut
-                sn match match expr {}
+                sn while while expr {}
                 sn not   !expr
-                sn ok    Ok(expr)
                 sn ref   &expr
                 sn refm  &mut expr
+                sn match match expr {}
+                sn box   Box::new(expr)
+                sn ok    Ok(expr)
                 sn some  Some(expr)
-                sn while while expr {}
+                sn dbg   dbg!(expr)
+                sn dbgr  dbg!(&expr)
+                sn call  function(expr)
+                sn let   let
+                sn letm  let mut
             "#]],
         );
     }
index bc23bea3fafa8266e7d8adea49883ef8e7909dd1..1300f00b2f22c59d63ccf605a7d7cfc7a2b81ae0 100644 (file)
@@ -199,22 +199,22 @@ fn completes_primitives() {
         check_builtin(
             r#"fn main() { let _: <|> = 92; }"#,
             expect![[r#"
+                bt u32
                 bt bool
-                bt char
+                bt u8
+                bt isize
+                bt u16
+                bt u64
+                bt u128
                 bt f32
-                bt f64
                 bt i128
                 bt i16
-                bt i32
+                bt str
                 bt i64
+                bt char
+                bt f64
+                bt i32
                 bt i8
-                bt isize
-                bt str
-                bt u128
-                bt u16
-                bt u32
-                bt u64
-                bt u8
                 bt usize
             "#]],
         );
@@ -279,8 +279,8 @@ fn completes_use_item_starting_with_crate() {
 use crate::Sp<|>
 "#,
             expect![[r#"
-                st Spam
                 md foo
+                st Spam
             "#]],
         );
     }
@@ -296,8 +296,8 @@ fn completes_nested_use_tree() {
 use crate::{Sp<|>};
 "#,
             expect![[r#"
-                st Spam
                 md foo
+                st Spam
             "#]],
         );
     }
@@ -330,8 +330,8 @@ enum E { Foo, Bar(i32) }
 fn foo() { let _ = E::<|> }
 "#,
             expect![[r#"
-                ev Bar(…) (i32)
                 ev Foo    ()
+                ev Bar(…) (i32)
             "#]],
         );
     }
@@ -353,10 +353,10 @@ fn b(&self) {}
 fn foo() { let _ = S::<|> }
 "#,
             expect![[r#"
-                ct C    const C: i32 = 42;
-                ta T    type T = i32;
                 fn a()  fn a()
                 me b(…) fn b(&self)
+                ct C    const C: i32 = 42;
+                ta T    type T = i32;
             "#]],
         );
     }
@@ -381,9 +381,9 @@ fn private_method() { }
 fn foo() { let _ = S::<|> }
 "#,
             expect![[r#"
+                fn public_method() pub(crate) fn public_method()
                 ct PUBLIC_CONST    pub(crate) const PUBLIC_CONST: u32 = 1;
                 ta PublicType      pub(crate) type PublicType = u32;
-                fn public_method() pub(crate) fn public_method()
             "#]],
         );
     }
@@ -503,14 +503,14 @@ fn submethod(&self) {}
 fn foo<T: Sub>() { T::<|> }
 "#,
             expect![[r#"
-                ct C2           const C2: ();
-                ct CONST        const CONST: u8;
                 ta SubTy        type SubTy;
                 ta Ty           type Ty;
-                fn func()       fn func()
-                me method(…)    fn method(&self)
+                ct C2           const C2: ();
                 fn subfunc()    fn subfunc()
                 me submethod(…) fn submethod(&self)
+                ct CONST        const CONST: u8;
+                fn func()       fn func()
+                me method(…)    fn method(&self)
             "#]],
         );
     }
@@ -543,12 +543,12 @@ fn subfunc() {
 }
 "#,
             expect![[r#"
-                ct C2           const C2: () = ();
-                ct CONST        const CONST: u8 = 0;
                 ta SubTy        type SubTy;
                 ta Ty           type Ty;
+                ct CONST        const CONST: u8 = 0;
                 fn func()       fn func()
                 me method(…)    fn method(&self)
+                ct C2           const C2: () = ();
                 fn subfunc()    fn subfunc()
                 me submethod(…) fn submethod(&self)
             "#]],
@@ -567,8 +567,8 @@ impl T { fn bar() {} }
 fn main() { T::<|>; }
 "#,
             expect![[r#"
-                fn bar() fn bar()
                 fn foo() fn foo()
+                fn bar() fn bar()
             "#]],
         );
     }
@@ -583,9 +583,9 @@ macro_rules! foo { () => {} }
 fn main() { let _ = crate::<|> }
         "#,
             expect![[r##"
+                fn main()  fn main()
                 ma foo!(…) #[macro_export]
                 macro_rules! foo
-                fn main()  fn main()
             "##]],
         );
     }
@@ -603,8 +603,8 @@ mod c { use super::super::<|> }
 }
 "#,
             expect![[r#"
-                ct A
                 md b
+                ct A
             "#]],
         );
     }
@@ -628,8 +628,8 @@ fn wrong_fn() {}
 "#,
             expect![[r#"
                 ct RIGHT_CONST
-                st RightType
                 fn right_fn()  fn wrong_fn()
+                st RightType
             "#]],
         );
 
@@ -675,8 +675,8 @@ macro_rules! m { ($e:expr) => { $e } }
 fn foo() {}
 "#,
             expect![[r#"
-                fn foo()  fn foo()
                 fn main() fn main()
+                fn foo()  fn foo()
             "#]],
         );
     }
@@ -747,8 +747,8 @@ fn main() {
 }
 "#,
             expect![[r#"
-                fn foo(…) fn foo(a: i32, b: i32)
                 fn main() fn main()
+                fn foo(…) fn foo(a: i32, b: i32)
             "#]],
         );
     }
index eaa44c97d1f1e1eafea158fd716d2500f5ef8935..91bf4a8ad95234acc8b526edf855c259843b015d 100644 (file)
@@ -94,9 +94,9 @@ fn process(f: S) {
         check_snippet(
             test_code,
             expect![[r#"
-                fd ..Default::default()
                 sn pd
                 sn ppd
+                fd ..Default::default()
             "#]],
         );
     }
@@ -160,8 +160,8 @@ fn process(e: E) {
 }
 "#,
             expect![[r#"
-                fd bar ()
                 fd foo u32
+                fd bar ()
             "#]],
         );
     }
index 6f0c000781c94bc952cc932b87832e911f26a2d5..84259013002f4ca642c18c5ec811543cfa03e85a 100644 (file)
@@ -105,9 +105,9 @@ mod tests {
 }
 "#,
             expect![[r#"
-                sn macro_rules
-                sn tfn (Test function)
                 sn tmod (Test module)
+                sn tfn (Test function)
+                sn macro_rules
             "#]],
         )
     }
index e2fe44aff9fa17cabc1b672527db33028e6d1aab..c4e0d06698f27cc2db416b69a2aa0d1cadc565f8 100644 (file)
@@ -266,10 +266,10 @@ impl Test for T {
 }
 "#,
             expect![["
+ta type TestType = \n\
 ct const TEST_CONST: u16 = \n\
 fn fn test()
-ta type TestType = \n\
-            "]],
+"]],
         );
     }
 
index b9315f6c04973187ec8ec0248a50dbe40608aad5..099ffb4d48bd0b4bfbc35d86c8f242fc549d6342 100644 (file)
@@ -1,7 +1,7 @@
 //! Completion of names from the current scope, e.g. locals and imported items.
 
 use either::Either;
-use hir::{Adt, ModuleDef, ScopeDef, Type};
+use hir::{Adt, ModPath, ModuleDef, ScopeDef, Type};
 use ide_db::helpers::insert_use::ImportScope;
 use ide_db::imports_locator;
 use syntax::AstNode;
@@ -126,7 +126,7 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
     let anchor = ctx.name_ref_syntax.as_ref()?;
     let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
 
-    let possible_imports = imports_locator::find_similar_imports(
+    let mut all_mod_paths = imports_locator::find_similar_imports(
         &ctx.sema,
         ctx.krate?,
         Some(100),
@@ -144,33 +144,65 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
         })
     })
     .filter(|(mod_path, _)| mod_path.len() > 1)
-    .filter_map(|(import_path, definition)| {
+    .collect::<Vec<_>>();
+
+    let user_input_lowercased = potential_import_name.to_lowercase();
+    all_mod_paths.sort_by_cached_key(|(mod_path, _)| {
+        compute_fuzzy_completion_order_key(mod_path, &user_input_lowercased)
+    });
+
+    acc.add_all(all_mod_paths.into_iter().filter_map(|(import_path, definition)| {
         render_resolution_with_import(
             RenderContext::new(ctx),
             ImportEdit { import_path, import_scope: import_scope.clone() },
             &definition,
         )
-    });
-
-    acc.add_all(possible_imports);
+    }));
     Some(())
 }
 
+fn compute_fuzzy_completion_order_key(
+    proposed_mod_path: &ModPath,
+    user_input_lowercased: &str,
+) -> usize {
+    mark::hit!(certain_fuzzy_order_test);
+    let proposed_import_name = match proposed_mod_path.segments.last() {
+        Some(name) => name.to_string().to_lowercase(),
+        None => return usize::MAX,
+    };
+    match proposed_import_name.match_indices(user_input_lowercased).next() {
+        Some((first_matching_index, _)) => first_matching_index,
+        None => usize::MAX,
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use expect_test::{expect, Expect};
     use test_utils::mark;
 
     use crate::{
-        test_utils::{check_edit, check_edit_with_config, completion_list},
+        test_utils::{check_edit, check_edit_with_config, completion_list_with_config},
         CompletionConfig, CompletionKind,
     };
 
     fn check(ra_fixture: &str, expect: Expect) {
-        let actual = completion_list(ra_fixture, CompletionKind::Reference);
+        check_with_config(CompletionConfig::default(), ra_fixture, expect);
+    }
+
+    fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) {
+        let actual = completion_list_with_config(config, ra_fixture, CompletionKind::Reference);
         expect.assert_eq(&actual)
     }
 
+    fn fuzzy_completion_config() -> CompletionConfig {
+        let mut completion_config = CompletionConfig::default();
+        completion_config
+            .active_resolve_capabilities
+            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
+        completion_config
+    }
+
     #[test]
     fn self_fulfilling_completion() {
         mark::check!(self_fulfilling_completion);
@@ -246,9 +278,9 @@ fn quux(x: i32) {
 }
 "#,
             expect![[r#"
-                fn quux(…) fn quux(x: i32)
-                bn x       i32
                 bn y       i32
+                bn x       i32
+                fn quux(…) fn quux(x: i32)
             "#]],
         );
     }
@@ -268,8 +300,8 @@ fn quux() {
 }
 "#,
             expect![[r#"
-                bn a
                 bn b      i32
+                bn a
                 fn quux() fn quux()
             "#]],
         );
@@ -284,8 +316,8 @@ fn quux() {
 }
 "#,
             expect![[r#"
-                fn quux() fn quux()
                 bn x
+                fn quux() fn quux()
             "#]],
         );
     }
@@ -326,9 +358,9 @@ fn completes_generic_params_in_struct() {
         check(
             r#"struct S<T> { x: <|>}"#,
             expect![[r#"
-                st S<…>
                 tp Self
                 tp T
+                st S<…>
             "#]],
         );
     }
@@ -353,9 +385,9 @@ enum E {}
 fn quux() { <|> }
 "#,
             expect![[r#"
-                en E
                 st S
                 fn quux() fn quux()
+                en E
             "#]],
         );
     }
@@ -407,8 +439,8 @@ fn quux() { <|> }
 }
 "#,
             expect![[r#"
-                st Bar
                 fn quux() fn quux()
+                st Bar
             "#]],
         );
     }
@@ -453,8 +485,8 @@ fn completes_self_in_methods() {
         check(
             r#"impl S { fn foo(&self) { <|> } }"#,
             expect![[r#"
-                tp Self
                 bn self &{unknown}
+                tp Self
             "#]],
         );
     }
@@ -473,9 +505,9 @@ fn foo() { let x: <|> }
 mod prelude { struct Option; }
 "#,
             expect![[r#"
-                st Option
                 fn foo()  fn foo()
                 md std
+                st Option
             "#]],
         );
     }
@@ -500,10 +532,10 @@ fn foo() { let x: <|> }
 mod prelude { struct String; }
 "#,
             expect![[r#"
-                st String
-                md core
                 fn foo()  fn foo()
                 md std
+                md core
+                st String
             "#]],
         );
     }
@@ -529,13 +561,13 @@ macro_rules! baz { () => {} }
 fn main() { let v = <|> }
 "#,
             expect![[r##"
-                ma bar!(…) macro_rules! bar
+                md m1
                 ma baz!(…) #[macro_export]
                 macro_rules! baz
-                ma foo!(…) macro_rules! foo
-                md m1
-                md m2
                 fn main()  fn main()
+                md m2
+                ma bar!(…) macro_rules! bar
+                ma foo!(…) macro_rules! foo
             "##]],
         );
     }
@@ -548,8 +580,8 @@ macro_rules! foo { () => {} }
 fn foo() { <|> }
 "#,
             expect![[r#"
-                ma foo!(…) macro_rules! foo
                 fn foo()   fn foo()
+                ma foo!(…) macro_rules! foo
             "#]],
         );
     }
@@ -562,8 +594,8 @@ macro_rules! foo { () => {} }
 fn main() { let x: <|> }
 "#,
             expect![[r#"
-                ma foo!(…) macro_rules! foo
                 fn main()  fn main()
+                ma foo!(…) macro_rules! foo
             "#]],
         );
     }
@@ -576,8 +608,8 @@ macro_rules! foo { () => {} }
 fn main() { <|> }
 "#,
             expect![[r#"
-                ma foo!(…) macro_rules! foo
                 fn main()  fn main()
+                ma foo!(…) macro_rules! foo
             "#]],
         );
     }
@@ -609,10 +641,10 @@ fn quux(x: i32) {
 }
 "#,
             expect![[r#"
-                ma m!(…)   macro_rules! m
-                fn quux(…) fn quux(x: i32)
-                bn x       i32
                 bn y       i32
+                bn x       i32
+                fn quux(…) fn quux(x: i32)
+                ma m!(…)   macro_rules! m
             "#]],
         );
     }
@@ -628,10 +660,10 @@ fn quux(x: i32) {
 }
 ",
             expect![[r#"
-                ma m!(…)   macro_rules! m
-                fn quux(…) fn quux(x: i32)
-                bn x       i32
                 bn y       i32
+                bn x       i32
+                fn quux(…) fn quux(x: i32)
+                ma m!(…)   macro_rules! m
             "#]],
         );
     }
@@ -647,10 +679,10 @@ fn quux(x: i32) {
 }
 "#,
             expect![[r#"
-                ma m!(…)   macro_rules! m
-                fn quux(…) fn quux(x: i32)
-                bn x       i32
                 bn y       i32
+                bn x       i32
+                fn quux(…) fn quux(x: i32)
+                ma m!(…)   macro_rules! m
             "#]],
         );
     }
@@ -664,8 +696,8 @@ fn completes_unresolved_uses() {
 fn main() { <|> }
 "#,
             expect![[r#"
-                ?? Quux
                 fn main() fn main()
+                ?? Quux
             "#]],
         );
     }
@@ -681,10 +713,10 @@ fn main() {
 }
 "#,
             expect![[r#"
-                en Foo
                 ev Foo::Bar  ()
                 ev Foo::Baz  ()
                 ev Foo::Quux ()
+                en Foo
             "#]],
         )
     }
@@ -701,10 +733,10 @@ fn main() {
 }
 "#,
             expect![[r#"
-                en Foo
                 ev Foo::Bar  ()
                 ev Foo::Baz  ()
                 ev Foo::Quux ()
+                en Foo
             "#]],
         )
     }
@@ -717,10 +749,10 @@ enum Foo { Bar, Baz, Quux }
 fn main() { let foo: Foo = Q<|> }
 "#,
             expect![[r#"
-                en Foo
                 ev Foo::Bar  ()
                 ev Foo::Baz  ()
                 ev Foo::Quux ()
+                en Foo
                 fn main()    fn main()
             "#]],
         )
@@ -734,9 +766,9 @@ mod m { pub enum E { V } }
 fn f() -> m::E { V<|> }
 "#,
             expect![[r#"
-                fn f()     fn f() -> m::E
-                md m
                 ev m::E::V ()
+                md m
+                fn f()     fn f() -> m::E
             "#]],
         )
     }
@@ -763,22 +795,17 @@ struct MyStruct {}
 impl My<|>
 "#,
             expect![[r#"
-                st MyStruct
-                tt MyTrait
                 tp Self
+                tt MyTrait
+                st MyStruct
             "#]],
         )
     }
 
     #[test]
     fn function_fuzzy_completion() {
-        let mut completion_config = CompletionConfig::default();
-        completion_config
-            .active_resolve_capabilities
-            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
-
         check_edit_with_config(
-            completion_config,
+            fuzzy_completion_config(),
             "stdin",
             r#"
 //- /lib.rs crate:dep
@@ -803,13 +830,8 @@ fn main() {
 
     #[test]
     fn macro_fuzzy_completion() {
-        let mut completion_config = CompletionConfig::default();
-        completion_config
-            .active_resolve_capabilities
-            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
-
         check_edit_with_config(
-            completion_config,
+            fuzzy_completion_config(),
             "macro_with_curlies!",
             r#"
 //- /lib.rs crate:dep
@@ -836,13 +858,8 @@ fn main() {
 
     #[test]
     fn struct_fuzzy_completion() {
-        let mut completion_config = CompletionConfig::default();
-        completion_config
-            .active_resolve_capabilities
-            .insert(crate::CompletionResolveCapability::AdditionalTextEdits);
-
         check_edit_with_config(
-            completion_config,
+            fuzzy_completion_config(),
             "ThirdStruct",
             r#"
 //- /lib.rs crate:dep
@@ -868,4 +885,44 @@ fn main() {
 "#,
         );
     }
+
+    #[test]
+    fn fuzzy_completions_come_in_specific_order() {
+        mark::check!(certain_fuzzy_order_test);
+        check_with_config(
+            fuzzy_completion_config(),
+            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<|>
+}
+"#,
+            expect![[r#"
+                fn main()           fn main()
+                st SecondStruct
+                st FirstStruct
+                md dep
+                st dep::some_module::ThirdStruct
+                st dep::some_module::AfterThirdStruct
+                st dep::some_module::ThiiiiiirdStruct
+            "#]],
+        );
+    }
 }
index b940388df26aabbd40dddbeed4f27092763c7ca4..1092a48256181ef4e7e8d4674c29070c89a8451e 100644 (file)
@@ -19,7 +19,7 @@
     CompletionKind, CompletionScore,
 };
 
-use crate::render::{enum_variant::render_enum_variant, function::render_fn, macro_::render_macro};
+use crate::render::{enum_variant::render_variant, function::render_fn, macro_::render_macro};
 
 pub(crate) fn render_field<'a>(
     ctx: RenderContext<'a>,
@@ -159,9 +159,8 @@ fn render_resolution(
                 let item = render_fn(self.ctx, import_to_add, Some(local_name), *func);
                 return Some(item);
             }
-            ScopeDef::ModuleDef(EnumVariant(var)) => {
-                let item =
-                    render_enum_variant(self.ctx, import_to_add, Some(local_name), *var, None);
+            ScopeDef::ModuleDef(Variant(var)) => {
+                let item = render_variant(self.ctx, import_to_add, Some(local_name), *var, None);
                 return Some(item);
             }
             ScopeDef::MacroDef(mac) => {
@@ -257,7 +256,7 @@ fn docs(&self, resolution: &ScopeDef) -> Option<Documentation> {
         match resolution {
             ScopeDef::ModuleDef(Module(it)) => it.docs(self.ctx.db()),
             ScopeDef::ModuleDef(Adt(it)) => it.docs(self.ctx.db()),
-            ScopeDef::ModuleDef(EnumVariant(it)) => it.docs(self.ctx.db()),
+            ScopeDef::ModuleDef(Variant(it)) => it.docs(self.ctx.db()),
             ScopeDef::ModuleDef(Const(it)) => it.docs(self.ctx.db()),
             ScopeDef::ModuleDef(Static(it)) => it.docs(self.ctx.db()),
             ScopeDef::ModuleDef(Trait(it)) => it.docs(self.ctx.db()),
index 8e0fea6c0fc5768e6ee2acfa912371f323c371ea..7176fd9b3d1bed555259105bdda6f95d49eb750b 100644 (file)
@@ -9,35 +9,35 @@
     render::{builder_ext::Params, RenderContext},
 };
 
-pub(crate) fn render_enum_variant<'a>(
+pub(crate) fn render_variant<'a>(
     ctx: RenderContext<'a>,
     import_to_add: Option<ImportEdit>,
     local_name: Option<String>,
-    variant: hir::EnumVariant,
+    variant: hir::Variant,
     path: Option<ModPath>,
 ) -> CompletionItem {
     let _p = profile::span("render_enum_variant");
-    EnumVariantRender::new(ctx, local_name, variant, path).render(import_to_add)
+    EnumRender::new(ctx, local_name, variant, path).render(import_to_add)
 }
 
 #[derive(Debug)]
-struct EnumVariantRender<'a> {
+struct EnumRender<'a> {
     ctx: RenderContext<'a>,
     name: String,
-    variant: hir::EnumVariant,
+    variant: hir::Variant,
     path: Option<ModPath>,
     qualified_name: String,
     short_qualified_name: String,
     variant_kind: StructKind,
 }
 
-impl<'a> EnumVariantRender<'a> {
+impl<'a> EnumRender<'a> {
     fn new(
         ctx: RenderContext<'a>,
         local_name: Option<String>,
-        variant: hir::EnumVariant,
+        variant: hir::Variant,
         path: Option<ModPath>,
-    ) -> EnumVariantRender<'a> {
+    ) -> EnumRender<'a> {
         let name = local_name.unwrap_or_else(|| variant.name(ctx.db()).to_string());
         let variant_kind = variant.kind(ctx.db());
 
@@ -51,15 +51,7 @@ fn new(
             None => (name.to_string(), name.to_string()),
         };
 
-        EnumVariantRender {
-            ctx,
-            name,
-            variant,
-            path,
-            qualified_name,
-            short_qualified_name,
-            variant_kind,
-        }
+        EnumRender { ctx, name, variant, path, qualified_name, short_qualified_name, variant_kind }
     }
 
     fn render(self, import_to_add: Option<ImportEdit>) -> CompletionItem {
index 6cfbd6c9ba8a22f34686db06af989921865eb297..dac79592f7f22ad24f1ef805fa69ed33cc049bb2 100644 (file)
@@ -41,6 +41,7 @@ fn new(ctx: RenderContext<'a>, name: String, macro_: hir::MacroDef) -> MacroRend
     fn render(&self, import_to_add: Option<ImportEdit>) -> Option<CompletionItem> {
         // FIXME: Currently proc-macro do not have ast-node,
         // such that it does not have source
+        // more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913
         if self.macro_.is_proc_macro() {
             return None;
         }
index db896b2df23441d8edc1862a51e4fc103919735e..eb0c16f52bd22d8e79a5681a40d25dc106e00341 100644 (file)
@@ -47,9 +47,8 @@ pub(crate) fn completion_list_with_config(
     code: &str,
     kind: CompletionKind,
 ) -> String {
-    let mut kind_completions: Vec<CompletionItem> =
+    let kind_completions: Vec<CompletionItem> =
         get_all_items(config, code).into_iter().filter(|c| c.completion_kind == kind).collect();
-    kind_completions.sort_by_key(|c| c.label().to_owned());
     let label_width = kind_completions
         .iter()
         .map(|it| monospace_width(it.label()))
index 1f2ee2580018565036ffdd4aa5f72a634faeeb89..d32ce37edb2264882670262feaa1b5cb52dabd51 100644 (file)
@@ -10,8 +10,8 @@
 use syntax::ast;
 
 use crate::{
-    Adt, Const, Enum, EnumVariant, Field, Function, MacroDef, Module, ModuleDef, Static, Struct,
-    Trait, TypeAlias, Union,
+    Adt, Const, Enum, Field, Function, MacroDef, Module, ModuleDef, Static, Struct, Trait,
+    TypeAlias, Union, Variant,
 };
 
 pub trait HasAttrs {
@@ -53,7 +53,7 @@ fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace
 
 impl_has_attrs![
     (Field, FieldId),
-    (EnumVariant, EnumVariantId),
+    (Variant, EnumVariantId),
     (Static, StaticId),
     (Const, ConstId),
     (Trait, TraitId),
index afe229c32fc8e7121c45732933ff4d0908ad7ad9..73ca6ba9f481e5555ea6b6534f7e72839a1a3ae6 100644 (file)
@@ -161,7 +161,7 @@ pub enum ModuleDef {
     Function(Function),
     Adt(Adt),
     // Can't be directly declared, but can be imported.
-    EnumVariant(EnumVariant),
+    Variant(Variant),
     Const(Const),
     Static(Static),
     Trait(Trait),
@@ -172,7 +172,7 @@ pub enum ModuleDef {
     Module,
     Function,
     Adt(Struct, Enum, Union),
-    EnumVariant,
+    Variant,
     Const,
     Static,
     Trait,
@@ -186,7 +186,7 @@ fn from(var: VariantDef) -> Self {
         match var {
             VariantDef::Struct(t) => Adt::from(t).into(),
             VariantDef::Union(t) => Adt::from(t).into(),
-            VariantDef::EnumVariant(t) => t.into(),
+            VariantDef::Variant(t) => t.into(),
         }
     }
 }
@@ -197,7 +197,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
             ModuleDef::Module(it) => it.parent(db),
             ModuleDef::Function(it) => Some(it.module(db)),
             ModuleDef::Adt(it) => Some(it.module(db)),
-            ModuleDef::EnumVariant(it) => Some(it.module(db)),
+            ModuleDef::Variant(it) => Some(it.module(db)),
             ModuleDef::Const(it) => Some(it.module(db)),
             ModuleDef::Static(it) => Some(it.module(db)),
             ModuleDef::Trait(it) => Some(it.module(db)),
@@ -221,7 +221,7 @@ pub fn definition_visibility(&self, db: &dyn HirDatabase) -> Option<Visibility>
             ModuleDef::Module(it) => it.parent(db)?,
             ModuleDef::Function(it) => return Some(it.visibility(db)),
             ModuleDef::Adt(it) => it.module(db),
-            ModuleDef::EnumVariant(it) => {
+            ModuleDef::Variant(it) => {
                 let parent = it.parent_enum(db);
                 let module = it.module(db);
                 return module.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent)));
@@ -241,7 +241,7 @@ pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
             ModuleDef::Adt(it) => Some(it.name(db)),
             ModuleDef::Trait(it) => Some(it.name(db)),
             ModuleDef::Function(it) => Some(it.name(db)),
-            ModuleDef::EnumVariant(it) => Some(it.name(db)),
+            ModuleDef::Variant(it) => Some(it.name(db)),
             ModuleDef::TypeAlias(it) => Some(it.name(db)),
             ModuleDef::Module(it) => it.name(db),
             ModuleDef::Const(it) => it.name(db),
@@ -455,7 +455,7 @@ pub fn signature_ty(&self, db: &dyn HirDatabase) -> Type {
         let generic_def_id: GenericDefId = match self.parent {
             VariantDef::Struct(it) => it.id.into(),
             VariantDef::Union(it) => it.id.into(),
-            VariantDef::EnumVariant(it) => it.parent.id.into(),
+            VariantDef::Variant(it) => it.parent.id.into(),
         };
         let substs = Substs::type_params(db, generic_def_id);
         let ty = db.field_types(var_id)[self.id].clone().subst(&substs);
@@ -566,12 +566,8 @@ pub fn name(self, db: &dyn HirDatabase) -> Name {
         db.enum_data(self.id).name.clone()
     }
 
-    pub fn variants(self, db: &dyn HirDatabase) -> Vec<EnumVariant> {
-        db.enum_data(self.id)
-            .variants
-            .iter()
-            .map(|(id, _)| EnumVariant { parent: self, id })
-            .collect()
+    pub fn variants(self, db: &dyn HirDatabase) -> Vec<Variant> {
+        db.enum_data(self.id).variants.iter().map(|(id, _)| Variant { parent: self, id }).collect()
     }
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
@@ -580,12 +576,12 @@ pub fn ty(self, db: &dyn HirDatabase) -> Type {
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct EnumVariant {
+pub struct Variant {
     pub(crate) parent: Enum,
     pub(crate) id: LocalEnumVariantId,
 }
 
-impl EnumVariant {
+impl Variant {
     pub fn module(self, db: &dyn HirDatabase) -> Module {
         self.parent.module(db)
     }
@@ -662,16 +658,16 @@ pub fn name(self, db: &dyn HirDatabase) -> Name {
 pub enum VariantDef {
     Struct(Struct),
     Union(Union),
-    EnumVariant(EnumVariant),
+    Variant(Variant),
 }
-impl_from!(Struct, Union, EnumVariant for VariantDef);
+impl_from!(Struct, Union, Variant for VariantDef);
 
 impl VariantDef {
     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
         match self {
             VariantDef::Struct(it) => it.fields(db),
             VariantDef::Union(it) => it.fields(db),
-            VariantDef::EnumVariant(it) => it.fields(db),
+            VariantDef::Variant(it) => it.fields(db),
         }
     }
 
@@ -679,7 +675,7 @@ pub fn module(self, db: &dyn HirDatabase) -> Module {
         match self {
             VariantDef::Struct(it) => it.module(db),
             VariantDef::Union(it) => it.module(db),
-            VariantDef::EnumVariant(it) => it.module(db),
+            VariantDef::Variant(it) => it.module(db),
         }
     }
 
@@ -687,7 +683,7 @@ pub fn name(&self, db: &dyn HirDatabase) -> Name {
         match self {
             VariantDef::Struct(s) => s.name(db),
             VariantDef::Union(u) => u.name(db),
-            VariantDef::EnumVariant(e) => e.name(db),
+            VariantDef::Variant(e) => e.name(db),
         }
     }
 
@@ -695,7 +691,7 @@ pub(crate) fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
         match self {
             VariantDef::Struct(it) => it.variant_data(db),
             VariantDef::Union(it) => it.variant_data(db),
-            VariantDef::EnumVariant(it) => it.variant_data(db),
+            VariantDef::Variant(it) => it.variant_data(db),
         }
     }
 }
@@ -983,6 +979,12 @@ pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
 
     /// XXX: this parses the file
     pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
+        // FIXME: Currently proc-macro do not have ast-node,
+        // such that it does not have source
+        // more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913
+        if self.is_proc_macro() {
+            return None;
+        }
         self.source(db).value.name().map(|it| it.as_name())
     }
 
@@ -1089,7 +1091,7 @@ pub enum GenericDef {
     Impl(Impl),
     // enum variants cannot have generics themselves, but their parent enums
     // can, and this makes some code easier to write
-    EnumVariant(EnumVariant),
+    Variant(Variant),
     // consts can have type parameters from their parents (i.e. associated consts of traits)
     Const(Const),
 }
@@ -1099,7 +1101,7 @@ pub enum GenericDef {
     Trait,
     TypeAlias,
     Impl,
-    EnumVariant,
+    Variant,
     Const
     for GenericDef
 );
@@ -1283,14 +1285,12 @@ pub fn for_trait(db: &dyn HirDatabase, krate: Crate, trait_: Trait) -> Vec<Impl>
         impls.for_trait(trait_.id).map(Self::from).collect()
     }
 
+    // FIXME: the return type is wrong. This should be a hir version of
+    // `TraitRef` (ie, resolved `TypeRef`).
     pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> {
         db.impl_data(self.id).target_trait.clone()
     }
 
-    pub fn target_type(self, db: &dyn HirDatabase) -> TypeRef {
-        db.impl_data(self.id).target_type.clone()
-    }
-
     pub fn target_ty(self, db: &dyn HirDatabase) -> Type {
         let impl_data = db.impl_data(self.id);
         let resolver = self.id.resolver(db.upcast());
@@ -1324,6 +1324,7 @@ pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>
         let item = src.file_id.is_builtin_derive(db.upcast())?;
         let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id);
 
+        // FIXME: handle `cfg_attr`
         let attr = item
             .value
             .attrs()
@@ -1841,7 +1842,7 @@ pub struct Callable {
 pub enum CallableKind {
     Function(Function),
     TupleStruct(Struct),
-    TupleEnumVariant(EnumVariant),
+    TupleEnumVariant(Variant),
     Closure,
 }
 
index 8d0f84508d2ac5ce5fccaead0fb9d106d9f247f2..8e0c571b8510283bb0007f42c7346669c00840ba 100644 (file)
@@ -9,8 +9,7 @@
 };
 
 use crate::{
-    Adt, AssocItem, DefWithBody, EnumVariant, Field, GenericDef, Local, MacroDef, ModuleDef,
-    VariantDef,
+    Adt, AssocItem, DefWithBody, Field, GenericDef, Local, MacroDef, ModuleDef, Variant, VariantDef,
 };
 
 macro_rules! from_id {
@@ -65,14 +64,14 @@ fn from(id: Adt) -> Self {
     }
 }
 
-impl From<EnumVariantId> for EnumVariant {
+impl From<EnumVariantId> for Variant {
     fn from(id: EnumVariantId) -> Self {
-        EnumVariant { parent: id.parent.into(), id: id.local_id }
+        Variant { parent: id.parent.into(), id: id.local_id }
     }
 }
 
-impl From<EnumVariant> for EnumVariantId {
-    fn from(def: EnumVariant) -> Self {
+impl From<Variant> for EnumVariantId {
+    fn from(def: Variant) -> Self {
         EnumVariantId { parent: def.parent.id, local_id: def.id }
     }
 }
@@ -83,7 +82,7 @@ fn from(id: ModuleDefId) -> Self {
             ModuleDefId::ModuleId(it) => ModuleDef::Module(it.into()),
             ModuleDefId::FunctionId(it) => ModuleDef::Function(it.into()),
             ModuleDefId::AdtId(it) => ModuleDef::Adt(it.into()),
-            ModuleDefId::EnumVariantId(it) => ModuleDef::EnumVariant(it.into()),
+            ModuleDefId::EnumVariantId(it) => ModuleDef::Variant(it.into()),
             ModuleDefId::ConstId(it) => ModuleDef::Const(it.into()),
             ModuleDefId::StaticId(it) => ModuleDef::Static(it.into()),
             ModuleDefId::TraitId(it) => ModuleDef::Trait(it.into()),
@@ -99,7 +98,7 @@ fn from(id: ModuleDef) -> Self {
             ModuleDef::Module(it) => ModuleDefId::ModuleId(it.into()),
             ModuleDef::Function(it) => ModuleDefId::FunctionId(it.into()),
             ModuleDef::Adt(it) => ModuleDefId::AdtId(it.into()),
-            ModuleDef::EnumVariant(it) => ModuleDefId::EnumVariantId(it.into()),
+            ModuleDef::Variant(it) => ModuleDefId::EnumVariantId(it.into()),
             ModuleDef::Const(it) => ModuleDefId::ConstId(it.into()),
             ModuleDef::Static(it) => ModuleDefId::StaticId(it.into()),
             ModuleDef::Trait(it) => ModuleDefId::TraitId(it.into()),
@@ -147,7 +146,7 @@ fn from(def: GenericDef) -> Self {
             GenericDef::Trait(it) => GenericDefId::TraitId(it.id),
             GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id),
             GenericDef::Impl(it) => GenericDefId::ImplId(it.id),
-            GenericDef::EnumVariant(it) => {
+            GenericDef::Variant(it) => {
                 GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id })
             }
             GenericDef::Const(it) => GenericDefId::ConstId(it.id),
@@ -164,7 +163,7 @@ fn from(def: GenericDefId) -> Self {
             GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
             GenericDefId::ImplId(it) => GenericDef::Impl(it.into()),
             GenericDefId::EnumVariantId(it) => {
-                GenericDef::EnumVariant(EnumVariant { parent: it.parent.into(), id: it.local_id })
+                GenericDef::Variant(Variant { parent: it.parent.into(), id: it.local_id })
             }
             GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
         }
@@ -185,7 +184,7 @@ impl From<VariantId> for VariantDef {
     fn from(def: VariantId) -> Self {
         match def {
             VariantId::StructId(it) => VariantDef::Struct(it.into()),
-            VariantId::EnumVariantId(it) => VariantDef::EnumVariant(it.into()),
+            VariantId::EnumVariantId(it) => VariantDef::Variant(it.into()),
             VariantId::UnionId(it) => VariantDef::Union(it.into()),
         }
     }
@@ -195,7 +194,7 @@ impl From<VariantDef> for VariantId {
     fn from(def: VariantDef) -> Self {
         match def {
             VariantDef::Struct(it) => VariantId::StructId(it.id),
-            VariantDef::EnumVariant(it) => VariantId::EnumVariantId(it.into()),
+            VariantDef::Variant(it) => VariantId::EnumVariantId(it.into()),
             VariantDef::Union(it) => VariantId::UnionId(it.id),
         }
     }
index c5b81b2524be1607a2e77f3436a63038196c87af..0dc07c33e22832f2663088c8f1d0d148d59177d4 100644 (file)
@@ -10,8 +10,8 @@
 use syntax::ast;
 
 use crate::{
-    db::HirDatabase, Const, Enum, EnumVariant, Field, FieldSource, Function, Impl, LifetimeParam,
-    MacroDef, Module, Static, Struct, Trait, TypeAlias, TypeParam, Union,
+    db::HirDatabase, Const, Enum, Field, FieldSource, Function, Impl, LifetimeParam, MacroDef,
+    Module, Static, Struct, Trait, TypeAlias, TypeParam, Union, Variant,
 };
 
 pub trait HasSource {
@@ -73,7 +73,7 @@ fn source(self, db: &dyn HirDatabase) -> InFile<ast::Enum> {
         self.id.lookup(db.upcast()).source(db.upcast())
     }
 }
-impl HasSource for EnumVariant {
+impl HasSource for Variant {
     type Ast = ast::Variant;
     fn source(self, db: &dyn HirDatabase) -> InFile<ast::Variant> {
         self.parent.id.child_source(db.upcast()).map(|map| map[self.id].clone())
index 3f4f8d8e4af80e6c338d6a2dc4bd566603a39f45..bdd270c58d373e3e0d87594ca4289ebf5e37324e 100644 (file)
@@ -34,9 +34,9 @@
     attrs::{HasAttrs, Namespace},
     code_model::{
         Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const,
-        Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function,
-        GenericDef, HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef,
-        ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef,
+        Crate, CrateDependency, DefWithBody, Enum, Field, FieldSource, Function, GenericDef,
+        HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef, ScopeDef, Static,
+        Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef,
     },
     has_source::HasSource,
     semantics::{PathResolution, Semantics, SemanticsScope},
index 83ec91f587f8f4c0df058c9af462fe69658190f1..25ebf73d88ef47c591829c14cd84e93fbe29d539 100644 (file)
@@ -51,7 +51,7 @@ fn in_type_ns(&self) -> Option<TypeNs> {
                 Some(TypeNs::BuiltinType(*builtin))
             }
             PathResolution::Def(ModuleDef::Const(_))
-            | PathResolution::Def(ModuleDef::EnumVariant(_))
+            | PathResolution::Def(ModuleDef::Variant(_))
             | PathResolution::Def(ModuleDef::Function(_))
             | PathResolution::Def(ModuleDef::Module(_))
             | PathResolution::Def(ModuleDef::Static(_))
@@ -715,7 +715,7 @@ fn to_def(sema: &SemanticsImpl, src: InFile<Self>) -> Option<Self::Def> {
     (crate::Function, ast::Fn, fn_to_def),
     (crate::Field, ast::RecordField, record_field_to_def),
     (crate::Field, ast::TupleField, tuple_field_to_def),
-    (crate::EnumVariant, ast::Variant, enum_variant_to_def),
+    (crate::Variant, ast::Variant, enum_variant_to_def),
     (crate::TypeParam, ast::TypeParam, type_param_to_def),
     (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
     (crate::MacroDef, ast::MacroRules, macro_rules_to_def),
index bf0c959feef22778d20055484536528726895af1..bddc49c05a85686e63155e57bcc3fefa45cc446a 100644 (file)
@@ -28,8 +28,8 @@
 };
 
 use crate::{
-    db::HirDatabase, semantics::PathResolution, Adt, Const, EnumVariant, Field, Function, Local,
-    MacroDef, ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam,
+    db::HirDatabase, semantics::PathResolution, Adt, Const, Field, Function, Local, MacroDef,
+    ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Variant,
 };
 use base_db::CrateId;
 
@@ -230,7 +230,7 @@ pub(crate) fn resolve_path(
             if let Some(VariantId::EnumVariantId(variant)) =
                 self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
             {
-                return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into())));
+                return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
             }
         }
 
@@ -242,7 +242,7 @@ pub(crate) fn resolve_path(
             if let Some(VariantId::EnumVariantId(variant)) =
                 self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
             {
-                return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into())));
+                return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
             }
         }
 
@@ -251,7 +251,7 @@ pub(crate) fn resolve_path(
             if let Some(VariantId::EnumVariantId(variant)) =
                 self.infer.as_ref()?.variant_resolution_for_expr(expr_id)
             {
-                return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into())));
+                return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
             }
         }
 
@@ -260,7 +260,7 @@ pub(crate) fn resolve_path(
             if let Some(VariantId::EnumVariantId(variant)) =
                 self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
             {
-                return Some(PathResolution::Def(ModuleDef::EnumVariant(variant.into())));
+                return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
             }
         }
 
@@ -459,7 +459,7 @@ pub(crate) fn resolve_hir_path(
             TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => {
                 PathResolution::Def(Adt::from(it).into())
             }
-            TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
+            TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
             TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
             TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
             TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
@@ -477,7 +477,7 @@ pub(crate) fn resolve_hir_path(
                 ValueNs::ConstId(it) => PathResolution::Def(Const::from(it).into()),
                 ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()),
                 ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()),
-                ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
+                ValueNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
                 ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()),
             };
             Some(res)
@@ -526,7 +526,7 @@ fn resolve_hir_path_qualifier(
         TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
         TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }),
         TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => PathResolution::Def(Adt::from(it).into()),
-        TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()),
+        TypeNs::EnumVariantId(it) => PathResolution::Def(Variant::from(it).into()),
         TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
         TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
         TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
index eafa3abb6ab599e85791e9854c3755269f06330e..236d6f1b7c973951e9e4c38c6af8a112930f1527 100644 (file)
@@ -3,6 +3,7 @@
 use std::sync::Arc;
 
 use arena::{map::ArenaMap, Arena};
+use base_db::CrateId;
 use either::Either;
 use hir_expand::{
     name::{AsName, Name},
@@ -66,8 +67,13 @@ pub enum ReprKind {
     Other,
 }
 
-fn repr_from_value(item_tree: &ItemTree, of: AttrOwner) -> Option<ReprKind> {
-    item_tree.attrs(of).by_key("repr").tt_values().find_map(parse_repr_tt)
+fn repr_from_value(
+    db: &dyn DefDatabase,
+    krate: CrateId,
+    item_tree: &ItemTree,
+    of: AttrOwner,
+) -> Option<ReprKind> {
+    item_tree.attrs(db, krate, of).by_key("repr").tt_values().find_map(parse_repr_tt)
 }
 
 fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> {
@@ -86,12 +92,13 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> {
 impl StructData {
     pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> {
         let loc = id.lookup(db);
+        let krate = loc.container.module(db).krate;
         let item_tree = db.item_tree(loc.id.file_id);
-        let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into());
+        let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
         let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
 
         let strukt = &item_tree[loc.id.value];
-        let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields, None);
+        let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &strukt.fields, None);
         Arc::new(StructData {
             name: strukt.name.clone(),
             variant_data: Arc::new(variant_data),
@@ -100,12 +107,13 @@ pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<Struc
     }
     pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> {
         let loc = id.lookup(db);
+        let krate = loc.container.module(db).krate;
         let item_tree = db.item_tree(loc.id.file_id);
-        let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into());
+        let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
         let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
 
         let union = &item_tree[loc.id.value];
-        let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields, None);
+        let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &union.fields, None);
 
         Arc::new(StructData {
             name: union.name.clone(),
@@ -118,16 +126,23 @@ pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructD
 impl EnumData {
     pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> {
         let loc = e.lookup(db);
+        let krate = loc.container.module(db).krate;
         let item_tree = db.item_tree(loc.id.file_id);
-        let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
+        let cfg_options = db.crate_graph()[krate].cfg_options.clone();
 
         let enum_ = &item_tree[loc.id.value];
         let mut variants = Arena::new();
         for var_id in enum_.variants.clone() {
-            if item_tree.attrs(var_id.into()).is_cfg_enabled(&cfg_options) {
+            if item_tree.attrs(db, krate, var_id.into()).is_cfg_enabled(&cfg_options) {
                 let var = &item_tree[var_id];
-                let var_data =
-                    lower_fields(&item_tree, &cfg_options, &var.fields, Some(enum_.visibility));
+                let var_data = lower_fields(
+                    db,
+                    krate,
+                    &item_tree,
+                    &cfg_options,
+                    &var.fields,
+                    Some(enum_.visibility),
+                );
 
                 variants.alloc(EnumVariantData {
                     name: var.name.clone(),
@@ -170,7 +185,7 @@ fn lower_enum(
         .variant_list()
         .into_iter()
         .flat_map(|it| it.variants())
-        .filter(|var| expander.is_cfg_enabled(var));
+        .filter(|var| expander.is_cfg_enabled(db, var));
     for var in variants {
         trace.alloc(
             || var.clone(),
@@ -262,7 +277,7 @@ fn lower_struct(
     match &ast.value {
         ast::StructKind::Tuple(fl) => {
             for (i, fd) in fl.fields().enumerate() {
-                if !expander.is_cfg_enabled(&fd) {
+                if !expander.is_cfg_enabled(db, &fd) {
                     continue;
                 }
 
@@ -279,7 +294,7 @@ fn lower_struct(
         }
         ast::StructKind::Record(fl) => {
             for fd in fl.fields() {
-                if !expander.is_cfg_enabled(&fd) {
+                if !expander.is_cfg_enabled(db, &fd) {
                     continue;
                 }
 
@@ -299,6 +314,8 @@ fn lower_struct(
 }
 
 fn lower_fields(
+    db: &dyn DefDatabase,
+    krate: CrateId,
     item_tree: &ItemTree,
     cfg_options: &CfgOptions,
     fields: &Fields,
@@ -308,7 +325,7 @@ fn lower_fields(
         Fields::Record(flds) => {
             let mut arena = Arena::new();
             for field_id in flds.clone() {
-                if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) {
+                if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) {
                     arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
                 }
             }
@@ -317,7 +334,7 @@ fn lower_fields(
         Fields::Tuple(flds) => {
             let mut arena = Arena::new();
             for field_id in flds.clone() {
-                if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) {
+                if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) {
                     arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
                 }
             }
index c64b78445cc229824e2d7a7d8da3fd046a3f80ca..042e119b12e35fd5f25757b016817e3b62c36f3e 100644 (file)
@@ -2,22 +2,24 @@
 
 use std::{ops, sync::Arc};
 
+use base_db::CrateId;
 use cfg::{CfgExpr, CfgOptions};
 use either::Either;
-use hir_expand::{hygiene::Hygiene, AstId, InFile};
+use hir_expand::{hygiene::Hygiene, name::AsName, AstId, InFile};
 use itertools::Itertools;
 use mbe::ast_to_token_tree;
 use syntax::{
     ast::{self, AstNode, AttrsOwner},
     match_ast, AstToken, SmolStr, SyntaxNode,
 };
+use test_utils::mark;
 use tt::Subtree;
 
 use crate::{
     db::DefDatabase,
     item_tree::{ItemTreeId, ItemTreeNode},
     nameres::ModuleSource,
-    path::ModPath,
+    path::{ModPath, PathKind},
     src::HasChildSource,
     AdtId, AttrDefId, Lookup,
 };
@@ -38,12 +40,16 @@ fn from(Documentation(string): Documentation) -> Self {
     }
 }
 
+/// Syntactical attributes, without filtering of `cfg_attr`s.
 #[derive(Default, Debug, Clone, PartialEq, Eq)]
-pub struct Attrs {
+pub(crate) struct RawAttrs {
     entries: Option<Arc<[Attr]>>,
 }
 
-impl ops::Deref for Attrs {
+#[derive(Default, Debug, Clone, PartialEq, Eq)]
+pub struct Attrs(RawAttrs);
+
+impl ops::Deref for RawAttrs {
     type Target = [Attr];
 
     fn deref(&self) -> &[Attr] {
@@ -54,19 +60,147 @@ fn deref(&self) -> &[Attr] {
     }
 }
 
+impl ops::Deref for Attrs {
+    type Target = [Attr];
+
+    fn deref(&self) -> &[Attr] {
+        match &self.0.entries {
+            Some(it) => &*it,
+            None => &[],
+        }
+    }
+}
+
+impl RawAttrs {
+    pub(crate) const EMPTY: Self = Self { entries: None };
+
+    pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Self {
+        let attrs: Vec<_> = collect_attrs(owner).collect();
+        let entries = if attrs.is_empty() {
+            // Avoid heap allocation
+            None
+        } else {
+            Some(
+                attrs
+                    .into_iter()
+                    .enumerate()
+                    .flat_map(|(i, attr)| match attr {
+                        Either::Left(attr) => Attr::from_src(attr, hygiene).map(|attr| (i, attr)),
+                        Either::Right(comment) => comment.doc_comment().map(|doc| {
+                            (
+                                i,
+                                Attr {
+                                    index: 0,
+                                    input: Some(AttrInput::Literal(SmolStr::new(doc))),
+                                    path: ModPath::from(hir_expand::name!(doc)),
+                                },
+                            )
+                        }),
+                    })
+                    .map(|(i, attr)| Attr { index: i as u32, ..attr })
+                    .collect(),
+            )
+        };
+        Self { entries }
+    }
+
+    fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Self {
+        let hygiene = Hygiene::new(db.upcast(), owner.file_id);
+        Self::new(owner.value, &hygiene)
+    }
+
+    pub(crate) fn merge(&self, other: Self) -> Self {
+        match (&self.entries, &other.entries) {
+            (None, None) => Self::EMPTY,
+            (Some(entries), None) | (None, Some(entries)) => {
+                Self { entries: Some(entries.clone()) }
+            }
+            (Some(a), Some(b)) => {
+                Self { entries: Some(a.iter().chain(b.iter()).cloned().collect()) }
+            }
+        }
+    }
+
+    /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`.
+    pub(crate) fn filter(self, db: &dyn DefDatabase, krate: CrateId) -> Attrs {
+        let has_cfg_attrs = self.iter().any(|attr| {
+            attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr])
+        });
+        if !has_cfg_attrs {
+            return Attrs(self);
+        }
+
+        let crate_graph = db.crate_graph();
+        let new_attrs = self
+            .iter()
+            .filter_map(|attr| {
+                let attr = attr.clone();
+                let is_cfg_attr =
+                    attr.path.as_ident().map_or(false, |name| *name == hir_expand::name![cfg_attr]);
+                if !is_cfg_attr {
+                    return Some(attr);
+                }
+
+                let subtree = match &attr.input {
+                    Some(AttrInput::TokenTree(it)) => it,
+                    _ => return Some(attr),
+                };
+
+                // Input subtree is: `(cfg, attr)`
+                // Split it up into a `cfg` and an `attr` subtree.
+                // FIXME: There should be a common API for this.
+                let mut saw_comma = false;
+                let (mut cfg, attr): (Vec<_>, Vec<_>) =
+                    subtree.clone().token_trees.into_iter().partition(|tree| {
+                        if saw_comma {
+                            return false;
+                        }
+
+                        match tree {
+                            tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
+                                saw_comma = true;
+                            }
+                            _ => {}
+                        }
+
+                        true
+                    });
+                cfg.pop(); // `,` ends up in here
+
+                let attr = Subtree { delimiter: None, token_trees: attr };
+                let cfg = Subtree { delimiter: subtree.delimiter, token_trees: cfg };
+                let cfg = CfgExpr::parse(&cfg);
+
+                let cfg_options = &crate_graph[krate].cfg_options;
+                if cfg_options.check(&cfg) == Some(false) {
+                    None
+                } else {
+                    mark::hit!(cfg_attr_active);
+
+                    let attr = ast::Attr::parse(&format!("#[{}]", attr)).ok()?;
+                    let hygiene = Hygiene::new_unhygienic(); // FIXME
+                    Attr::from_src(attr, &hygiene)
+                }
+            })
+            .collect();
+
+        Attrs(RawAttrs { entries: Some(new_attrs) })
+    }
+}
+
 impl Attrs {
-    pub const EMPTY: Attrs = Attrs { entries: None };
+    pub const EMPTY: Self = Self(RawAttrs::EMPTY);
 
     pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs {
-        match def {
+        let raw_attrs = match def {
             AttrDefId::ModuleId(module) => {
                 let def_map = db.crate_def_map(module.krate);
                 let mod_data = &def_map[module.local_id];
                 match mod_data.declaration_source(db) {
                     Some(it) => {
-                        Attrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner))
+                        RawAttrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner))
                     }
-                    None => Attrs::from_attrs_owner(
+                    None => RawAttrs::from_attrs_owner(
                         db,
                         mod_data.definition_source(db).as_ref().map(|src| match src {
                             ModuleSource::SourceFile(file) => file as &dyn AttrsOwner,
@@ -78,14 +212,14 @@ pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs {
             AttrDefId::FieldId(it) => {
                 let src = it.parent.child_source(db);
                 match &src.value[it.local_id] {
-                    Either::Left(_tuple) => Attrs::default(),
-                    Either::Right(record) => Attrs::from_attrs_owner(db, src.with_value(record)),
+                    Either::Left(_tuple) => RawAttrs::default(),
+                    Either::Right(record) => RawAttrs::from_attrs_owner(db, src.with_value(record)),
                 }
             }
             AttrDefId::EnumVariantId(var_id) => {
                 let src = var_id.parent.child_source(db);
                 let src = src.as_ref().map(|it| &it[var_id.local_id]);
-                Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
+                RawAttrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
             }
             AttrDefId::AdtId(it) => match it {
                 AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db),
@@ -101,55 +235,9 @@ pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs {
             AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db),
             AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
             AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db),
-        }
-    }
-
-    pub fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs {
-        let hygiene = Hygiene::new(db.upcast(), owner.file_id);
-        Attrs::new(owner.value, &hygiene)
-    }
-
-    pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs {
-        let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
-            .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs))));
-
-        let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
-        let attrs = outer_attrs
-            .chain(inner_attrs.into_iter().flatten())
-            .map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene)));
-
-        let outer_docs =
-            ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer);
-        let docs = outer_docs.chain(inner_docs.into_iter().flatten()).map(|docs_text| {
-            (
-                docs_text.syntax().text_range().start(),
-                docs_text.doc_comment().map(|doc| Attr {
-                    input: Some(AttrInput::Literal(SmolStr::new(doc))),
-                    path: ModPath::from(hir_expand::name!(doc)),
-                }),
-            )
-        });
-        // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved
-        let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect();
-        let entries = if attrs.is_empty() {
-            // Avoid heap allocation
-            None
-        } else {
-            Some(attrs.into_iter().flat_map(|(_, attr)| attr).collect())
         };
-        Attrs { entries }
-    }
 
-    pub fn merge(&self, other: Attrs) -> Attrs {
-        match (&self.entries, &other.entries) {
-            (None, None) => Attrs { entries: None },
-            (Some(entries), None) | (None, Some(entries)) => {
-                Attrs { entries: Some(entries.clone()) }
-            }
-            (Some(a), Some(b)) => {
-                Attrs { entries: Some(a.iter().chain(b.iter()).cloned().collect()) }
-            }
-        }
+        raw_attrs.filter(db, def.krate(db))
     }
 
     pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
@@ -157,7 +245,6 @@ pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
     }
 
     pub fn cfg(&self) -> Option<CfgExpr> {
-        // FIXME: handle cfg_attr :-)
         let mut cfgs = self.by_key("cfg").tt_values().map(CfgExpr::parse).collect::<Vec<_>>();
         match cfgs.len() {
             0 => None,
@@ -228,6 +315,7 @@ fn inner_attributes(
 
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct Attr {
+    index: u32,
     pub(crate) path: ModPath,
     pub(crate) input: Option<AttrInput>,
 }
@@ -254,7 +342,59 @@ fn from_src(ast: ast::Attr, hygiene: &Hygiene) -> Option<Attr> {
         } else {
             None
         };
-        Some(Attr { path, input })
+        Some(Attr { index: 0, path, input })
+    }
+
+    /// Maps this lowered `Attr` back to its original syntax node.
+    ///
+    /// `owner` must be the original owner of the attribute.
+    ///
+    /// Note that the returned syntax node might be a `#[cfg_attr]`, or a doc comment, instead of
+    /// the attribute represented by `Attr`.
+    pub fn to_src(&self, owner: &dyn AttrsOwner) -> Either<ast::Attr, ast::Comment> {
+        collect_attrs(owner).nth(self.index as usize).unwrap_or_else(|| {
+            panic!("cannot find `Attr` at index {} in {}", self.index, owner.syntax())
+        })
+    }
+
+    /// Parses this attribute as a `#[derive]`, returns an iterator that yields all contained paths
+    /// to derive macros.
+    ///
+    /// Returns `None` when the attribute is not a well-formed `#[derive]` attribute.
+    pub(crate) fn parse_derive(&self) -> Option<impl Iterator<Item = ModPath>> {
+        if self.path.as_ident() != Some(&hir_expand::name![derive]) {
+            return None;
+        }
+
+        match &self.input {
+            Some(AttrInput::TokenTree(args)) => {
+                let mut counter = 0;
+                let paths = args
+                    .token_trees
+                    .iter()
+                    .group_by(move |tt| {
+                        match tt {
+                            tt::TokenTree::Leaf(tt::Leaf::Punct(p)) if p.char == ',' => {
+                                counter += 1;
+                            }
+                            _ => {}
+                        }
+                        counter
+                    })
+                    .into_iter()
+                    .map(|(_, tts)| {
+                        let segments = tts.filter_map(|tt| match tt {
+                            tt::TokenTree::Leaf(tt::Leaf::Ident(id)) => Some(id.as_name()),
+                            _ => None,
+                        });
+                        ModPath::from_segments(PathKind::Plain, segments)
+                    })
+                    .collect::<Vec<_>>();
+
+                Some(paths.into_iter())
+            }
+            _ => None,
+        }
     }
 }
 
@@ -283,7 +423,7 @@ pub fn exists(self) -> bool {
         self.attrs().next().is_some()
     }
 
-    fn attrs(self) -> impl Iterator<Item = &'a Attr> {
+    pub(crate) fn attrs(self) -> impl Iterator<Item = &'a Attr> {
         let key = self.key;
         self.attrs
             .iter()
@@ -291,16 +431,36 @@ fn attrs(self) -> impl Iterator<Item = &'a Attr> {
     }
 }
 
-fn attrs_from_ast<N>(src: AstId<N>, db: &dyn DefDatabase) -> Attrs
+fn attrs_from_ast<N>(src: AstId<N>, db: &dyn DefDatabase) -> RawAttrs
 where
     N: ast::AttrsOwner,
 {
     let src = InFile::new(src.file_id, src.to_node(db.upcast()));
-    Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
+    RawAttrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
 }
 
-fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs {
+fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs {
     let tree = db.item_tree(id.file_id);
     let mod_item = N::id_to_mod_item(id.value);
-    tree.attrs(mod_item.into()).clone()
+    tree.raw_attrs(mod_item.into()).clone()
+}
+
+fn collect_attrs(owner: &dyn AttrsOwner) -> impl Iterator<Item = Either<ast::Attr, ast::Comment>> {
+    let (inner_attrs, inner_docs) = inner_attributes(owner.syntax())
+        .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs))));
+
+    let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none());
+    let attrs = outer_attrs
+        .chain(inner_attrs.into_iter().flatten())
+        .map(|attr| (attr.syntax().text_range().start(), Either::Left(attr)));
+
+    let outer_docs =
+        ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer);
+    let docs = outer_docs
+        .chain(inner_docs.into_iter().flatten())
+        .map(|docs_text| (docs_text.syntax().text_range().start(), Either::Right(docs_text)));
+    // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved
+    let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect();
+
+    attrs.into_iter().map(|(_, attr)| attr)
 }
index c5d6f5fb0f37642e73c2e3d69844528f845b0717..998b826010e4e7cbc8506740a2fd5dd98babc23b 100644 (file)
@@ -24,7 +24,7 @@
 pub(crate) use lower::LowerCtx;
 
 use crate::{
-    attr::Attrs,
+    attr::{Attrs, RawAttrs},
     db::DefDatabase,
     expr::{Expr, ExprId, Pat, PatId},
     item_scope::BuiltinShadowMode,
@@ -40,6 +40,7 @@
 pub(crate) struct CfgExpander {
     cfg_options: CfgOptions,
     hygiene: Hygiene,
+    krate: CrateId,
 }
 
 pub(crate) struct Expander {
@@ -65,15 +66,15 @@ pub(crate) fn new(
     ) -> CfgExpander {
         let hygiene = Hygiene::new(db.upcast(), current_file_id);
         let cfg_options = db.crate_graph()[krate].cfg_options.clone();
-        CfgExpander { cfg_options, hygiene }
+        CfgExpander { cfg_options, hygiene, krate }
     }
 
-    pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs {
-        Attrs::new(owner, &self.hygiene)
+    pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs {
+        RawAttrs::new(owner, &self.hygiene).filter(db, self.krate)
     }
 
-    pub(crate) fn is_cfg_enabled(&self, owner: &dyn ast::AttrsOwner) -> bool {
-        let attrs = self.parse_attrs(owner);
+    pub(crate) fn is_cfg_enabled(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> bool {
+        let attrs = self.parse_attrs(db, owner);
         attrs.is_cfg_enabled(&self.cfg_options)
     }
 }
@@ -189,8 +190,8 @@ pub(crate) fn to_source<T>(&self, value: T) -> InFile<T> {
         InFile { file_id: self.current_file_id, value }
     }
 
-    pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs {
-        self.cfg_expander.parse_attrs(owner)
+    pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs {
+        self.cfg_expander.parse_attrs(db, owner)
     }
 
     pub(crate) fn cfg_options(&self) -> &CfgOptions {
index 3b3d7498744f45e99f27a2904368bd9eb01b85b7..0f404be1b7c4b9e12e23cfc3de2bd725e2cd670a 100644 (file)
@@ -963,7 +963,7 @@ fn collect_tuple_pat(&mut self, args: AstChildren<ast::Pat>) -> (Vec<PatId>, Opt
     /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when
     /// not.
     fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> {
-        match self.expander.parse_attrs(owner).cfg() {
+        match self.expander.parse_attrs(self.db, owner).cfg() {
             Some(cfg) => {
                 if self.expander.cfg_options().check(&cfg) != Some(false) {
                     return Some(());
index dd3a906af0c0f00c5ad15531553c24e27d384362..e7b7724f75fb245157d55f4d7e144673b0c17560 100644 (file)
@@ -35,6 +35,7 @@ pub struct FunctionData {
 impl FunctionData {
     pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> {
         let loc = func.lookup(db);
+        let krate = loc.container.module(db).krate;
         let item_tree = db.item_tree(loc.id.file_id);
         let func = &item_tree[loc.id.value];
 
@@ -42,7 +43,7 @@ pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<Funct
             name: func.name.clone(),
             params: func.params.to_vec(),
             ret_type: func.ret_type.clone(),
-            attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(),
+            attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()).clone(),
             has_self_param: func.has_self_param,
             has_body: func.has_body,
             is_unsafe: func.is_unsafe,
@@ -233,7 +234,7 @@ fn collect_items(
         match item {
             AssocItem::Function(id) => {
                 let item = &item_tree[id];
-                let attrs = item_tree.attrs(ModItem::from(id).into());
+                let attrs = item_tree.attrs(db, module.krate, ModItem::from(id).into());
                 if !attrs.is_cfg_enabled(&cfg_options) {
                     continue;
                 }
index b8e09e3af3138513977b95319b56074b34136d84..100dbf5d6571ced6fcae71ef81722b2ecc244c74 100644 (file)
@@ -12,7 +12,8 @@
 };
 
 use arena::{Arena, Idx, RawId};
-use ast::{AstNode, AttrsOwner, NameOwner, StructKind};
+use ast::{AstNode, NameOwner, StructKind};
+use base_db::CrateId;
 use either::Either;
 use hir_expand::{
     ast_id_map::FileAstId,
@@ -26,7 +27,7 @@
 use test_utils::mark;
 
 use crate::{
-    attr::Attrs,
+    attr::{Attrs, RawAttrs},
     db::DefDatabase,
     generics::GenericParams,
     path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind},
@@ -67,7 +68,7 @@ impl GenericParamsId {
 #[derive(Debug, Eq, PartialEq)]
 pub struct ItemTree {
     top_level: SmallVec<[ModItem; 1]>,
-    attrs: FxHashMap<AttrOwner, Attrs>,
+    attrs: FxHashMap<AttrOwner, RawAttrs>,
     inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>,
 
     data: Option<Box<ItemTreeData>>,
@@ -88,7 +89,7 @@ pub fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree
         let mut item_tree = match_ast! {
             match syntax {
                 ast::SourceFile(file) => {
-                    top_attrs = Some(Attrs::new(&file, &hygiene));
+                    top_attrs = Some(RawAttrs::new(&file, &hygiene));
                     ctx.lower_module_items(&file)
                 },
                 ast::MacroItems(items) => {
@@ -180,12 +181,16 @@ pub fn top_level_items(&self) -> &[ModItem] {
     }
 
     /// Returns the inner attributes of the source file.
-    pub fn top_level_attrs(&self) -> &Attrs {
-        self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY)
+    pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs {
+        self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone().filter(db, krate)
     }
 
-    pub fn attrs(&self, of: AttrOwner) -> &Attrs {
-        self.attrs.get(&of).unwrap_or(&Attrs::EMPTY)
+    pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs {
+        self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY)
+    }
+
+    pub fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs {
+        self.raw_attrs(of).clone().filter(db, krate)
     }
 
     /// Returns the lowered inner items that `ast` corresponds to.
@@ -490,7 +495,6 @@ pub struct Import {
     pub alias: Option<ImportAlias>,
     pub visibility: RawVisibilityId,
     pub is_glob: bool,
-    pub is_prelude: bool,
     /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many
     /// `Import`s can map to the same `use` item.
     pub ast_id: FileAstId<ast::Use>,
@@ -506,8 +510,6 @@ pub struct ExternCrate {
     pub name: Name,
     pub alias: Option<ImportAlias>,
     pub visibility: RawVisibilityId,
-    /// Whether this is a `#[macro_use] extern crate ...`.
-    pub is_macro_use: bool,
     pub ast_id: FileAstId<ast::ExternCrate>,
 }
 
index 7de385ee83ecf8047daaa7c14c6d18538a3eb670..3b206ef85e63f9b48bff7a96416037c053408b3e 100644 (file)
@@ -10,7 +10,6 @@
 };
 
 use crate::{
-    attr::Attrs,
     generics::{GenericParams, TypeParamData, TypeParamProvenance},
     type_ref::LifetimeRef,
 };
@@ -105,7 +104,7 @@ fn lower_mod_item(&mut self, item: &ast::Item, inner: bool) -> Option<ModItems>
             | ast::Item::MacroDef(_) => {}
         };
 
-        let attrs = Attrs::new(item, &self.hygiene);
+        let attrs = RawAttrs::new(item, &self.hygiene);
         let items = match item {
             ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into),
             ast::Item::Union(ast) => self.lower_union(ast).map(Into::into),
@@ -138,7 +137,7 @@ fn lower_mod_item(&mut self, item: &ast::Item, inner: bool) -> Option<ModItems>
         items
     }
 
-    fn add_attrs(&mut self, item: AttrOwner, attrs: Attrs) {
+    fn add_attrs(&mut self, item: AttrOwner, attrs: RawAttrs) {
         match self.tree.attrs.entry(item) {
             Entry::Occupied(mut entry) => {
                 *entry.get_mut() = entry.get().merge(attrs);
@@ -205,7 +204,7 @@ fn lower_record_fields(&mut self, fields: &ast::RecordFieldList) -> IdRange<Fiel
         for field in fields.fields() {
             if let Some(data) = self.lower_record_field(&field) {
                 let idx = self.data().fields.alloc(data);
-                self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene));
+                self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene));
             }
         }
         let end = self.next_field_idx();
@@ -225,7 +224,7 @@ fn lower_tuple_fields(&mut self, fields: &ast::TupleFieldList) -> IdRange<Field>
         for (i, field) in fields.fields().enumerate() {
             let data = self.lower_tuple_field(i, &field);
             let idx = self.data().fields.alloc(data);
-            self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene));
+            self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene));
         }
         let end = self.next_field_idx();
         IdRange::new(start..end)
@@ -270,7 +269,7 @@ fn lower_variants(&mut self, variants: &ast::VariantList) -> IdRange<Variant> {
         for variant in variants.variants() {
             if let Some(data) = self.lower_variant(&variant) {
                 let idx = self.data().variants.alloc(data);
-                self.add_attrs(idx.into(), Attrs::new(&variant, &self.hygiene));
+                self.add_attrs(idx.into(), RawAttrs::new(&variant, &self.hygiene));
             }
         }
         let end = self.next_variant_idx();
@@ -438,7 +437,7 @@ fn lower_trait(&mut self, trait_def: &ast::Trait) -> Option<FileItemTreeId<Trait
             self.with_inherited_visibility(visibility, |this| {
                 list.assoc_items()
                     .filter_map(|item| {
-                        let attrs = Attrs::new(&item, &this.hygiene);
+                        let attrs = RawAttrs::new(&item, &this.hygiene);
                         this.collect_inner_items(item.syntax());
                         this.lower_assoc_item(&item).map(|item| {
                             this.add_attrs(ModItem::from(item).into(), attrs);
@@ -475,7 +474,7 @@ fn lower_impl(&mut self, impl_def: &ast::Impl) -> Option<FileItemTreeId<Impl>> {
             .filter_map(|item| {
                 self.collect_inner_items(item.syntax());
                 let assoc = self.lower_assoc_item(&item)?;
-                let attrs = Attrs::new(&item, &self.hygiene);
+                let attrs = RawAttrs::new(&item, &self.hygiene);
                 self.add_attrs(ModItem::from(assoc).into(), attrs);
                 Some(assoc)
             })
@@ -486,8 +485,6 @@ fn lower_impl(&mut self, impl_def: &ast::Impl) -> Option<FileItemTreeId<Impl>> {
     }
 
     fn lower_use(&mut self, use_item: &ast::Use) -> Vec<FileItemTreeId<Import>> {
-        // FIXME: cfg_attr
-        let is_prelude = use_item.has_atom_attr("prelude_import");
         let visibility = self.lower_visibility(use_item);
         let ast_id = self.source_ast_id_map.ast_id(use_item);
 
@@ -503,7 +500,6 @@ fn lower_use(&mut self, use_item: &ast::Use) -> Vec<FileItemTreeId<Import>> {
                     alias,
                     visibility,
                     is_glob,
-                    is_prelude,
                     ast_id,
                     index: imports.len(),
                 })));
@@ -523,10 +519,8 @@ fn lower_extern_crate(
         });
         let visibility = self.lower_visibility(extern_crate);
         let ast_id = self.source_ast_id_map.ast_id(extern_crate);
-        // FIXME: cfg_attr
-        let is_macro_use = extern_crate.has_atom_attr("macro_use");
 
-        let res = ExternCrate { name, alias, visibility, is_macro_use, ast_id };
+        let res = ExternCrate { name, alias, visibility, ast_id };
         Some(id(self.data().extern_crates.alloc(res)))
     }
 
@@ -560,7 +554,7 @@ fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> {
             list.extern_items()
                 .filter_map(|item| {
                     self.collect_inner_items(item.syntax());
-                    let attrs = Attrs::new(&item, &self.hygiene);
+                    let attrs = RawAttrs::new(&item, &self.hygiene);
                     let id: ModItem = match item {
                         ast::ExternItem::Fn(ast) => {
                             let func_id = self.lower_function(&ast)?;
index 7e2199a9c7f6e5be73a411c699f9f3ae55c9f0dc..ba09a9126bffb461b29ec443ddd7bd1a8161d9aa 100644 (file)
@@ -425,6 +425,16 @@ fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
     }
 }
 
+impl HasModule for VariantId {
+    fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
+        match self {
+            VariantId::EnumVariantId(it) => it.parent.lookup(db).container.module(db),
+            VariantId::StructId(it) => it.lookup(db).container.module(db),
+            VariantId::UnionId(it) => it.lookup(db).container.module(db),
+        }
+    }
+}
+
 impl HasModule for DefWithBodyId {
     fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
         match self {
@@ -465,6 +475,26 @@ fn module(&self, db: &dyn db::DefDatabase) -> ModuleId {
     }
 }
 
+impl AttrDefId {
+    pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId {
+        match self {
+            AttrDefId::ModuleId(it) => it.krate,
+            AttrDefId::FieldId(it) => it.parent.module(db).krate,
+            AttrDefId::AdtId(it) => it.module(db).krate,
+            AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate,
+            AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db).krate,
+            AttrDefId::StaticId(it) => it.lookup(db).module(db).krate,
+            AttrDefId::ConstId(it) => it.lookup(db).module(db).krate,
+            AttrDefId::TraitId(it) => it.lookup(db).container.module(db).krate,
+            AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate,
+            AttrDefId::ImplId(it) => it.lookup(db).container.module(db).krate,
+            // FIXME: `MacroDefId` should store the defining module, then this can implement
+            // `HasModule`
+            AttrDefId::MacroDefId(it) => it.krate,
+        }
+    }
+}
+
 /// A helper trait for converting to MacroCallId
 pub trait AsMacroCall {
     fn as_call_id(
index 1936348fb43b74bc465cc275a056a71e578e6572..a636ec77d71b9dac4f7c4a5e3cf84f5d24e5a291 100644 (file)
@@ -136,23 +136,35 @@ struct Import {
 }
 
 impl Import {
-    fn from_use(tree: &ItemTree, id: ItemTreeId<item_tree::Import>) -> Self {
+    fn from_use(
+        db: &dyn DefDatabase,
+        krate: CrateId,
+        tree: &ItemTree,
+        id: ItemTreeId<item_tree::Import>,
+    ) -> Self {
         let it = &tree[id.value];
+        let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
         let visibility = &tree[it.visibility];
         Self {
             path: it.path.clone(),
             alias: it.alias.clone(),
             visibility: visibility.clone(),
             is_glob: it.is_glob,
-            is_prelude: it.is_prelude,
+            is_prelude: attrs.by_key("prelude_import").exists(),
             is_extern_crate: false,
             is_macro_use: false,
             source: ImportSource::Import(id),
         }
     }
 
-    fn from_extern_crate(tree: &ItemTree, id: ItemTreeId<item_tree::ExternCrate>) -> Self {
+    fn from_extern_crate(
+        db: &dyn DefDatabase,
+        krate: CrateId,
+        tree: &ItemTree,
+        id: ItemTreeId<item_tree::ExternCrate>,
+    ) -> Self {
         let it = &tree[id.value];
+        let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
         let visibility = &tree[it.visibility];
         Self {
             path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
@@ -161,7 +173,7 @@ fn from_extern_crate(tree: &ItemTree, id: ItemTreeId<item_tree::ExternCrate>) ->
             is_glob: false,
             is_prelude: false,
             is_extern_crate: true,
-            is_macro_use: it.is_macro_use,
+            is_macro_use: attrs.by_key("macro_use").exists(),
             source: ImportSource::ExternCrate(id),
         }
     }
@@ -221,17 +233,20 @@ fn collect(&mut self) {
         let item_tree = self.db.item_tree(file_id.into());
         let module_id = self.def_map.root;
         self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id };
-        let mut root_collector = ModCollector {
-            def_collector: &mut *self,
-            macro_depth: 0,
-            module_id,
-            file_id: file_id.into(),
-            item_tree: &item_tree,
-            mod_dir: ModDir::root(),
-        };
-        if item_tree.top_level_attrs().cfg().map_or(true, |cfg| root_collector.is_cfg_enabled(&cfg))
+        if item_tree
+            .top_level_attrs(self.db, self.def_map.krate)
+            .cfg()
+            .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false))
         {
-            root_collector.collect(item_tree.top_level_items());
+            ModCollector {
+                def_collector: &mut *self,
+                macro_depth: 0,
+                module_id,
+                file_id: file_id.into(),
+                item_tree: &item_tree,
+                mod_dir: ModDir::root(),
+            }
+            .collect(item_tree.top_level_items());
         }
 
         // main name resolution fixed-point loop.
@@ -905,6 +920,8 @@ struct ModCollector<'a, 'b> {
 
 impl ModCollector<'_, '_> {
     fn collect(&mut self, items: &[ModItem]) {
+        let krate = self.def_collector.def_map.krate;
+
         // Note: don't assert that inserted value is fresh: it's simply not true
         // for macros.
         self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
@@ -921,11 +938,16 @@ fn collect(&mut self, items: &[ModItem]) {
         // `#[macro_use] extern crate` is hoisted to imports macros before collecting
         // any other items.
         for item in items {
-            let attrs = self.item_tree.attrs((*item).into());
+            let attrs = self.item_tree.attrs(self.def_collector.db, krate, (*item).into());
             if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) {
                 if let ModItem::ExternCrate(id) = item {
                     let import = self.item_tree[*id].clone();
-                    if import.is_macro_use {
+                    let attrs = self.item_tree.attrs(
+                        self.def_collector.db,
+                        krate,
+                        ModItem::from(*id).into(),
+                    );
+                    if attrs.by_key("macro_use").exists() {
                         self.def_collector.import_macros_from_extern_crate(self.module_id, &import);
                     }
                 }
@@ -933,7 +955,7 @@ fn collect(&mut self, items: &[ModItem]) {
         }
 
         for &item in items {
-            let attrs = self.item_tree.attrs(item.into());
+            let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into());
             if let Some(cfg) = attrs.cfg() {
                 if !self.is_cfg_enabled(&cfg) {
                     self.emit_unconfigured_diagnostic(item, &cfg);
@@ -946,11 +968,13 @@ fn collect(&mut self, items: &[ModItem]) {
 
             let mut def = None;
             match item {
-                ModItem::Mod(m) => self.collect_module(&self.item_tree[m], attrs),
+                ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs),
                 ModItem::Import(import_id) => {
                     self.def_collector.unresolved_imports.push(ImportDirective {
                         module_id: self.module_id,
                         import: Import::from_use(
+                            self.def_collector.db,
+                            krate,
                             &self.item_tree,
                             InFile::new(self.file_id, import_id),
                         ),
@@ -961,6 +985,8 @@ fn collect(&mut self, items: &[ModItem]) {
                     self.def_collector.unresolved_imports.push(ImportDirective {
                         module_id: self.module_id,
                         import: Import::from_extern_crate(
+                            self.def_collector.db,
+                            krate,
                             &self.item_tree,
                             InFile::new(self.file_id, import_id),
                         ),
@@ -975,7 +1001,11 @@ fn collect(&mut self, items: &[ModItem]) {
 
                     // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it
                     // to define builtin macros, so we support at least that part.
-                    let attrs = self.item_tree.attrs(ModItem::from(id).into());
+                    let attrs = self.item_tree.attrs(
+                        self.def_collector.db,
+                        krate,
+                        ModItem::from(id).into(),
+                    );
                     if attrs.by_key("rustc_builtin_macro").exists() {
                         let krate = self.def_collector.def_map.krate;
                         let macro_id = find_builtin_macro(&mac.name, krate, ast_id)
@@ -1012,7 +1042,7 @@ fn collect(&mut self, items: &[ModItem]) {
                 ModItem::Function(id) => {
                     let func = &self.item_tree[id];
 
-                    self.collect_proc_macro_def(&func.name, attrs);
+                    self.collect_proc_macro_def(&func.name, &attrs);
 
                     def = Some(DefData {
                         id: FunctionLoc {
@@ -1032,7 +1062,7 @@ fn collect(&mut self, items: &[ModItem]) {
                     // FIXME: check attrs to see if this is an attribute macro invocation;
                     // in which case we don't add the invocation, just a single attribute
                     // macro invocation
-                    self.collect_derives(attrs, it.ast_id.upcast());
+                    self.collect_derives(&attrs, it.ast_id.upcast());
 
                     def = Some(DefData {
                         id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1049,7 +1079,7 @@ fn collect(&mut self, items: &[ModItem]) {
                     // FIXME: check attrs to see if this is an attribute macro invocation;
                     // in which case we don't add the invocation, just a single attribute
                     // macro invocation
-                    self.collect_derives(attrs, it.ast_id.upcast());
+                    self.collect_derives(&attrs, it.ast_id.upcast());
 
                     def = Some(DefData {
                         id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1066,7 +1096,7 @@ fn collect(&mut self, items: &[ModItem]) {
                     // FIXME: check attrs to see if this is an attribute macro invocation;
                     // in which case we don't add the invocation, just a single attribute
                     // macro invocation
-                    self.collect_derives(attrs, it.ast_id.upcast());
+                    self.collect_derives(&attrs, it.ast_id.upcast());
 
                     def = Some(DefData {
                         id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) }
@@ -1259,20 +1289,20 @@ fn push_child_module(
     }
 
     fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId<ast::Item>) {
-        for derive_subtree in attrs.by_key("derive").tt_values() {
-            // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree
-            for tt in &derive_subtree.token_trees {
-                let ident = match &tt {
-                    tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => ident,
-                    tt::TokenTree::Leaf(tt::Leaf::Punct(_)) => continue, // , is ok
-                    _ => continue, // anything else would be an error (which we currently ignore)
-                };
-                let path = ModPath::from_tt_ident(ident);
-
-                let ast_id = AstIdWithPath::new(self.file_id, ast_id, path);
-                self.def_collector
-                    .unexpanded_attribute_macros
-                    .push(DeriveDirective { module_id: self.module_id, ast_id });
+        for derive in attrs.by_key("derive").attrs() {
+            match derive.parse_derive() {
+                Some(derive_macros) => {
+                    for path in derive_macros {
+                        let ast_id = AstIdWithPath::new(self.file_id, ast_id, path);
+                        self.def_collector
+                            .unexpanded_attribute_macros
+                            .push(DeriveDirective { module_id: self.module_id, ast_id });
+                    }
+                }
+                None => {
+                    // FIXME: diagnose
+                    log::debug!("malformed derive: {:?}", derive);
+                }
             }
         }
     }
@@ -1303,8 +1333,9 @@ fn collect_proc_macro_def(&mut self, func_name: &Name, attrs: &Attrs) {
     }
 
     fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) {
+        let krate = self.def_collector.def_map.krate;
         let mac = &self.item_tree[id];
-        let attrs = self.item_tree.attrs(ModItem::from(id).into());
+        let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into());
         let ast_id = InFile::new(self.file_id, mac.ast_id.upcast());
 
         let export_attr = attrs.by_key("macro_export");
index a4d1fb8f31d922282dadcdd575b3ec75bd69db22..c459fa66d2760ea4c3a560a800ab5a698926ab29 100644 (file)
@@ -13,8 +13,8 @@
 
 use crate::{db::DefDatabase, nameres::*, test_db::TestDB};
 
-fn compute_crate_def_map(fixture: &str) -> Arc<CrateDefMap> {
-    let db = TestDB::with_files(fixture);
+fn compute_crate_def_map(ra_fixture: &str) -> Arc<CrateDefMap> {
+    let db = TestDB::with_files(ra_fixture);
     let krate = db.crate_graph().iter().next().unwrap();
     db.crate_def_map(krate)
 }
index 1a7b988318e895ee0103779dafcb66d0c3d7ca25..58d69d3c6b2b33412ce675455aed5b0370f449f4 100644 (file)
@@ -1,4 +1,5 @@
 use base_db::fixture::WithFixture;
+use test_utils::mark;
 
 use crate::test_db::TestDB;
 
@@ -119,3 +120,20 @@ fn inactive_item() {
         "#,
     );
 }
+
+/// Tests that `cfg` attributes behind `cfg_attr` is handled properly.
+#[test]
+fn inactive_via_cfg_attr() {
+    mark::check!(cfg_attr_active);
+    check_diagnostics(
+        r#"
+        //- /lib.rs
+          #[cfg_attr(not(never), cfg(no))] fn f() {}
+        //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ code is inactive due to #[cfg] directives: no is disabled
+
+          #[cfg_attr(not(never), cfg(not(no)))] fn f() {}
+
+          #[cfg_attr(never, cfg(no))] fn g() {}
+        "#,
+    );
+}
index 6fe2ee78a1fcbd176cfb10b9d6ecc359f03e7a50..f9bf5bc7253f6ac8e0f5e14e1c729589e72bcac7 100644 (file)
@@ -632,11 +632,11 @@ macro_rules! foo {
 #[test]
 fn expand_derive() {
     let map = compute_crate_def_map(
-        "
+        r#"
         //- /main.rs crate:main deps:core
-        use core::*;
+        use core::Copy;
 
-        #[derive(Copy, Clone)]
+        #[derive(Copy, core::Clone)]
         struct Foo;
 
         //- /core.rs crate:core
@@ -645,7 +645,7 @@ fn expand_derive() {
 
         #[rustc_builtin_macro]
         pub macro Clone {}
-        ",
+        "#,
     );
     assert_eq!(map.modules[map.root].scope.impls().len(), 2);
 }
index 00a69a8a63d23b4ebea0e1c185e1318d5276736b..e2bf85bbc3a145080d5e15c02959275bb6a66e38 100644 (file)
@@ -9,11 +9,8 @@
 
 use crate::{body::LowerCtx, type_ref::LifetimeRef};
 use base_db::CrateId;
-use hir_expand::{
-    hygiene::Hygiene,
-    name::{AsName, Name},
-};
-use syntax::ast::{self};
+use hir_expand::{hygiene::Hygiene, name::Name};
+use syntax::ast;
 
 use crate::{
     type_ref::{TypeBound, TypeRef},
@@ -56,11 +53,6 @@ pub fn from_segments(kind: PathKind, segments: impl IntoIterator<Item = Name>) -
         ModPath { kind, segments }
     }
 
-    /// Converts an `tt::Ident` into a single-identifier `Path`.
-    pub(crate) fn from_tt_ident(ident: &tt::Ident) -> ModPath {
-        ident.as_name().into()
-    }
-
     /// Calls `cb` with all paths, represented by this use item.
     pub(crate) fn expand_use_item(
         item_src: InFile<ast::Use>,
index 7fb4caea3682b3c3f7ecfbcb2e7ad9691b325808..2f44876a8a3c382320363705d67dda4d821c0458 100644 (file)
@@ -152,7 +152,9 @@ macro_rules! known_names {
         str,
         // Special names
         macro_rules,
+        derive,
         doc,
+        cfg_attr,
         // Components of known path (value or mod name)
         std,
         core,
index 8ad50a2ee5ed91657d145dea80d66125a6a5562f..60e0cd4addfe5ddb7005f735077e5d41f47a59cf 100644 (file)
@@ -181,8 +181,8 @@ fn caller() {
     call<|>ee();
 }
 "#,
-            "callee FN FileId(0) 0..14 3..9",
-            &["caller FN FileId(0) 15..44 18..24 : [33..39]"],
+            "callee Function FileId(0) 0..14 3..9",
+            &["caller Function FileId(0) 15..44 18..24 : [33..39]"],
             &[],
         );
     }
@@ -197,8 +197,8 @@ fn caller() {
     callee();
 }
 "#,
-            "callee FN FileId(0) 0..14 3..9",
-            &["caller FN FileId(0) 15..44 18..24 : [33..39]"],
+            "callee Function FileId(0) 0..14 3..9",
+            &["caller Function FileId(0) 15..44 18..24 : [33..39]"],
             &[],
         );
     }
@@ -214,8 +214,8 @@ fn caller() {
     callee();
 }
 "#,
-            "callee FN FileId(0) 0..14 3..9",
-            &["caller FN FileId(0) 15..58 18..24 : [33..39, 47..53]"],
+            "callee Function FileId(0) 0..14 3..9",
+            &["caller Function FileId(0) 15..58 18..24 : [33..39, 47..53]"],
             &[],
         );
     }
@@ -234,10 +234,10 @@ fn caller2() {
     callee();
 }
 "#,
-            "callee FN FileId(0) 0..14 3..9",
+            "callee Function FileId(0) 0..14 3..9",
             &[
-                "caller1 FN FileId(0) 15..45 18..25 : [34..40]",
-                "caller2 FN FileId(0) 47..77 50..57 : [66..72]",
+                "caller1 Function FileId(0) 15..45 18..25 : [34..40]",
+                "caller2 Function FileId(0) 47..77 50..57 : [66..72]",
             ],
             &[],
         );
@@ -263,10 +263,10 @@ fn test_caller() {
     }
 }
 "#,
-            "callee FN FileId(0) 0..14 3..9",
+            "callee Function FileId(0) 0..14 3..9",
             &[
-                "caller1 FN FileId(0) 15..45 18..25 : [34..40]",
-                "test_caller FN FileId(0) 95..149 110..121 : [134..140]",
+                "caller1 Function FileId(0) 15..45 18..25 : [34..40]",
+                "test_caller Function FileId(0) 95..149 110..121 : [134..140]",
             ],
             &[],
         );
@@ -287,8 +287,8 @@ fn caller() {
 //- /foo/mod.rs
 pub fn callee() {}
 "#,
-            "callee FN FileId(1) 0..18 7..13",
-            &["caller FN FileId(0) 27..56 30..36 : [45..51]"],
+            "callee Function FileId(1) 0..18 7..13",
+            &["caller Function FileId(0) 27..56 30..36 : [45..51]"],
             &[],
         );
     }
@@ -304,9 +304,9 @@ fn call<|>er() {
     callee();
 }
 "#,
-            "caller FN FileId(0) 15..58 18..24",
+            "caller Function FileId(0) 15..58 18..24",
             &[],
-            &["callee FN FileId(0) 0..14 3..9 : [33..39, 47..53]"],
+            &["callee Function FileId(0) 0..14 3..9 : [33..39, 47..53]"],
         );
     }
 
@@ -325,9 +325,9 @@ fn call<|>er() {
 //- /foo/mod.rs
 pub fn callee() {}
 "#,
-            "caller FN FileId(0) 27..56 30..36",
+            "caller Function FileId(0) 27..56 30..36",
             &[],
-            &["callee FN FileId(1) 0..18 7..13 : [45..51]"],
+            &["callee Function FileId(1) 0..18 7..13 : [45..51]"],
         );
     }
 
@@ -348,9 +348,9 @@ fn caller3() {
 
 }
 "#,
-            "caller2 FN FileId(0) 33..64 36..43",
-            &["caller1 FN FileId(0) 0..31 3..10 : [19..26]"],
-            &["caller3 FN FileId(0) 66..83 69..76 : [52..59]"],
+            "caller2 Function FileId(0) 33..64 36..43",
+            &["caller1 Function FileId(0) 0..31 3..10 : [19..26]"],
+            &["caller3 Function FileId(0) 66..83 69..76 : [52..59]"],
         );
     }
 
@@ -368,9 +368,9 @@ fn main() {
     a<|>()
 }
 "#,
-            "a FN FileId(0) 0..18 3..4",
-            &["main FN FileId(0) 31..52 34..38 : [47..48]"],
-            &["b FN FileId(0) 20..29 23..24 : [13..14]"],
+            "a Function FileId(0) 0..18 3..4",
+            &["main Function FileId(0) 31..52 34..38 : [47..48]"],
+            &["b Function FileId(0) 20..29 23..24 : [13..14]"],
         );
 
         check_hierarchy(
@@ -385,8 +385,8 @@ fn main() {
     a()
 }
 "#,
-            "b FN FileId(0) 20..29 23..24",
-            &["a FN FileId(0) 0..18 3..4 : [13..14]"],
+            "b Function FileId(0) 20..29 23..24",
+            &["a Function FileId(0) 0..18 3..4 : [13..14]"],
             &[],
         );
     }
index 13240672f0b79ea0862b4c09ecee2652def55ed8..e8b89662385b8f7029d9fb95ffff86dda5660059 100644 (file)
@@ -166,7 +166,7 @@ fn missing_record_expr_field_fix(
             def_file_id = source.file_id;
             source.value.record_field_list()?
         }
-        VariantDef::EnumVariant(e) => {
+        VariantDef::Variant(e) => {
             module = e.module(sema.db);
             let source = e.source(sema.db);
             def_file_id = source.file_id;
index 0650915c531450960cc0ef3479efcdf494fc8edc..bae9e40dfa2d03c65831f177d6ac2487f999b9d8 100644 (file)
@@ -1,10 +1,9 @@
 //! This module contains utilities for turning SyntaxNodes and HIR types
 //! into types that may be used to render in a UI.
 
-mod navigation_target;
+pub(crate) mod navigation_target;
 mod short_label;
 
-pub use navigation_target::NavigationTarget;
 pub(crate) use navigation_target::{ToNav, TryToNav};
 pub(crate) use short_label::ShortLabel;
 
index 54b33a98eacb99ee2c75ecc7b8b38ba3b7a7dc2e..cd8ec54fa72e20c469e167ee325e9b593725405a 100644 (file)
@@ -1,28 +1,51 @@
 //! FIXME: write short doc here
 
+use std::fmt;
+
 use either::Either;
-use hir::{
-    AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirFileId, InFile, ModuleSource,
+use hir::{AssocItem, Documentation, FieldSource, HasAttrs, HasSource, InFile, ModuleSource};
+use ide_db::{
+    base_db::{FileId, SourceDatabase},
+    symbol_index::FileSymbolKind,
 };
-use ide_db::base_db::{FileId, SourceDatabase};
 use ide_db::{defs::Definition, RootDatabase};
 use syntax::{
     ast::{self, NameOwner},
-    match_ast, AstNode, SmolStr,
-    SyntaxKind::{self, IDENT_PAT, LIFETIME_PARAM, TYPE_PARAM},
-    TextRange,
+    match_ast, AstNode, SmolStr, TextRange,
 };
 
 use crate::FileSymbol;
 
 use super::short_label::ShortLabel;
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
+pub enum SymbolKind {
+    Module,
+    Impl,
+    Field,
+    TypeParam,
+    LifetimeParam,
+    ValueParam,
+    SelfParam,
+    Local,
+    Function,
+    Const,
+    Static,
+    Struct,
+    Enum,
+    Variant,
+    Union,
+    TypeAlias,
+    Trait,
+    Macro,
+}
+
 /// `NavigationTarget` represents and element in the editor's UI which you can
 /// click on to navigate to a particular piece of code.
 ///
 /// Typically, a `NavigationTarget` corresponds to some element in the source
 /// code, like a function or a struct, but this is not strictly required.
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[derive(Clone, PartialEq, Eq, Hash)]
 pub struct NavigationTarget {
     pub file_id: FileId,
     /// Range which encompasses the whole element.
@@ -42,12 +65,30 @@ pub struct NavigationTarget {
     /// Clients should place the cursor on this range when navigating to this target.
     pub focus_range: Option<TextRange>,
     pub name: SmolStr,
-    pub kind: SyntaxKind,
+    pub kind: Option<SymbolKind>,
     pub container_name: Option<SmolStr>,
     pub description: Option<String>,
     pub docs: Option<Documentation>,
 }
 
+impl fmt::Debug for NavigationTarget {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let mut f = f.debug_struct("NavigationTarget");
+        macro_rules! opt {
+            ($($name:ident)*) => {$(
+                if let Some(it) = &self.$name {
+                    f.field(stringify!($name), it);
+                }
+            )*}
+        }
+        f.field("file_id", &self.file_id).field("full_range", &self.full_range);
+        opt!(focus_range);
+        f.field("name", &self.name);
+        opt!(kind container_name description docs);
+        f.finish()
+    }
+}
+
 pub(crate) trait ToNav {
     fn to_nav(&self, db: &RootDatabase) -> NavigationTarget;
 }
@@ -71,7 +112,7 @@ pub(crate) fn from_module_to_decl(db: &RootDatabase, module: hir::Module) -> Nav
                 name,
                 None,
                 frange.range,
-                src.value.syntax().kind(),
+                SymbolKind::Module,
             );
             res.docs = module.attrs(db).docs();
             res.description = src.value.short_label();
@@ -88,8 +129,13 @@ pub(crate) fn assert_match(&self, expected: &str) {
 
     #[cfg(test)]
     pub(crate) fn debug_render(&self) -> String {
-        let mut buf =
-            format!("{} {:?} {:?} {:?}", self.name, self.kind, self.file_id, self.full_range);
+        let mut buf = format!(
+            "{} {:?} {:?} {:?}",
+            self.name,
+            self.kind.unwrap(),
+            self.file_id,
+            self.full_range
+        );
         if let Some(focus_range) = self.focus_range {
             buf.push_str(&format!(" {:?}", focus_range))
         }
@@ -103,6 +149,7 @@ pub(crate) fn debug_render(&self) -> String {
     pub(crate) fn from_named(
         db: &RootDatabase,
         node: InFile<&dyn ast::NameOwner>,
+        kind: SymbolKind,
     ) -> NavigationTarget {
         let name =
             node.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_"));
@@ -110,32 +157,7 @@ pub(crate) fn from_named(
             node.value.name().map(|it| node.with_value(it.syntax()).original_file_range(db).range);
         let frange = node.map(|it| it.syntax()).original_file_range(db);
 
-        NavigationTarget::from_syntax(
-            frange.file_id,
-            name,
-            focus_range,
-            frange.range,
-            node.value.syntax().kind(),
-        )
-    }
-
-    /// Allows `NavigationTarget` to be created from a `DocCommentsOwner` and a `NameOwner`
-    pub(crate) fn from_doc_commented(
-        db: &RootDatabase,
-        named: InFile<&dyn ast::NameOwner>,
-        node: InFile<&dyn ast::DocCommentsOwner>,
-    ) -> NavigationTarget {
-        let name =
-            named.value.name().map(|it| it.text().clone()).unwrap_or_else(|| SmolStr::new("_"));
-        let frange = node.map(|it| it.syntax()).original_file_range(db);
-
-        NavigationTarget::from_syntax(
-            frange.file_id,
-            name,
-            None,
-            frange.range,
-            node.value.syntax().kind(),
-        )
+        NavigationTarget::from_syntax(frange.file_id, name, focus_range, frange.range, kind)
     }
 
     fn from_syntax(
@@ -143,12 +165,12 @@ fn from_syntax(
         name: SmolStr,
         focus_range: Option<TextRange>,
         full_range: TextRange,
-        kind: SyntaxKind,
+        kind: SymbolKind,
     ) -> NavigationTarget {
         NavigationTarget {
             file_id,
             name,
-            kind,
+            kind: Some(kind),
             full_range,
             focus_range,
             container_name: None,
@@ -163,12 +185,22 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
         NavigationTarget {
             file_id: self.file_id,
             name: self.name.clone(),
-            kind: self.kind,
+            kind: Some(match self.kind {
+                FileSymbolKind::Function => SymbolKind::Function,
+                FileSymbolKind::Struct => SymbolKind::Struct,
+                FileSymbolKind::Enum => SymbolKind::Enum,
+                FileSymbolKind::Trait => SymbolKind::Trait,
+                FileSymbolKind::Module => SymbolKind::Module,
+                FileSymbolKind::TypeAlias => SymbolKind::TypeAlias,
+                FileSymbolKind::Const => SymbolKind::Const,
+                FileSymbolKind::Static => SymbolKind::Static,
+                FileSymbolKind::Macro => SymbolKind::Macro,
+            }),
             full_range: self.range,
             focus_range: self.name_range,
             container_name: self.container_name.clone(),
             description: description_from_symbol(db, self),
-            docs: docs_from_symbol(db, self),
+            docs: None,
         }
     }
 }
@@ -176,7 +208,15 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
 impl TryToNav for Definition {
     fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
         match self {
-            Definition::Macro(it) => Some(it.to_nav(db)),
+            Definition::Macro(it) => {
+                // FIXME: Currently proc-macro do not have ast-node,
+                // such that it does not have source
+                // more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913
+                if it.is_proc_macro() {
+                    return None;
+                }
+                Some(it.to_nav(db))
+            }
             Definition::Field(it) => Some(it.to_nav(db)),
             Definition::ModuleDef(it) => it.try_to_nav(db),
             Definition::SelfType(it) => Some(it.to_nav(db)),
@@ -193,7 +233,7 @@ fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
             hir::ModuleDef::Module(it) => it.to_nav(db),
             hir::ModuleDef::Function(it) => it.to_nav(db),
             hir::ModuleDef::Adt(it) => it.to_nav(db),
-            hir::ModuleDef::EnumVariant(it) => it.to_nav(db),
+            hir::ModuleDef::Variant(it) => it.to_nav(db),
             hir::ModuleDef::Const(it) => it.to_nav(db),
             hir::ModuleDef::Static(it) => it.to_nav(db),
             hir::ModuleDef::Trait(it) => it.to_nav(db),
@@ -204,16 +244,36 @@ fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> {
     }
 }
 
-pub(crate) trait ToNavFromAst {}
-impl ToNavFromAst for hir::Function {}
-impl ToNavFromAst for hir::Const {}
-impl ToNavFromAst for hir::Static {}
-impl ToNavFromAst for hir::Struct {}
-impl ToNavFromAst for hir::Enum {}
-impl ToNavFromAst for hir::EnumVariant {}
-impl ToNavFromAst for hir::Union {}
-impl ToNavFromAst for hir::TypeAlias {}
-impl ToNavFromAst for hir::Trait {}
+pub(crate) trait ToNavFromAst {
+    const KIND: SymbolKind;
+}
+impl ToNavFromAst for hir::Function {
+    const KIND: SymbolKind = SymbolKind::Function;
+}
+impl ToNavFromAst for hir::Const {
+    const KIND: SymbolKind = SymbolKind::Const;
+}
+impl ToNavFromAst for hir::Static {
+    const KIND: SymbolKind = SymbolKind::Static;
+}
+impl ToNavFromAst for hir::Struct {
+    const KIND: SymbolKind = SymbolKind::Struct;
+}
+impl ToNavFromAst for hir::Enum {
+    const KIND: SymbolKind = SymbolKind::Enum;
+}
+impl ToNavFromAst for hir::Variant {
+    const KIND: SymbolKind = SymbolKind::Variant;
+}
+impl ToNavFromAst for hir::Union {
+    const KIND: SymbolKind = SymbolKind::Union;
+}
+impl ToNavFromAst for hir::TypeAlias {
+    const KIND: SymbolKind = SymbolKind::TypeAlias;
+}
+impl ToNavFromAst for hir::Trait {
+    const KIND: SymbolKind = SymbolKind::Trait;
+}
 
 impl<D> ToNav for D
 where
@@ -222,8 +282,11 @@ impl<D> ToNav for D
 {
     fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
         let src = self.source(db);
-        let mut res =
-            NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner));
+        let mut res = NavigationTarget::from_named(
+            db,
+            src.as_ref().map(|it| it as &dyn ast::NameOwner),
+            D::KIND,
+        );
         res.docs = self.docs(db);
         res.description = src.value.short_label();
         res
@@ -241,7 +304,7 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
             }
         };
         let frange = src.with_value(syntax).original_file_range(db);
-        NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, syntax.kind())
+        NavigationTarget::from_syntax(frange.file_id, name, focus, frange.range, SymbolKind::Module)
     }
 }
 
@@ -265,7 +328,7 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
             "impl".into(),
             focus_range,
             frange.range,
-            src.value.syntax().kind(),
+            SymbolKind::Impl,
         )
     }
 }
@@ -276,7 +339,8 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
 
         match &src.value {
             FieldSource::Named(it) => {
-                let mut res = NavigationTarget::from_named(db, src.with_value(it));
+                let mut res =
+                    NavigationTarget::from_named(db, src.with_value(it), SymbolKind::Field);
                 res.docs = self.docs(db);
                 res.description = it.short_label();
                 res
@@ -288,7 +352,7 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
                     "".into(),
                     None,
                     frange.range,
-                    it.syntax().kind(),
+                    SymbolKind::Field,
                 )
             }
         }
@@ -299,8 +363,11 @@ impl ToNav for hir::MacroDef {
     fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
         let src = self.source(db);
         log::debug!("nav target {:#?}", src.value.syntax());
-        let mut res =
-            NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner));
+        let mut res = NavigationTarget::from_named(
+            db,
+            src.as_ref().map(|it| it as &dyn ast::NameOwner),
+            SymbolKind::Macro,
+        );
         res.docs = self.docs(db);
         res
     }
@@ -340,10 +407,11 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
             Some(it) => it.to_string().into(),
             None => "".into(),
         };
+        let kind = if self.is_param(db) { SymbolKind::ValueParam } else { SymbolKind::Local };
         NavigationTarget {
             file_id: full_range.file_id,
             name,
-            kind: IDENT_PAT,
+            kind: Some(kind),
             full_range: full_range.range,
             focus_range: None,
             container_name: None,
@@ -367,7 +435,7 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
         NavigationTarget {
             file_id: src.file_id.original_file(db),
             name: self.name(db).to_string().into(),
-            kind: TYPE_PARAM,
+            kind: Some(SymbolKind::TypeParam),
             full_range,
             focus_range,
             container_name: None,
@@ -384,7 +452,7 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
         NavigationTarget {
             file_id: src.file_id.original_file(db),
             name: self.name(db).to_string().into(),
-            kind: LIFETIME_PARAM,
+            kind: Some(SymbolKind::LifetimeParam),
             full_range,
             focus_range: Some(full_range),
             container_name: None,
@@ -394,30 +462,6 @@ fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
     }
 }
 
-pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<Documentation> {
-    let parse = db.parse(symbol.file_id);
-    let node = symbol.ptr.to_node(parse.tree().syntax());
-    let file_id = HirFileId::from(symbol.file_id);
-
-    let it = match_ast! {
-        match node {
-            ast::Fn(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Struct(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Enum(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Trait(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Module(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::TypeAlias(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Const(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Static(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::RecordField(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Variant(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::MacroCall(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            _ => return None,
-        }
-    };
-    it.docs()
-}
-
 /// Get a description of a symbol.
 ///
 /// e.g. `struct Name`, `enum Name`, `fn Name`
@@ -465,34 +509,21 @@ fn foo() { enum FooInner { } }
                         0,
                     ),
                     full_range: 0..17,
-                    focus_range: Some(
-                        5..13,
-                    ),
+                    focus_range: 5..13,
                     name: "FooInner",
-                    kind: ENUM,
-                    container_name: None,
-                    description: Some(
-                        "enum FooInner",
-                    ),
-                    docs: None,
+                    kind: Enum,
+                    description: "enum FooInner",
                 },
                 NavigationTarget {
                     file_id: FileId(
                         0,
                     ),
                     full_range: 29..46,
-                    focus_range: Some(
-                        34..42,
-                    ),
+                    focus_range: 34..42,
                     name: "FooInner",
-                    kind: ENUM,
-                    container_name: Some(
-                        "foo",
-                    ),
-                    description: Some(
-                        "enum FooInner",
-                    ),
-                    docs: None,
+                    kind: Enum,
+                    container_name: "foo",
+                    description: "enum FooInner",
                 },
             ]
         "#]]
index 79c081cac26343589c7e206407c6fe84299800d7..b61ea0b3e40919f75403d5c8d2b3cbcda30808b8 100644 (file)
@@ -181,7 +181,7 @@ fn rewrite_intra_doc_link(
             ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns),
             ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns),
             ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns),
-            ModuleDef::EnumVariant(it) => it.resolve_doc_path(db, link, ns),
+            ModuleDef::Variant(it) => it.resolve_doc_path(db, link, ns),
             ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns),
             ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns),
             ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns),
@@ -390,7 +390,7 @@ fn get_symbol_filename(db: &dyn HirDatabase, definition: &ModuleDef) -> Option<S
         ModuleDef::TypeAlias(t) => format!("type.{}.html", t.name(db)),
         ModuleDef::BuiltinType(t) => format!("primitive.{}.html", t.as_name()),
         ModuleDef::Function(f) => format!("fn.{}.html", f.name(db)),
-        ModuleDef::EnumVariant(ev) => {
+        ModuleDef::Variant(ev) => {
             format!("enum.{}.html#variant.{}", ev.parent_enum(db).name(db), ev.name(db))
         }
         ModuleDef::Const(c) => format!("const.{}.html", c.name(db)?),
index c515313914254b25fda7f66dd695491846aefd20..32556dad33a1347115a94409de3678927f758860 100644 (file)
@@ -1,15 +1,17 @@
 use syntax::{
     ast::{self, AttrsOwner, GenericParamsOwner, NameOwner},
-    match_ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, WalkEvent,
+    match_ast, AstNode, SourceFile, SyntaxNode, TextRange, WalkEvent,
 };
 
+use crate::SymbolKind;
+
 #[derive(Debug, Clone)]
 pub struct StructureNode {
     pub parent: Option<usize>,
     pub label: String,
     pub navigation_range: TextRange,
     pub node_range: TextRange,
-    pub kind: SyntaxKind,
+    pub kind: SymbolKind,
     pub detail: Option<String>,
     pub deprecated: bool,
 }
@@ -51,25 +53,27 @@ pub(crate) fn file_structure(file: &SourceFile) -> Vec<StructureNode> {
 }
 
 fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
-    fn decl<N: NameOwner + AttrsOwner>(node: N) -> Option<StructureNode> {
-        decl_with_detail(&node, None)
+    fn decl<N: NameOwner + AttrsOwner>(node: N, kind: SymbolKind) -> Option<StructureNode> {
+        decl_with_detail(&node, None, kind)
     }
 
     fn decl_with_type_ref<N: NameOwner + AttrsOwner>(
         node: &N,
         type_ref: Option<ast::Type>,
+        kind: SymbolKind,
     ) -> Option<StructureNode> {
         let detail = type_ref.map(|type_ref| {
             let mut detail = String::new();
             collapse_ws(type_ref.syntax(), &mut detail);
             detail
         });
-        decl_with_detail(node, detail)
+        decl_with_detail(node, detail, kind)
     }
 
     fn decl_with_detail<N: NameOwner + AttrsOwner>(
         node: &N,
         detail: Option<String>,
+        kind: SymbolKind,
     ) -> Option<StructureNode> {
         let name = node.name()?;
 
@@ -78,7 +82,7 @@ fn decl_with_detail<N: NameOwner + AttrsOwner>(
             label: name.text().to_string(),
             navigation_range: name.syntax().text_range(),
             node_range: node.syntax().text_range(),
-            kind: node.syntax().kind(),
+            kind,
             detail,
             deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"),
         })
@@ -117,18 +121,18 @@ fn collapse_ws(node: &SyntaxNode, output: &mut String) {
                     collapse_ws(ret_type.syntax(), &mut detail);
                 }
 
-                decl_with_detail(&it, Some(detail))
+                decl_with_detail(&it, Some(detail), SymbolKind::Function)
             },
-            ast::Struct(it) => decl(it),
-            ast::Union(it) => decl(it),
-            ast::Enum(it) => decl(it),
-            ast::Variant(it) => decl(it),
-            ast::Trait(it) => decl(it),
-            ast::Module(it) => decl(it),
-            ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty()),
-            ast::RecordField(it) => decl_with_type_ref(&it, it.ty()),
-            ast::Const(it) => decl_with_type_ref(&it, it.ty()),
-            ast::Static(it) => decl_with_type_ref(&it, it.ty()),
+            ast::Struct(it) => decl(it, SymbolKind::Struct),
+            ast::Union(it) => decl(it, SymbolKind::Union),
+            ast::Enum(it) => decl(it, SymbolKind::Enum),
+            ast::Variant(it) => decl(it, SymbolKind::Variant),
+            ast::Trait(it) => decl(it, SymbolKind::Trait),
+            ast::Module(it) => decl(it, SymbolKind::Module),
+            ast::TypeAlias(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::TypeAlias),
+            ast::RecordField(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Field),
+            ast::Const(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Const),
+            ast::Static(it) => decl_with_type_ref(&it, it.ty(), SymbolKind::Static),
             ast::Impl(it) => {
                 let target_type = it.self_ty()?;
                 let target_trait = it.trait_();
@@ -144,13 +148,13 @@ fn collapse_ws(node: &SyntaxNode, output: &mut String) {
                     label,
                     navigation_range: target_type.syntax().text_range(),
                     node_range: it.syntax().text_range(),
-                    kind: it.syntax().kind(),
+                    kind: SymbolKind::Impl,
                     detail: None,
                     deprecated: false,
                 };
                 Some(node)
             },
-            ast::MacroRules(it) => decl(it),
+            ast::MacroRules(it) => decl(it, SymbolKind::Macro),
             _ => None,
         }
     }
@@ -222,7 +226,7 @@ fn very_obsolete() {}
                         label: "Foo",
                         navigation_range: 8..11,
                         node_range: 1..26,
-                        kind: STRUCT,
+                        kind: Struct,
                         detail: None,
                         deprecated: false,
                     },
@@ -233,7 +237,7 @@ fn very_obsolete() {}
                         label: "x",
                         navigation_range: 18..19,
                         node_range: 18..24,
-                        kind: RECORD_FIELD,
+                        kind: Field,
                         detail: Some(
                             "i32",
                         ),
@@ -244,7 +248,7 @@ fn very_obsolete() {}
                         label: "m",
                         navigation_range: 32..33,
                         node_range: 28..158,
-                        kind: MODULE,
+                        kind: Module,
                         detail: None,
                         deprecated: false,
                     },
@@ -255,7 +259,7 @@ fn very_obsolete() {}
                         label: "bar1",
                         navigation_range: 43..47,
                         node_range: 40..52,
-                        kind: FN,
+                        kind: Function,
                         detail: Some(
                             "fn()",
                         ),
@@ -268,7 +272,7 @@ fn very_obsolete() {}
                         label: "bar2",
                         navigation_range: 60..64,
                         node_range: 57..81,
-                        kind: FN,
+                        kind: Function,
                         detail: Some(
                             "fn<T>(t: T) -> T",
                         ),
@@ -281,7 +285,7 @@ fn very_obsolete() {}
                         label: "bar3",
                         navigation_range: 89..93,
                         node_range: 86..156,
-                        kind: FN,
+                        kind: Function,
                         detail: Some(
                             "fn<A, B>(a: A, b: B) -> Vec< u32 >",
                         ),
@@ -292,7 +296,7 @@ fn very_obsolete() {}
                         label: "E",
                         navigation_range: 165..166,
                         node_range: 160..180,
-                        kind: ENUM,
+                        kind: Enum,
                         detail: None,
                         deprecated: false,
                     },
@@ -303,7 +307,7 @@ fn very_obsolete() {}
                         label: "X",
                         navigation_range: 169..170,
                         node_range: 169..170,
-                        kind: VARIANT,
+                        kind: Variant,
                         detail: None,
                         deprecated: false,
                     },
@@ -314,7 +318,7 @@ fn very_obsolete() {}
                         label: "Y",
                         navigation_range: 172..173,
                         node_range: 172..178,
-                        kind: VARIANT,
+                        kind: Variant,
                         detail: None,
                         deprecated: false,
                     },
@@ -323,7 +327,7 @@ fn very_obsolete() {}
                         label: "T",
                         navigation_range: 186..187,
                         node_range: 181..193,
-                        kind: TYPE_ALIAS,
+                        kind: TypeAlias,
                         detail: Some(
                             "()",
                         ),
@@ -334,7 +338,7 @@ fn very_obsolete() {}
                         label: "S",
                         navigation_range: 201..202,
                         node_range: 194..213,
-                        kind: STATIC,
+                        kind: Static,
                         detail: Some(
                             "i32",
                         ),
@@ -345,7 +349,7 @@ fn very_obsolete() {}
                         label: "C",
                         navigation_range: 220..221,
                         node_range: 214..232,
-                        kind: CONST,
+                        kind: Const,
                         detail: Some(
                             "i32",
                         ),
@@ -356,7 +360,7 @@ fn very_obsolete() {}
                         label: "impl E",
                         navigation_range: 239..240,
                         node_range: 234..243,
-                        kind: IMPL,
+                        kind: Impl,
                         detail: None,
                         deprecated: false,
                     },
@@ -365,7 +369,7 @@ fn very_obsolete() {}
                         label: "impl fmt::Debug for E",
                         navigation_range: 265..266,
                         node_range: 245..269,
-                        kind: IMPL,
+                        kind: Impl,
                         detail: None,
                         deprecated: false,
                     },
@@ -374,7 +378,7 @@ fn very_obsolete() {}
                         label: "mc",
                         navigation_range: 284..286,
                         node_range: 271..303,
-                        kind: MACRO_RULES,
+                        kind: Macro,
                         detail: None,
                         deprecated: false,
                     },
@@ -383,7 +387,7 @@ fn very_obsolete() {}
                         label: "mcexp",
                         navigation_range: 334..339,
                         node_range: 305..356,
-                        kind: MACRO_RULES,
+                        kind: Macro,
                         detail: None,
                         deprecated: false,
                     },
@@ -392,7 +396,7 @@ fn very_obsolete() {}
                         label: "mcexp",
                         navigation_range: 387..392,
                         node_range: 358..409,
-                        kind: MACRO_RULES,
+                        kind: Macro,
                         detail: None,
                         deprecated: false,
                     },
@@ -401,7 +405,7 @@ fn very_obsolete() {}
                         label: "obsolete",
                         navigation_range: 428..436,
                         node_range: 411..441,
-                        kind: FN,
+                        kind: Function,
                         detail: Some(
                             "fn()",
                         ),
@@ -412,7 +416,7 @@ fn very_obsolete() {}
                         label: "very_obsolete",
                         navigation_range: 481..494,
                         node_range: 443..499,
-                        kind: FN,
+                        kind: Function,
                         detail: Some(
                             "fn()",
                         ),
index d75ae447bb0c0bf841ba327156ed504154961b31..431da5d9c75197126314fcd48d2f38fa956a9974 100644 (file)
@@ -9,7 +9,7 @@
 
 use crate::{
     display::{ToNav, TryToNav},
-    FilePosition, NavigationTarget, RangeInfo,
+    FilePosition, NavigationTarget, RangeInfo, SymbolKind,
 };
 
 // Feature: Go to Definition
@@ -86,7 +86,7 @@ fn self_to_nav_target(self_param: ast::SelfParam, file_id: FileId) -> Option<Nav
         full_range: self_param.syntax().text_range(),
         focus_range: Some(self_token.text_range()),
         name: self_token.text().clone(),
-        kind: self_token.kind(),
+        kind: Some(SymbolKind::SelfParam),
         container_name: None,
         description: None,
         docs: None,
index e82aad6d59df6566342414daf1c113d9376bd71d..52f993cc92b46f2d7778cfb5627bb882b57ca4a7 100644 (file)
@@ -297,7 +297,7 @@ fn definition_owner_name(db: &RootDatabase, def: &Definition) -> Option<String>
                 AssocItemContainer::Trait(t) => Some(t.name(db)),
                 AssocItemContainer::Impl(i) => i.target_ty(db).as_adt().map(|adt| adt.name(db)),
             },
-            ModuleDef::EnumVariant(e) => Some(e.parent_enum(db).name(db)),
+            ModuleDef::Variant(e) => Some(e.parent_enum(db).name(db)),
             _ => None,
         },
         _ => None,
@@ -324,6 +324,12 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> {
     let mod_path = definition_mod_path(db, &def);
     return match def {
         Definition::Macro(it) => {
+            // FIXME: Currently proc-macro do not have ast-node,
+            // such that it does not have source
+            // more discussion: https://github.com/rust-analyzer/rust-analyzer/issues/6913
+            if it.is_proc_macro() {
+                return None;
+            }
             let label = macro_label(&it.source(db).value);
             from_def_source_labeled(db, it, Some(label), mod_path)
         }
@@ -349,7 +355,7 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> {
             ModuleDef::Adt(Adt::Struct(it)) => from_def_source(db, it, mod_path),
             ModuleDef::Adt(Adt::Union(it)) => from_def_source(db, it, mod_path),
             ModuleDef::Adt(Adt::Enum(it)) => from_def_source(db, it, mod_path),
-            ModuleDef::EnumVariant(it) => from_def_source(db, it, mod_path),
+            ModuleDef::Variant(it) => from_def_source(db, it, mod_path),
             ModuleDef::Const(it) => from_def_source(db, it, mod_path),
             ModuleDef::Static(it) => from_def_source(db, it, mod_path),
             ModuleDef::Trait(it) => from_def_source(db, it, mod_path),
@@ -2181,14 +2187,9 @@ fn foo_<|>test() {}
                                     0,
                                 ),
                                 full_range: 0..24,
-                                focus_range: Some(
-                                    11..19,
-                                ),
+                                focus_range: 11..19,
                                 name: "foo_test",
-                                kind: FN,
-                                container_name: None,
-                                description: None,
-                                docs: None,
+                                kind: Function,
                             },
                             kind: Test {
                                 test_id: Path(
@@ -2224,14 +2225,9 @@ fn foo_test() {}
                                     0,
                                 ),
                                 full_range: 0..46,
-                                focus_range: Some(
-                                    4..9,
-                                ),
+                                focus_range: 4..9,
                                 name: "tests",
-                                kind: MODULE,
-                                container_name: None,
-                                description: None,
-                                docs: None,
+                                kind: Module,
                             },
                             kind: TestMod {
                                 path: "tests",
@@ -2263,16 +2259,10 @@ struct S{ f1: u32 }
                                         0,
                                     ),
                                     full_range: 0..19,
-                                    focus_range: Some(
-                                        7..8,
-                                    ),
+                                    focus_range: 7..8,
                                     name: "S",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S",
                                 },
                             },
                         ],
@@ -2302,16 +2292,10 @@ struct S<T>{ f1: T }
                                         0,
                                     ),
                                     full_range: 17..37,
-                                    focus_range: Some(
-                                        24..25,
-                                    ),
+                                    focus_range: 24..25,
                                     name: "S",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2321,16 +2305,10 @@ struct S<T>{ f1: T }
                                         0,
                                     ),
                                     full_range: 0..16,
-                                    focus_range: Some(
-                                        7..10,
-                                    ),
+                                    focus_range: 7..10,
                                     name: "Arg",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct Arg",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct Arg",
                                 },
                             },
                         ],
@@ -2360,16 +2338,10 @@ struct S<T>{ f1: T }
                                         0,
                                     ),
                                     full_range: 17..37,
-                                    focus_range: Some(
-                                        24..25,
-                                    ),
+                                    focus_range: 24..25,
                                     name: "S",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2379,16 +2351,10 @@ struct S<T>{ f1: T }
                                         0,
                                     ),
                                     full_range: 0..16,
-                                    focus_range: Some(
-                                        7..10,
-                                    ),
+                                    focus_range: 7..10,
                                     name: "Arg",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct Arg",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct Arg",
                                 },
                             },
                         ],
@@ -2421,16 +2387,10 @@ mod M {
                                         0,
                                     ),
                                     full_range: 0..14,
-                                    focus_range: Some(
-                                        7..8,
-                                    ),
+                                    focus_range: 7..8,
                                     name: "A",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct A",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct A",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2440,16 +2400,10 @@ mod M {
                                         0,
                                     ),
                                     full_range: 15..29,
-                                    focus_range: Some(
-                                        22..23,
-                                    ),
+                                    focus_range: 22..23,
                                     name: "B",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct B",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct B",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2459,16 +2413,10 @@ mod M {
                                         0,
                                     ),
                                     full_range: 42..60,
-                                    focus_range: Some(
-                                        53..54,
-                                    ),
+                                    focus_range: 53..54,
                                     name: "C",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "pub struct C",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "pub struct C",
                                 },
                             },
                         ],
@@ -2498,16 +2446,10 @@ fn foo() -> impl Foo {}
                                         0,
                                     ),
                                     full_range: 0..12,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                         ],
@@ -2538,16 +2480,10 @@ fn foo() -> impl Foo<S> {}
                                         0,
                                     ),
                                     full_range: 0..15,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2557,16 +2493,10 @@ fn foo() -> impl Foo<S> {}
                                         0,
                                     ),
                                     full_range: 16..25,
-                                    focus_range: Some(
-                                        23..24,
-                                    ),
+                                    focus_range: 23..24,
                                     name: "S",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S",
                                 },
                             },
                         ],
@@ -2597,16 +2527,10 @@ fn foo() -> impl Foo + Bar {}
                                         0,
                                     ),
                                     full_range: 0..12,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2616,16 +2540,10 @@ fn foo() -> impl Foo + Bar {}
                                         0,
                                     ),
                                     full_range: 13..25,
-                                    focus_range: Some(
-                                        19..22,
-                                    ),
+                                    focus_range: 19..22,
                                     name: "Bar",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Bar",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Bar",
                                 },
                             },
                         ],
@@ -2659,16 +2577,10 @@ fn foo() -> impl Foo<S1> + Bar<S2> {}
                                         0,
                                     ),
                                     full_range: 0..15,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2678,16 +2590,10 @@ fn foo() -> impl Foo<S1> + Bar<S2> {}
                                         0,
                                     ),
                                     full_range: 16..31,
-                                    focus_range: Some(
-                                        22..25,
-                                    ),
+                                    focus_range: 22..25,
                                     name: "Bar",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Bar",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Bar",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2697,16 +2603,10 @@ fn foo() -> impl Foo<S1> + Bar<S2> {}
                                         0,
                                     ),
                                     full_range: 32..44,
-                                    focus_range: Some(
-                                        39..41,
-                                    ),
+                                    focus_range: 39..41,
                                     name: "S1",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S1",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S1",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2716,16 +2616,10 @@ fn foo() -> impl Foo<S1> + Bar<S2> {}
                                         0,
                                     ),
                                     full_range: 45..57,
-                                    focus_range: Some(
-                                        52..54,
-                                    ),
+                                    focus_range: 52..54,
                                     name: "S2",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S2",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S2",
                                 },
                             },
                         ],
@@ -2753,16 +2647,10 @@ fn foo(ar<|>g: &impl Foo) {}
                                         0,
                                     ),
                                     full_range: 0..12,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                         ],
@@ -2793,16 +2681,10 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {}
                                         0,
                                     ),
                                     full_range: 0..12,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2812,16 +2694,10 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {}
                                         0,
                                     ),
                                     full_range: 13..28,
-                                    focus_range: Some(
-                                        19..22,
-                                    ),
+                                    focus_range: 19..22,
                                     name: "Bar",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Bar",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Bar",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2831,16 +2707,10 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {}
                                         0,
                                     ),
                                     full_range: 29..39,
-                                    focus_range: Some(
-                                        36..37,
-                                    ),
+                                    focus_range: 36..37,
                                     name: "S",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S",
                                 },
                             },
                         ],
@@ -2876,16 +2746,10 @@ mod future {
                                         0,
                                     ),
                                     full_range: 101..163,
-                                    focus_range: Some(
-                                        140..146,
-                                    ),
+                                    focus_range: 140..146,
                                     name: "Future",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "pub trait Future",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "pub trait Future",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2895,16 +2759,10 @@ mod future {
                                         0,
                                     ),
                                     full_range: 0..9,
-                                    focus_range: Some(
-                                        7..8,
-                                    ),
+                                    focus_range: 7..8,
                                     name: "S",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S",
                                 },
                             },
                         ],
@@ -2933,16 +2791,10 @@ fn foo(ar<|>g: &impl Foo<S>) {}
                                         0,
                                     ),
                                     full_range: 0..15,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                             HoverGotoTypeData {
@@ -2952,16 +2804,10 @@ fn foo(ar<|>g: &impl Foo<S>) {}
                                         0,
                                     ),
                                     full_range: 16..27,
-                                    focus_range: Some(
-                                        23..24,
-                                    ),
+                                    focus_range: 23..24,
                                     name: "S",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S",
                                 },
                             },
                         ],
@@ -2995,16 +2841,10 @@ fn foo() -> B<dyn Foo> {}
                                         0,
                                     ),
                                     full_range: 42..55,
-                                    focus_range: Some(
-                                        49..50,
-                                    ),
+                                    focus_range: 49..50,
                                     name: "B",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct B",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct B",
                                 },
                             },
                             HoverGotoTypeData {
@@ -3014,16 +2854,10 @@ fn foo() -> B<dyn Foo> {}
                                         0,
                                     ),
                                     full_range: 0..12,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                         ],
@@ -3051,16 +2885,10 @@ fn foo(ar<|>g: &dyn Foo) {}
                                         0,
                                     ),
                                     full_range: 0..12,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                         ],
@@ -3089,16 +2917,10 @@ fn foo(ar<|>g: &dyn Foo<S>) {}
                                         0,
                                     ),
                                     full_range: 0..15,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                             HoverGotoTypeData {
@@ -3108,16 +2930,10 @@ fn foo(ar<|>g: &dyn Foo<S>) {}
                                         0,
                                     ),
                                     full_range: 16..27,
-                                    focus_range: Some(
-                                        23..24,
-                                    ),
+                                    focus_range: 23..24,
                                     name: "S",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S",
                                 },
                             },
                         ],
@@ -3149,16 +2965,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
                                         0,
                                     ),
                                     full_range: 0..21,
-                                    focus_range: Some(
-                                        6..15,
-                                    ),
+                                    focus_range: 6..15,
                                     name: "ImplTrait",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait ImplTrait",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait ImplTrait",
                                 },
                             },
                             HoverGotoTypeData {
@@ -3168,16 +2978,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
                                         0,
                                     ),
                                     full_range: 43..57,
-                                    focus_range: Some(
-                                        50..51,
-                                    ),
+                                    focus_range: 50..51,
                                     name: "B",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct B",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct B",
                                 },
                             },
                             HoverGotoTypeData {
@@ -3187,16 +2991,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
                                         0,
                                     ),
                                     full_range: 22..42,
-                                    focus_range: Some(
-                                        28..36,
-                                    ),
+                                    focus_range: 28..36,
                                     name: "DynTrait",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait DynTrait",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait DynTrait",
                                 },
                             },
                             HoverGotoTypeData {
@@ -3206,16 +3004,10 @@ fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {}
                                         0,
                                     ),
                                     full_range: 58..69,
-                                    focus_range: Some(
-                                        65..66,
-                                    ),
+                                    focus_range: 65..66,
                                     name: "S",
-                                    kind: STRUCT,
-                                    container_name: None,
-                                    description: Some(
-                                        "struct S",
-                                    ),
-                                    docs: None,
+                                    kind: Struct,
+                                    description: "struct S",
                                 },
                             },
                         ],
@@ -3254,16 +3046,10 @@ fn test() -> impl Foo { S {} }
                                         0,
                                     ),
                                     full_range: 0..62,
-                                    focus_range: Some(
-                                        6..9,
-                                    ),
+                                    focus_range: 6..9,
                                     name: "Foo",
-                                    kind: TRAIT,
-                                    container_name: None,
-                                    description: Some(
-                                        "trait Foo",
-                                    ),
-                                    docs: None,
+                                    kind: Trait,
+                                    description: "trait Foo",
                                 },
                             },
                         ],
index c5c652cda49e52f50f6df5f50641c47f151baa3e..dbad9a84f6a0244764fca82e100006acd314bca2 100644 (file)
@@ -57,14 +57,14 @@ macro_rules! eprintln {
     symbol_index::{self, FileSymbol},
     LineIndexDatabase,
 };
-use syntax::{SourceFile, TextRange, TextSize};
+use syntax::SourceFile;
 
 use crate::display::ToNav;
 
 pub use crate::{
     call_hierarchy::CallItem,
     diagnostics::{Diagnostic, DiagnosticsConfig, Fix, Severity},
-    display::NavigationTarget,
+    display::navigation_target::{NavigationTarget, SymbolKind},
     expand_macro::ExpandedMacro,
     file_structure::StructureNode,
     folding_ranges::{Fold, FoldKind},
@@ -79,21 +79,20 @@ macro_rules! eprintln {
         HighlightedRange,
     },
 };
+pub use assists::{Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist};
 pub use completion::{
     CompletionConfig, CompletionItem, CompletionItemKind, CompletionResolveCapability,
     CompletionScore, ImportEdit, InsertTextFormat,
 };
-pub use ide_db::{
-    call_info::CallInfo,
-    search::{Reference, ReferenceAccess, ReferenceKind},
-};
-
-pub use assists::{Assist, AssistConfig, AssistId, AssistKind, ResolvedAssist};
 pub use hir::{Documentation, Semantics};
 pub use ide_db::base_db::{
     Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, SourceRoot,
     SourceRootId,
 };
+pub use ide_db::{
+    call_info::CallInfo,
+    search::{Reference, ReferenceAccess, ReferenceKind},
+};
 pub use ide_db::{
     label::Label,
     line_index::{LineCol, LineIndex},
@@ -103,6 +102,7 @@ macro_rules! eprintln {
     RootDatabase,
 };
 pub use ssr::SsrError;
+pub use syntax::{TextRange, TextSize};
 pub use text_edit::{Indel, TextEdit};
 
 pub type Cancelable<T> = Result<T, Canceled>;
index 6cc3b2991cdedc70d573e0e8327d8d270ed4e4c1..be344a09b32352571860c25329de4e07a372b7b2 100644 (file)
@@ -78,7 +78,7 @@ fn test_resolve_parent_module() {
             ",
         );
         let nav = analysis.parent_module(pos).unwrap().pop().unwrap();
-        nav.assert_match("foo MODULE FileId(0) 0..8");
+        nav.assert_match("foo Module FileId(0) 0..8");
     }
 
     #[test]
@@ -97,7 +97,7 @@ fn test_resolve_parent_module_on_module_decl() {
             ",
         );
         let nav = analysis.parent_module(pos).unwrap().pop().unwrap();
-        nav.assert_match("foo MODULE FileId(0) 0..8");
+        nav.assert_match("foo Module FileId(0) 0..8");
     }
 
     #[test]
@@ -113,7 +113,7 @@ mod baz { <|> }
             ",
         );
         let nav = analysis.parent_module(pos).unwrap().pop().unwrap();
-        nav.assert_match("baz MODULE FileId(0) 32..44");
+        nav.assert_match("baz Module FileId(0) 32..44");
     }
 
     #[test]
index 98190a86b254fe713edcc74a1a453506e0964fd5..18ea1930525b76f78f62007bdfb186f7f53b3677 100644 (file)
@@ -24,7 +24,7 @@
     match_ast, AstNode, SyntaxKind, SyntaxNode, TextRange, TokenAtOffset,
 };
 
-use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo};
+use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo, SymbolKind};
 
 #[derive(Debug, Clone)]
 pub struct ReferenceSearchResult {
@@ -278,7 +278,7 @@ fn try_find_self_references(
             full_range: self_param.syntax().text_range(),
             focus_range: Some(param_self_token.text_range()),
             name: param_self_token.text().clone(),
-            kind: param_self_token.kind(),
+            kind: Some(SymbolKind::SelfParam),
             container_name: None,
             description: None,
             docs: None,
@@ -343,7 +343,7 @@ fn main() {
 }
 "#,
             expect![[r#"
-                Foo STRUCT FileId(0) 0..26 7..10 Other
+                Foo Struct FileId(0) 0..26 7..10 Other
 
                 FileId(0) 101..104 StructLiteral
             "#]],
@@ -361,7 +361,7 @@ fn main() {
 }
 "#,
             expect![[r#"
-                Foo STRUCT FileId(0) 0..13 7..10 Other
+                Foo Struct FileId(0) 0..13 7..10 Other
 
                 FileId(0) 41..44 Other
                 FileId(0) 54..57 StructLiteral
@@ -380,7 +380,7 @@ fn main() {
 }
 "#,
             expect![[r#"
-                Foo STRUCT FileId(0) 0..16 7..10 Other
+                Foo Struct FileId(0) 0..16 7..10 Other
 
                 FileId(0) 64..67 StructLiteral
             "#]],
@@ -399,7 +399,7 @@ fn main() {
 }
 "#,
             expect![[r#"
-                Foo STRUCT FileId(0) 0..16 7..10 Other
+                Foo Struct FileId(0) 0..16 7..10 Other
 
                 FileId(0) 54..57 StructLiteral
             "#]],
@@ -420,7 +420,7 @@ fn main() {
 }
 "#,
             expect![[r#"
-                Foo ENUM FileId(0) 0..26 5..8 Other
+                Foo Enum FileId(0) 0..26 5..8 Other
 
                 FileId(0) 63..66 EnumLiteral
             "#]],
@@ -441,7 +441,7 @@ fn main() {
 }
 "#,
             expect![[r#"
-                Foo ENUM FileId(0) 0..26 5..8 Other
+                Foo Enum FileId(0) 0..26 5..8 Other
 
                 FileId(0) 50..53 Other
                 FileId(0) 63..66 EnumLiteral
@@ -463,7 +463,7 @@ fn main() {
 }
 "#,
             expect![[r#"
-                Foo ENUM FileId(0) 0..32 5..8 Other
+                Foo Enum FileId(0) 0..32 5..8 Other
 
                 FileId(0) 73..76 EnumLiteral
             "#]],
@@ -484,7 +484,7 @@ fn main() {
 }
 "#,
             expect![[r#"
-                Foo ENUM FileId(0) 0..33 5..8 Other
+                Foo Enum FileId(0) 0..33 5..8 Other
 
                 FileId(0) 70..73 EnumLiteral
             "#]],
@@ -507,7 +507,7 @@ fn main() {
     i = 5;
 }"#,
             expect![[r#"
-                i IDENT_PAT FileId(0) 24..25 Other Write
+                i Local FileId(0) 24..25 Other Write
 
                 FileId(0) 50..51 Other Write
                 FileId(0) 54..55 Other Read
@@ -531,7 +531,7 @@ fn bar() {
 }
 "#,
             expect![[r#"
-                spam IDENT_PAT FileId(0) 19..23 Other
+                spam Local FileId(0) 19..23 Other
 
                 FileId(0) 34..38 Other Read
                 FileId(0) 41..45 Other Read
@@ -546,7 +546,7 @@ fn test_find_all_refs_for_param_inside() {
 fn foo(i : u32) -> u32 { i<|> }
 "#,
             expect![[r#"
-                i IDENT_PAT FileId(0) 7..8 Other
+                i ValueParam FileId(0) 7..8 Other
 
                 FileId(0) 25..26 Other Read
             "#]],
@@ -560,7 +560,7 @@ fn test_find_all_refs_for_fn_param() {
 fn foo(i<|> : u32) -> u32 { i }
 "#,
             expect![[r#"
-                i IDENT_PAT FileId(0) 7..8 Other
+                i ValueParam FileId(0) 7..8 Other
 
                 FileId(0) 25..26 Other Read
             "#]],
@@ -581,7 +581,7 @@ fn main(s: Foo) {
 }
 "#,
             expect![[r#"
-                spam RECORD_FIELD FileId(0) 17..30 21..25 Other
+                spam Field FileId(0) 17..30 21..25 Other
 
                 FileId(0) 67..71 Other Read
             "#]],
@@ -598,7 +598,7 @@ fn f<|>(&self) {  }
 }
 "#,
             expect![[r#"
-                f FN FileId(0) 27..43 30..31 Other
+                f Function FileId(0) 27..43 30..31 Other
 
             "#]],
         );
@@ -615,7 +615,7 @@ enum Foo {
 }
 "#,
             expect![[r#"
-                B VARIANT FileId(0) 22..23 22..23 Other
+                B Variant FileId(0) 22..23 22..23 Other
 
             "#]],
         );
@@ -632,7 +632,7 @@ enum Foo {
 }
 "#,
             expect![[r#"
-                field RECORD_FIELD FileId(0) 26..35 26..31 Other
+                field Field FileId(0) 26..35 26..31 Other
 
             "#]],
         );
@@ -673,7 +673,7 @@ fn f() {
 }
 "#,
             expect![[r#"
-                Foo STRUCT FileId(1) 17..51 28..31 Other
+                Foo Struct FileId(1) 17..51 28..31 Other
 
                 FileId(0) 53..56 StructLiteral
                 FileId(2) 79..82 StructLiteral
@@ -703,7 +703,7 @@ pub struct Foo {
 }
 "#,
             expect![[r#"
-                foo SOURCE_FILE FileId(1) 0..35 Other
+                foo Module FileId(1) 0..35 Other
 
                 FileId(0) 14..17 Other
             "#]],
@@ -731,7 +731,7 @@ pub(super) struct Foo<|> {
 }
 "#,
             expect![[r#"
-                Foo STRUCT FileId(2) 0..41 18..21 Other
+                Foo Struct FileId(2) 0..41 18..21 Other
 
                 FileId(1) 20..23 Other
                 FileId(1) 47..50 StructLiteral
@@ -759,7 +759,7 @@ pub fn quux<|>() {}
             code,
             None,
             expect![[r#"
-                quux FN FileId(0) 19..35 26..30 Other
+                quux Function FileId(0) 19..35 26..30 Other
 
                 FileId(1) 16..20 StructLiteral
                 FileId(2) 16..20 StructLiteral
@@ -770,7 +770,7 @@ pub fn quux<|>() {}
             code,
             Some(SearchScope::single_file(FileId(2))),
             expect![[r#"
-                quux FN FileId(0) 19..35 26..30 Other
+                quux Function FileId(0) 19..35 26..30 Other
 
                 FileId(2) 16..20 StructLiteral
             "#]],
@@ -790,7 +790,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-                m1 MACRO_RULES FileId(0) 0..46 29..31 Other
+                m1 Macro FileId(0) 0..46 29..31 Other
 
                 FileId(0) 63..65 StructLiteral
                 FileId(0) 73..75 StructLiteral
@@ -808,7 +808,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-                i IDENT_PAT FileId(0) 23..24 Other Write
+                i Local FileId(0) 23..24 Other Write
 
                 FileId(0) 34..35 Other Write
                 FileId(0) 38..39 Other Read
@@ -830,7 +830,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-                f RECORD_FIELD FileId(0) 15..21 15..16 Other
+                f Field FileId(0) 15..21 15..16 Other
 
                 FileId(0) 55..56 RecordFieldExprOrPat Read
                 FileId(0) 68..69 Other Write
@@ -848,7 +848,7 @@ fn foo() {
 }
 "#,
             expect![[r#"
-                i IDENT_PAT FileId(0) 19..20 Other
+                i Local FileId(0) 19..20 Other
 
                 FileId(0) 26..27 Other Write
             "#]],
@@ -872,7 +872,7 @@ fn main() {
 }
 "#,
             expect![[r#"
-                new FN FileId(0) 54..81 61..64 Other
+                new Function FileId(0) 54..81 61..64 Other
 
                 FileId(0) 126..129 StructLiteral
             "#]],
@@ -894,7 +894,7 @@ fn f<|>() {}
 fn g() { f(); }
 "#,
             expect![[r#"
-                f FN FileId(0) 22..31 25..26 Other
+                f Function FileId(0) 22..31 25..26 Other
 
                 FileId(1) 11..12 Other
                 FileId(1) 24..25 StructLiteral
@@ -917,7 +917,7 @@ fn f(s: S) {
 }
 "#,
             expect![[r#"
-                field RECORD_FIELD FileId(0) 15..24 15..20 Other
+                field Field FileId(0) 15..24 15..20 Other
 
                 FileId(0) 68..73 FieldShorthandForField Read
             "#]],
@@ -941,7 +941,7 @@ fn f(e: En) {
 }
 "#,
             expect![[r#"
-                field RECORD_FIELD FileId(0) 32..41 32..37 Other
+                field Field FileId(0) 32..41 32..37 Other
 
                 FileId(0) 102..107 FieldShorthandForField Read
             "#]],
@@ -965,7 +965,7 @@ fn f() -> m::En {
 }
 "#,
             expect![[r#"
-                field RECORD_FIELD FileId(0) 56..65 56..61 Other
+                field Field FileId(0) 56..65 56..61 Other
 
                 FileId(0) 125..130 RecordFieldExprOrPat Read
             "#]],
@@ -990,7 +990,7 @@ fn foo(self) {
 }
 "#,
             expect![[r#"
-                self SELF_KW FileId(0) 47..51 47..51 SelfKw Read
+                self SelfParam FileId(0) 47..51 47..51 SelfKw Read
 
                 FileId(0) 71..75 SelfKw Read
                 FileId(0) 152..156 SelfKw Read
@@ -1038,7 +1038,7 @@ fn bar<'a>(_: &'a ()) {}
 }
 "#,
             expect![[r#"
-                'a LIFETIME_PARAM FileId(0) 55..57 55..57 Lifetime
+                'a LifetimeParam FileId(0) 55..57 55..57 Lifetime
 
                 FileId(0) 63..65 Lifetime
                 FileId(0) 71..73 Lifetime
@@ -1056,7 +1056,7 @@ fn test_find_lifetimes_type_alias() {
 type Foo<'a, T> where T: 'a<|> = &'a T;
 "#,
             expect![[r#"
-                'a LIFETIME_PARAM FileId(0) 9..11 9..11 Lifetime
+                'a LifetimeParam FileId(0) 9..11 9..11 Lifetime
 
                 FileId(0) 25..27 Lifetime
                 FileId(0) 31..33 Lifetime
@@ -1078,7 +1078,7 @@ fn foo() -> &'a<|> () {
 }
 "#,
             expect![[r#"
-                'a LIFETIME_PARAM FileId(0) 47..49 47..49 Lifetime
+                'a LifetimeParam FileId(0) 47..49 47..49 Lifetime
 
                 FileId(0) 55..57 Lifetime
                 FileId(0) 64..66 Lifetime
index 56e9238414d2babbce4c57d9ee65ca50c1bf980a..cd721b7ebcb382442d871037c702e297423fbd9f 100644 (file)
@@ -1488,4 +1488,39 @@ fn foo() -> &'yeeee () {
 "#,
         )
     }
+
+    #[test]
+    fn test_rename_bind_pat() {
+        check(
+            "new_name",
+            r#"
+fn main() {
+    enum CustomOption<T> {
+        None,
+        Some(T),
+    }
+
+    let test_variable = CustomOption::Some(22);
+
+    match test_variable {
+        CustomOption::Some(foo<|>) if foo == 11 => {}
+        _ => (),
+    }
+}"#,
+            r#"
+fn main() {
+    enum CustomOption<T> {
+        None,
+        Some(T),
+    }
+
+    let test_variable = CustomOption::Some(22);
+
+    match test_variable {
+        CustomOption::Some(new_name) if new_name == 11 => {}
+        _ => (),
+    }
+}"#,
+        );
+    }
 }
index 96462a7b0aa81c0490dbced973fae2da099ec475..2f2b99130e3b117ec6405609219e79ad21207d6e 100644 (file)
@@ -2,7 +2,7 @@
 
 use assists::utils::test_related_attribute;
 use cfg::CfgExpr;
-use hir::{AsAssocItem, Attrs, HirFileId, InFile, Semantics};
+use hir::{AsAssocItem, HasAttrs, InFile, Semantics};
 use ide_db::RootDatabase;
 use itertools::Itertools;
 use syntax::{
     match_ast, SyntaxNode,
 };
 
-use crate::{display::ToNav, FileId, NavigationTarget};
+use crate::{
+    display::{ToNav, TryToNav},
+    FileId, NavigationTarget, SymbolKind,
+};
 
 #[derive(Debug, Clone)]
 pub struct Runnable {
@@ -101,124 +104,113 @@ pub(crate) fn runnable(
     item: SyntaxNode,
     file_id: FileId,
 ) -> Option<Runnable> {
-    match_ast! {
-        match item {
-            ast::Struct(it) => runnable_struct(sema, it, file_id),
+    let runnable_item = match_ast! {
+        match (item.clone()) {
             ast::Fn(it) => runnable_fn(sema, it, file_id),
-            ast::Module(it) => runnable_mod(sema, it, file_id),
+            ast::Module(it) => runnable_mod(sema, it),
             _ => None,
         }
-    }
+    };
+    runnable_item.or_else(|| runnable_doctest(sema, item))
 }
 
-fn runnable_fn(
-    sema: &Semantics<RootDatabase>,
-    fn_def: ast::Fn,
-    file_id: FileId,
-) -> Option<Runnable> {
-    let name_string = fn_def.name()?.text().to_string();
+fn runnable_fn(sema: &Semantics<RootDatabase>, func: ast::Fn, file_id: FileId) -> Option<Runnable> {
+    let def = sema.to_def(&func)?;
+    let name_string = func.name()?.text().to_string();
 
-    let attrs = Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &fn_def));
     let kind = if name_string == "main" {
         RunnableKind::Bin
     } else {
-        let test_id = match sema.to_def(&fn_def).map(|def| def.module(sema.db)) {
-            Some(module) => {
-                let def = sema.to_def(&fn_def)?;
-                let impl_trait_name = def.as_assoc_item(sema.db).and_then(|assoc_item| {
-                    match assoc_item.container(sema.db) {
-                        hir::AssocItemContainer::Trait(trait_item) => {
-                            Some(trait_item.name(sema.db).to_string())
-                        }
-                        hir::AssocItemContainer::Impl(impl_def) => impl_def
-                            .target_ty(sema.db)
-                            .as_adt()
-                            .map(|adt| adt.name(sema.db).to_string()),
-                    }
-                });
-
-                let path_iter = module
-                    .path_to_root(sema.db)
-                    .into_iter()
-                    .rev()
-                    .filter_map(|it| it.name(sema.db))
-                    .map(|name| name.to_string());
-
-                let path = if let Some(impl_trait_name) = impl_trait_name {
-                    path_iter
-                        .chain(std::iter::once(impl_trait_name))
-                        .chain(std::iter::once(name_string))
-                        .join("::")
-                } else {
-                    path_iter.chain(std::iter::once(name_string)).join("::")
-                };
-
-                TestId::Path(path)
-            }
-            None => TestId::Name(name_string),
-        };
-
-        if test_related_attribute(&fn_def).is_some() {
-            let attr = TestAttr::from_fn(&fn_def);
+        let canonical_path = sema.to_def(&func).and_then(|def| {
+            let def: hir::ModuleDef = def.into();
+            def.canonical_path(sema.db)
+        });
+        let test_id = canonical_path.map(TestId::Path).unwrap_or(TestId::Name(name_string));
+
+        if test_related_attribute(&func).is_some() {
+            let attr = TestAttr::from_fn(&func);
             RunnableKind::Test { test_id, attr }
-        } else if fn_def.has_atom_attr("bench") {
+        } else if func.has_atom_attr("bench") {
             RunnableKind::Bench { test_id }
-        } else if has_runnable_doc_test(&attrs) {
-            RunnableKind::DocTest { test_id }
         } else {
             return None;
         }
     };
 
-    let cfg = attrs.cfg();
-
-    let nav = if let RunnableKind::DocTest { .. } = kind {
-        NavigationTarget::from_doc_commented(
-            sema.db,
-            InFile::new(file_id.into(), &fn_def),
-            InFile::new(file_id.into(), &fn_def),
-        )
-    } else {
-        NavigationTarget::from_named(sema.db, InFile::new(file_id.into(), &fn_def))
-    };
+    let nav = NavigationTarget::from_named(
+        sema.db,
+        InFile::new(file_id.into(), &func),
+        SymbolKind::Function,
+    );
+    let cfg = def.attrs(sema.db).cfg();
     Some(Runnable { nav, kind, cfg })
 }
 
-fn runnable_struct(
-    sema: &Semantics<RootDatabase>,
-    struct_def: ast::Struct,
-    file_id: FileId,
-) -> Option<Runnable> {
-    let name_string = struct_def.name()?.text().to_string();
+fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> {
+    match_ast! {
+        match item {
+            ast::Fn(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
+            ast::Struct(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
+            ast::Enum(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
+            ast::Union(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
+            ast::Trait(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
+            ast::Const(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
+            ast::Static(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
+            ast::TypeAlias(it) => module_def_doctest(sema, sema.to_def(&it)?.into()),
+            _ => None,
+        }
+    }
+}
 
-    let attrs =
-        Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &struct_def));
+fn module_def_doctest(sema: &Semantics<RootDatabase>, def: hir::ModuleDef) -> Option<Runnable> {
+    let attrs = match def {
+        hir::ModuleDef::Module(it) => it.attrs(sema.db),
+        hir::ModuleDef::Function(it) => it.attrs(sema.db),
+        hir::ModuleDef::Adt(it) => it.attrs(sema.db),
+        hir::ModuleDef::Variant(it) => it.attrs(sema.db),
+        hir::ModuleDef::Const(it) => it.attrs(sema.db),
+        hir::ModuleDef::Static(it) => it.attrs(sema.db),
+        hir::ModuleDef::Trait(it) => it.attrs(sema.db),
+        hir::ModuleDef::TypeAlias(it) => it.attrs(sema.db),
+        hir::ModuleDef::BuiltinType(_) => return None,
+    };
     if !has_runnable_doc_test(&attrs) {
         return None;
     }
-    let cfg = attrs.cfg();
-
-    let test_id = match sema.to_def(&struct_def).map(|def| def.module(sema.db)) {
-        Some(module) => {
-            let path_iter = module
-                .path_to_root(sema.db)
-                .into_iter()
-                .rev()
-                .filter_map(|it| it.name(sema.db))
-                .map(|name| name.to_string());
-            let path = path_iter.chain(std::iter::once(name_string)).join("::");
-
-            TestId::Path(path)
-        }
-        None => TestId::Name(name_string),
-    };
-
-    let nav = NavigationTarget::from_doc_commented(
-        sema.db,
-        InFile::new(file_id.into(), &struct_def),
-        InFile::new(file_id.into(), &struct_def),
-    );
-    Some(Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg })
+    let def_name = def.name(sema.db).map(|it| it.to_string());
+    let test_id = def
+        .canonical_path(sema.db)
+        // This probably belongs to canonical path?
+        .map(|path| {
+            let assoc_def = match def {
+                hir::ModuleDef::Function(it) => it.as_assoc_item(sema.db),
+                hir::ModuleDef::Const(it) => it.as_assoc_item(sema.db),
+                hir::ModuleDef::TypeAlias(it) => it.as_assoc_item(sema.db),
+                _ => None,
+            };
+            // FIXME: this also looks very wrong
+            if let Some(assoc_def) = assoc_def {
+                if let hir::AssocItemContainer::Impl(imp) = assoc_def.container(sema.db) {
+                    if let Some(adt) = imp.target_ty(sema.db).as_adt() {
+                        let name = adt.name(sema.db).to_string();
+                        let idx = path.rfind(':').unwrap_or(0);
+                        let (prefix, suffix) = path.split_at(idx);
+                        return format!("{}{}::{}", prefix, name, suffix);
+                    }
+                }
+            }
+            path
+        })
+        .map(TestId::Path)
+        .or_else(|| def_name.clone().map(TestId::Name))?;
+
+    let mut nav = def.try_to_nav(sema.db)?;
+    nav.focus_range = None;
+    nav.description = None;
+    nav.docs = None;
+    nav.kind = None;
+    let res = Runnable { nav, kind: RunnableKind::DocTest { test_id }, cfg: attrs.cfg() };
+    Some(res)
 }
 
 #[derive(Debug, Copy, Clone)]
@@ -262,11 +254,7 @@ fn has_runnable_doc_test(attrs: &hir::Attrs) -> bool {
     })
 }
 
-fn runnable_mod(
-    sema: &Semantics<RootDatabase>,
-    module: ast::Module,
-    file_id: FileId,
-) -> Option<Runnable> {
+fn runnable_mod(sema: &Semantics<RootDatabase>, module: ast::Module) -> Option<Runnable> {
     if !has_test_function_or_multiple_test_submodules(&module) {
         return None;
     }
@@ -279,7 +267,8 @@ fn runnable_mod(
         .filter_map(|it| it.name(sema.db))
         .join("::");
 
-    let attrs = Attrs::from_attrs_owner(sema.db, InFile::new(HirFileId::from(file_id), &module));
+    let def = sema.to_def(&module)?;
+    let attrs = def.attrs(sema.db);
     let cfg = attrs.cfg();
     let nav = module_def.to_nav(sema.db);
     Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg })
@@ -319,7 +308,7 @@ mod tests {
 
     use crate::fixture;
 
-    use super::{RunnableAction, BENCH, BIN, DOCTEST, TEST};
+    use super::*;
 
     fn check(
         ra_fixture: &str,
@@ -363,14 +352,9 @@ fn bench() {}
                                 0,
                             ),
                             full_range: 1..13,
-                            focus_range: Some(
-                                4..8,
-                            ),
+                            focus_range: 4..8,
                             name: "main",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Bin,
                         cfg: None,
@@ -381,14 +365,9 @@ fn bench() {}
                                 0,
                             ),
                             full_range: 15..39,
-                            focus_range: Some(
-                                26..34,
-                            ),
+                            focus_range: 26..34,
                             name: "test_foo",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
@@ -406,14 +385,9 @@ fn bench() {}
                                 0,
                             ),
                             full_range: 41..75,
-                            focus_range: Some(
-                                62..70,
-                            ),
+                            focus_range: 62..70,
                             name: "test_foo",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
@@ -431,14 +405,9 @@ fn bench() {}
                                 0,
                             ),
                             full_range: 77..99,
-                            focus_range: Some(
-                                89..94,
-                            ),
+                            focus_range: 89..94,
                             name: "bench",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Bench {
                             test_id: Path(
@@ -528,14 +497,9 @@ fn should_have_no_runnable_6() {}
                                 0,
                             ),
                             full_range: 1..13,
-                            focus_range: Some(
-                                4..8,
-                            ),
+                            focus_range: 4..8,
                             name: "main",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Bin,
                         cfg: None,
@@ -546,12 +510,7 @@ fn should_have_no_runnable_6() {}
                                 0,
                             ),
                             full_range: 15..74,
-                            focus_range: None,
                             name: "should_have_runnable",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
                         },
                         kind: DocTest {
                             test_id: Path(
@@ -566,12 +525,7 @@ fn should_have_no_runnable_6() {}
                                 0,
                             ),
                             full_range: 76..148,
-                            focus_range: None,
                             name: "should_have_runnable_1",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
                         },
                         kind: DocTest {
                             test_id: Path(
@@ -586,12 +540,7 @@ fn should_have_no_runnable_6() {}
                                 0,
                             ),
                             full_range: 150..254,
-                            focus_range: None,
                             name: "should_have_runnable_2",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
                         },
                         kind: DocTest {
                             test_id: Path(
@@ -606,12 +555,7 @@ fn should_have_no_runnable_6() {}
                                 0,
                             ),
                             full_range: 756..821,
-                            focus_range: None,
                             name: "StructWithRunnable",
-                            kind: STRUCT,
-                            container_name: None,
-                            description: None,
-                            docs: None,
                         },
                         kind: DocTest {
                             test_id: Path(
@@ -650,14 +594,9 @@ fn foo() {}
                                 0,
                             ),
                             full_range: 1..13,
-                            focus_range: Some(
-                                4..8,
-                            ),
+                            focus_range: 4..8,
                             name: "main",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Bin,
                         cfg: None,
@@ -668,12 +607,7 @@ fn foo() {}
                                 0,
                             ),
                             full_range: 44..98,
-                            focus_range: None,
                             name: "foo",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
                         },
                         kind: DocTest {
                             test_id: Path(
@@ -707,14 +641,9 @@ fn test_foo1() {}
                                 0,
                             ),
                             full_range: 1..51,
-                            focus_range: Some(
-                                5..13,
-                            ),
+                            focus_range: 5..13,
                             name: "test_mod",
-                            kind: MODULE,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Module,
                         },
                         kind: TestMod {
                             path: "test_mod",
@@ -727,14 +656,9 @@ fn test_foo1() {}
                                 0,
                             ),
                             full_range: 20..49,
-                            focus_range: Some(
-                                35..44,
-                            ),
+                            focus_range: 35..44,
                             name: "test_foo1",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
@@ -787,14 +711,9 @@ mod nested_tests_4 {}
                                 0,
                             ),
                             full_range: 22..323,
-                            focus_range: Some(
-                                26..40,
-                            ),
+                            focus_range: 26..40,
                             name: "nested_tests_0",
-                            kind: MODULE,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Module,
                         },
                         kind: TestMod {
                             path: "root_tests::nested_tests_0",
@@ -807,14 +726,9 @@ mod nested_tests_4 {}
                                 0,
                             ),
                             full_range: 51..192,
-                            focus_range: Some(
-                                55..69,
-                            ),
+                            focus_range: 55..69,
                             name: "nested_tests_1",
-                            kind: MODULE,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Module,
                         },
                         kind: TestMod {
                             path: "root_tests::nested_tests_0::nested_tests_1",
@@ -827,14 +741,9 @@ mod nested_tests_4 {}
                                 0,
                             ),
                             full_range: 84..126,
-                            focus_range: Some(
-                                107..121,
-                            ),
+                            focus_range: 107..121,
                             name: "nested_test_11",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
@@ -852,14 +761,9 @@ mod nested_tests_4 {}
                                 0,
                             ),
                             full_range: 140..182,
-                            focus_range: Some(
-                                163..177,
-                            ),
+                            focus_range: 163..177,
                             name: "nested_test_12",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
@@ -877,14 +781,9 @@ mod nested_tests_4 {}
                                 0,
                             ),
                             full_range: 202..286,
-                            focus_range: Some(
-                                206..220,
-                            ),
+                            focus_range: 206..220,
                             name: "nested_tests_2",
-                            kind: MODULE,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Module,
                         },
                         kind: TestMod {
                             path: "root_tests::nested_tests_0::nested_tests_2",
@@ -897,14 +796,9 @@ mod nested_tests_4 {}
                                 0,
                             ),
                             full_range: 235..276,
-                            focus_range: Some(
-                                258..271,
-                            ),
+                            focus_range: 258..271,
                             name: "nested_test_2",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
@@ -940,14 +834,9 @@ fn test_foo1() {}
                                 0,
                             ),
                             full_range: 1..50,
-                            focus_range: Some(
-                                36..45,
-                            ),
+                            focus_range: 36..45,
                             name: "test_foo1",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
@@ -990,14 +879,9 @@ fn test_foo1() {}
                                 0,
                             ),
                             full_range: 1..72,
-                            focus_range: Some(
-                                58..67,
-                            ),
+                            focus_range: 58..67,
                             name: "test_foo1",
-                            kind: FN,
-                            container_name: None,
-                            description: None,
-                            docs: None,
+                            kind: Function,
                         },
                         kind: Test {
                             test_id: Path(
index 488969f1a15c4b1a9d3bad597daee7be974b0def..00c717c7c7e9256f833cb6ce2f4b199fa9ba4f7f 100644 (file)
@@ -23,7 +23,7 @@
     syntax_highlighting::{
         format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight,
     },
-    FileId, HighlightModifier, HighlightTag,
+    FileId, HighlightModifier, HighlightTag, SymbolKind,
 };
 
 pub(crate) use html::highlight_as_html;
@@ -103,7 +103,7 @@ pub(crate) fn highlight(
                 if let Some(range) = macro_call_range(&mc) {
                     stack.add(HighlightedRange {
                         range,
-                        highlight: HighlightTag::Macro.into(),
+                        highlight: HighlightTag::Symbol(SymbolKind::Macro).into(),
                         binding_hash: None,
                     });
                 }
@@ -470,13 +470,13 @@ fn highlight_element(
             };
 
             match name_kind {
-                Some(NameClass::ExternCrate(_)) => HighlightTag::Module.into(),
+                Some(NameClass::ExternCrate(_)) => HighlightTag::Symbol(SymbolKind::Module).into(),
                 Some(NameClass::Definition(def)) => {
                     highlight_def(db, def) | HighlightModifier::Definition
                 }
                 Some(NameClass::ConstReference(def)) => highlight_def(db, def),
                 Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
-                    let mut h = HighlightTag::Field.into();
+                    let mut h = HighlightTag::Symbol(SymbolKind::Field).into();
                     if let Definition::Field(field) = field_ref {
                         if let VariantDef::Union(_) = field.parent_def(db) {
                             h |= HighlightModifier::Unsafe;
@@ -493,14 +493,16 @@ fn highlight_element(
         NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => {
             // even though we track whether we are in an attribute or not we still need this special case
             // as otherwise we would emit unresolved references for name refs inside attributes
-            Highlight::from(HighlightTag::Function)
+            Highlight::from(HighlightTag::Symbol(SymbolKind::Function))
         }
         NAME_REF => {
             let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap();
             highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| {
                 match NameRefClass::classify(sema, &name_ref) {
                     Some(name_kind) => match name_kind {
-                        NameRefClass::ExternCrate(_) => HighlightTag::Module.into(),
+                        NameRefClass::ExternCrate(_) => {
+                            HighlightTag::Symbol(SymbolKind::Module).into()
+                        }
                         NameRefClass::Definition(def) => {
                             if let Definition::Local(local) = &def {
                                 if let Some(name) = local.name(db) {
@@ -530,7 +532,9 @@ fn highlight_element(
 
                             h
                         }
-                        NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(),
+                        NameRefClass::FieldShorthand { .. } => {
+                            HighlightTag::Symbol(SymbolKind::Field).into()
+                        }
                     },
                     None if syntactic_name_ref_highlighting => {
                         highlight_name_ref_by_syntax(name_ref, sema)
@@ -556,7 +560,7 @@ fn highlight_element(
         CHAR => HighlightTag::CharLiteral.into(),
         QUESTION => Highlight::new(HighlightTag::Operator) | HighlightModifier::ControlFlow,
         LIFETIME => {
-            let h = Highlight::new(HighlightTag::Lifetime);
+            let h = Highlight::new(HighlightTag::Symbol(SymbolKind::LifetimeParam));
             match element.parent().map(|it| it.kind()) {
                 Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition,
                 _ => h,
@@ -580,7 +584,7 @@ fn highlight_element(
                 HighlightTag::Operator.into()
             }
             T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => {
-                HighlightTag::Macro.into()
+                HighlightTag::Symbol(SymbolKind::Macro).into()
             }
             T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => {
                 HighlightTag::BuiltinType.into()
@@ -659,7 +663,7 @@ fn highlight_element(
                         .and_then(SyntaxNode::parent)
                         .and_then(ast::Path::cast)
                         .and_then(|p| sema.resolve_path(&p));
-                    let mut h = HighlightTag::SelfKeyword.into();
+                    let mut h = HighlightTag::Symbol(SymbolKind::SelfParam).into();
                     if self_param_is_mut
                         || matches!(self_path,
                             Some(hir::PathResolution::Local(local))
@@ -732,7 +736,8 @@ fn highlight_method_call(
     method_call: &ast::MethodCallExpr,
 ) -> Option<Highlight> {
     let func = sema.resolve_method_call(&method_call)?;
-    let mut h = HighlightTag::Method.into();
+    let mut h = HighlightTag::Symbol(SymbolKind::Function).into();
+    h |= HighlightModifier::Associated;
     if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) {
         h |= HighlightModifier::Unsafe;
     }
@@ -756,35 +761,45 @@ fn highlight_method_call(
 
 fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
     match def {
-        Definition::Macro(_) => HighlightTag::Macro,
-        Definition::Field(_) => HighlightTag::Field,
+        Definition::Macro(_) => HighlightTag::Symbol(SymbolKind::Macro),
+        Definition::Field(_) => HighlightTag::Symbol(SymbolKind::Field),
         Definition::ModuleDef(def) => match def {
-            hir::ModuleDef::Module(_) => HighlightTag::Module,
+            hir::ModuleDef::Module(_) => HighlightTag::Symbol(SymbolKind::Module),
             hir::ModuleDef::Function(func) => {
-                let mut h = if func.as_assoc_item(db).is_some() {
+                let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Function));
+                if func.as_assoc_item(db).is_some() {
+                    h |= HighlightModifier::Associated;
                     if func.self_param(db).is_none() {
-                        Highlight::from(HighlightTag::Method) | HighlightModifier::Static
-                    } else {
-                        HighlightTag::Method.into()
+                        h |= HighlightModifier::Static
                     }
-                } else {
-                    HighlightTag::Function.into()
-                };
+                }
                 if func.is_unsafe(db) {
                     h |= HighlightModifier::Unsafe;
                 }
                 return h;
             }
-            hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct,
-            hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum,
-            hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Union,
-            hir::ModuleDef::EnumVariant(_) => HighlightTag::EnumVariant,
-            hir::ModuleDef::Const(_) => HighlightTag::Constant,
-            hir::ModuleDef::Trait(_) => HighlightTag::Trait,
-            hir::ModuleDef::TypeAlias(_) => HighlightTag::TypeAlias,
+            hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Symbol(SymbolKind::Struct),
+            hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Symbol(SymbolKind::Enum),
+            hir::ModuleDef::Adt(hir::Adt::Union(_)) => HighlightTag::Symbol(SymbolKind::Union),
+            hir::ModuleDef::Variant(_) => HighlightTag::Symbol(SymbolKind::Variant),
+            hir::ModuleDef::Const(konst) => {
+                let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Const));
+                if konst.as_assoc_item(db).is_some() {
+                    h |= HighlightModifier::Associated
+                }
+                return h;
+            }
+            hir::ModuleDef::Trait(_) => HighlightTag::Symbol(SymbolKind::Trait),
+            hir::ModuleDef::TypeAlias(type_) => {
+                let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::TypeAlias));
+                if type_.as_assoc_item(db).is_some() {
+                    h |= HighlightModifier::Associated
+                }
+                return h;
+            }
             hir::ModuleDef::BuiltinType(_) => HighlightTag::BuiltinType,
             hir::ModuleDef::Static(s) => {
-                let mut h = Highlight::new(HighlightTag::Static);
+                let mut h = Highlight::new(HighlightTag::Symbol(SymbolKind::Static));
                 if s.is_mut(db) {
                     h |= HighlightModifier::Mutable;
                     h |= HighlightModifier::Unsafe;
@@ -792,11 +807,14 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
                 return h;
             }
         },
-        Definition::SelfType(_) => HighlightTag::SelfType,
-        Definition::TypeParam(_) => HighlightTag::TypeParam,
+        Definition::SelfType(_) => HighlightTag::Symbol(SymbolKind::Impl),
+        Definition::TypeParam(_) => HighlightTag::Symbol(SymbolKind::TypeParam),
         Definition::Local(local) => {
-            let tag =
-                if local.is_param(db) { HighlightTag::ValueParam } else { HighlightTag::Local };
+            let tag = if local.is_param(db) {
+                HighlightTag::Symbol(SymbolKind::ValueParam)
+            } else {
+                HighlightTag::Symbol(SymbolKind::Local)
+            };
             let mut h = Highlight::new(tag);
             if local.is_mut(db) || local.ty(db).is_mutable_reference() {
                 h |= HighlightModifier::Mutable;
@@ -806,7 +824,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
             }
             return h;
         }
-        Definition::LifetimeParam(_) => HighlightTag::Lifetime,
+        Definition::LifetimeParam(_) => HighlightTag::Symbol(SymbolKind::LifetimeParam),
     }
     .into()
 }
@@ -820,19 +838,19 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight {
     };
 
     let tag = match parent.kind() {
-        STRUCT => HighlightTag::Struct,
-        ENUM => HighlightTag::Enum,
-        UNION => HighlightTag::Union,
-        TRAIT => HighlightTag::Trait,
-        TYPE_ALIAS => HighlightTag::TypeAlias,
-        TYPE_PARAM => HighlightTag::TypeParam,
-        RECORD_FIELD => HighlightTag::Field,
-        MODULE => HighlightTag::Module,
-        FN => HighlightTag::Function,
-        CONST => HighlightTag::Constant,
-        STATIC => HighlightTag::Static,
-        VARIANT => HighlightTag::EnumVariant,
-        IDENT_PAT => HighlightTag::Local,
+        STRUCT => HighlightTag::Symbol(SymbolKind::Struct),
+        ENUM => HighlightTag::Symbol(SymbolKind::Enum),
+        VARIANT => HighlightTag::Symbol(SymbolKind::Variant),
+        UNION => HighlightTag::Symbol(SymbolKind::Union),
+        TRAIT => HighlightTag::Symbol(SymbolKind::Trait),
+        TYPE_ALIAS => HighlightTag::Symbol(SymbolKind::TypeAlias),
+        TYPE_PARAM => HighlightTag::Symbol(SymbolKind::TypeParam),
+        RECORD_FIELD => HighlightTag::Symbol(SymbolKind::Field),
+        MODULE => HighlightTag::Symbol(SymbolKind::Module),
+        FN => HighlightTag::Symbol(SymbolKind::Function),
+        CONST => HighlightTag::Symbol(SymbolKind::Const),
+        STATIC => HighlightTag::Symbol(SymbolKind::Static),
+        IDENT_PAT => HighlightTag::Symbol(SymbolKind::Local),
         _ => default,
     };
 
@@ -851,10 +869,10 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
         METHOD_CALL_EXPR => {
             return ast::MethodCallExpr::cast(parent)
                 .and_then(|method_call| highlight_method_call(sema, &method_call))
-                .unwrap_or_else(|| HighlightTag::Function.into());
+                .unwrap_or_else(|| HighlightTag::Symbol(SymbolKind::Function).into());
         }
         FIELD_EXPR => {
-            let h = HighlightTag::Field;
+            let h = HighlightTag::Symbol(SymbolKind::Field);
             let is_union = ast::FieldExpr::cast(parent)
                 .and_then(|field_expr| {
                     let field = sema.resolve_field(&field_expr)?;
@@ -881,9 +899,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
                 _ => {
                     // within path, decide whether it is module or adt by checking for uppercase name
                     return if name.text().chars().next().unwrap_or_default().is_uppercase() {
-                        HighlightTag::Struct
+                        HighlightTag::Symbol(SymbolKind::Struct)
                     } else {
-                        HighlightTag::Module
+                        HighlightTag::Symbol(SymbolKind::Module)
                     }
                     .into();
                 }
@@ -894,11 +912,11 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas
             };
 
             match parent.kind() {
-                CALL_EXPR => HighlightTag::Function.into(),
+                CALL_EXPR => HighlightTag::Symbol(SymbolKind::Function).into(),
                 _ => if name.text().chars().next().unwrap_or_default().is_uppercase() {
-                    HighlightTag::Struct.into()
+                    HighlightTag::Symbol(SymbolKind::Struct)
                 } else {
-                    HighlightTag::Constant
+                    HighlightTag::Symbol(SymbolKind::Const)
                 }
                 .into(),
             }
index 42f27df5d9be7cc1371ba07a24ab55e532a2a391..26416022b88a046802ff5528200bf2787ba64fc2 100644 (file)
@@ -4,7 +4,9 @@
     AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange,
 };
 
-use crate::{syntax_highlighting::HighlightedRangeStack, HighlightTag, HighlightedRange};
+use crate::{
+    syntax_highlighting::HighlightedRangeStack, HighlightTag, HighlightedRange, SymbolKind,
+};
 
 #[derive(Default)]
 pub(super) struct FormatStringHighlighter {
@@ -71,6 +73,6 @@ fn highlight_format_specifier(kind: FormatSpecifier) -> Option<HighlightTag> {
         | FormatSpecifier::Asterisk
         | FormatSpecifier::QuestionMark => HighlightTag::FormatSpecifier,
         FormatSpecifier::Integer | FormatSpecifier::Zero => HighlightTag::NumericLiteral,
-        FormatSpecifier::Identifier => HighlightTag::Local,
+        FormatSpecifier::Identifier => HighlightTag::Symbol(SymbolKind::Local),
     })
 }
index e97d1be1aa8644cc631350236ab120be64778157..9eb184c74bffa2e0ce8bf5cc255be4ca0184eb8d 100644 (file)
@@ -179,6 +179,5 @@ pub(super) fn highlight_doc_comment(
         stack.add(comment);
     }
     stack.pop_and_inject(None);
-    stack
-        .pop_and_inject(Some(Highlight::from(HighlightTag::Generic) | HighlightModifier::Injected));
+    stack.pop_and_inject(Some(Highlight::from(HighlightTag::Dummy) | HighlightModifier::Injected));
 }
index ffd9588b840e0227f10450f35d960fdcb22658b2..974f54fa01eff5009396524958cbf0a8355bee7e 100644 (file)
@@ -3,6 +3,8 @@
 
 use std::{fmt, ops};
 
+use crate::SymbolKind;
+
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct Highlight {
     pub tag: HighlightTag,
@@ -14,40 +16,25 @@ pub struct Highlight {
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub enum HighlightTag {
-    Attribute,
+    Symbol(SymbolKind),
+
     BoolLiteral,
     BuiltinType,
     ByteLiteral,
     CharLiteral,
+    NumericLiteral,
+    StringLiteral,
+    Attribute,
     Comment,
-    Constant,
-    Enum,
-    EnumVariant,
     EscapeSequence,
-    Field,
-    Function,
-    Generic,
+    FormatSpecifier,
     Keyword,
-    Lifetime,
-    Macro,
-    Method,
-    Module,
-    NumericLiteral,
     Punctuation,
-    SelfKeyword,
-    SelfType,
-    Static,
-    StringLiteral,
-    Struct,
-    Trait,
-    TypeAlias,
-    TypeParam,
-    Union,
-    ValueParam,
-    Local,
-    UnresolvedReference,
-    FormatSpecifier,
     Operator,
+    UnresolvedReference,
+
+    // For things which don't have proper Tag, but want to use modifiers.
+    Dummy,
 }
 
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
@@ -64,48 +51,53 @@ pub enum HighlightModifier {
     Injected,
     Mutable,
     Consuming,
-    Unsafe,
     Callable,
     /// Used for associated functions
     Static,
+    /// Used for items in impls&traits.
+    Associated,
+
+    /// Keep this last!
+    Unsafe,
 }
 
 impl HighlightTag {
     fn as_str(self) -> &'static str {
         match self {
+            HighlightTag::Symbol(symbol) => match symbol {
+                SymbolKind::Const => "constant",
+                SymbolKind::Static => "static",
+                SymbolKind::Enum => "enum",
+                SymbolKind::Variant => "enum_variant",
+                SymbolKind::Struct => "struct",
+                SymbolKind::Union => "union",
+                SymbolKind::Field => "field",
+                SymbolKind::Module => "module",
+                SymbolKind::Trait => "trait",
+                SymbolKind::Function => "function",
+                SymbolKind::TypeAlias => "type_alias",
+                SymbolKind::TypeParam => "type_param",
+                SymbolKind::LifetimeParam => "lifetime",
+                SymbolKind::Macro => "macro",
+                SymbolKind::Local => "variable",
+                SymbolKind::ValueParam => "value_param",
+                SymbolKind::SelfParam => "self_keyword",
+                SymbolKind::Impl => "self_type",
+            },
             HighlightTag::Attribute => "attribute",
             HighlightTag::BoolLiteral => "bool_literal",
             HighlightTag::BuiltinType => "builtin_type",
             HighlightTag::ByteLiteral => "byte_literal",
             HighlightTag::CharLiteral => "char_literal",
             HighlightTag::Comment => "comment",
-            HighlightTag::Constant => "constant",
-            HighlightTag::Enum => "enum",
-            HighlightTag::EnumVariant => "enum_variant",
             HighlightTag::EscapeSequence => "escape_sequence",
-            HighlightTag::Field => "field",
             HighlightTag::FormatSpecifier => "format_specifier",
-            HighlightTag::Function => "function",
-            HighlightTag::Generic => "generic",
+            HighlightTag::Dummy => "dummy",
             HighlightTag::Keyword => "keyword",
-            HighlightTag::Lifetime => "lifetime",
             HighlightTag::Punctuation => "punctuation",
-            HighlightTag::Macro => "macro",
-            HighlightTag::Method => "method",
-            HighlightTag::Module => "module",
             HighlightTag::NumericLiteral => "numeric_literal",
             HighlightTag::Operator => "operator",
-            HighlightTag::SelfKeyword => "self_keyword",
-            HighlightTag::SelfType => "self_type",
-            HighlightTag::Static => "static",
             HighlightTag::StringLiteral => "string_literal",
-            HighlightTag::Struct => "struct",
-            HighlightTag::Trait => "trait",
-            HighlightTag::TypeAlias => "type_alias",
-            HighlightTag::TypeParam => "type_param",
-            HighlightTag::Union => "union",
-            HighlightTag::ValueParam => "value_param",
-            HighlightTag::Local => "variable",
             HighlightTag::UnresolvedReference => "unresolved_reference",
         }
     }
@@ -118,7 +110,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 }
 
 impl HighlightModifier {
-    const ALL: &'static [HighlightModifier] = &[
+    const ALL: &'static [HighlightModifier; HighlightModifier::Unsafe as u8 as usize + 1] = &[
         HighlightModifier::Attribute,
         HighlightModifier::ControlFlow,
         HighlightModifier::Definition,
@@ -126,9 +118,10 @@ impl HighlightModifier {
         HighlightModifier::Injected,
         HighlightModifier::Mutable,
         HighlightModifier::Consuming,
-        HighlightModifier::Unsafe,
         HighlightModifier::Callable,
         HighlightModifier::Static,
+        HighlightModifier::Associated,
+        HighlightModifier::Unsafe,
     ];
 
     fn as_str(self) -> &'static str {
@@ -143,6 +136,7 @@ fn as_str(self) -> &'static str {
             HighlightModifier::Unsafe => "unsafe",
             HighlightModifier::Callable => "callable",
             HighlightModifier::Static => "static",
+            HighlightModifier::Associated => "associated",
         }
     }
 
@@ -209,6 +203,10 @@ fn bitor(mut self, rhs: HighlightModifier) -> Highlight {
 }
 
 impl HighlightModifiers {
+    pub fn contains(self, m: HighlightModifier) -> bool {
+        self.0 & m.mask() == m.mask()
+    }
+
     pub fn iter(self) -> impl Iterator<Item = HighlightModifier> {
         HighlightModifier::ALL.iter().copied().filter(move |it| self.0 & it.mask() == it.mask())
     }
index 6fb606a4729bc11160428fb77f4c76630b012ada..db6f32d3397f1ba85c9b375b5b633855a899b564 100644 (file)
@@ -40,17 +40,17 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="punctuation">{</span><span class="punctuation">}</span>
 
 <span class="keyword">impl</span> <span class="struct">foo</span> <span class="punctuation">{</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration static">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
 <span class="punctuation">}</span>
 
 <span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="punctuation">{</span>
-    <span class="keyword">fn</span> <span class="method declaration static">t_is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
-    <span class="keyword">fn</span> <span class="method declaration">t_is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
+    <span class="keyword">fn</span> <span class="function declaration static associated">t_is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">t_is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
 <span class="punctuation">}</span>
 
 <span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="punctuation">{</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration static">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
 <span class="punctuation">}</span>
         </code></pre>
\ No newline at end of file
index 920956b51f0bf85a801a6cd73c0a92176c05a841..4e511baa932c6a397ad8bddd1914af0db42311fa 100644 (file)
@@ -36,24 +36,24 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
 </style>
 <pre><code><span class="comment documentation">/// ```</span>
-<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="punctuation injected">_</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="punctuation injected">;</span><span class="punctuation injected">
+<span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="punctuation injected">_</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="punctuation injected">;</span><span class="punctuation injected">
 </span><span class="comment documentation">/// ```</span>
 <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span>
     <span class="field declaration">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span><span class="punctuation">,</span>
 <span class="punctuation">}</span>
 
 <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
-    <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="punctuation">;</span>
+    <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration associated">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="punctuation">;</span>
 
     <span class="comment documentation">/// Constructs a new `Foo`.</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">/// # Examples</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">/// ```</span>
-    <span class="comment documentation">/// #</span><span class="generic injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="punctuation attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="punctuation attribute injected">)</span><span class="attribute attribute injected">]</span>
-    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="keyword injected">mut</span><span class="generic injected"> </span><span class="variable declaration injected mutable">foo</span><span class="punctuation injected">:</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected">
+    <span class="comment documentation">/// #</span><span class="dummy injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="punctuation attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="punctuation attribute injected">)</span><span class="attribute attribute injected">]</span>
+    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="keyword injected">mut</span><span class="dummy injected"> </span><span class="variable declaration injected mutable">foo</span><span class="punctuation injected">:</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected">
 </span>    <span class="comment documentation">/// ```</span>
-    <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="method declaration static">new</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
+    <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration static associated">new</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
         <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">bar</span><span class="punctuation">:</span> <span class="bool_literal">true</span> <span class="punctuation">}</span>
     <span class="punctuation">}</span>
 
@@ -62,32 +62,32 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="comment documentation">/// # Examples</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">/// ```</span>
-    <span class="comment documentation">/// </span><span class="keyword injected">use</span><span class="generic injected"> </span><span class="module injected">x</span><span class="operator injected">::</span><span class="module injected">y</span><span class="punctuation injected">;</span>
+    <span class="comment documentation">/// </span><span class="keyword injected">use</span><span class="dummy injected"> </span><span class="module injected">x</span><span class="operator injected">::</span><span class="module injected">y</span><span class="punctuation injected">;</span>
     <span class="comment documentation">///</span>
-    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">foo</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span>
+    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">foo</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span>
-    <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="punctuation injected">(</span><span class="generic injected">foo</span><span class="operator injected">.</span><span class="generic injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span>
+    <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="punctuation injected">(</span><span class="dummy injected">foo</span><span class="operator injected">.</span><span class="dummy injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span>
     <span class="comment documentation">///</span>
-    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">bar</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="generic injected"> </span><span class="operator injected">||</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="punctuation injected">;</span>
+    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">bar</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="dummy injected"> </span><span class="operator injected">||</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="punctuation injected">;</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">/// </span><span class="comment injected">/* multi-line
     </span><span class="comment documentation">/// </span><span class="comment injected">       comment */</span>
     <span class="comment documentation">///</span>
-    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="string_literal injected">"Foo
+    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="string_literal injected">"Foo
     </span><span class="comment documentation">/// </span><span class="string_literal injected">  bar
     </span><span class="comment documentation">/// </span><span class="string_literal injected">         "</span><span class="punctuation injected">;</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">/// ```</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">/// ```rust,no_run</span>
-    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="generic injected"> </span><span class="variable declaration injected">foobar</span><span class="generic injected"> </span><span class="operator injected">=</span><span class="generic injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected">
+    <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="dummy injected"> </span><span class="variable declaration injected">foobar</span><span class="dummy injected"> </span><span class="operator injected">=</span><span class="dummy injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span><span class="punctuation injected">
 </span>    <span class="comment documentation">/// ```</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">/// ```sh</span>
     <span class="comment documentation">/// echo 1</span>
     <span class="comment documentation">/// ```</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="method declaration">foo</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="punctuation">{</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">foo</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="punctuation">{</span>
         <span class="bool_literal">true</span>
     <span class="punctuation">}</span>
 <span class="punctuation">}</span>
index 31daf2bd0b4de56313d77e147484ec87445bff7c..7f18ad297f23d392fe22f704a9983ad59f11b3dc 100644 (file)
@@ -40,7 +40,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
     <span class="function">fixture</span><span class="punctuation">(</span><span class="string_literal">r#"</span>
         <span class="keyword">trait</span> <span class="trait declaration">Foo</span> <span class="punctuation">{</span>
-            <span class="keyword">fn</span> <span class="method declaration static">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
+            <span class="keyword">fn</span> <span class="function declaration static associated">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
                 <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"2 + 2 = {}"</span><span class="punctuation">,</span> <span class="numeric_literal">4</span><span class="punctuation">)</span><span class="punctuation">;</span>
             <span class="punctuation">}</span>
         <span class="punctuation">}</span><span class="string_literal">"#</span>
index 67ec73f1592814d30fc2e043497e8bceeeff2b65..d26f485162e9f0cf6904534a6cb771134f93619f 100644 (file)
@@ -45,7 +45,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span>
 
 <span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span>
-    <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="method declaration unsafe">unsafe_method</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
+    <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration associated unsafe">unsafe_method</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
 <span class="punctuation">}</span>
 
 <span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="punctuation">{</span>
@@ -60,11 +60,11 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="punctuation">}</span>
 
 <span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="punctuation">{</span>
-    <span class="keyword">fn</span> <span class="method declaration">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span><span class="punctuation">;</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span><span class="punctuation">;</span>
 <span class="punctuation">}</span>
 
 <span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="punctuation">{</span>
-    <span class="keyword">fn</span> <span class="method declaration">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span>
 <span class="punctuation">}</span>
 
 <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span>
@@ -78,7 +78,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
             <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
             <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">a</span> <span class="punctuation">}</span> <span class="operator">=&gt;</span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
         <span class="punctuation">}</span>
-        <span class="struct">HasUnsafeFn</span><span class="operator">.</span><span class="method unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
+        <span class="struct">HasUnsafeFn</span><span class="operator">.</span><span class="function associated unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
 
         <span class="comment">// unsafe deref</span>
         <span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="variable">x</span><span class="punctuation">;</span>
@@ -94,6 +94,6 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
         <span class="keyword">let</span> <span class="struct">Packed</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="keyword unsafe">ref</span> <span class="variable declaration">_a</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="variable">packed</span><span class="punctuation">;</span>
 
         <span class="comment">// unsafe auto ref of packed field</span>
-        <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="operator">.</span><span class="method unsafe">calls_autoref</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
+        <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="operator">.</span><span class="function associated unsafe">calls_autoref</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
     <span class="punctuation">}</span>
 <span class="punctuation">}</span></code></pre>
\ No newline at end of file
index 3530a5fdb4b4c70a47ea05ab45d50dd3cab9282c..588e86a34f979a9eb478aeb885deb8209183fb0b 100644 (file)
@@ -65,25 +65,25 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="punctuation">}</span>
 
 <span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="punctuation">{</span>
-    <span class="keyword">fn</span> <span class="method declaration">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="punctuation">;</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="punctuation">;</span>
 <span class="punctuation">}</span>
 
 <span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
-    <span class="keyword">fn</span> <span class="method declaration">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
         <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span>
     <span class="punctuation">}</span>
 <span class="punctuation">}</span>
 
 <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span>
-    <span class="keyword">fn</span> <span class="method declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
-        <span class="value_param">f</span><span class="operator">.</span><span class="method consuming">baz</span><span class="punctuation">(</span><span class="self_keyword mutable consuming">self</span><span class="punctuation">)</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
+        <span class="value_param">f</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="punctuation">(</span><span class="self_keyword mutable consuming">self</span><span class="punctuation">)</span>
     <span class="punctuation">}</span>
 
-    <span class="keyword">fn</span> <span class="method declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
         <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span>
     <span class="punctuation">}</span>
 
-    <span class="keyword">fn</span> <span class="method declaration">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="punctuation">{</span>
         <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span>
     <span class="punctuation">}</span>
 <span class="punctuation">}</span>
@@ -94,15 +94,15 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="punctuation">}</span>
 
 <span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span>
-    <span class="keyword">fn</span> <span class="method declaration">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">FooCopy</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span>
-        <span class="value_param">f</span><span class="operator">.</span><span class="method">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">)</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">FooCopy</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span>
+        <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">)</span>
     <span class="punctuation">}</span>
 
-    <span class="keyword">fn</span> <span class="method declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span>
         <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span>
     <span class="punctuation">}</span>
 
-    <span class="keyword">fn</span> <span class="method declaration">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="punctuation">{</span>
         <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span>
     <span class="punctuation">}</span>
 <span class="punctuation">}</span>
@@ -178,17 +178,17 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
     <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span>
     <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span>
-    <span class="variable mutable">foo</span><span class="operator">.</span><span class="method">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
-    <span class="variable mutable">foo</span><span class="operator">.</span><span class="method mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
-    <span class="variable mutable">foo</span><span class="operator">.</span><span class="method consuming">baz</span><span class="punctuation">(</span><span class="variable consuming">foo2</span><span class="punctuation">)</span><span class="punctuation">;</span>
+    <span class="variable mutable">foo</span><span class="operator">.</span><span class="function associated">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
+    <span class="variable mutable">foo</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
+    <span class="variable mutable">foo</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="punctuation">(</span><span class="variable consuming">foo2</span><span class="punctuation">)</span><span class="punctuation">;</span>
 
     <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> <span class="field">x</span> <span class="punctuation">}</span><span class="punctuation">;</span>
-    <span class="variable mutable">copy</span><span class="operator">.</span><span class="method">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
-    <span class="variable mutable">copy</span><span class="operator">.</span><span class="method mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
-    <span class="variable mutable">copy</span><span class="operator">.</span><span class="method">baz</span><span class="punctuation">(</span><span class="variable mutable">copy</span><span class="punctuation">)</span><span class="punctuation">;</span>
+    <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
+    <span class="variable mutable">copy</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span>
+    <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">baz</span><span class="punctuation">(</span><span class="variable mutable">copy</span><span class="punctuation">)</span><span class="punctuation">;</span>
 
     <span class="keyword">let</span> <span class="variable declaration callable">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="punctuation">;</span>
-    <span class="keyword">let</span> <span class="variable declaration callable">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="method">baz</span><span class="punctuation">;</span>
+    <span class="keyword">let</span> <span class="variable declaration callable">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="function associated">baz</span><span class="punctuation">;</span>
 
     <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="punctuation">;</span>
     <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="punctuation">;</span>
@@ -203,7 +203,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="punctuation">;</span>
 
 <span class="keyword">impl</span><span class="punctuation">&lt;</span><span class="type_param declaration">T</span><span class="punctuation">&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">T</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
-    <span class="keyword">fn</span> <span class="method declaration">and</span><span class="punctuation">&lt;</span><span class="type_param declaration">U</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">U</span><span class="punctuation">&gt;</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
+    <span class="keyword">fn</span> <span class="function declaration associated">and</span><span class="punctuation">&lt;</span><span class="type_param declaration">U</span><span class="punctuation">&gt;</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="type_param">U</span><span class="punctuation">&gt;</span><span class="punctuation">)</span> <span class="operator">-&gt;</span> <span class="enum">Option</span><span class="punctuation">&lt;</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">&gt;</span> <span class="punctuation">{</span>
         <span class="keyword control">match</span> <span class="value_param">other</span> <span class="punctuation">{</span>
             <span class="enum_variant">None</span> <span class="operator">=&gt;</span> <span class="macro">unimplemented!</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span>
             <span class="variable declaration">Nope</span> <span class="operator">=&gt;</span> <span class="variable">Nope</span><span class="punctuation">,</span>
index bd2afc887602df6f73820307487d627479618f66..9d7dce1d47dbccd8feb5ac2c87064f951f60f931 100644 (file)
@@ -66,7 +66,7 @@ pub fn name(&self, db: &RootDatabase) -> Option<Name> {
                     hir::Adt::Union(it) => it.name(db),
                     hir::Adt::Enum(it) => it.name(db),
                 },
-                hir::ModuleDef::EnumVariant(it) => it.name(db),
+                hir::ModuleDef::Variant(it) => it.name(db),
                 hir::ModuleDef::Const(it) => it.name(db)?,
                 hir::ModuleDef::Static(it) => it.name(db)?,
                 hir::ModuleDef::Trait(it) => it.name(db),
@@ -207,7 +207,7 @@ pub fn classify(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<Name
                     Some(NameClass::Definition(Definition::ModuleDef(def.into())))
                 },
                 ast::Variant(it) => {
-                    let def: hir::EnumVariant = sema.to_def(&it)?;
+                    let def: hir::Variant = sema.to_def(&it)?;
                     Some(NameClass::Definition(Definition::ModuleDef(def.into())))
                 },
                 ast::Fn(it) => {
index 9be36d59bdc34f2fa49354c1653405f8a7c4b2bf..d6b498be36dbd9205554dcc1c6d3ede3a84e1651 100644 (file)
@@ -9,7 +9,7 @@
     ast::{
         self,
         edit::{AstNodeEdit, IndentLevel},
-        make, AstNode, PathSegmentKind, VisibilityOwner,
+        make, AstNode, AttrsOwner, PathSegmentKind, VisibilityOwner,
     },
     AstToken, InsertPosition, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxToken,
 };
@@ -180,6 +180,15 @@ fn eq_visibility(vis0: Option<ast::Visibility>, vis1: Option<ast::Visibility>) -
     }
 }
 
+fn eq_attrs(
+    attrs0: impl Iterator<Item = ast::Attr>,
+    attrs1: impl Iterator<Item = ast::Attr>,
+) -> bool {
+    let attrs0 = attrs0.map(|attr| attr.to_string());
+    let attrs1 = attrs1.map(|attr| attr.to_string());
+    attrs0.eq(attrs1)
+}
+
 pub fn try_merge_imports(
     lhs: &ast::Use,
     rhs: &ast::Use,
@@ -189,6 +198,10 @@ pub fn try_merge_imports(
     if !eq_visibility(lhs.visibility(), rhs.visibility()) {
         return None;
     }
+    if !eq_attrs(lhs.attrs(), rhs.attrs()) {
+        return None;
+    }
+
     let lhs_tree = lhs.use_tree()?;
     let rhs_tree = rhs.use_tree()?;
     let merged = try_merge_trees(&lhs_tree, &rhs_tree, merge_behavior)?;
index 9e194354e24a0d0f0deca5c58e87a54c2601cd61..a603fe87f2c692331b0ae43a0a36d02821a61416 100644 (file)
@@ -447,6 +447,20 @@ fn merge_groups_skip_pub_crate() {
     )
 }
 
+#[test]
+fn merge_groups_skip_attributed() {
+    check_full(
+        "std::io",
+        r#"
+#[cfg(feature = "gated")] use std::fmt::{Result, Display};
+"#,
+        r#"
+#[cfg(feature = "gated")] use std::fmt::{Result, Display};
+use std::io;
+"#,
+    )
+}
+
 #[test]
 #[ignore] // FIXME: Support this
 fn split_out_merge() {
index 525c8a41fed4110cc8bdbade1cc7817d1c4855ee..ff10f71c358aa9ef5948ce94acfe79d8900a9aec 100644 (file)
@@ -141,7 +141,7 @@ fn search_scope(&self, db: &RootDatabase) -> SearchScope {
                 hir::GenericDef::Trait(it) => it.source(db).value.syntax().text_range(),
                 hir::GenericDef::TypeAlias(it) => it.source(db).value.syntax().text_range(),
                 hir::GenericDef::Impl(it) => it.source(db).value.syntax().text_range(),
-                hir::GenericDef::EnumVariant(it) => it.source(db).value.syntax().text_range(),
+                hir::GenericDef::Variant(it) => it.source(db).value.syntax().text_range(),
                 hir::GenericDef::Const(it) => it.source(db).value.syntax().text_range(),
             };
             let mut res = FxHashMap::default();
index ca455fa03e32b850f7000c9fdcb81807d40f6340..0aa6a076517e6cfbfb7502398317615d879f90a9 100644 (file)
@@ -39,7 +39,7 @@
 use syntax::{
     ast::{self, NameOwner},
     match_ast, AstNode, Parse, SmolStr, SourceFile,
-    SyntaxKind::{self, *},
+    SyntaxKind::*,
     SyntaxNode, SyntaxNodePtr, TextRange, WalkEvent,
 };
 
@@ -323,7 +323,7 @@ pub(crate) fn search(self, indices: &[&SymbolIndex]) -> Vec<FileSymbol> {
                 let (start, end) = SymbolIndex::map_value_to_range(indexed_value.value);
 
                 for symbol in &symbol_index.symbols[start..end] {
-                    if self.only_types && !is_type(symbol.kind) {
+                    if self.only_types && !symbol.kind.is_type() {
                         continue;
                     }
                     if self.exact && symbol.name != self.query {
@@ -341,23 +341,44 @@ pub(crate) fn search(self, indices: &[&SymbolIndex]) -> Vec<FileSymbol> {
     }
 }
 
-fn is_type(kind: SyntaxKind) -> bool {
-    matches!(kind, STRUCT | ENUM | TRAIT | TYPE_ALIAS)
-}
-
 /// The actual data that is stored in the index. It should be as compact as
 /// possible.
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct FileSymbol {
     pub file_id: FileId,
     pub name: SmolStr,
-    pub kind: SyntaxKind,
+    pub kind: FileSymbolKind,
     pub range: TextRange,
     pub ptr: SyntaxNodePtr,
     pub name_range: Option<TextRange>,
     pub container_name: Option<SmolStr>,
 }
 
+#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)]
+pub enum FileSymbolKind {
+    Function,
+    Struct,
+    Enum,
+    Trait,
+    Module,
+    TypeAlias,
+    Const,
+    Static,
+    Macro,
+}
+
+impl FileSymbolKind {
+    fn is_type(self: FileSymbolKind) -> bool {
+        matches!(
+            self,
+            FileSymbolKind::Struct
+                | FileSymbolKind::Enum
+                | FileSymbolKind::Trait
+                | FileSymbolKind::TypeAlias
+        )
+    }
+}
+
 fn source_file_to_file_symbols(source_file: &SourceFile, file_id: FileId) -> Vec<FileSymbol> {
     let mut symbols = Vec::new();
     let mut stack = Vec::new();
@@ -412,7 +433,18 @@ fn decl<N: NameOwner>(node: N) -> Option<(SmolStr, SyntaxNodePtr, TextRange)> {
 fn to_file_symbol(node: &SyntaxNode, file_id: FileId) -> Option<FileSymbol> {
     to_symbol(node).map(move |(name, ptr, name_range)| FileSymbol {
         name,
-        kind: node.kind(),
+        kind: match node.kind() {
+            FN => FileSymbolKind::Function,
+            STRUCT => FileSymbolKind::Struct,
+            ENUM => FileSymbolKind::Enum,
+            TRAIT => FileSymbolKind::Trait,
+            MODULE => FileSymbolKind::Module,
+            TYPE_ALIAS => FileSymbolKind::TypeAlias,
+            CONST => FileSymbolKind::Const,
+            STATIC => FileSymbolKind::Static,
+            MACRO_RULES => FileSymbolKind::Macro,
+            kind => unreachable!("{:?}", kind),
+        },
         range: node.text_range(),
         ptr,
         file_id,
index 616119ba9c8b879874fa8871f05283f8cabe33c8..57592dc92935b8bd6113dd07dccc18bf11ca2164 100644 (file)
@@ -97,7 +97,7 @@ fn expand_subtree(
                 err = err.or(e);
                 arena.push(tt.into());
             }
-            Op::Var { name, kind: _ } => {
+            Op::Var { name, .. } => {
                 let ExpandResult { value: fragment, err: e } = expand_var(ctx, name);
                 err = err.or(e);
                 push_fragment(arena, fragment);
index 6b46a1673c38e17e012f26478e42143c4f37483d..c3fdd40404894e5009e4fd33c70fb39a41060482 100644 (file)
@@ -101,7 +101,9 @@ fn next_op<'a>(
                     Op::Repeat { subtree, separator, kind }
                 }
                 tt::TokenTree::Leaf(leaf) => match leaf {
-                    tt::Leaf::Punct(..) => return Err(ExpandError::UnexpectedToken),
+                    tt::Leaf::Punct(_) => {
+                        return Err(ExpandError::UnexpectedToken);
+                    }
                     tt::Leaf::Ident(ident) => {
                         let name = &ident.text;
                         let kind = eat_fragment_kind(src, mode)?;
index 265c0d63d85c6dbd67b13fc240c4142f94567468..2bec7fd495b27673363c558d85bc3ffe06e6cca9 100644 (file)
@@ -313,7 +313,7 @@ fn collect_leaf(&mut self, result: &mut Vec<tt::TokenTree>) {
             return;
         }
 
-        result.push(if k.is_punct() {
+        result.push(if k.is_punct() && k != UNDERSCORE {
             assert_eq!(range.len(), TextSize::of('.'));
             let delim = match k {
                 T!['('] => Some((tt::DelimiterKind::Parenthesis, T![')'])),
@@ -378,6 +378,7 @@ macro_rules! make_leaf {
             let leaf: tt::Leaf = match k {
                 T![true] | T![false] => make_leaf!(Ident),
                 IDENT => make_leaf!(Ident),
+                UNDERSCORE => make_leaf!(Ident),
                 k if k.is_keyword() => make_leaf!(Ident),
                 k if k.is_literal() => make_leaf!(Literal),
                 LIFETIME_IDENT => {
index dff6e98c2da33de06cdde5243e746cf0dcc5c57b..f10e7a9b69ec35b5711aa2846f69f3ba4fed37e0 100644 (file)
@@ -991,6 +991,18 @@ macro_rules! foo {
     );
 }
 
+#[test]
+fn test_underscore() {
+    parse_macro(
+        r#"
+            macro_rules! foo {
+                 ($_:tt) => { 0 }
+            }
+    "#,
+    )
+    .assert_expand_items(r#"foo! { => }"#, r#"0"#);
+}
+
 #[test]
 fn test_lifetime() {
     parse_macro(
index 23039eba4958457dc55e29606aa1534ffca433e4..1a078f6b4cf4bc42525f47065830cfa6ede4f2fc 100644 (file)
@@ -133,6 +133,10 @@ pub(crate) fn macro_stmts(p: &mut Parser) {
 
         m.complete(p, MACRO_STMTS);
     }
+
+    pub(crate) fn attr(p: &mut Parser) {
+        attributes::outer_attrs(p)
+    }
 }
 
 pub(crate) fn reparser(
index 41e62116f88c4999da37ed5a5f214b8d711f1ee7..ab8e4c70e80955fbac22a026ff8d1564c126ef99 100644 (file)
@@ -99,6 +99,8 @@ pub enum FragmentKind {
     // FIXME: use separate fragment kinds for macro inputs and outputs?
     Items,
     Statements,
+
+    Attr,
 }
 
 pub fn parse_fragment(
@@ -118,6 +120,7 @@ pub fn parse_fragment(
         FragmentKind::Statement => grammar::fragments::stmt,
         FragmentKind::Items => grammar::fragments::macro_items,
         FragmentKind::Statements => grammar::fragments::macro_stmts,
+        FragmentKind::Attr => grammar::fragments::attr,
     };
     parse_from_tokens(token_source, tree_sink, parser)
 }
index 894c5c952aae0eeb0c786dfefbdf772bd088abe6..bb3b6f2efbbf76ce5e4e247961029101bedc69a2 100644 (file)
@@ -16,6 +16,7 @@
 use rustc_hash::FxHashMap;
 
 use crate::cfg_flag::CfgFlag;
+use crate::utf8_stdout;
 
 /// `CargoWorkspace` represents the logical structure of, well, a Cargo
 /// workspace. It pretty closely mirrors `cargo metadata` output.
@@ -166,8 +167,34 @@ pub fn from_cargo_metadata(
         if let Some(parent) = cargo_toml.parent() {
             meta.current_dir(parent.to_path_buf());
         }
-        if let Some(target) = config.target.as_ref() {
-            meta.other_options(vec![String::from("--filter-platform"), target.clone()]);
+        let target = if let Some(target) = config.target.as_ref() {
+            Some(target.clone())
+        } else {
+            // cargo metadata defaults to giving information for _all_ targets.
+            // In the absence of a preference from the user, we use the host platform.
+            let mut rustc = Command::new(toolchain::rustc());
+            rustc.current_dir(cargo_toml.parent().unwrap()).arg("-vV");
+            log::debug!("Discovering host platform by {:?}", rustc);
+            match utf8_stdout(rustc) {
+                Ok(stdout) => {
+                    let field = "host: ";
+                    let target = stdout.lines().find_map(|l| l.strip_prefix(field));
+                    if let Some(target) = target {
+                        Some(target.to_string())
+                    } else {
+                        // If we fail to resolve the host platform, it's not the end of the world.
+                        log::info!("rustc -vV did not report host platform, got:\n{}", stdout);
+                        None
+                    }
+                }
+                Err(e) => {
+                    log::warn!("Failed to discover host platform: {}", e);
+                    None
+                }
+            }
+        };
+        if let Some(target) = target {
+            meta.other_options(vec![String::from("--filter-platform"), target]);
         }
         let mut meta = meta.exec().with_context(|| {
             format!("Failed to run `cargo metadata --manifest-path {}`", cargo_toml.display())
index 039976e4baa98abadf3bd2dbe94cf45356d36193..0b4d3f4ebbe70f60834d1f8d8fb55f698beb82ab 100644 (file)
@@ -21,7 +21,7 @@ env_logger = { version = "0.8.1", default-features = false }
 itertools = "0.9.0"
 jod-thread = "0.1.0"
 log = "0.4.8"
-lsp-types = { version = "0.85.0", features = ["proposed"] }
+lsp-types = { version = "0.86.0", features = ["proposed"] }
 parking_lot = "0.11.0"
 pico-args = "0.3.1"
 oorandom = "11.1.2"
index 5e4c22bc5c88c1e7e28303b293655c54a8f67bd7..de5eb93b50683a9cda82988db35f6e143b90abb0 100644 (file)
@@ -64,7 +64,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
             prepare_provider: Some(true),
             work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
         })),
-        on_type_rename_provider: None,
+        linked_editing_range_provider: None,
         document_link_provider: None,
         color_provider: None,
         execute_command_provider: None,
@@ -83,6 +83,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
             }
             .into(),
         ),
+        moniker_provider: None,
         experimental: Some(json!({
             "joinLines": true,
             "ssr": true,
index af226c10900ec0ad66994441a9e34a0b8794d05c..66f8bee991579feea8218dca29cc620d8a67e44b 100644 (file)
@@ -9,7 +9,7 @@
 
 use ide::{
     CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData,
-    NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit,
+    NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, SymbolKind, TextEdit,
 };
 use itertools::Itertools;
 use lsp_server::ErrorCode;
@@ -27,7 +27,7 @@
 use serde::{Deserialize, Serialize};
 use serde_json::to_value;
 use stdx::{format_to, split_once};
-use syntax::{algo, ast, AstNode, SyntaxKind, TextRange, TextSize};
+use syntax::{algo, ast, AstNode, TextRange, TextSize};
 
 use crate::{
     cargo_target_spec::CargoTargetSpec,
@@ -385,7 +385,10 @@ fn exec_query(snap: &GlobalStateSnapshot, query: Query) -> Result<Vec<SymbolInfo
             #[allow(deprecated)]
             let info = SymbolInformation {
                 name: nav.name.to_string(),
-                kind: to_proto::symbol_kind(nav.kind),
+                kind: nav
+                    .kind
+                    .map(to_proto::symbol_kind)
+                    .unwrap_or(lsp_types::SymbolKind::Variable),
                 tags: None,
                 location: to_proto::location_from_nav(snap, nav)?,
                 container_name,
@@ -1037,10 +1040,10 @@ pub(crate) fn handle_code_lens(
                 .filter(|it| {
                     matches!(
                         it.kind,
-                        SyntaxKind::TRAIT
-                            | SyntaxKind::STRUCT
-                            | SyntaxKind::ENUM
-                            | SyntaxKind::UNION
+                        SymbolKind::Trait
+                            | SymbolKind::Struct
+                            | SymbolKind::Enum
+                            | SymbolKind::Union
                     )
                 })
                 .map(|it| {
@@ -1263,7 +1266,7 @@ pub(crate) fn handle_call_hierarchy_prepare(
     let RangeInfo { range: _, info: navs } = nav_info;
     let res = navs
         .into_iter()
-        .filter(|it| it.kind == SyntaxKind::FN)
+        .filter(|it| it.kind == Some(SymbolKind::Function))
         .map(|it| to_proto::call_hierarchy_item(&snap, it))
         .collect::<Result<Vec<_>>>()?;
 
index 715f8927a5edd5eaddba80d50b9cc219f72a600e..e0561b5a7a8a63645c0e9626dd3b5131a84fd3c1 100644 (file)
@@ -5,14 +5,13 @@
 };
 
 use ide::{
-    Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation,
-    FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange,
-    Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget,
-    ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit,
+    Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, FileId,
+    FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag,
+    HighlightedRange, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup,
+    NavigationTarget, ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange,
+    SourceFileEdit, SymbolKind, TextEdit, TextRange, TextSize,
 };
-use ide_db::base_db::{FileId, FileRange};
 use itertools::Itertools;
-use syntax::{SyntaxKind, TextRange, TextSize};
 
 use crate::{
     cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot,
@@ -30,21 +29,25 @@ pub(crate) fn range(line_index: &LineIndex, range: TextRange) -> lsp_types::Rang
     lsp_types::Range::new(start, end)
 }
 
-pub(crate) fn symbol_kind(syntax_kind: SyntaxKind) -> lsp_types::SymbolKind {
-    match syntax_kind {
-        SyntaxKind::FN => lsp_types::SymbolKind::Function,
-        SyntaxKind::STRUCT => lsp_types::SymbolKind::Struct,
-        SyntaxKind::ENUM => lsp_types::SymbolKind::Enum,
-        SyntaxKind::VARIANT => lsp_types::SymbolKind::EnumMember,
-        SyntaxKind::TRAIT => lsp_types::SymbolKind::Interface,
-        SyntaxKind::MACRO_CALL => lsp_types::SymbolKind::Function,
-        SyntaxKind::MODULE => lsp_types::SymbolKind::Module,
-        SyntaxKind::TYPE_ALIAS => lsp_types::SymbolKind::TypeParameter,
-        SyntaxKind::RECORD_FIELD => lsp_types::SymbolKind::Field,
-        SyntaxKind::STATIC => lsp_types::SymbolKind::Constant,
-        SyntaxKind::CONST => lsp_types::SymbolKind::Constant,
-        SyntaxKind::IMPL => lsp_types::SymbolKind::Object,
-        _ => lsp_types::SymbolKind::Variable,
+pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind {
+    match symbol_kind {
+        SymbolKind::Function => lsp_types::SymbolKind::Function,
+        SymbolKind::Struct => lsp_types::SymbolKind::Struct,
+        SymbolKind::Enum => lsp_types::SymbolKind::Enum,
+        SymbolKind::Variant => lsp_types::SymbolKind::EnumMember,
+        SymbolKind::Trait => lsp_types::SymbolKind::Interface,
+        SymbolKind::Macro => lsp_types::SymbolKind::Function,
+        SymbolKind::Module => lsp_types::SymbolKind::Module,
+        SymbolKind::TypeAlias | SymbolKind::TypeParam => lsp_types::SymbolKind::TypeParameter,
+        SymbolKind::Field => lsp_types::SymbolKind::Field,
+        SymbolKind::Static => lsp_types::SymbolKind::Constant,
+        SymbolKind::Const => lsp_types::SymbolKind::Constant,
+        SymbolKind::Impl => lsp_types::SymbolKind::Object,
+        SymbolKind::Local
+        | SymbolKind::SelfParam
+        | SymbolKind::LifetimeParam
+        | SymbolKind::ValueParam => lsp_types::SymbolKind::Variable,
+        SymbolKind::Union => lsp_types::SymbolKind::Struct,
     }
 }
 
@@ -369,34 +372,41 @@ fn semantic_token_type_and_modifiers(
 ) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) {
     let mut mods = semantic_tokens::ModifierSet::default();
     let type_ = match highlight.tag {
-        HighlightTag::Struct => lsp_types::SemanticTokenType::STRUCT,
-        HighlightTag::Enum => lsp_types::SemanticTokenType::ENUM,
-        HighlightTag::Union => semantic_tokens::UNION,
-        HighlightTag::TypeAlias => semantic_tokens::TYPE_ALIAS,
-        HighlightTag::Trait => lsp_types::SemanticTokenType::INTERFACE,
+        HighlightTag::Symbol(symbol) => match symbol {
+            SymbolKind::Module => lsp_types::SemanticTokenType::NAMESPACE,
+            SymbolKind::Impl => lsp_types::SemanticTokenType::TYPE,
+            SymbolKind::Field => lsp_types::SemanticTokenType::PROPERTY,
+            SymbolKind::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER,
+            SymbolKind::LifetimeParam => semantic_tokens::LIFETIME,
+            SymbolKind::ValueParam => lsp_types::SemanticTokenType::PARAMETER,
+            SymbolKind::SelfParam => semantic_tokens::SELF_KEYWORD,
+            SymbolKind::Local => lsp_types::SemanticTokenType::VARIABLE,
+            SymbolKind::Function => {
+                if highlight.modifiers.contains(HighlightModifier::Associated) {
+                    lsp_types::SemanticTokenType::METHOD
+                } else {
+                    lsp_types::SemanticTokenType::FUNCTION
+                }
+            }
+            SymbolKind::Const => {
+                mods |= semantic_tokens::CONSTANT;
+                mods |= lsp_types::SemanticTokenModifier::STATIC;
+                lsp_types::SemanticTokenType::VARIABLE
+            }
+            SymbolKind::Static => {
+                mods |= lsp_types::SemanticTokenModifier::STATIC;
+                lsp_types::SemanticTokenType::VARIABLE
+            }
+            SymbolKind::Struct => lsp_types::SemanticTokenType::STRUCT,
+            SymbolKind::Enum => lsp_types::SemanticTokenType::ENUM,
+            SymbolKind::Variant => lsp_types::SemanticTokenType::ENUM_MEMBER,
+            SymbolKind::Union => semantic_tokens::UNION,
+            SymbolKind::TypeAlias => semantic_tokens::TYPE_ALIAS,
+            SymbolKind::Trait => lsp_types::SemanticTokenType::INTERFACE,
+            SymbolKind::Macro => lsp_types::SemanticTokenType::MACRO,
+        },
         HighlightTag::BuiltinType => semantic_tokens::BUILTIN_TYPE,
-        HighlightTag::SelfKeyword => semantic_tokens::SELF_KEYWORD,
-        HighlightTag::SelfType => lsp_types::SemanticTokenType::TYPE,
-        HighlightTag::Field => lsp_types::SemanticTokenType::PROPERTY,
-        HighlightTag::Function => lsp_types::SemanticTokenType::FUNCTION,
-        HighlightTag::Generic => semantic_tokens::GENERIC,
-        HighlightTag::Module => lsp_types::SemanticTokenType::NAMESPACE,
-        HighlightTag::Method => lsp_types::SemanticTokenType::METHOD,
-        HighlightTag::Constant => {
-            mods |= semantic_tokens::CONSTANT;
-            mods |= lsp_types::SemanticTokenModifier::STATIC;
-            lsp_types::SemanticTokenType::VARIABLE
-        }
-        HighlightTag::Static => {
-            mods |= lsp_types::SemanticTokenModifier::STATIC;
-            lsp_types::SemanticTokenType::VARIABLE
-        }
-        HighlightTag::EnumVariant => lsp_types::SemanticTokenType::ENUM_MEMBER,
-        HighlightTag::Macro => lsp_types::SemanticTokenType::MACRO,
-        HighlightTag::ValueParam => lsp_types::SemanticTokenType::PARAMETER,
-        HighlightTag::Local => lsp_types::SemanticTokenType::VARIABLE,
-        HighlightTag::TypeParam => lsp_types::SemanticTokenType::TYPE_PARAMETER,
-        HighlightTag::Lifetime => semantic_tokens::LIFETIME,
+        HighlightTag::Dummy => semantic_tokens::GENERIC,
         HighlightTag::ByteLiteral | HighlightTag::NumericLiteral => {
             lsp_types::SemanticTokenType::NUMBER
         }
@@ -426,6 +436,7 @@ fn semantic_token_type_and_modifiers(
             HighlightModifier::Unsafe => semantic_tokens::UNSAFE,
             HighlightModifier::Callable => semantic_tokens::CALLABLE,
             HighlightModifier::Static => lsp_types::SemanticTokenModifier::STATIC,
+            HighlightModifier::Associated => continue,
         };
         mods |= modifier;
     }
@@ -633,7 +644,7 @@ pub(crate) fn resource_op(
             lsp_types::ResourceOp::Create(lsp_types::CreateFile {
                 uri,
                 options: None,
-                annotation: None,
+                annotation_id: None,
             })
         }
         FileSystemEdit::MoveFile { src, dst } => {
@@ -643,7 +654,7 @@ pub(crate) fn resource_op(
                 old_uri,
                 new_uri,
                 options: None,
-                annotation: None,
+                annotation_id: None,
             })
         }
     }
@@ -708,6 +719,7 @@ fn from(snippet_workspace_edit: lsp_ext::SnippetWorkspaceEdit) -> lsp_types::Wor
                         .collect(),
                 )
             }),
+            change_annotations: None,
         }
     }
 }
@@ -718,7 +730,7 @@ pub(crate) fn call_hierarchy_item(
 ) -> Result<lsp_types::CallHierarchyItem> {
     let name = target.name.to_string();
     let detail = target.description.clone();
-    let kind = symbol_kind(target.kind);
+    let kind = target.kind.map(symbol_kind).unwrap_or(lsp_types::SymbolKind::Function);
     let (uri, range, selection_range) = location_info(snap, target)?;
     Ok(lsp_types::CallHierarchyItem {
         name,
index 16b079c42acf04a71d82a2c6fc02fbe6f6605c07..ba7e5d2fb10524751803cf9174c0543b2ed9ece5 100644 (file)
@@ -20,6 +20,9 @@ pub fn name_ref(text: &str) -> ast::NameRef {
 pub fn ty(text: &str) -> ast::Type {
     ast_from_text(&format!("impl {} for D {{}};", text))
 }
+pub fn ty_unit() -> ast::Type {
+    ty("()")
+}
 
 pub fn assoc_item_list() -> ast::AssocItemList {
     ast_from_text("impl C for D {};")
index e753b11bb84586365d198e1fe1b30ca0985f50ad..4d272f367ad39ba4ac36f93b3fd5a98fc7322fa3 100644 (file)
@@ -205,6 +205,13 @@ pub fn parse(text: &str) -> Result<Self, ()> {
     }
 }
 
+impl ast::Attr {
+    /// Returns `text`, parsed as an attribute, but only if it has no errors.
+    pub fn parse(text: &str) -> Result<Self, ()> {
+        parsing::parse_text_fragment(text, parser::FragmentKind::Attr)
+    }
+}
+
 /// Matches a `SyntaxNode` against an `ast` type.
 ///
 /// # Example:
index e83b116a73738004c762f07cbe70e9e1e752a0c5..2d717e3667abe2eb8c09d0582771689290e79c49 100644 (file)
             }
         },
         "@types/vscode": {
-            "version": "1.51.0",
-            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.51.0.tgz",
-            "integrity": "sha512-C/jZ35OT5k/rsJyAK8mS1kM++vMcm89oSWegkzxRCvHllIq0cToZAkIDs6eCY4SKrvik3nrhELizyLcM0onbQA==",
+            "version": "1.52.0",
+            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.52.0.tgz",
+            "integrity": "sha512-Kt3bvWzAvvF/WH9YEcrCICDp0Z7aHhJGhLJ1BxeyNP6yRjonWqWnAIh35/pXAjswAnWOABrYlF7SwXR9+1nnLA==",
             "dev": true
         },
         "@typescript-eslint/eslint-plugin": {
         "balanced-match": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-            "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-            "dev": true
+            "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
         },
         "binary-extensions": {
             "version": "2.1.0",
             "version": "1.1.11",
             "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
             "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-            "dev": true,
             "requires": {
                 "balanced-match": "^1.0.0",
                 "concat-map": "0.0.1"
         "concat-map": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-            "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-            "dev": true
+            "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
         },
         "cross-spawn": {
             "version": "7.0.3",
             "version": "3.0.4",
             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
             "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-            "dev": true,
             "requires": {
                 "brace-expansion": "^1.1.7"
             }
             "dev": true
         },
         "semver": {
-            "version": "6.3.0",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
-            "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
+            "version": "7.3.4",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+            "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+            "requires": {
+                "lru-cache": "^6.0.0"
+            },
+            "dependencies": {
+                "lru-cache": {
+                    "version": "6.0.0",
+                    "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+                    "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+                    "requires": {
+                        "yallist": "^4.0.0"
+                    }
+                },
+                "yallist": {
+                    "version": "4.0.0",
+                    "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+                    "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+                }
+            }
         },
         "serialize-javascript": {
             "version": "5.0.1",
             }
         },
         "vscode-jsonrpc": {
-            "version": "6.0.0-next.7",
-            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0-next.7.tgz",
-            "integrity": "sha512-1nG+6cuTtpzmXe7yYfO9GCkYlyV6Ai+jDnwidHiT2T7zhc+bJM+VTtc0T/CdTlDyTNTqIcCj0V1nD4TcVjJ7Ug=="
+            "version": "6.0.0",
+            "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz",
+            "integrity": "sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg=="
         },
         "vscode-languageclient": {
-            "version": "7.0.0-next.14",
-            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0-next.14.tgz",
-            "integrity": "sha512-QUccfXK2F6AXXRFR8QJCaIz7N2BhJK6ok8E1aO8LHq2IBU33+5hTSJBXs7nEqrqZ/cY2VlDDbMWtMvCxz+/y1w==",
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz",
+            "integrity": "sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==",
             "requires": {
-                "semver": "^6.3.0",
-                "vscode-languageserver-protocol": "3.16.0-next.11"
+                "minimatch": "^3.0.4",
+                "semver": "^7.3.4",
+                "vscode-languageserver-protocol": "3.16.0"
             }
         },
         "vscode-languageserver-protocol": {
-            "version": "3.16.0-next.11",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0-next.11.tgz",
-            "integrity": "sha512-31FmupmSmfznuMuGp7qN6h3d/hKUbexbvcwTvrUE/igqRlzFU542s8MtGICx1ERbVuDOLGp96W2Z92qbUbmBPA==",
+            "version": "3.16.0",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz",
+            "integrity": "sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==",
             "requires": {
-                "vscode-jsonrpc": "6.0.0-next.7",
-                "vscode-languageserver-types": "3.16.0-next.5"
+                "vscode-jsonrpc": "6.0.0",
+                "vscode-languageserver-types": "3.16.0"
             }
         },
         "vscode-languageserver-types": {
-            "version": "3.16.0-next.5",
-            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0-next.5.tgz",
-            "integrity": "sha512-lf8Y1XXMtF1r2oDDAmJe+drizNXkybSRXAQQk5dPy2rYJsY9SPXYNO074L3THu9zNYepzV5fRJZUPo/V/TLBRQ=="
+            "version": "3.16.0",
+            "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz",
+            "integrity": "sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA=="
         },
         "vscode-test": {
             "version": "1.4.1",
index 160a62e4678cc05d135fe528c3304739680474e0..ad01fea7b6ca16d0489b7d079d9f0dd9c479ce6c 100644 (file)
@@ -21,7 +21,7 @@
         "Programming Languages"
     ],
     "engines": {
-        "vscode": "^1.51.0"
+        "vscode": "^1.52.0"
     },
     "enableProposedApi": true,
     "scripts": {
@@ -36,7 +36,7 @@
     },
     "dependencies": {
         "node-fetch": "^2.6.1",
-        "vscode-languageclient": "7.0.0-next.14"
+        "vscode-languageclient": "7.0.0"
     },
     "devDependencies": {
         "@rollup/plugin-commonjs": "^17.0.0",
@@ -45,7 +45,7 @@
         "@types/mocha": "^8.0.4",
         "@types/node": "~12.12.6",
         "@types/node-fetch": "^2.5.7",
-        "@types/vscode": "^1.51.0",
+        "@types/vscode": "^1.52.0",
         "@typescript-eslint/eslint-plugin": "^4.9.0",
         "@typescript-eslint/parser": "^4.9.0",
         "eslint": "^7.15.0",
index 2f3dde8acd6dedc51fc58a6560cfdae304156783..191960960a34b69f62e12dbf111b9c0441264654 100644 (file)
@@ -132,6 +132,7 @@ async function tryActivate(context: vscode.ExtensionContext) {
     ctx.pushCleanup(activateTaskProvider(workspaceFolder, ctx.config));
 
     activateInlayHints(ctx);
+    warnAboutRustLangExtensionConflict();
 
     vscode.workspace.onDidChangeConfiguration(
         _ => ctx?.client?.sendNotification('workspace/didChangeConfiguration', { settings: "" }),
@@ -399,3 +400,13 @@ async function queryForGithubToken(state: PersistentState): Promise<void> {
         await state.updateGithubToken(newToken);
     }
 }
+
+function warnAboutRustLangExtensionConflict() {
+    const rustLangExt = vscode.extensions.getExtension("rust-lang.rust");
+    if (rustLangExt !== undefined) {
+        vscode.window.showWarningMessage(
+            "You have both rust-analyzer (matklad.rust-analyzer) and Rust (rust-lang.rust) " +
+            "plugins enabled. These are known to conflict and cause various functions of " +
+            "both plugins to not work correctly. You should disable one of them.", "Got it");
+    };
+}