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

Problem with declarative macros #104

Closed
davidli2010 opened this issue Jun 8, 2020 · 3 comments · Fixed by #105
Closed

Problem with declarative macros #104

davidli2010 opened this issue Jun 8, 2020 · 3 comments · Fixed by #105

Comments

@davidli2010
Copy link

Hello there. I have problem with declarative macros. The code is simplified as below:

use async_trait::async_trait;

#[async_trait]
trait T1 {
    async fn id(&self) -> i32;
}

macro_rules! impl_t1 {
    ($ty: ty, $id: expr) => {
        #[async_trait]
        impl T1 for $ty {
            async fn id(&self) -> i32 {
                $id
            }
        }
    };
}

struct Foo;

impl_t1!(Foo, 1);

fn main() {}

rust compiler generates an error:

error[E0424]: expected value, found module `self`
  --> src/main.rs:10:9
   |
1  | / use async_trait::async_trait;
2  | |
3  | | #[async_trait]
4  | | trait T1 {
...  |
9  | |     ($ty: ty, $id: expr) => {
10 | |         #[async_trait]
   | |         ^^^^^^^^^^^^^-
   | |_________|____________|
   |           |            this function doesn't have a `self` parameter
   |           `self` value is a keyword only available in methods with a `self` parameter
...
21 |   impl_t1!(Foo, 1);
   |   ----------------- in this macro invocation
   |
   = note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to previous error

For more information about this error, try `rustc --explain E0424`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.
@dtolnay
Copy link
Owner

dtolnay commented Jun 8, 2020

This is a compiler bug (rust-lang/rust#43081). You can work around it by writing the decl macro as:

macro_rules! impl_t1 {
    ($ty:tt, $($id:tt)*) => {
        #[async_trait]
        impl T1 for $ty {
            async fn id(&self) -> i32 {
                $($id)*
            }
        }
    };
}

@taiki-e
Copy link
Contributor

taiki-e commented Jun 8, 2020

This will be fixed in #105.

@davidli2010
Copy link
Author

This is a compiler bug (rust-lang/rust#43081). You can work around it by writing the decl macro as:

macro_rules! impl_t1 {
    ($ty:tt, $($id:tt)*) => {
        #[async_trait]
        impl T1 for $ty {
            async fn id(&self) -> i32 {
                $($id)*
            }
        }
    };
}

It works. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants