Skip to content

Commit c692e07

Browse files
bors[bot]matklad
andauthored
Merge #3367
3367: Fix highlighting of const patterns r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 93f632c + 56ce34c commit c692e07

File tree

13 files changed

+144
-71
lines changed

13 files changed

+144
-71
lines changed

crates/ra_hir/src/semantics.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use crate::{
1717
db::HirDatabase,
1818
source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer},
1919
source_binder::{ChildContainer, SourceBinder},
20-
Function, HirFileId, InFile, Local, MacroDef, Module, Name, Origin, Path, PathResolution,
21-
ScopeDef, StructField, Trait, Type, TypeParam, VariantDef,
20+
Function, HirFileId, InFile, Local, MacroDef, Module, ModuleDef, Name, Origin, Path,
21+
PathResolution, ScopeDef, StructField, Trait, Type, TypeParam, VariantDef,
2222
};
2323
use hir_expand::ExpansionInfo;
2424
use ra_prof::profile;
@@ -129,6 +129,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
129129
self.analyze(path.syntax()).resolve_path(self.db, path)
130130
}
131131

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+
132136
// FIXME: use this instead?
133137
// pub fn resolve_name_ref(&self, name_ref: &ast::NameRef) -> Option<???>;
134138

crates/ra_hir/src/source_analyzer.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use either::Either;
1111
use hir_def::{
1212
body::{
1313
scope::{ExprScopes, ScopeId},
14-
BodySourceMap,
14+
Body, BodySourceMap,
1515
},
16-
expr::{ExprId, PatId},
16+
expr::{ExprId, Pat, PatId},
1717
resolver::{resolver_for_scope, Resolver, TypeNs, ValueNs},
1818
AsMacroCall, DefWithBodyId,
1919
};
@@ -25,8 +25,8 @@ use ra_syntax::{
2525
};
2626

2727
use crate::{
28-
db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, Path, Static, Struct,
29-
Trait, Type, TypeAlias, TypeParam,
28+
db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, ModuleDef, Path, Static,
29+
Struct, Trait, Type, TypeAlias, TypeParam,
3030
};
3131

