Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Proc macros full path best practices
Procedural macros or code generation build scripts typically should produce context-independent outputs. In practice, this means that, as a rule of thumb, all name paths should be explicit and unambiguous, and they shouldn't rely on the "call site" context:
quote! {
let foo = ::std::option::Option::Some(bar);
};
This isn't an issue for small programs, but for complex code generation systems, manually managing full paths becomes challenging. At least in terms of maintenance. I've been working on such tasks for quite a long time, but I still haven't come up with a truly convenient solution.
What I usually do is maintain an independent module inside my codegen crate (proc macro or build script) where I put all external paths my program ever uses. Then I refer to this registry module throughout the crate.
// registry module:
pub(crate) struct Facade;
impl Facade {
pub(crate) fn option() -> TokenStream { quote!(::std::option::Option) }
pub(crate) fn deserialize() -> TokenStream { quote!(serde::de::Deserialize) }
}
// usage site:
fn codegen_smthng() -> TokenStream {
let face_option = Facade::option();
let face_de = Facade::deserialize();
quote!( let x = #face_option::Some(<y as #face_de>::deserialize()) )
}
This approach partially solves the maintenance problem: every time I need to change or refactor an external dependency, I check the registry module first. Plus, it makes my quote!
expressions more readable and less prone to typos. However, this approach isn't very convenient in other aspects. Namely, I have to access this "Facade" registry explicitly from almost every codegen function.
Another alternative is to use isolated scopes with imports (quote!({ use ::std::option::Option; })
), but this approach also has drawbacks, especially when the codegen system consists of dozens of small, mostly independent procedures.
I'd like to ask the community: how do you usually deal with this problem?
Thanks in advance,
Ilya
4 posts - 3 participants
🏷️ Rust_feed