Почему proc-макросы должны быть определены в proc-macro crate? - PullRequest
5 голосов
/ 22 июня 2019

Я пытался создать производный макрос для моей черты, чтобы упростить некоторые вещи.

Я столкнулся с некоторыми проблемами:

the `#[proc_macro_derive]` attribute is only usable with crates of the `proc-macro` crate type

и, после небольшого исправления proc-macro=true:

proc-macro` crate types cannot export any items other than functions tagged with `#[proc_macro_derive]` currently
functions tagged with `#[proc_macro_derive]` must currently reside in the root of the crate`

В чем причина такого поведения?

1 Ответ

8 голосов
/ 22 июня 2019

Процедурные макросы принципиально отличаются от обычных зависимостей в вашем коде.Обычная библиотека просто связана с вашим кодом, но процедурный макрос на самом деле является компилятором плагин .

Рассмотрим случай кросс-компиляции: вы работаете на машине с Linux, но собираетепроект WASM.

  • Обычный ящик будет кросс-скомпилирован, сгенерирован код WASM и связан с остальными ящиками.
  • Ящик proc-macro должен быть скомпилирован изначально,в данном случае это код Linux, связанный с текущей средой выполнения компилятора (стабильный, бета, ночной) и загружаемый самим компилятором при компиляции ящиков, где он фактически используется. not будет связан с остальными ящиками (другая архитектура!).

И поскольку поток компиляции отличается, тип ящика также должен быть другим, то естьпочему требуется proc_macro=true.

Об этом ограничении:

proc-macro типы ящиков не могут экспортировать любые элементы, кроме функций, помеченных #[proc_macro_derive]

Что ж, поскольку ящик proc-macro загружается компилятором, а не связан с остальными вашими ящиками, любой код non-proc-macro, который вы экспортируете из этого ящика, будет бесполезным.

Обратите внимание, чтосообщение об ошибке является неточным, так как вы также можете экспортировать тег функции с помощью #[proc_macro].

И об этом другом ограничении:

функции, отмеченные #[proc_macro_derive], должны в настоящее время находиться вкорень ящика

Добавление элементов proc_macro или proc_macro_derive во вложенные модули в настоящее время не поддерживается и не представляется особенно полезным, ИМХО.

...