Как получить содержимое модуля, передаваемого внутреннему атрибуту макроса? - PullRequest
0 голосов
/ 09 февраля 2020

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

#[proc_macro_attribute]
pub fn hello(attr: TokenStream, item: TokenStream) -> TokenStream {
  println!("attr: {}", attr);
  println!("item: {}", item);
  item
}

, затем я применяю этот макрос pro c к не встроенному модулю:

// In file some_mod.rs
#![hello]

fn foo() {}
fn bar() {}

Выходные данные компилятор указывает, что элемент, передаваемый в pro c macro hello, равен mod some_mod; без каких-либо элементов в модуле. Однако я хочу внести некоторые изменения в содержание модуля some_mod.

Я выяснил, что встроенный модуль работает:

mod some_mod {
  #![hello]
  fn foo() { }
  fo bar() { }
}

Элемент, переданный моему макросу c, равен mod some_mod { fn foo() { } fn bar() { } }.
Но я буду использовать свой профи c макрос в сложной иерархии модулей, я не хочу помещать все эти модули в один файл.

Есть ли способ заставить мой pro c макрос получить содержимое не встроенного модуля

1 Ответ

0 голосов
/ 12 февраля 2020

Проблема, которую вы описываете, связана с тем, что использование процедурных макросов в положении внутренних атрибутов в настоящее время нестабильно. Уже около 1,5 лет существует проблема отслеживания для этой проблемы, и в этом комментарии явно упоминается проблема, с которой вы сталкиваетесь в настоящее время, когда применение макроса к встроенному модулю дает результаты, отличные от применения это к файловому модулю.

Насколько я знаю, в настоящее время нет готового решения этой проблемы.

В качестве альтернативы, так как вы по сути только модифицируете поток токенов файла, вы можете попытаться подключить вашу программу через build.rs к процессу компиляции (вы можете загрузить любые библиотеки, которые вы хотите для процесса сборки), но это будет включать ручное просеивание всех файлов и необходимость создания новых файлов из входных токенов потоки на лету. К сожалению, я не могу - в настоящее время - не думать ни о каком лучшем варианте, если вам действительно нужен макрос, чтобы взять весь модуль в качестве входных данных.

...