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

Read full topic

Source: View source