Skip to content

Better diagnostics for proc macro attributes #102923

Closed
@afetisov

Description

Given the following code:

#[proc_macro]
pub fn mac() {}

#[proc_macro_attribute]
pub fn attrib() {}

#[proc_macro_derive(D)]
pub fn derive() {}

The current output is:

error[E0593]: function is expected to take 1 argument, but it takes 0 arguments
   --> mac/src/lib.rs:9:1
    |
9   | pub fn mac() {}
    | ------------^^^
    | |
    | expected function that takes 1 argument
    | takes 0 arguments
    |
note: required by a bound in `ProcMacro::bang`
   --> /home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/proc_macro/src/bridge/client.rs:506:22
    |
506 |         expand: impl Fn(crate::TokenStream) -> crate::TokenStream + Copy,
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProcMacro::bang`

error[E0593]: function is expected to take 2 arguments, but it takes 0 arguments
   --> mac/src/lib.rs:12:1
    |
12  | pub fn attrib() {}
    | -------------^^^
    | |
    | expected function that takes 2 arguments
    | takes 0 arguments
    |
note: required by a bound in `ProcMacro::attr`
   --> /home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/proc_macro/src/bridge/client.rs:499:22
    |
499 |         expand: impl Fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream + Copy,
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProcMacro::attr`

error[E0593]: function is expected to take 1 argument, but it takes 0 arguments
   --> mac/src/lib.rs:15:1
    |
15  | pub fn derive() {}
    | ---------------^^^
    | |
    | expected function that takes 1 argument
    | takes 0 arguments
    |
note: required by a bound in `ProcMacro::custom_derive`
   --> /home/user/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/proc_macro/src/bridge/client.rs:492:22
    |
492 |         expand: impl Fn(crate::TokenStream) -> crate::TokenStream + Copy,
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `ProcMacro::custom_derive`

The compiler knows the meaning of #[proc_macro*] attributes, so it could provide more helpful error messages. The ProcMacro::custom_derive etc types are not part of the API that the users normally work with, so listing them is unhelpful. Since the signatures of proc macro functions are fixed, the compiler can directly list them:

error[E0???]: function is expected to take 1 argument, but it takes 0 arguments
   --> mac/src/lib.rs:9:1
    |
9   | pub fn mac() {}
    | ----------^^^
    | |
    | functions annotated with `#[proc_macro]` must have the signature 
    |     `pub fn mac(item: TokenStream) -> TokenStream`

error[E0???]: function is expected to take 2 arguments, but it takes 0 arguments
   --> mac/src/lib.rs:12:1
    |
12  | pub fn attrib() {}
    | ----------^^^
    | |
    | functions annotated with `#[proc_macro_attribute]` must have the signature 
    |     `pub fn attrib(attr: TokenStream, item: TokenStream) -> TokenStream`

error[E0???]: function is expected to take 1 argument, but it takes 0 arguments
   --> mac/src/lib.rs:15:1
    |
15  | pub fn derive() {}
    | ----------^^^
    | |
    | functions annotated with `#[proc_macro_derive(..)]` must have the signature 
    |     `pub fn derive(item: TokenStream) -> TokenStream`

Note that the signature includes the function name and argument names, allowing the proper signature to be copy-pasted in code. This also disambiguates arguments for attribute proc macros, where there may be confusion w.r.t. order of arguments.

Activity

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

Metadata

Assignees

Labels

A-diagnosticsArea: Messages for errors, warnings, and lintsT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions