It might be advantageous to some procedural macros to have limited knowledge about their context. So far a procedural macro can only inspect the AST that it is allowed to operate on without any contextual information.
Limited contextual information, for example the module_path!
at which the procedural macro has been invoked, could potentially bring a lot to the table for what a procedural macro can achieve.
In one of my code bases the feature to query the call-site module_path!
would solve an ambiguity problem we currently have to work around with "hacks". On an abstract level we try to find unique serializable identifiers to call methods of traits for communication between different end points.
Now imagine we'd have a TraitMethod<const ID: u64>
trait with which we can query some useful information about a trait method. (Reflection-like)
The problem is that we need to calculate this unique ID: u64
at proc. macro compilation time.
pub trait TraitMethodInfo<const ID: u64> {
/// Is true if the trait method has a `&mut self` receiver.
const IS_MUT: bool;
/// The number of inputs without the `self` receiver.
const NUM_INPUTS: usize;
}
Now let us consider the following code:
mod foo1 {
#[derive_trait_method_info]
pub trait Foo {
fn foo(&self);
}
}
mod foo2 {
#[derive_trait_method_info]
pub trait Foo {
fn foo(&self);
}
}
Note: Using a work around we can indirectly implement traits on trait definitions. (At least in our own use case.)
In this example, both foo1::Foo
and foo2::Foo
have absolutely the same internal layout. So a procedural macro without this contextual information about their module path would not be able to properly disambiguate them and would end up generating the same non-unique identifiers ID
for both foo1::Foo::foo
and foo2::Foo::foo
trait methods.
This is a problem to us. I happily appreciate other ideas for potential solutions to our problem or a nice discussion whether a feature like this was useful to other Rust projects. If deemed useful I'd be willing to write an RFC.
We could solve this by adding another parameter to procedural macros that is similar to syn::Path
in order to provide the proc. macro with this kind of limited context information.
If you read until this point, thank you a lot for your attention!