Skip to content

Commit 5ebfcb9

Browse files
committed
Fix highlighting of const patterns
1 parent 209eb32 commit 5ebfcb9

File tree

5 files changed

+61
-16
lines changed

5 files changed

+61
-16
lines changed

crates/ra_hir/src/semantics.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ use crate::{
1818
db::HirDatabase,
1919
source_analyzer::{resolve_hir_path, ReferenceDescriptor, SourceAnalyzer},
2020
source_binder::{ChildContainer, SourceBinder},
21-
Function, HirFileId, InFile, Local, MacroDef, Module, Name, Origin, Path, PathResolution,
22-
ScopeDef, StructField, Trait, Type, TypeParam, VariantDef,
21+
Function, HirFileId, InFile, Local, MacroDef, Module, ModuleDef, Name, Origin, Path,
22+
PathResolution, ScopeDef, StructField, Trait, Type, TypeParam, VariantDef,
2323
};
2424
use ra_prof::profile;
2525

@@ -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/snapshots/highlighting.html

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,17 @@
6565
<span class="variable mutable">y</span>;
6666
}
6767

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>)
68+
<span class="keyword">enum</span> <span class="enum">Option</span>&lt;<span class="type_param">T</span>&gt; {
69+
<span class="enum_variant">Some</span>(<span class="type_param">T</span>),
70+
<span class="enum_variant">None</span>,
7071
}
72+
<span class="keyword">use</span> <span class="enum">Option</span>::*;
7173

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; {}
74+
<span class="keyword">impl</span>&lt;<span class="type_param">T</span>&gt; <span class="enum">Option</span>&lt;<span class="type_param">T</span>&gt; {
75+
<span class="keyword">fn</span> <span class="function">and</span>&lt;<span class="type_param">U</span>&gt;(<span class="keyword">self</span>, <span class="variable">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; {
76+
<span class="keyword control">match</span> <span class="variable">other</span> {
77+
<span class="enum_variant">None</span> =&gt; <span class="macro">todo</span><span class="macro">!</span>(),
78+
<span class="variable">Nope</span> =&gt; <span class="variable">Nope</span>,
79+
}
80+
}
7481
}</code></pre>

crates/ra_ide/src/syntax_highlighting/tests.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,19 @@ fn main() {
5050
y;
5151
}
5252
53-
enum E<X> {
54-
V(X)
53+
enum Option<T> {
54+
Some(T),
55+
None,
5556
}
56-
57-
impl<X> E<X> {
58-
fn new<T>() -> E<T> {}
57+
use Option::*;
58+
59+
impl<T> Option<T> {
60+
fn and<U>(self, other: Option<U>) -> Option<(T, U)> {
61+
match other {
62+
None => todo!(),
63+
Nope => Nope,
64+
}
65+
}
5966
}
6067
"#
6168
.trim(),

crates/ra_ide_db/src/defs.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ impl NameClass {
9090
}
9191

9292
pub 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+
9399
classify_name_inner(sema, name).map(NameClass::NameDefinition)
94100
}
95101

0 commit comments

Comments
 (0)