Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compile error mixing declarative macros with #[tokio::test] #3579

Open
incidental-complexity opened this issue Mar 4, 2021 · 4 comments
Open
Labels
A-tokio-macros Area: The tokio-macros crate C-bug Category: This is a bug.

Comments

@incidental-complexity
Copy link

This is reproducible in the playground:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=fb6d73cfb878547b438d8ec49431a4d2

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 );
}
@incidental-complexity incidental-complexity added C-bug Category: This is a bug. A-tokio Area: The main tokio crate labels Mar 4, 2021
@Darksonn Darksonn added A-tokio-macros Area: The tokio-macros crate and removed A-tokio Area: The main tokio crate labels Mar 4, 2021
@Darksonn
Copy link
Contributor

Darksonn commented Mar 4, 2021

I strongly doubt Tokio can do anything about this. You can fix it with an extra set of parenthesises.

#[tokio::test]
async fn async_test() {
    $crate::test_suite::async_test(($foo_factory)()).await;
}

@incidental-complexity
Copy link
Author

Cross posted with rust-lang

Kestrer added a commit to Kestrer/tokio that referenced this issue Mar 5, 2021
When user-generated token streams are returned from proc macros, all
none-delimited groups are flattened. This can cause compilation errors
as shown in the issue below. By instead passing the function body token
stream straight through from the input of the proc macro to its output,
it does not get deconstructed and reconstructed, and so the
none-delimited groups are not lost.

Fixes: tokio-rs#3579
Kestrer added a commit to Kestrer/tokio that referenced this issue Mar 5, 2021
When user-generated token streams are returned from proc macros, all
none-delimited groups are flattened. This can cause compilation errors
as shown in the issue below. By instead passing the function body token
stream straight through from the input of the proc macro to its output,
it does not get deconstructed and reconstructed, and so the
none-delimited groups are not lost.

Fixes: tokio-rs#3579
Kestrer added a commit to Kestrer/tokio that referenced this issue Mar 5, 2021
When user-generated token streams are returned from proc macros, all
none-delimited groups are flattened. This can cause compilation errors
as shown in the issue below. By instead passing the function body token
stream straight through from the input of the proc macro to its output,
it does not get deconstructed and reconstructed, and so the
none-delimited groups are not lost.

Fixes: tokio-rs#3579
@carllerche
Copy link
Member

Thoughts @taiki-e ?

@taiki-e taiki-e self-assigned this Mar 9, 2021
@taiki-e
Copy link
Member

taiki-e commented May 6, 2021

Looks like this is a regression introduced in Rust 1.49.0 (it works with all versions of 1.45 to 1.48.), see rust-lang/rust#82784 (comment) for more.

@taiki-e taiki-e removed their assignment May 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-tokio-macros Area: The tokio-macros crate C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants