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

self parameter gets expanded as module self in macro #46

Closed
Marwes opened this issue Oct 28, 2019 · 3 comments · Fixed by #105
Closed

self parameter gets expanded as module self in macro #46

Marwes opened this issue Oct 28, 2019 · 3 comments · Fixed by #105

Comments

@Marwes
Copy link
Contributor

Marwes commented Oct 28, 2019

Minimal reproduction

macro_rules! implement_commands {
    (
        $tyargs:ident : $ty:ident
    ) => {
        #[async_trait]
        pub trait AsyncCommands: Sized {
            async fn f<$tyargs: $ty>(&mut self, x: $tyargs) {
                self.f(x).await
            }
        }
    };
}

implement_commands! { K: Send }
error[E0424]: expected value, found module `self`
   --> tests/test.rs:434:9
    |
434 |         #[async_trait]
    |         ^^^^^^^^^^^^^^ `self` value is a keyword only available in methods with `self` parameter
...
443 | implement_commands! { K: Send }
    | ------------------------------- in this macro invocation
@dtolnay
Copy link
Owner

dtolnay commented Oct 28, 2019

Thanks! Looks like some kind of span issue because the code we are emitting does work by itself. I will take a look in the next couple days (but I would gladly accept a PR to fix this if you get to it first).

Here is the code we currently expand this to:

pub trait AsyncCommands: Sized {
    fn f<'life0, 'async_trait, K: Send>(
        &'life0 mut self,
        x: K,
    ) -> ::core::pin::Pin<
        Box<dyn ::core::future::Future<Output = ()> + ::core::marker::Send + 'async_trait>,
    >
    where
        K: 'async_trait,
        'life0: 'async_trait,
        Self: ::core::marker::Send + 'async_trait,
    {
        #[allow(clippy::used_underscore_binding)]
        async fn __f<K: Send, AsyncTrait: ?Sized + AsyncCommands + ::core::marker::Send>(
            _self: &mut AsyncTrait,
            x: K,
        ) {
            _self.f(x).await
        }
        Box::pin(__f::<K, Self>(self, x))
    }
}

@dtolnay
Copy link
Owner

dtolnay commented Oct 29, 2019

This is being caused by rust-lang/rust#43081 which means unfortunately there is nothing we can do about it in async-trait. The compiler loses all span information on the macro input before it's even passed in to async-trait, which makes self in the input meaningless.

TokenStream [
    Ident {
        ident: "pub",
        span: #0 bytes(0..0),
    },
    Ident {
        ident: "trait",
        span: #0 bytes(0..0),
    },
    Ident {
        ident: "AsyncCommands",
        span: #0 bytes(0..0),
    },
    Punct {
        ch: ':',
        spacing: Alone,
        span: #0 bytes(0..0),
    },
    Ident {
        ident: "Sized",
        span: #0 bytes(0..0),
    },
    Group {

As a workaround, for some reason the compiler doesn't mess up if you use $:tt in the macro variables instead.

($tyargs:tt : $ty:tt) => {

@tyranron
Copy link
Contributor

tyranron commented Feb 5, 2020

@dtolnay is this a compiler bug which will be fixed eventually, or intended compiler behavior?

Repository owner locked and limited conversation to collaborators Apr 25, 2020
Repository owner deleted a comment from fundon Apr 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants