Skip to content

Commit 0fee14b

Browse files
committed
When descending tokens don't bail on failed macro call expansions
1 parent 2aee17e commit 0fee14b

File tree

1 file changed

+57
-49
lines changed

1 file changed

+57
-49
lines changed

crates/hir/src/semantics.rs

+57-49
Original file line numberDiff line numberDiff line change
@@ -467,65 +467,73 @@ impl<'db> SemanticsImpl<'db> {
467467
let mut queue = vec![InFile::new(sa.file_id, token)];
468468
let mut cache = self.expansion_info_cache.borrow_mut();
469469
let mut res = smallvec![];
470+
// Remap the next token in the queue into a macro call its in, if it is not being remapped
471+
// either due to not being in a macro-call or because its unused push it into the result vec,
472+
// otherwise push the remapped tokens back into the queue as they can potentially be remapped again.
470473
while let Some(token) = queue.pop() {
471474
self.db.unwind_if_cancelled();
472475

473476
let was_not_remapped = (|| {
474477
for node in token.value.ancestors() {
475-
match_ast! {
476-
match node {
477-
ast::MacroCall(macro_call) => {
478-
let tt = macro_call.token_tree()?;
479-
let l_delim = match tt.left_delimiter_token() {
480-
Some(it) => it.text_range().end(),
481-
None => tt.syntax().text_range().start()
482-
};
483-
let r_delim = match tt.right_delimiter_token() {
484-
Some(it) => it.text_range().start(),
485-
None => tt.syntax().text_range().end()
486-
};
487-
if !TextRange::new(l_delim, r_delim).contains_range(token.value.text_range()) {
488-
return None;
489-
}
490-
let file_id = sa.expand(self.db, token.with_value(&macro_call))?;
491-
let tokens = cache
492-
.entry(file_id)
493-
.or_insert_with(|| file_id.expansion_info(self.db.upcast()))
494-
.as_ref()?
495-
.map_token_down(self.db.upcast(), None, token.as_ref())?;
496-
497-
let len = queue.len();
498-
queue.extend(tokens.inspect(|token| {
499-
if let Some(parent) = token.value.parent() {
500-
self.cache(find_root(&parent), token.file_id);
501-
}
502-
}));
503-
return (queue.len() != len).then(|| ());
504-
},
505-
ast::Item(item) => {
506-
if let Some(call_id) = self.with_ctx(|ctx| ctx.item_to_macro_call(token.with_value(item.clone()))) {
507-
let file_id = call_id.as_file();
508-
let tokens = cache
509-
.entry(file_id)
510-
.or_insert_with(|| file_id.expansion_info(self.db.upcast()))
511-
.as_ref()?
512-
.map_token_down(self.db.upcast(), Some(item), token.as_ref())?;
513-
514-
let len = queue.len();
515-
queue.extend(tokens.inspect(|token| {
516-
if let Some(parent) = token.value.parent() {
517-
self.cache(find_root(&parent), token.file_id);
518-
}
519-
}));
520-
return (queue.len() != len).then(|| ());
478+
if let Some(macro_call) = ast::MacroCall::cast(node.clone()) {
479+
let tt = match macro_call.token_tree() {
480+
Some(tt) => tt,
481+
None => continue,
482+
};
483+
let l_delim = match tt.left_delimiter_token() {
484+
Some(it) => it.text_range().end(),
485+
None => tt.syntax().text_range().start(),
486+
};
487+
let r_delim = match tt.right_delimiter_token() {
488+
Some(it) => it.text_range().start(),
489+
None => tt.syntax().text_range().end(),
490+
};
491+
if !TextRange::new(l_delim, r_delim)
492+
.contains_range(token.value.text_range())
493+
{
494+
continue;
495+
}
496+
let file_id = match sa.expand(self.db, token.with_value(&macro_call)) {
497+
Some(file_id) => file_id,
498+
None => continue,
499+
};
500+
let tokens = cache
501+
.entry(file_id)
502+
.or_insert_with(|| file_id.expansion_info(self.db.upcast()))
503+
.as_ref()?
504+
.map_token_down(self.db.upcast(), None, token.as_ref())?;
505+
506+
let len = queue.len();
507+
queue.extend(tokens.inspect(|token| {
508+
if let Some(parent) = token.value.parent() {
509+
self.cache(find_root(&parent), token.file_id);
510+
}
511+
}));
512+
return (queue.len() != len).then(|| ());
513+
} else if let Some(item) = ast::Item::cast(node.clone()) {
514+
if let Some(call_id) = self
515+
.with_ctx(|ctx| ctx.item_to_macro_call(token.with_value(item.clone())))
516+
{
517+
let file_id = call_id.as_file();
518+
let tokens = cache
519+
.entry(file_id)
520+
.or_insert_with(|| file_id.expansion_info(self.db.upcast()))
521+
.as_ref()?
522+
.map_token_down(self.db.upcast(), Some(item), token.as_ref())?;
523+
524+
let len = queue.len();
525+
queue.extend(tokens.inspect(|token| {
526+
if let Some(parent) = token.value.parent() {
527+
self.cache(find_root(&parent), token.file_id);
521528
}
522-
},
523-
_ => {}
529+
}));
530+
return (queue.len() != len).then(|| ());
524531
}
525532
}
526533
}
527534
None
528-
})().is_none();
535+
})()
536+
.is_none();
529537
if was_not_remapped {
530538
res.push(token.value)
531539
}

0 commit comments

Comments
 (0)