Skip to content

Commit f22eea9

Browse files
bors[bot]Veykril
andauthored
Merge #10372
10372: minor: Cleanup descend_into_macros_impl r=Veykril a=Veykril bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents ffcaceb + 75660ff commit f22eea9

File tree

1 file changed

+43
-36
lines changed

1 file changed

+43
-36
lines changed

crates/hir/src/semantics.rs

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -544,38 +544,54 @@ impl<'db> SemanticsImpl<'db> {
544544
let sa = self.analyze(&parent);
545545
let mut queue = vec![InFile::new(sa.file_id, token)];
546546
let mut cache = self.expansion_info_cache.borrow_mut();
547+
548+
let mut process_expansion_for_token =
549+
|queue: &mut Vec<_>, file_id, item, token: InFile<&_>| {
550+
let mapped_tokens = cache
551+
.entry(file_id)
552+
.or_insert_with(|| file_id.expansion_info(self.db.upcast()))
553+
.as_ref()?
554+
.map_token_down(self.db.upcast(), item, token)?;
555+
556+
let len = queue.len();
557+
// requeue the tokens we got from mapping our current token down
558+
queue.extend(mapped_tokens.inspect(|token| {
559+
if let Some(parent) = token.value.parent() {
560+
self.cache(find_root(&parent), token.file_id);
561+
}
562+
}));
563+
// if the length changed we have found a mapping for the token
564+
(queue.len() != len).then(|| ())
565+
};
566+
547567
// Remap the next token in the queue into a macro call its in, if it is not being remapped
548568
// either due to not being in a macro-call or because its unused push it into the result vec,
549569
// otherwise push the remapped tokens back into the queue as they can potentially be remapped again.
550570
while let Some(token) = queue.pop() {
551571
self.db.unwind_if_cancelled();
552572
let was_not_remapped = (|| {
553-
if let Some((call_id, item)) = token
554-
.value
555-
.ancestors()
556-
.filter_map(ast::Item::cast)
557-
.filter_map(|item| {
558-
self.with_ctx(|ctx| ctx.item_to_macro_call(token.with_value(item.clone())))
559-
.zip(Some(item))
560-
})
561-
.last()
562-
{
573+
// are we inside an attribute macro call
574+
let containing_attribute_macro_call = self.with_ctx(|ctx| {
575+
token
576+
.value
577+
.ancestors()
578+
.filter_map(ast::Item::cast)
579+
.filter_map(|item| {
580+
Some((ctx.item_to_macro_call(token.with_value(item.clone()))?, item))
581+
})
582+
.last()
583+
});
584+
if let Some((call_id, item)) = containing_attribute_macro_call {
563585
let file_id = call_id.as_file();
564-
let tokens = cache
565-
.entry(file_id)
566-
.or_insert_with(|| file_id.expansion_info(self.db.upcast()))
567-
.as_ref()?
568-
.map_token_down(self.db.upcast(), Some(item), token.as_ref())?;
569-
570-
let len = queue.len();
571-
queue.extend(tokens.inspect(|token| {
572-
if let Some(parent) = token.value.parent() {
573-
self.cache(find_root(&parent), token.file_id);
574-
}
575-
}));
576-
return (queue.len() != len).then(|| ());
586+
return process_expansion_for_token(
587+
&mut queue,
588+
file_id,
589+
Some(item),
590+
token.as_ref(),
591+
);
577592
}
578593

594+
// or are we inside a function-like macro call
579595
if let Some(macro_call) = token.value.ancestors().find_map(ast::MacroCall::cast) {
580596
let tt = macro_call.token_tree()?;
581597
let l_delim = match tt.left_delimiter_token() {
@@ -589,21 +605,12 @@ impl<'db> SemanticsImpl<'db> {
589605
if !TextRange::new(l_delim, r_delim).contains_range(token.value.text_range()) {
590606
return None;
591607
}
608+
592609
let file_id = sa.expand(self.db, token.with_value(&macro_call))?;
593-
let tokens = cache
594-
.entry(file_id)
595-
.or_insert_with(|| file_id.expansion_info(self.db.upcast()))
596-
.as_ref()?
597-
.map_token_down(self.db.upcast(), None, token.as_ref())?;
598-
599-
let len = queue.len();
600-
queue.extend(tokens.inspect(|token| {
601-
if let Some(parent) = token.value.parent() {
602-
self.cache(find_root(&parent), token.file_id);
603-
}
604-
}));
605-
return (queue.len() != len).then(|| ());
610+
return process_expansion_for_token(&mut queue, file_id, None, token.as_ref());
606611
}
612+
613+
// outside of a macro invocation so this is a "final" token
607614
None
608615
})()
609616
.is_none();

0 commit comments

Comments
 (0)