Eager expansion in proc_macro attribute

Hi all,

I got another question about procedure_macro_attribute.

Suppose I have this attribute:

#[attribute(module_path!())]
// a rust item

What I am trying to do here is that I want to get the module path of the code at call site and use that in my attribute:

// the path should be the module path of the src which calls the attribute
#[attribute(crate::mod::name)]
// rust item

However, I don't know if there's anyway to force an eager expansion of module_path!(), currently my attribute cannot handle module_path!() as input, it can only handle a valid rust path.

How should I do that? Or is there any workaround to get the module path of the call site of proc_macro?

There isn't a way to ask the compiler to expand a particular macro invocation as far as I know, although I know there are a bunch of people (myself included) who want it. At the moment only macros like concat!() support eager expansion, and that's because they are built into the compiler.

One crappy workaround would be to make the user write the module path manually then create a test that ensures it is kept in sync.

So something like this...

#[attribute(crate::mod::name)]
fn foo() { }

... would expand to something like this...

fn foo() {}

#[cfg(test)]
#[test]
fn assert_foo_module_path_is_in_sync() {
  assert_eq!("crate::mod::name", module_name!());
}

If it's not possible to force an eager evaluation, do you know if there's any way that can get the call site module path in proc_macro invocation?

The proc_macro2 crate's Span::source_file() method might help, but it's explicitly marked as procmacro2_semver_exempt (i.e. "this is nightly and may break at any time").

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.