2

I'd like to create a custom derive macro that uses the new namespaced attribute syntax: example::attr. I've been able to get this to work with attributes within the type (on a struct field or an enum variant, for example), but not when applied to the type itself.

src/main.rs

use repro_derive::Example;

#[derive(Example)]
#[example::attr]     // Does not work
struct Demo {
    #[example::attr] // Works
    field: i32,
}

fn main() {}

The procedural macro itself does nothing, other than to declare that example::attr is a valid attribute.

repro-derive/src/lib.rs

extern crate proc_macro;

use proc_macro::TokenStream;

#[proc_macro_derive(Example, attributes(example::attr))]
pub fn example_derive(_input: TokenStream) -> TokenStream {
    TokenStream::new()
}

Compiling yields:

error[E0433]: failed to resolve: use of undeclared type or module `example`
 --> src/main.rs:4:3
  |
4 | #[example::attr]
  |   ^^^^^^^ use of undeclared type or module `example`

Switching to a non-namespaced form of the attribute (example_attr) works fine.


I'm using Rust 1.32.0. The project layout is

$ tree
.
├── Cargo.lock
├── Cargo.toml
├── repro-derive
│   ├── Cargo.toml
│   └── src
│       └── lib.rs
└── src
    └── main.rs

Cargo.toml

$ cat Cargo.toml
[package]
name = "repro"
version = "0.1.0"
authors = ["Author"]
edition = "2018"

[dependencies]
repro-derive = { path = "repro-derive" }

repro-derive/Cargo.toml

[package]
name = "repro-derive"
version = "0.1.0"
authors = ["Author"]
edition = "2018"

[lib]
proc-macro = true

[dependencies]
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366

1 Answers1

2

The namespace declared in the proc_macro_derive attribute is entirely ignored, and this is a known bug. Because of this bug, the following code can be compiled, though it shouldn't be.

#[derive(Example)]
#[attr]             // Works (but shouldn't)
struct Demo {
    #[lolwut::attr] // Works (but shouldn't)
    field: i32,
}

Until the bug is fixed, you should keep using the non-namespaced form (example_attr).

Also, according to this bug report, as of Rust 1.33.0 there is no way to achieve what OP wants via proc-macros, and how to allow #[example::attr] to work is still under design.

kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005