Skip to content

Commit 19f1ff5

Browse files
committed
give resolve_derive_ident a more robust api
1 parent 44b0fe8 commit 19f1ff5

File tree

3 files changed

+39
-22
lines changed

3 files changed

+39
-22
lines changed

crates/hir/src/semantics.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,12 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
356356
self.imp.resolve_bind_pat_to_const(pat)
357357
}
358358

359-
pub fn resolve_derive_ident(&self, ident: &ast::Ident) -> Option<PathResolution> {
360-
self.imp.resolve_derive_ident(ident)
359+
pub fn resolve_derive_ident(
360+
&self,
361+
derive: &ast::Attr,
362+
ident: &ast::Ident,
363+
) -> Option<PathResolution> {
364+
self.imp.resolve_derive_ident(derive, ident)
361365
}
362366

363367
// FIXME: use this instead?
@@ -900,23 +904,26 @@ impl<'db> SemanticsImpl<'db> {
900904
self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat)
901905
}
902906

903-
fn resolve_derive_ident(&self, ident: &ast::Ident) -> Option<PathResolution> {
907+
fn resolve_derive_ident(
908+
&self,
909+
derive: &ast::Attr,
910+
ident: &ast::Ident,
911+
) -> Option<PathResolution> {
912+
debug_assert!(ident.syntax().parent().and_then(ast::TokenTree::cast).is_some());
913+
debug_assert!(ident.syntax().ancestors().any(|anc| anc == *derive.syntax()));
904914
// derive macros are always at depth 2, tokentree -> meta -> attribute
905915
let syntax = ident.syntax();
906-
let attr = syntax.ancestors().nth(2).and_then(ast::Attr::cast)?;
907916

908-
let tt = attr.token_tree()?;
909-
if !tt.syntax().text_range().contains_range(ident.syntax().text_range()) {
910-
return None;
911-
}
912-
913-
let file = self.find_file(attr.syntax());
914-
let adt = attr.syntax().parent().and_then(ast::Adt::cast)?;
917+
let tt = derive.token_tree()?;
918+
let file = self.find_file(derive.syntax());
919+
let adt = derive.syntax().parent().and_then(ast::Adt::cast)?;
915920

916921
let res = self.with_ctx(|ctx| {
917-
let attr_def = ctx.attr_to_def(file.with_value(attr.clone()))?;
918-
let derives = ctx
919-
.attr_to_derive_macro_call(file.with_value(&adt), file.with_value(attr.clone()))?;
922+
let attr_def = ctx.attr_to_def(file.with_value(derive.clone()))?;
923+
let derives = ctx.attr_to_derive_macro_call(
924+
file.with_value(&adt),
925+
file.with_value(derive.clone()),
926+
)?;
920927

921928
let mut derive_paths = attr_def.parse_path_comma_token_tree()?;
922929

@@ -951,7 +958,7 @@ impl<'db> SemanticsImpl<'db> {
951958
match res {
952959
Either::Left(path) => resolve_hir_path(
953960
self.db,
954-
&self.scope(attr.syntax()).resolver,
961+
&self.scope(derive.syntax()).resolver,
955962
&Path::from_known_path(path, []),
956963
)
957964
.filter(|res| matches!(res, PathResolution::Def(ModuleDef::Module(_)))),

crates/ide/src/syntax_highlighting/highlight.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,17 @@ pub(super) fn token(
3939
INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(),
4040
BYTE => HlTag::ByteLiteral.into(),
4141
CHAR => HlTag::CharLiteral.into(),
42-
IDENT if parent_matches::<ast::TokenTree>(&token) => {
43-
match sema.resolve_derive_ident(&ast::Ident::cast(token).unwrap()) {
44-
Some(res) => highlight_def(sema, krate, Definition::from(res)),
45-
None => HlTag::None.into(),
46-
}
42+
IDENT => {
43+
let tt = ast::TokenTree::cast(token.parent()?)?;
44+
let ident = ast::Ident::cast(token)?;
45+
// from this point on we are inside a token tree, this only happens for identifiers
46+
// that were not mapped down into macro invocations
47+
(|| {
48+
let attr = tt.parent_meta()?.parent_attr()?;
49+
let res = sema.resolve_derive_ident(&attr, &ident)?;
50+
Some(highlight_def(sema, krate, Definition::from(res)))
51+
})()
52+
.unwrap_or_else(|| HlTag::None.into())
4753
}
4854
p if p.is_punct() => punctuation(sema, token, p),
4955
k if k.is_keyword() => keyword(sema, token, k)?,

crates/ide_db/src/defs.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,12 @@ impl Definition {
5555
let attr = ast::TokenTree::cast(parent.clone())
5656
.and_then(|tt| tt.parent_meta())
5757
.and_then(|meta| meta.parent_attr());
58-
if let Some(_) = attr {
59-
return sema.resolve_derive_ident(&ident).map(Into::into).into_iter().collect();
58+
if let Some(attr) = attr {
59+
return sema
60+
.resolve_derive_ident(&attr, &ident)
61+
.map(Into::into)
62+
.into_iter()
63+
.collect();
6064
}
6165
}
6266
Self::from_node(sema, &parent)

0 commit comments

Comments
 (0)