proc_macro_attribute 函数中是否有一致的编译上下文?
Is there a consistent compilation context inside a proc_macro_attribute function?
举个例子:
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
}
虽然处理的订单属性可能不同,但对于以下情况每次最终计数是否相同:
- 增量建筑
- 注册表 crate 和本地 crate 共享相同的 proc_macro 库和版本
- 编译器内部并行性
一个实际用例(尤其是我的用例)正在生成一个编译时伪静态变量内存布局,它将在静态链接的可执行文件中的多个内存管理器中重复使用。
虽然有些事情可能适用于当前的实现,但过程宏不应使用全局变量并期望它们在调用之间保留。
目前没有官方机制来存储过程宏调用之间的状态。
问题 “Crate local state for procedural macros?” 提到了以下几点:
- Proc 宏可能不会在每次编译时 运行,例如,如果增量编译打开并且它们位于干净的模块中
- 无法保证排序——如果
do_it!
需要来自所有 config!
次调用的数据,那就有问题了。
- 正确支持此功能意味着添加新的 API
举个例子:
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
}
虽然处理的订单属性可能不同,但对于以下情况每次最终计数是否相同:
- 增量建筑
- 注册表 crate 和本地 crate 共享相同的 proc_macro 库和版本
- 编译器内部并行性
一个实际用例(尤其是我的用例)正在生成一个编译时伪静态变量内存布局,它将在静态链接的可执行文件中的多个内存管理器中重复使用。
虽然有些事情可能适用于当前的实现,但过程宏不应使用全局变量并期望它们在调用之间保留。
目前没有官方机制来存储过程宏调用之间的状态。
问题 “Crate local state for procedural macros?” 提到了以下几点:
- Proc 宏可能不会在每次编译时 运行,例如,如果增量编译打开并且它们位于干净的模块中
- 无法保证排序——如果
do_it!
需要来自所有config!
次调用的数据,那就有问题了。 - 正确支持此功能意味着添加新的 API