Expanding Inner Macros
I am trying to make a proc macro that needs to know the file/crate path to the caller at compile time.
The simplest example similar to what I am trying to do is hashing the module path. The hash_macro!()
should be same if and only if they are called within the same module.
I tried to do something like:
#[proc_macro]
pub fn hashing_macro(_input: TokenStream) -> TokenStream {
let mut hasher = std::hash::DefaultHasher::new();
module_path!().hash(&mut hasher);
line!().hash(&mut hasher);
let hash = hasher.finish();
quote! {
#hash
}.into()
}
but this didn't work, so I reluctantly tried a janky version that was more annoying
#[proc_macro]
pub fn jank_hashing_helper(input: TokenStream) -> TokenStream {
let mut hasher = std::hash::DefaultHasher::new();
input.to_string().hash(&mut hasher);
let hash = hasher.finish();
quote! {
#hash
}.into()
}
#[proc_macro]
pub fn jank_hashing_macro(_input: TokenStream) -> TokenStream {
quote! {
jank_hashing_helper!(module_path!())
}.into()
}
and this one didn't work either.
I tested their values with the following script:
use my_macro_crate::{hashing_macro, jank_hashing_helper, jank_hashing_macro};
const HASH: u64 = hashing_macro!();
const JANK_HASH_HELPER: u64 = jank_hashing_helper!(module_path!());
const JANK_HASH: u64 = jank_hashing_macro!();
#[test]
fn print_hash() {
dbg!(HASH);
dbg!(JANK_HASH_HELPER);
dbg!(JANK_HASH);
dbg!(module_path!());
}
I ran this exact same script in two different testing files, one called module_a and the other called module_b.
This was the output for module_a:
[.../tests/module_a.rs:9:5] HASH = 17192937734722882082
[.../tests/module_a.rs:10:5] JANK_HASH_HELPER = 9961261794398595528
[.../tests/module_a.rs:11:5] JANK_HASH = 3029096996050824686
[.../tests/module_a.rs:12:5] module_path!() = "module_a"
This was the output for module_b:
[.../tests/module_b.rs:9:5] HASH = 17192937734722882082
[.../tests/module_b.rs:10:5] JANK_HASH_HELPER = 9961261794398595528
[.../tests/module_b.rs:11:5] JANK_HASH = 3029096996050824686
[.../tests/module_b.rs:12:5] module_path!() = "module_b"
The "module_path!()" are different, but all of my hashing attempts resulted in the same output for the two different modules.
Could I have some help with this?
(This is my first post, so if there are meta-comments, please let me know about that as well.)
Much thanks!
3 posts - 3 participants
Source: View source