aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/semantics.rs8
-rw-r--r--crates/ra_hir/src/source_analyzer.rs31
-rw-r--r--crates/ra_ide/src/goto_definition.rs13
-rw-r--r--crates/ra_ide/src/hover.rs6
-rw-r--r--crates/ra_ide/src/references.rs2
-rw-r--r--crates/ra_ide/src/snapshots/highlighting.html42
-rw-r--r--crates/ra_ide/src/snapshots/rainbow_highlighting.html18
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs25
-rw-r--r--crates/ra_ide/src/syntax_highlighting/html.rs2
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tags.rs8
-rw-r--r--crates/ra_ide/src/syntax_highlighting/tests.rs24
-rw-r--r--crates/ra_ide_db/src/defs.rs33
-rw-r--r--crates/ra_ide_db/src/imports_locator.rs3
13 files changed, 144 insertions, 71 deletions
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index eecccdae2..178d74be1 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -17,8 +17,8 @@ use crate::{
17 db::HirDatabase, 17 db::HirDatabase,
18 source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer}, 18 source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer},
19 source_binder::{ChildContainer, SourceBinder}, 19 source_binder::{ChildContainer, SourceBinder},
20 Function, HirFileId, InFile, Local, MacroDef, Module, Name, Origin, Path, PathResolution, 20 Function, HirFileId, InFile, Local, MacroDef, Module, ModuleDef, Name, Origin, Path,
21 ScopeDef, StructField, Trait, Type, TypeParam, VariantDef, 21 PathResolution, ScopeDef, StructField, Trait, Type, TypeParam, VariantDef,
22}; 22};
23use hir_expand::ExpansionInfo; 23use hir_expand::ExpansionInfo;
24use ra_prof::profile; 24use ra_prof::profile;
@@ -129,6 +129,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
129 self.analyze(path.syntax()).resolve_path(self.db, path) 129 self.analyze(path.syntax()).resolve_path(self.db, path)
130 } 130 }
131 131
132 pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> {
133 self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat)
134 }
135
132 // FIXME: use this instead? 136 // FIXME: use this instead?
133 // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>; 137 // pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>;
134 138
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index b655e2c32..c650a9e08 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -11,9 +11,9 @@ use either::Either;
11use hir_def::{ 11use hir_def::{
12 body::{ 12 body::{
13 scope::{ExprScopes, ScopeId}, 13 scope::{ExprScopes, ScopeId},
14 BodySourceMap, 14 Body, BodySourceMap,
15 }, 15 },
16 expr::{ExprId, PatId}, 16 expr::{ExprId, Pat, PatId},
17 resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs}, 17 resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
18 AsMacroCall, DefWithBodyId, 18 AsMacroCall, DefWithBodyId,
19}; 19};
@@ -25,8 +25,8 @@ use ra_syntax::{
25}; 25};
26 26
27use crate::{ 27use crate::{
28 db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, Path, Static, Struct, 28 db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, ModuleDef, Path, Static,
29 Trait, Type, TypeAlias, TypeParam, 29 Struct, Trait, Type, TypeAlias, TypeParam,
30}; 30};
31 31
32/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of 32/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
@@ -35,6 +35,7 @@ use crate::{
35pub(crate) struct SourceAnalyzer { 35pub(crate) struct SourceAnalyzer {
36 file_id: HirFileId, 36 file_id: HirFileId,
37 pub(crate) resolver: Resolver, 37 pub(crate) resolver: Resolver,
38 body: Option<Arc<Body>>,
38 body_source_map: Option<Arc<BodySourceMap>>, 39 body_source_map: Option<Arc<BodySourceMap>>,
39 infer: Option<Arc<InferenceResult>>, 40 infer: Option<Arc<InferenceResult>>,
40 scopes: Option<Arc<ExprScopes>>, 41 scopes: Option<Arc<ExprScopes>>,
@@ -66,7 +67,7 @@ impl SourceAnalyzer {
66 node: InFile<&SyntaxNode>, 67 node: InFile<&SyntaxNode>,
67 offset: Option<TextUnit>, 68 offset: Option<TextUnit>,
68 ) -> SourceAnalyzer { 69 ) -> SourceAnalyzer {
69 let (_body, source_map) = db.body_with_source_map(def); 70 let (body, source_map) = db.body_with_source_map(def);
70 let scopes = db.expr_scopes(def); 71 let scopes = db.expr_scopes(def);
71 let scope = match offset { 72 let scope = match offset {
72 None => scope_for(&scopes, &source_map, node), 73 None => scope_for(&scopes, &source_map, node),
@@ -75,6 +76,7 @@ impl SourceAnalyzer {
75 let resolver = resolver_for_scope(db, def, scope); 76 let resolver = resolver_for_scope(db, def, scope);
76 SourceAnalyzer { 77 SourceAnalyzer {
77 resolver, 78 resolver,
79 body: Some(body),
78 body_source_map: Some(source_map), 80 body_source_map: Some(source_map),
79 infer: Some(db.infer(def)), 81 infer: Some(db.infer(def)),
80 scopes: Some(scopes), 82 scopes: Some(scopes),
@@ -88,6 +90,7 @@ impl SourceAnalyzer {
88 ) -> SourceAnalyzer { 90 ) -> SourceAnalyzer {
89 SourceAnalyzer { 91 SourceAnalyzer {
90 resolver, 92 resolver,
93 body: None,
91 body_source_map: None, 94 body_source_map: None,
92 infer: None, 95 infer: None,
93 scopes: None, 96 scopes: None,
@@ -197,6 +200,24 @@ impl SourceAnalyzer {
197 self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into()) 200 self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into())
198 } 201 }
199 202
203 pub(crate) fn resolve_bind_pat_to_const(
204 &self,
205 db: &impl HirDatabase,
206 pat: &ast::BindPat,
207 ) -> Option<ModuleDef> {
208 let pat_id = self.pat_id(&pat.clone().into())?;
209 let body = self.body.as_ref()?;
210 let path = match &body[pat_id] {
211 Pat::Path(path) => path,
212 _ => return None,
213 };
214 let res = resolve_hir_path(db, &self.resolver, &path)?;
215 match res {
216 PathResolution::Def(def) => Some(def),
217 _ => None,
218 }
219 }
220
200 pub(crate) fn resolve_path( 221 pub(crate) fn resolve_path(
201 &self, 222 &self,
202 db: &impl HirDatabase, 223 db: &impl HirDatabase,
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index 6053c1bb6..621ab982c 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -30,7 +30,9 @@ pub(crate) fn goto_definition(
30 reference_definition(&sema, &name_ref).to_vec() 30 reference_definition(&sema, &name_ref).to_vec()
31 }, 31 },
32 ast::Name(name) => { 32 ast::Name(name) => {
33 name_definition(&sema, &name)? 33 let def = classify_name(&sema, &name)?.definition();
34 let nav = def.try_to_nav(sema.db)?;
35 vec![nav]
34 }, 36 },
35 _ => return None, 37 _ => return None,
36 } 38 }
@@ -88,15 +90,6 @@ pub(crate) fn reference_definition(
88 Approximate(navs) 90 Approximate(navs)
89} 91}
90 92
91fn name_definition(
92 sema: &Semantics<RootDatabase>,
93 name: &ast::Name,
94) -> Option<Vec<NavigationTarget>> {
95 let def = classify_name(sema, name)?;
96 let nav = def.try_to_nav(sema.db)?;
97 Some(vec![nav])
98}
99
100#[cfg(test)] 93#[cfg(test)]
101mod tests { 94mod tests {
102 use test_utils::{assert_eq_text, covers}; 95 use test_utils::{assert_eq_text, covers};
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index cc79f1fab..5073bb1cf 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -156,7 +156,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
156 classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d)) 156 classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d))
157 }, 157 },
158 ast::Name(name) => { 158 ast::Name(name) => {
159 classify_name(&sema, &name).map(|d| (name.syntax().clone(), d)) 159 classify_name(&sema, &name).map(|d| (name.syntax().clone(), d.definition()))
160 }, 160 },
161 _ => None, 161 _ => None,
162 } 162 }
@@ -785,13 +785,13 @@ fn func(foo: i32) { if true { <|>foo; }; }
785 fn test_hover_through_literal_string_in_builtin_macro() { 785 fn test_hover_through_literal_string_in_builtin_macro() {
786 check_hover_no_result( 786 check_hover_no_result(
787 r#" 787 r#"
788 //- /lib.rs 788 //- /lib.rs
789 #[rustc_builtin_macro] 789 #[rustc_builtin_macro]
790 macro_rules! assert { 790 macro_rules! assert {
791 ($cond:expr) => {{ /* compiler built-in */ }}; 791 ($cond:expr) => {{ /* compiler built-in */ }};
792 ($cond:expr,) => {{ /* compiler built-in */ }}; 792 ($cond:expr,) => {{ /* compiler built-in */ }};
793 ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }}; 793 ($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
794 } 794 }
795 795
796 fn foo() { 796 fn foo() {
797 assert!("hel<|>lo"); 797 assert!("hel<|>lo");
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index baa8a4d29..f763013ae 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -155,7 +155,7 @@ fn find_name(
155 opt_name: Option<ast::Name>, 155 opt_name: Option<ast::Name>,
156) -> Option<RangeInfo<(String, NameDefinition)>> { 156) -> Option<RangeInfo<(String, NameDefinition)>> {
157 if let Some(name) = opt_name { 157 if let Some(name) = opt_name {
158 let def = classify_name(sema, &name)?; 158 let def = classify_name(sema, &name)?.definition();
159 let range = name.syntax().text_range(); 159 let range = name.syntax().text_range();
160 return Some(RangeInfo::new(range, (name.text().to_string(), def))); 160 return Some(RangeInfo::new(range, (name.text().to_string(), def)));
161 } 161 }
diff --git a/crates/ra_ide/src/snapshots/highlighting.html b/crates/ra_ide/src/snapshots/highlighting.html
index 8c372ad27..495b07f69 100644
--- a/crates/ra_ide/src/snapshots/highlighting.html
+++ b/crates/ra_ide/src/snapshots/highlighting.html
@@ -3,7 +3,7 @@
3body { margin: 0; } 3body { margin: 0; }
4pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } 4pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
5 5
6 6.lifetime { color: #DFAF8F; font-style: italic; }
7.comment { color: #7F9F7F; } 7.comment { color: #7F9F7F; }
8.struct, .enum { color: #7CB8BB; } 8.struct, .enum { color: #7CB8BB; }
9.enum_variant { color: #BDE0F3; } 9.enum_variant { color: #BDE0F3; }
@@ -27,14 +27,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
27.control { font-style: italic; } 27.control { font-style: italic; }
28</style> 28</style>
29<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span> 29<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span>
30<span class="keyword">struct</span> <span class="struct">Foo</span> { 30<span class="keyword">struct</span> <span class="struct declaration">Foo</span> {
31 <span class="keyword">pub</span> <span class="field">x</span>: <span class="builtin_type">i32</span>, 31 <span class="keyword">pub</span> <span class="field declaration">x</span>: <span class="builtin_type">i32</span>,
32 <span class="keyword">pub</span> <span class="field">y</span>: <span class="builtin_type">i32</span>, 32 <span class="keyword">pub</span> <span class="field declaration">y</span>: <span class="builtin_type">i32</span>,
33} 33}
34 34
35<span class="keyword">fn</span> <span class="function">foo</span>&lt;<span class="type_param">T</span>&gt;() -&gt; <span class="type_param">T</span> { 35<span class="keyword">fn</span> <span class="function declaration">foo</span>&lt;<span class="lifetime declaration">'a</span>, <span class="type_param declaration">T</span>&gt;() -&gt; <span class="type_param">T</span> {
36 <span class="macro">unimplemented</span><span class="macro">!</span>(); 36 <span class="function">foo</span>::&lt;<span class="lifetime">'a</span>, <span class="builtin_type">i32</span>&gt;()
37 <span class="function">foo</span>::&lt;<span class="builtin_type">i32</span>&gt;();
38} 37}
39 38
40<span class="macro">macro_rules</span><span class="macro">!</span> def_fn { 39<span class="macro">macro_rules</span><span class="macro">!</span> def_fn {
@@ -42,33 +41,40 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
42} 41}
43 42
44<span class="macro">def_fn</span><span class="macro">!</span> { 43<span class="macro">def_fn</span><span class="macro">!</span> {
45 <span class="keyword">fn</span> <span class="function">bar</span>() -&gt; <span class="builtin_type">u32</span> { 44 <span class="keyword">fn</span> <span class="function declaration">bar</span>() -&gt; <span class="builtin_type">u32</span> {
46 <span class="numeric_literal">100</span> 45 <span class="numeric_literal">100</span>
47 } 46 }
48} 47}
49 48
50<span class="comment">// comment</span> 49<span class="comment">// comment</span>
51<span class="keyword">fn</span> <span class="function">main</span>() { 50<span class="keyword">fn</span> <span class="function declaration">main</span>() {
52 <span class="macro">println</span><span class="macro">!</span>(<span class="string_literal">"Hello, {}!"</span>, <span class="numeric_literal">92</span>); 51 <span class="macro">println</span><span class="macro">!</span>(<span class="string_literal">"Hello, {}!"</span>, <span class="numeric_literal">92</span>);
53 52
54 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable mutable">vec</span> = Vec::new(); 53 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">vec</span> = Vec::new();
55 <span class="keyword control">if</span> <span class="keyword">true</span> { 54 <span class="keyword control">if</span> <span class="keyword">true</span> {
56 <span class="keyword">let</span> <span class="variable">x</span> = <span class="numeric_literal">92</span>; 55 <span class="keyword">let</span> <span class="variable declaration">x</span> = <span class="numeric_literal">92</span>;
57 <span class="variable mutable">vec</span>.push(<span class="struct">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="numeric_literal">1</span> }); 56 <span class="variable mutable">vec</span>.push(<span class="struct">Foo</span> { <span class="field">x</span>, <span class="field">y</span>: <span class="numeric_literal">1</span> });
58 } 57 }
59 <span class="keyword unsafe">unsafe</span> { <span class="variable mutable">vec</span>.set_len(<span class="numeric_literal">0</span>); } 58 <span class="keyword unsafe">unsafe</span> { <span class="variable mutable">vec</span>.set_len(<span class="numeric_literal">0</span>); }
60 59
61 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable mutable">x</span> = <span class="numeric_literal">42</span>; 60 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">x</span> = <span class="numeric_literal">42</span>;
62 <span class="keyword">let</span> <span class="variable mutable">y</span> = &<span class="keyword">mut</span> <span class="variable mutable">x</span>; 61 <span class="keyword">let</span> <span class="variable declaration mutable">y</span> = &<span class="keyword">mut</span> <span class="variable mutable">x</span>;
63 <span class="keyword">let</span> <span class="variable">z</span> = &<span class="variable mutable">y</span>; 62 <span class="keyword">let</span> <span class="variable declaration">z</span> = &<span class="variable mutable">y</span>;
64 63
65 <span class="variable mutable">y</span>; 64 <span class="variable mutable">y</span>;
66} 65}
67 66
68<span class="keyword">enum</span> <span class="enum">E</span>&lt;<span class="type_param">X</span>&gt; { 67<span class="keyword">enum</span> <span class="enum declaration">Option</span>&lt;<span class="type_param declaration">T</span>&gt; {
69 <span class="enum_variant">V</span>(<span class="type_param">X</span>) 68 <span class="enum_variant declaration">Some</span>(<span class="type_param">T</span>),
69 <span class="enum_variant declaration">None</span>,
70} 70}
71<span class="keyword">use</span> <span class="enum">Option</span>::*;
71 72
72<span class="keyword">impl</span>&lt;<span class="type_param">X</span>&gt; <span class="enum">E</span>&lt;<span class="type_param">X</span>&gt; { 73<span class="keyword">impl</span>&lt;<span class="type_param declaration">T</span>&gt; <span class="enum">Option</span>&lt;<span class="type_param">T</span>&gt; {
73 <span class="keyword">fn</span> <span class="function">new</span>&lt;<span class="type_param">T</span>&gt;() -&gt; <span class="enum">E</span>&lt;<span class="type_param">T</span>&gt; {} 74 <span class="keyword">fn</span> <span class="function declaration">and</span>&lt;<span class="type_param declaration">U</span>&gt;(<span class="keyword">self</span>, <span class="variable declaration">other</span>: <span class="enum">Option</span>&lt;<span class="type_param">U</span>&gt;) -&gt; <span class="enum">Option</span>&lt;(<span class="type_param">T</span>, <span class="type_param">U</span>)&gt; {
75 <span class="keyword control">match</span> <span class="variable">other</span> {
76 <span class="enum_variant">None</span> =&gt; <span class="macro">unimplemented</span><span class="macro">!</span>(),
77 <span class="variable declaration">Nope</span> =&gt; <span class="variable">Nope</span>,
78 }
79 }
74}</code></pre> \ No newline at end of file 80}</code></pre> \ No newline at end of file
diff --git a/crates/ra_ide/src/snapshots/rainbow_highlighting.html b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
index f63e64b6d..dddbfc0dd 100644
--- a/crates/ra_ide/src/snapshots/rainbow_highlighting.html
+++ b/crates/ra_ide/src/snapshots/rainbow_highlighting.html
@@ -3,7 +3,7 @@
3body { margin: 0; } 3body { margin: 0; }
4pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } 4pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
5 5
6 6.lifetime { color: #DFAF8F; font-style: italic; }
7.comment { color: #7F9F7F; } 7.comment { color: #7F9F7F; }
8.struct, .enum { color: #7CB8BB; } 8.struct, .enum { color: #7CB8BB; }
9.enum_variant { color: #BDE0F3; } 9.enum_variant { color: #BDE0F3; }
@@ -26,15 +26,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
26.keyword.unsafe { color: #BC8383; font-weight: bold; } 26.keyword.unsafe { color: #BC8383; font-weight: bold; }
27.control { font-style: italic; } 27.control { font-style: italic; }
28</style> 28</style>
29<pre><code><span class="keyword">fn</span> <span class="function">main</span>() { 29<pre><code><span class="keyword">fn</span> <span class="function declaration">main</span>() {
30 <span class="keyword">let</span> <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>; 30 <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>;
31 <span class="keyword">let</span> <span class="variable" data-binding-hash="2705725358298919760" style="color: hsl(17,51%,74%);">x</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string(); 31 <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="2705725358298919760" style="color: hsl(17,51%,74%);">x</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string();
32 <span class="keyword">let</span> <span class="variable" data-binding-hash="3365759661443752373" style="color: hsl(127,76%,66%);">y</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string(); 32 <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="3365759661443752373" style="color: hsl(127,76%,66%);">y</span> = <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span>.to_string();
33 33
34 <span class="keyword">let</span> <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span> = <span class="string_literal">"other color please!"</span>; 34 <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span> = <span class="string_literal">"other color please!"</span>;
35 <span class="keyword">let</span> <span class="variable" data-binding-hash="6717528807933952652" style="color: hsl(85,49%,84%);">y</span> = <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span>.to_string(); 35 <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="6717528807933952652" style="color: hsl(85,49%,84%);">y</span> = <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(19,74%,76%);">x</span>.to_string();
36} 36}
37 37
38<span class="keyword">fn</span> <span class="function">bar</span>() { 38<span class="keyword">fn</span> <span class="function declaration">bar</span>() {
39 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable mutable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>; 39 <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>;
40}</code></pre> \ No newline at end of file 40}</code></pre> \ No newline at end of file
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index c0f7c1c9f..b94b6a022 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -7,7 +7,7 @@ mod tests;
7 7
8use hir::{Name, Semantics}; 8use hir::{Name, Semantics};
9use ra_ide_db::{ 9use ra_ide_db::{
10 defs::{classify_name, NameDefinition}, 10 defs::{classify_name, NameClass, NameDefinition},
11 RootDatabase, 11 RootDatabase,
12}; 12};
13use ra_prof::profile; 13use ra_prof::profile;
@@ -169,7 +169,7 @@ fn highlight_element(
169 let name = element.into_node().and_then(ast::Name::cast).unwrap(); 169 let name = element.into_node().and_then(ast::Name::cast).unwrap();
170 let name_kind = classify_name(sema, &name); 170 let name_kind = classify_name(sema, &name);
171 171
172 if let Some(NameDefinition::Local(local)) = &name_kind { 172 if let Some(NameClass::NameDefinition(NameDefinition::Local(local))) = &name_kind {
173 if let Some(name) = local.name(db) { 173 if let Some(name) = local.name(db) {
174 let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); 174 let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
175 *shadow_count += 1; 175 *shadow_count += 1;
@@ -177,11 +177,13 @@ fn highlight_element(
177 } 177 }
178 }; 178 };
179 179
180 let h = match name_kind { 180 match name_kind {
181 Some(name_kind) => highlight_name(db, name_kind), 181 Some(NameClass::NameDefinition(def)) => {
182 None => highlight_name_by_syntax(name), 182 highlight_name(db, def) | HighlightModifier::Definition
183 }; 183 }
184 h | HighlightModifier::Definition 184 Some(NameClass::ConstReference(def)) => highlight_name(db, def),
185 None => highlight_name_by_syntax(name) | HighlightModifier::Definition,
186 }
185 } 187 }
186 188
187 // Highlight references like the definitions they resolve to 189 // Highlight references like the definitions they resolve to
@@ -212,8 +214,13 @@ fn highlight_element(
212 INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(), 214 INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(),
213 BYTE => HighlightTag::ByteLiteral.into(), 215 BYTE => HighlightTag::ByteLiteral.into(),
214 CHAR => HighlightTag::CharLiteral.into(), 216 CHAR => HighlightTag::CharLiteral.into(),
215 // FIXME: set Declaration for decls 217 LIFETIME => {
216 LIFETIME => HighlightTag::Lifetime.into(), 218 let h = Highlight::new(HighlightTag::Lifetime);
219 dbg!(match element.parent().map(|it| it.kind()) {
220 Some(LIFETIME_PARAM) | Some(LABEL) => h | HighlightModifier::Definition,
221 _ => h,
222 })
223 }
217 224
218 k if k.is_keyword() => { 225 k if k.is_keyword() => {
219 let h = Highlight::new(HighlightTag::Keyword); 226 let h = Highlight::new(HighlightTag::Keyword);
diff --git a/crates/ra_ide/src/syntax_highlighting/html.rs b/crates/ra_ide/src/syntax_highlighting/html.rs
index 54678c278..e13766c9d 100644
--- a/crates/ra_ide/src/syntax_highlighting/html.rs
+++ b/crates/ra_ide/src/syntax_highlighting/html.rs
@@ -80,7 +80,7 @@ const STYLE: &str = "
80body { margin: 0; } 80body { margin: 0; }
81pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } 81pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
82 82
83 83.lifetime { color: #DFAF8F; font-style: italic; }
84.comment { color: #7F9F7F; } 84.comment { color: #7F9F7F; }
85.struct, .enum { color: #7CB8BB; } 85.struct, .enum { color: #7CB8BB; }
86.enum_variant { color: #BDE0F3; } 86.enum_variant { color: #BDE0F3; }
diff --git a/crates/ra_ide/src/syntax_highlighting/tags.rs b/crates/ra_ide/src/syntax_highlighting/tags.rs
index 9da80823c..8835a5de2 100644
--- a/crates/ra_ide/src/syntax_highlighting/tags.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tags.rs
@@ -90,8 +90,12 @@ impl fmt::Display for HighlightTag {
90} 90}
91 91
92impl HighlightModifier { 92impl HighlightModifier {
93 const ALL: &'static [HighlightModifier] = 93 const ALL: &'static [HighlightModifier] = &[
94 &[HighlightModifier::Mutable, HighlightModifier::Unsafe, HighlightModifier::Control]; 94 HighlightModifier::Control,
95 HighlightModifier::Definition,
96 HighlightModifier::Mutable,
97 HighlightModifier::Unsafe,
98 ];
95 99
96 fn as_str(self) -> &'static str { 100 fn as_str(self) -> &'static str {
97 match self { 101 match self {
diff --git a/crates/ra_ide/src/syntax_highlighting/tests.rs b/crates/ra_ide/src/syntax_highlighting/tests.rs
index 2d90a072f..98c030791 100644
--- a/crates/ra_ide/src/syntax_highlighting/tests.rs
+++ b/crates/ra_ide/src/syntax_highlighting/tests.rs
@@ -17,9 +17,8 @@ struct Foo {
17 pub y: i32, 17 pub y: i32,
18} 18}
19 19
20fn foo<T>() -> T { 20fn foo<'a, T>() -> T {
21 unimplemented!(); 21 foo::<'a, i32>()
22 foo::<i32>();
23} 22}
24 23
25macro_rules! def_fn { 24macro_rules! def_fn {
@@ -50,12 +49,19 @@ fn main() {
50 y; 49 y;
51} 50}
52 51
53enum E<X> { 52enum Option<T> {
54 V(X) 53 Some(T),
54 None,
55} 55}
56 56use Option::*;
57impl<X> E<X> { 57
58 fn new<T>() -> E<T> {} 58impl<T> Option<T> {
59 fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
60 match other {
61 None => unimplemented!(),
62 Nope => Nope,
63 }
64 }
59} 65}
60"# 66"#
61 .trim(), 67 .trim(),
@@ -123,5 +129,5 @@ fn test_ranges() {
123 .highlight_range(FileRange { file_id, range: TextRange::offset_len(82.into(), 1.into()) }) 129 .highlight_range(FileRange { file_id, range: TextRange::offset_len(82.into(), 1.into()) })
124 .unwrap(); 130 .unwrap();
125 131
126 assert_eq!(&highlights[0].highlight.to_string(), "field"); 132 assert_eq!(&highlights[0].highlight.to_string(), "field.declaration");
127} 133}
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index 484755158..93f32ba85 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -68,7 +68,38 @@ impl NameDefinition {
68 } 68 }
69} 69}
70 70
71pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameDefinition> { 71pub enum NameClass {
72 NameDefinition(NameDefinition),
73 /// `None` in `if let None = Some(82) {}`
74 ConstReference(NameDefinition),
75}
76
77impl NameClass {
78 pub fn into_definition(self) -> Option<NameDefinition> {
79 match self {
80 NameClass::NameDefinition(it) => Some(it),
81 NameClass::ConstReference(_) => None,
82 }
83 }
84
85 pub fn definition(self) -> NameDefinition {
86 match self {
87 NameClass::NameDefinition(it) | NameClass::ConstReference(it) => it,
88 }
89 }
90}
91
92pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> {
93 if let Some(bind_pat) = name.syntax().parent().and_then(ast::BindPat::cast) {
94 if let Some(def) = sema.resolve_bind_pat_to_const(&bind_pat) {
95 return Some(NameClass::ConstReference(NameDefinition::ModuleDef(def)));
96 }
97 }
98
99 classify_name_inner(sema, name).map(NameClass::NameDefinition)
100}
101
102fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameDefinition> {
72 let _p = profile("classify_name"); 103 let _p = profile("classify_name");
73 let parent = name.syntax().parent()?; 104 let parent = name.syntax().parent()?;
74 105
diff --git a/crates/ra_ide_db/src/imports_locator.rs b/crates/ra_ide_db/src/imports_locator.rs
index e590d2a5c..e5fc3c470 100644
--- a/crates/ra_ide_db/src/imports_locator.rs
+++ b/crates/ra_ide_db/src/imports_locator.rs
@@ -59,6 +59,7 @@ impl<'a> ImportsLocator<'a> {
59 } else { 59 } else {
60 candidate_node 60 candidate_node
61 }; 61 };
62 classify_name(&self.sema, &ast::Name::cast(candidate_name_node)?) 62 let name = ast::Name::cast(candidate_name_node)?;
63 classify_name(&self.sema, &name)?.into_definition()
63 } 64 }
64} 65}