Почему proc-макросы должны быть определены в proc-macro crate?
Я пытался создать производный макрос для моей черты, чтобы упростить некоторые вещи.
Я столкнулся с некоторыми проблемами:
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 ответ
Процедурные макросы в корне отличаются от обычных зависимостей в вашем коде. Нормальная библиотека просто связана с вашим кодом, но процедурный макрос на самом деле является плагином компилятора.
Рассмотрим случай кросс-компиляции: вы работаете на машине с Linux, но создаете проект WASM.
- Обычный ящик будет кросс-скомпилирован, генерировать код WASM и связываться с остальными ящиками.
- Ящик proc-macro должен быть скомпилирован нативно, в данном случае с кодом Linux, связан с текущей средой выполнения компилятора (стабильный, бета, ночной) и загружен самим компилятором при компиляции ящиков, где он фактически используется. Он не будет связан с остальными ящиками (другая архитектура!).
А поскольку поток компиляции отличается, тип ящика также должен быть другим, поэтому proc_macro=true
необходим.
Об этом ограничении:
proc-macro
типы ящиков не могут экспортировать какие-либо предметы, кроме функций, помеченных#[proc_macro_derive]
Итак, поскольку ящик proc-macro загружается компилятором, а не связан с остальными вашими ящиками, любой код не-proc-macro, который вы экспортируете из этого ящика, будет бесполезным.
Обратите внимание, что сообщение об ошибке является неточным, так как вы также можете экспортировать тег функции с помощью #[proc_macro]
,
И об этом другом ограничении:
функции с тегами
#[proc_macro_derive]
должен в настоящее время проживать в корне ящика
Добавление proc_macro
или же proc_macro_derive
элементы во вложенных модулях в настоящее время не поддерживаются и, похоже, не особенно полезны, имхо.