5

Is it possible to interpolate a macro_rules! variable, of type ident, into a string literal in a macro? In other words is it possible to "escape" the double quotes of the literal?

// `trace_macros!` requires nightly
#![feature(trace_macros)]
trace_macros!(true);

macro_rules! export_mod_if_feature {
    ($system:ident) => {
        #[cfg(target_os = "$system")] // <-- problem is here
        pub mod $system;
    };
}

export_mod_if_feature!(linux);

// ... should translate to:
#[cfg(target_os = "linux")]
pub mod linux;

// ... but instead it becomes:
#[cfg(target_os = "$system")]
pub mod linux;

I have tried using #[cfg(target_os = stringify!($system))] but the cfg requires an actual string literal after target_os =, not just a compile-time string.

BallpointBen
  • 9,406
  • 1
  • 32
  • 62

2 Answers2

0

Since the cfg attribute expects a literal and the pub mod expects a ident, I think you can use two values as the input of your macro and match one as a literal metavariable and the other as a ident metavariable. This would be more flexible when the names of the feature and the module are different.

#![feature(trace_macros)]
trace_macros!(true);

macro_rules! export_mod_if_feature {
    ($system:literal, $module:ident) => {
        #[cfg(target_os = $system)]
        pub mod $module;
    };
}

export_mod_if_feature!("linux", linux);

Playground

Joe_Jingyu
  • 1,024
  • 6
  • 9
-1

Yes, the stringify!(...) macro does that, so also this thread.