3232
/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
@@ -35,6 +35,7 @@ use crate::{
3535
pub(crate) struct SourceAnalyzer {
3636
file_id: HirFileId,
3737
pub(crate) resolver: Resolver,
38+
body: Option<Arc<Body>>,
3839
body_source_map: Option<Arc<BodySourceMap>>,
3940
infer: Option<Arc<InferenceResult>>,
4041
scopes: Option<Arc<ExprScopes>>,
@@ -66,7 +67,7 @@ impl SourceAnalyzer {
6667
node: InFile<&SyntaxNode>,
6768
offset: Option<TextUnit>,
6869
) -> SourceAnalyzer {
69-
let (_body, source_map) = db.body_with_source_map(def);
70+
let (body, source_map) = db.body_with_source_map(def);
7071
let scopes = db.expr_scopes(def);
7172
let scope = match offset {
7273
None => scope_for(&scopes, &source_map, node),
@@ -75,6 +76,7 @@ impl SourceAnalyzer {
7576
let resolver = resolver_for_scope(db, def, scope);
7677
SourceAnalyzer {
7778
resolver,
79+
body: Some(body),
7880
body_source_map: Some(source_map),
7981
infer: Some(db.infer(def)),
8082
scopes: Some(scopes),
@@ -88,6 +90,7 @@ impl SourceAnalyzer {
8890
) -> SourceAnalyzer {
8991
SourceAnalyzer {
9092
resolver,
93+
body: None,
9194
body_source_map: None,
9295
infer: None,
9396
scopes: None,
@@ -197,6 +200,24 @@ impl SourceAnalyzer {
197200
self.resolver.resolve_path_as_macro(db, path.mod_path()).map(|it| it.into())
198201
}
199202

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+
200221
pub(crate) fn resolve_path(
201222
&self,
202223
db: &impl HirDatabase,

crates/ra_ide/src/goto_definition.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@ pub(crate) fn goto_definition(
3030
reference_definition(&sema, &name_ref).to_vec()
3131
},
3232
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]
3436
},
3537
_ => return None,
3638
}
@@ -88,15 +90,6 @@ pub(crate) fn reference_definition(
8890
Approximate(navs)
8991
}
9092

91-
fn 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-
10093
#[cfg(test)]
10194
mod tests {
10295
use test_utils::{assert_eq_text, covers};

crates/ra_ide/src/hover.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
156156
classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d))
157157
},
158158
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()))
160160
},
161161
_ => None,
162162
}
@@ -785,13 +785,13 @@ fn func(foo: i32) { if true { <|>foo; }; }
785785
fn test_hover_through_literal_string_in_builtin_macro() {
786786
check_hover_no_result(
787787
r#"
788-
//- /lib.rs
788+
//- /lib.rs
789789
#[rustc_builtin_macro]
790790
macro_rules! assert {
791791
($cond:expr) => {{ /* compiler built-in */ }};
792792
($cond:expr,) => {{ /* compiler built-in */ }};
793793
($cond:expr, $($arg:tt)+) => {{ /* compiler built-in */ }};
794-
}
794+
}
795795
796796
fn foo() {
797797
assert!("hel<|>lo");

crates/ra_ide/src/references.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ fn find_name(
155155
opt_name: Option<ast::Name>,
156156
) -> Option<RangeInfo<(String, NameDefinition)>> {
157157
if let Some(name) = opt_name {
158-
let def = classify_name(sema, &name)?;
158+
let def = classify_name(sema, &name)?.definition();
159159
let range = name.syntax().text_range();
160160
return Some(RangeInfo::new(range, (name.text().to_string(), def)));
161161
}

crates/ra_ide/src/snapshots/highlighting.html

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
body { margin: 0; }
44
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
55

6-
6+
.lifetime { color: #DFAF8F; font-style: italic; }
77
.comment { color: #7F9F7F; }
88
.struct, .enum { color: #7CB8BB; }
99
.enum_variant { color: #BDE0F3; }
@@ -27,48 +27,54 @@
2727
.control { font-style: italic; }
2828
</style>
2929
<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> {
31-
<span class="keyword">pub</span> <span class="field">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>,
30+
<span class="keyword">struct</span> <span class="struct declaration">Foo</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 declaration">y</span>: <span class="builtin_type">i32</span>,
3333
}
3434

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> {
36-
<span class="macro">unimplemented</span><span class="macro">!</span>();
37-
<span class="function">foo</span>::&lt;<span class="builtin_type">i32</span>&gt;();
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="function">foo</span>::&lt;<span class="lifetime">'a</span>, <span class="builtin_type">i32</span>&gt;()
3837
}
3938

4039
<span class="macro">macro_rules</span><span class="macro">!</span> def_fn {
4140
($($tt:tt)*) =&gt; {$($tt)*}
4241
}
4342

4443
<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> {
4645
<span class="numeric_literal">100</span>
4746
}
4847
}
4948

5049
<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>() {
5251
<span class="macro">println</span><span class="macro">!</span>(<span class="string_literal">"Hello, {}!"</span>, <span class="numeric_literal">92</span>);
5352

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();
5554
<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>;
5756
<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> });
5857
}
5958
<span class="keyword unsafe">unsafe</span> { <span class="variable mutable">vec</span>.set_len(<span class="numeric_literal">0</span>); }
6059

61-
<span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable 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>;
63-
<span class="keyword">let</span> <span class="variable">z</span> = &<span class="variable mutable">y</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>;
61+
<span class="keyword">let</span> <span class="variable declaration mutable">y</span> = &<span class="keyword">mut</span> <span class="variable mutable">x</span>;
62+
<span class="keyword">let</span> <span class="variable declaration">z</span> = &<span class="variable mutable">y</span>;
6463

6564
<span class="variable mutable">y</span>;
6665
}
6766

68-
<span class="keyword">enum</span> <span class="enum">E</span>&lt;<span class="type_param">X</span>&gt; {
69-
<span class="enum_variant">V</span>(<span class="type_param">X</span>)
67+
<span class="keyword">enum</span> <span class="enum declaration">Option</span>&lt;<span class="type_param declaration">T</span>&gt; {
68+
<span class="enum_variant declaration">Some</span>(<span class="type_param">T</span>),
69+
<span class="enum_variant declaration">None</span>,
7070
}
71+
<span class="keyword">use</span> <span class="enum">Option</span>::*;
7172

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">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; {}
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; {
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+
}
7480
}</code></pre>

crates/ra_ide/src/snapshots/rainbow_highlighting.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
body { margin: 0; }
44
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
55

6-
6+
.lifetime { color: #DFAF8F; font-style: italic; }
77
.comment { color: #7F9F7F; }
88
.struct, .enum { color: #7CB8BB; }
99
.enum_variant { color: #BDE0F3; }
@@ -26,15 +26,15 @@
2626
.keyword.unsafe { color: #BC8383; font-weight: bold; }
2727
.control { font-style: italic; }
2828
</style>
29-
<pre><code><span class="keyword">fn</span> <span class="function">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>;
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();
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();
29+
<pre><code><span class="keyword">fn</span> <span class="function declaration">main</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 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 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();
3333

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>;
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();
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 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();
3636
}
3737

38-
<span class="keyword">fn</span> <span class="function">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>;
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 declaration mutable" data-binding-hash="8121853618659664005" style="color: hsl(261,57%,61%);">hello</span> = <span class="string_literal">"hello"</span>;
4040
}</code></pre>

crates/ra_ide/src/syntax_highlighting.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ mod tests;
77

88
use hir::{Name, Semantics};
99
use ra_ide_db::{
10-
defs::{classify_name, NameDefinition},
10+
defs::{classify_name, NameClass, NameDefinition},
1111
RootDatabase,
1212
};
1313
use ra_prof::profile;
@@ -169,19 +169,21 @@ fn highlight_element(
169169
let name = element.into_node().and_then(ast::Name::cast).unwrap();
170170
let name_kind = classify_name(sema, &name);
171171

172-
if let Some(NameDefinition::Local(local)) = &name_kind {
172+
if let Some(NameClass::NameDefinition(NameDefinition::Local(local))) = &name_kind {
173173
if let Some(name) = local.name(db) {
174174
let shadow_count = bindings_shadow_count.entry(name.clone()).or_default();
175175
*shadow_count += 1;
176176
binding_hash = Some(calc_binding_hash(&name, *shadow_count))
177177
}
178178
};
179179

180-
let h = match name_kind {
181-
Some(name_kind) => highlight_name(db, name_kind),
182-
None => highlight_name_by_syntax(name),
183-
};
184-
h | HighlightModifier::Definition
180+
match name_kind {
181+
Some(NameClass::NameDefinition(def)) => {
182+
highlight_name(db, def) | HighlightModifier::Definition
183+
}
184+
Some(NameClass::ConstReference(def)) => highlight_name(db, def),
185+
None => highlight_name_by_syntax(name) | HighlightModifier::Definition,
186+
}
185187
}
186188

187189
// Highlight references like the definitions they resolve to
@@ -212,8 +214,13 @@ fn highlight_element(
212214
INT_NUMBER | FLOAT_NUMBER => HighlightTag::NumericLiteral.into(),
213215
BYTE => HighlightTag::ByteLiteral.into(),
214216
CHAR => HighlightTag::CharLiteral.into(),
215-
// FIXME: set Declaration for decls
216-
LIFETIME => HighlightTag::Lifetime.into(),
217+
LIFETIME => {
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+
}
217224

218225
k if k.is_keyword() => {
219226
let h = Highlight::new(HighlightTag::Keyword);

crates/ra_ide/src/syntax_highlighting/html.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ const STYLE: &str = "
8080
body { margin: 0; }
8181
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
8282
83-
83+
.lifetime { color: #DFAF8F; font-style: italic; }
8484
.comment { color: #7F9F7F; }
8585
.struct, .enum { color: #7CB8BB; }
8686
.enum_variant { color: #BDE0F3; }

crates/ra_ide/src/syntax_highlighting/tags.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,12 @@ impl fmt::Display for HighlightTag {
9090
}
9191

9292
impl HighlightModifier {
93-
const ALL: &'static [HighlightModifier] =
94-
&[HighlightModifier::Mutable, HighlightModifier::Unsafe, HighlightModifier::Control];
93+
const ALL: &'static [HighlightModifier] = &[
94+
HighlightModifier::Control,
95+
HighlightModifier::Definition,
96+
HighlightModifier::Mutable,
97+
HighlightModifier::Unsafe,
98+
];
9599

96100
fn as_str(self) -> &'static str {
97101
match self {

0 commit comments

Comments
 (0)