Skip to content

Commit 44b0fe8

Browse files
committed
cleanup
1 parent aeb5d64 commit 44b0fe8

File tree

2 files changed

+49
-32
lines changed

2 files changed

+49
-32
lines changed

crates/hir/src/semantics.rs

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod source_to_def;
55
use std::{cell::RefCell, fmt};
66

77
use base_db::{FileId, FileRange};
8+
use either::Either;
89
use hir_def::{
910
body,
1011
resolver::{self, HasResolver, Resolver, TypeNs},
@@ -909,42 +910,54 @@ impl<'db> SemanticsImpl<'db> {
909910
return None;
910911
}
911912

912-
let attr_def =
913-
ast::Attr::to_def(self, self.find_file(attr.syntax()).with_value(attr.clone()))?;
914-
915-
let mut derive_paths = attr_def.parse_path_comma_token_tree()?;
916-
let derives = self.resolve_derive_macro(&attr)?;
913+
let file = self.find_file(attr.syntax());
914+
let adt = attr.syntax().parent().and_then(ast::Adt::cast)?;
917915

918-
let derive_idx = tt
919-
.syntax()
920-
.children_with_tokens()
921-
.filter_map(SyntaxElement::into_token)
922-
.take_while(|tok| tok != syntax)
923-
.filter(|t| t.kind() == T![,])
924-
.count();
925-
let path_segment_idx = syntax
926-
.siblings_with_tokens(Direction::Prev)
927-
.filter_map(SyntaxElement::into_token)
928-
.take_while(|tok| matches!(tok.kind(), T![:] | T![ident]))
929-
.filter(|tok| tok.kind() == T![ident])
930-
.count();
931-
932-
let mut mod_path = derive_paths.nth(derive_idx)?;
933-
934-
if path_segment_idx < mod_path.len() {
935-
// the path for the given ident is a qualifier, resolve to module if possible
936-
while path_segment_idx < mod_path.len() {
937-
mod_path.pop_segment();
916+
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()))?;
920+
921+
let mut derive_paths = attr_def.parse_path_comma_token_tree()?;
922+
923+
let derive_idx = tt
924+
.syntax()
925+
.children_with_tokens()
926+
.filter_map(SyntaxElement::into_token)
927+
.take_while(|tok| tok != syntax)
928+
.filter(|t| t.kind() == T![,])
929+
.count();
930+
let path_segment_idx = syntax
931+
.siblings_with_tokens(Direction::Prev)
932+
.filter_map(SyntaxElement::into_token)
933+
.take_while(|tok| matches!(tok.kind(), T![:] | T![ident]))
934+
.filter(|tok| tok.kind() == T![ident])
935+
.count();
936+
937+
let mut mod_path = derive_paths.nth(derive_idx)?;
938+
939+
if path_segment_idx < mod_path.len() {
940+
// the path for the given ident is a qualifier, resolve to module if possible
941+
while path_segment_idx < mod_path.len() {
942+
mod_path.pop_segment();
943+
}
944+
Some(Either::Left(mod_path))
945+
} else {
946+
// otherwise fetch the derive
947+
Some(Either::Right(derives[derive_idx]))
938948
}
939-
resolve_hir_path(
949+
})?;
950+
951+
match res {
952+
Either::Left(path) => resolve_hir_path(
940953
self.db,
941954
&self.scope(attr.syntax()).resolver,
942-
&Path::from_known_path(mod_path, []),
955+
&Path::from_known_path(path, []),
943956
)
944-
.filter(|res| matches!(res, PathResolution::Def(ModuleDef::Module(_))))
945-
} else {
946-
// otherwise fetch the derive
947-
derives.get(derive_idx)?.map(PathResolution::Macro)
957+
.filter(|res| matches!(res, PathResolution::Def(ModuleDef::Module(_)))),
958+
Either::Right(derive) => derive
959+
.map(|call| MacroDef { id: self.db.lookup_intern_macro_call(call).def })
960+
.map(PathResolution::Macro),
948961
}
949962
}
950963

crates/hir_def/src/attr.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,11 @@ impl Attr {
746746
})
747747
.collect::<Vec<_>>();
748748

749-
return Some(paths.into_iter());
749+
Some(paths.into_iter())
750+
}
751+
752+
pub fn path(&self) -> &ModPath {
753+
&self.path
750754
}
751755

752756
pub fn string_value(&self) -> Option<&SmolStr> {

0 commit comments

Comments
 (0)