Can (pub) use self::macro_rules be made to work?

#1

Due to various conditions, it’s not possible for macro-emitted code to do the “standard” method of faking macro_rules! macros exported from a non-root location:

#[macro_export] #[doc(hidden)]
macro_rules! __m { .. }
pub use crate::__m as m;

Is there any reason that self::__m cannot be made to “just work” for this case? What does macro_rules! actually do to exported names currently?

(I’m trying to emit a shim around syn::Token! as part of a compile-to-syn::Parse-types tool. I could restrict it to codegen only and not allow use as a macro, but that is very undesirable and I’m already using one “standard” hack (proc-macro shimming through derive to be able to emit macro_rules!) to make this possible as a proc-macro.)

#2

One workaround for that error is to use a scope-relative rather than module-relative path for referring to __m if possible.
(Assuming the edition is 2018 and uniform paths are in effect)

#[macro_export] #[doc(hidden)]
macro_rules! __m { .. }
pub use __m as m;
1 Like
#3

@CAD97, could you give a full reproduction for what you are trying to do?

#4

Huh. I was unaware that that worked. It actually solves my problem (as I’m using a generated name anyway), though it breaks my macro-writing intuition of “use absolute paths everywhere” :stuck_out_tongue:

#5

Here’s the full version of what I’m (now successfully) doing:

            output.append_all(quote! {
                pub mod kw {
                    #(::syn::custom_keyword!(#keywords);)*
                }
                pub mod punct {
                    #(::syn::custom_punctuation!(#punct_name, #punct_val);)*
                }
                #[macro_export]
                #[doc(hidden)]
                macro_rules! #token_macro {
                    #((#keywords) => {self::kw::#kws};)*
                    #((#punct_val) => {self::punct::#punct_name};)*
                    ($($tt:tt)*) => {::syn::Token![$($tt)*]};
                }
                pub use #token_macro as Token;
            });
#6

This specific case can be made to work with use crate::#token_macro, I think.
Note that the definition of macro_rules! #token_macro is macro-expanded, but not “more macro expanded” than its use, so we can relax the error using the technique from https://github.com/rust-lang/rust/pull/53778.