Compile error mixing declarative macros with #[tokio::test]
#3579
Open
Description
This is reproducible in the playground:
concrete_tests2
and concrete_tests3
compile whereas concrete_tests1
does not.
I'm producing a declarative macro that takes in an expr
that is meant to be a closure, and produces a #[tokio::test]
that invokes that closure. The compile error is:
error[E0618]: expected function, found `Concrete`
--> src/lib.rs:38:32
|
14 | $crate::test_suite::async_test($foo_factory()).await;
| -- call expression requires function
...
38 | crate::use_test_suite!( || crate::Concrete::default() );
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
The code (from the playground link above) is:
// /////////////////////////
// Define a trait Foo
// /////////////////////////
pub trait Foo{}
// /////////////////////////
// Define a test suite suitable for any implementator of Foo
// /////////////////////////
#[macro_export]
macro_rules! use_test_suite {
($foo_factory:expr) => {
#[tokio::test]
async fn async_test() {
$crate::test_suite::async_test($foo_factory()).await;
}
#[test]
fn sync_test() {
$crate::test_suite::sync_test($foo_factory());
}
}
}
pub mod test_suite {
pub async fn async_test(_foo: impl crate::Foo) -> u8 { 0 }
pub fn sync_test(_foo: impl crate::Foo) -> u8 { 0 }
}
// /////////////////////////
// Define an implementaion of Foo and test it
// /////////////////////////
#[derive(Default)]
struct Concrete;
impl Foo for Concrete {}
#[cfg(test)]
mod concrete_tests1 {
crate::use_test_suite!( || crate::Concrete::default() );
}
#[cfg(test)]
mod concrete_tests2 {
crate::use_test_suite!( (|| crate::Concrete::default()) );
}
#[cfg(test)]
mod concrete_tests3 {
crate::use_test_suite!( crate::Concrete::default );
}