Есть ли согласованный контекст компиляции внутри функции proc_macro_attribute?

Вот пример:

      static COUNT: AtomicUsize = AtomicUsize::new(0);

#[proc_macro_attribute]
pub fn count_usages(_attr: TokenStream, item: TokenStream) -> TokenStream {
    let c = COUNT.fetch_add(1, Ordering::AcqRel);
    println!("Do stuff with c: {}", c);
    item
}

Хотя обрабатываемые атрибуты порядка могут отличаться, будет ли окончательный счет каждый раз одинаковым для таких случаев, как:

  • Дополнительное строительство
  • Ящики реестра и локальные ящики с одной и той же библиотекой и версией proc_macro
  • Внутренний параллелизм компилятора

Практический вариант использования (в частности, мой) - создание макета памяти псевдостатических переменных во время компиляции, который будет повторно использоваться в нескольких диспетчерах памяти в статически связанном исполняемом файле.

1 ответ

Решение

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

В настоящее время нет официального механизма для хранения состояния между вызовами процедурного макроса.

Вопрос «Создать локальное состояние для процедурных макросов?»упоминает некоторые из этих моментов:

  • Макросы Proc могут не запускаться при каждой компиляции, например, если инкрементная компиляция включена и они находятся в чистом модуле.
  • Нет гарантии заказа - если do_it! нужны данные со всех config! заклинания, это проблема.
  • Правильная поддержка этой функции означает добавление нового API.
Другие вопросы по тегам