Motivation
This question arised during implementation of some rust software. Can declarative macros be conditionally compiled?
Declarative macros
Declarative macros give a limited mechanism to extend the syntax of a rust program. Declarative macros allow a programmer to define a set of rules which map some pattern to semantic elements which can be inserted into a block of code. Specifically, we define a meaningless macro for demonstration purposes called date
:
macro_rules! date {
($year:expr, $month:expr, $day:expr) => {
format!("{}-{}-{}", $year, $month, $day)
};
}
The three arguments year
, month
, and day
will be matched as expressions (besides expr
, there are other designators).
date!(2022, 12, 23)
Conditional compilation of the macro
Consider the target_os
condition. Is it possible to conditionally compile a declarative macro?
#[cfg(target_os = "linux")]
macro_rules! date {
($year:expr, $month:expr, $day:expr) => {
format!("{}-{}-{}", $year, $month, $day)
};
($year:expr, $month:expr) => {
format!("{}-{}-03", $year, $month)
};
}
fn main() {
println!("date: {}", date!(2022, 12, 23));
}
Yes, this compiles.
Conditional compilation of macro rules
Is it possible to conditionally compile only one rule of the declarative macro?
macro_rules! date {
($year:expr, $month:expr, $day:expr) => {
format!("{}-{}-{}", $year, $month, $day)
};
#[cfg(target_os = "linux")]
($year:expr, $month:expr) => {
format!("{}-{}-03", $year, $month)
};
}
fn main() {
println!("date: {}", date!(2022, 12, 23));
}
No, this does not compile.
Conclusion
So it can be conditionally compiled, but not individual rules of the macros. I expect procedural macros to support this feature, if you need it.