Бесконечная рекурсия в макросе Rust - PullRequest
0 голосов
/ 04 января 2019

Я сделал следующую ошибку в производном макросе в Rust:

extern crate proc_macro;

use crate::proc_macro::TokenStream;
use quote::quote;
use syn;

#[proc_macro_derive(DeserializeConfigurable)]
pub fn deserialize_configurable_derive(input: TokenStream) -> TokenStream {
    let ast: syn::DeriveInput = syn::parse(input).unwrap();
    let name = &ast.ident;
    let gen = quote! {
        impl<'de> Deserialize<'de> for #name {
            fn deserialize<D>(deserializer: D) -> Result<#name, D::Error>
            where
                D: Deserializer<'de>,
            {
                let config = <#name as Configurable>::Config::deserialize(deserializer)?;
                Ok(#name::from_config(config))
            }
        }
    };
    gen.into()
}

Цель состоит в том, чтобы предоставить конкретную общую реализацию для deserialize на основе другой черты, Configurable.

Однако, компилятор имеет следующую жалобу относительно моей цитаты:

достигнут предел рекурсии при расширении макроса stringify

Я не вижу здесь рекурсии. Я даже не использую stringify! Что здесь зовется в бесконечности?

1 Ответ

0 голосов
/ 04 января 2019

Попытка скомпилировать это локально приводит к полному сообщению об ошибке:

error: recursion limit reached while expanding the macro `stringify`
  --> src/lib.rs:13:15
   |
13 |       let gen = quote! {
   |  _______________^
14 | |         impl<'de> Deserialize<'de> for #name {
15 | |             fn deserialize<D>(deserializer: D) -> Result<#name, D::Error>
16 | |             where
...  |
22 | |         }
23 | |     };
   | |_____^
   |
   = help: consider adding a `#![recursion_limit="128"]` attribute to your crate
   = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)                                                                                                                                 

error: aborting due to previous error

Если в первой строке ящика указано следующее, ошибка исчезнет. Я предполагаю, что значение по умолчанию recursion_limit просто слишком мало для такого сложного макроса (который IMO не такой сложный). Я уверен, что есть веская причина, и я рад, что сообщение об ошибке содержало решение:

#![recursion_limit="128"]
...