Невозможно вызвать функциональный процедурный макрос: не может быть расширен до операторов

Я пытаюсь разобраться в функциональных процедурных макросах и борюсь с основами.

Для начала я попытался создать макрос, который просто печатает все токены и ничего не делает:

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 внутри макрос работает

Это, вероятно, просто некоторая лень в реализации - макрос охотно оценивается, а затем проверяется функциональный шлюз позже. Хотя в настоящий момент это может быть неэффективно, после полной стабилизации функции это не имеет значения.

Другие вопросы по тегам