Как использовать пользовательский атрибут пространства-имени для макроса имен вместо типа внутри? - PullRequest
0 голосов
/ 27 февраля 2019

Я хотел бы создать пользовательский макрос для производного, который использует новый синтаксис пространства имен: example::attr.Я смог заставить это работать с атрибутами в типе (например, в структурном поле или варианте enum), но не при применении к самому типу.

src / main.rs

use repro_derive::Example;

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

fn main() {}

Сам процедурный макрос ничего не делает, кроме как объявить, что example::attr является допустимым атрибутом.

repro-производный / 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()
}

Компиляция выходов:

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`

Переключение на форму атрибута без пространства имен (example_attr) работает нормально.


Я использую Rust 1.32.0.Макет проекта:

$ 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-производное / Cargo.toml

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

[lib]
proc-macro = true

[dependencies]

1 Ответ

0 голосов
/ 27 февраля 2019

Пространство имен, объявленное в атрибуте proc_macro_derive, полностью игнорируется , и это известная ошибка .Из-за этой ошибки следующий код может быть скомпилирован, хотя это не должно быть.

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

До тех пор, пока ошибка не будет исправлена, вы должны продолжать использовать форму без пространства имен (example_attr).

Кроме того, согласно этому отчету об ошибках, начиная с Rust 1.33.0, существует нет способа добиться того, что OP хочет через proc-макросы, и как разрешить #[example::attr] работатьвсе еще в разработке.

...