Warning: unused attribute for function argument attribute

I am getting warning: unused attribute while trying to use function argument attributes.

The attribute is parsed with syn::parse::<syn::ItemFn>(input):

#[proc_macro_attribute]
pub fn test_attr(_args: TokenStream, input: TokenStream) -> TokenStream {
    let function_result = syn::parse::<syn::ItemFn>(input)
        .map_err(|error| error.span().unstable().error(error.to_string()))
        .map_err(|d| d.help(String::from("#[test_attr] can only be used on functions")));
    // ...
}

The function declaration itself is not very interesting:

#[test_attr]
pub fn test(#[foo] _bar: ()) {
    // why is `#[foo]` considered to be unused?
    // look at codegen/src/lib.rs for the `#[test_attr]` codegen implementation
    // which actually uses `#[foo]`
}

The full warning is:

warning: unused attribute
 --> lib\src\lib.rs:6:13
  |
6 | pub fn test(#[foo] _bar: ()) {
  |             ^^^^^^
  |
  = note: `#[warn(unused_attributes)]` on by default

I have created an example repo so you can test it yourself:

The compiler I am currently using is:

$ rustc --version --verbose
rustc 1.38.0-nightly (60960a260 2019-08-12)
binary: rustc
commit-hash: 60960a260f7b5c695fd0717311d72ce62dd4eb43
commit-date: 2019-08-12
host: x86_64-pc-windows-gnu
release: 1.38.0-nightly
LLVM version: 9.0

What am I doing wrong?

You can define 'helper' attributes like this for a derive macro, but that option doesn't seem to be available to attribute macros yet...

1 Like

The compiler warns about an attribute that it does not recognize and that the final user is therefore not using.

When writing proc-macro code, the compiler is not talking to you, it is talking to the programmer / end user, and you are acting as a proxy in between both parties. The usage of your proc-macro-attribute is that the user tells you #[foo], and you instead tell other stuff to the compiler.

The key here is in that instead: some classical attributes are auto-removed when handled as a proc_macro, but this is not the case of custom attributes at arbitrary places. It is then your job to remove these custom attributes so that the compiler does not end up seeing them.

2 Likes

Thanks, that was indeed my problem.
While what you said makes perfect sense, I still wish I wouldn't have to manually remove the attribute, but it's no big deal.