Невозможно вызвать функциональный процедурный макрос: не может быть расширен до операторов
Я пытаюсь разобраться в функциональных процедурных макросах и борюсь с основами.
Для начала я попытался создать макрос, который просто печатает все токены и ничего не делает:
extern crate proc_macro;
extern crate syn;
use proc_macro::TokenStream;
#[proc_macro]
pub fn my_macro(input: TokenStream) -> TokenStream {
println!( "{:?}", input );
TokenStream::new()
}
Затем я попытался использовать его в другом двоичном файле:
extern crate rust_procmacro_test;
fn main() {
rust_procmacro_test::my_macro!( aaa );
}
Когда я делаю cargo build
Я получаю это:
Compiling rust_procmacro_test v0.1.0
Compiling procmacro_user v0.1.0
error[E0658]: procedural macros cannot be expanded to statements (see issue #54727)
--> src\main.rs:5:5
|
5 | rust_procmacro_test::my_macro!( aaa );
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TokenStream [Ident { ident: "aaa", span: #0 bytes(114..117) }]
error: aborting due to previous error
Это говорит мне, что это не может быть скомпилировано, но println
внутри макрос работает. Что происходит?
Вопрос № 54727 очень широкий, и я не уверен, как это связано с этим.
Я использую стабильный-i686-pc-windows-gnu, rustc 1.31.1 (b6c32da9b 2018-12-18).
1 ответ
Что происходит?
Хотя в стабильном Rust можно определить функциональный процедурный макрос, еще нельзя назвать его выражением / оператором. Это потому, что есть опасения по поводу того, как следует соблюдать гигиену. Существуют и другие местоположения, например, в позиции товара, где она доступна:
extern crate rust_procmacro_test;
rust_procmacro_test::my_macro!( aaa );
fn main() {}
но
println
внутри макрос работает
Это, вероятно, просто некоторая лень в реализации - макрос охотно оценивается, а затем проверяется функциональный шлюз позже. Хотя в настоящий момент это может быть неэффективно, после полной стабилизации функции это не имеет значения.