BallpointBen
BallpointBen

Reputation: 13750

Use macro defined in terms of non-public macro in test

I would like to define a public macro in terms of a private macro, but I am struggling with visibility issues. In my #[cfg(test)] code (and presumably in any external crate?), the visibility of the private macro prevents it from being expanded within the public macro.

// a public macro
#[macro_export]
macro_rules! a {
    () => {
        $crate::b!()
    };
}

// internal use only
macro_rules! b {
    () => {};
}

#[cfg(test)]
mod test {
    use super::a;

    #[test]
    fn test() {
        a!();
    }
}

Output

$ cargo test

warning: unused macro definition: `b`
  --> src/lib.rs:10:14
   |
10 | macro_rules! b {
   |              ^
   |
   = note: `#[warn(unused_macros)]` on by default

warning: `my-crate` (lib) generated 1 warning
error[E0433]: failed to resolve: could not find `b` in the crate root
  --> src/lib.rs:5:11
   |
5  |         $crate::b!()
   |                 ^ could not find `b` in the crate root
...
20 |         a!();
   |         ---- in this macro invocation
   |
   = note: this error originates in the macro `a` (in Nightly builds, run with -Z macro-backtrace for more info)

For more information about this error, try `rustc --explain E0433`.
warning: `my-crate` (lib test) generated 1 warning (1 duplicate)
error: could not compile `my-crate` (lib test) due to 1 previous error; 1 warning emitted

How can I make it so that a is public, b is private, and a can still successfully expand in external crates?

Upvotes: 1

Views: 24

Answers (0)

Related Questions