Skip to content

Commit 820ecdd

Browse files
committed
Fix runnables not seeing test and bench attributes
1 parent 45d7f30 commit 820ecdd

File tree

3 files changed

+42
-18
lines changed

3 files changed

+42
-18
lines changed

crates/hir_expand/src/db.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,12 @@ impl TokenExpander {
5454
TokenExpander::MacroDef { mac, .. } => mac.expand(tt),
5555
TokenExpander::Builtin(it) => it.expand(db, id, tt),
5656
// FIXME switch these to ExpandResult as well
57-
TokenExpander::BuiltinAttr(it) => {
58-
let macro_arg = match db.macro_arg(id) {
59-
Some(it) => it,
60-
None => {
61-
return mbe::ExpandResult::only_err(
62-
mbe::ExpandError::Other("No item argument for attribute".to_string())
63-
.into(),
64-
);
65-
}
66-
};
67-
it.expand(db, id, tt, &macro_arg.0).into()
68-
}
57+
TokenExpander::BuiltinAttr(it) => match db.macro_arg(id) {
58+
Some(macro_arg) => it.expand(db, id, tt, &macro_arg.0).into(),
59+
None => mbe::ExpandResult::only_err(
60+
mbe::ExpandError::Other("No item argument for attribute".to_string()).into(),
61+
),
62+
},
6963
TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(),
7064
TokenExpander::ProcMacro(_) => {
7165
// We store the result in salsa db to prevent non-deterministic behavior in

crates/hir_expand/src/lib.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,28 @@ impl<N: AstNode> InFile<N> {
547547
pub fn syntax(&self) -> InFile<&SyntaxNode> {
548548
self.with_value(self.value.syntax())
549549
}
550+
551+
pub fn nodes_with_attributes<'db>(
552+
self,
553+
db: &'db dyn db::AstDatabase,
554+
) -> impl Iterator<Item = InFile<N>> + 'db
555+
where
556+
N: 'db,
557+
{
558+
std::iter::successors(Some(self), move |node| {
559+
let InFile { file_id, value } = node.file_id.call_node(db)?;
560+
N::cast(value).map(|n| InFile::new(file_id, n))
561+
})
562+
}
563+
564+
pub fn node_with_attributes(self, db: &dyn db::AstDatabase) -> InFile<N> {
565+
std::iter::successors(Some(self), move |node| {
566+
let InFile { file_id, value } = node.file_id.call_node(db)?;
567+
N::cast(value).map(|n| InFile::new(file_id, n))
568+
})
569+
.last()
570+
.unwrap()
571+
}
550572
}
551573

552574
/// Given a `MacroCallId`, return what `FragmentKind` it belongs to.

crates/ide/src/runnables.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -232,22 +232,27 @@ fn find_related_tests(
232232
let functions = refs.iter().filter_map(|(range, _)| {
233233
let token = file.token_at_offset(range.start()).next()?;
234234
let token = sema.descend_into_macros(token);
235-
token.ancestors().find_map(ast::Fn::cast)
235+
// FIXME: This is the wrong file_id
236+
token
237+
.ancestors()
238+
.find_map(ast::Fn::cast)
239+
.map(|f| hir::InFile::new(file_id.into(), f))
236240
});
237241

238242
for fn_def in functions {
239-
if let Some(runnable) = as_test_runnable(sema, &fn_def) {
243+
// #[test/bench] expands to just the item causing us to lose the attribute, so recover them by going out of the attribute
244+
let fn_def = fn_def.node_with_attributes(sema.db);
245+
if let Some(runnable) = as_test_runnable(sema, &fn_def.value) {
240246
// direct test
241247
tests.insert(runnable);
242-
} else if let Some(module) = parent_test_module(sema, &fn_def) {
248+
} else if let Some(module) = parent_test_module(sema, &fn_def.value) {
243249
// indirect test
244-
find_related_tests_in_module(sema, &fn_def, &module, tests);
250+
find_related_tests_in_module(sema, &fn_def.value, &module, tests);
245251
}
246252
}
247253
}
248254
}
249255
}
250-
251256
fn find_related_tests_in_module(
252257
sema: &Semantics<RootDatabase>,
253258
fn_def: &ast::Fn,
@@ -292,7 +297,8 @@ fn parent_test_module(sema: &Semantics<RootDatabase>, fn_def: &ast::Fn) -> Optio
292297
}
293298

294299
pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> {
295-
let func = def.source(sema.db)?;
300+
// #[test/bench] expands to just the item causing us to lose the attribute, so recover them by going out of the attribute
301+
let func = def.source(sema.db)?.node_with_attributes(sema.db);
296302
let name_string = def.name(sema.db).to_string();
297303

298304
let root = def.module(sema.db).krate().root_module(sema.db);
@@ -499,6 +505,8 @@ fn has_test_function_or_multiple_test_submodules(
499505
match item {
500506
hir::ModuleDef::Function(f) => {
501507
if let Some(it) = f.source(sema.db) {
508+
// #[test/bench] expands to just the item causing us to lose the attribute, so recover them by going out of the attribute
509+
let it = it.node_with_attributes(sema.db);
502510
if test_related_attribute(&it.value).is_some() {
503511
return true;
504512
}

0 commit comments

Comments
 (0)