I agree that this is a desirable feature.
FWIW, wih enough macromancy one can achieve this:
make_cfg_alias! {
macro let (cfg_my_combination, cfg_not_my_combination) =
cfg_and_cfg_not!(
all(
feature = "a",
not(feature = "b"),
feature = "c",
),
)
;
}
#[macro_rules_attribute(cfg_my_combination!)]
fn main ()
{
println!("You win!");
}
#[macro_rules_attribute(cfg_not_my_combination!)]
fn main ()
{
println!("You lose.");
}
This is achieved by:
-
having a macro define the two associated dummy macros depending on the
cfg
:macro_rules! make_cfg_alias {( @with_dollar![$dol:tt] macro let ($yes:ident, $no:ident) = cfg_and_cfg_not! $cfgs:tt $(;)? ) => ( #[cfg $cfgs] macro_rules! $yes {($dol it:item) => ($dol it)} #[cfg $cfgs] macro_rules! $no {($dol it:item) => ()} #[cfg(not $cfgs)] macro_rules! $yes {($dol it:item) => ()} #[cfg(not $cfgs)] macro_rules! $no {($dol it:item) => ($dol it)} ); ($($t:tt)*) => (make_cfg_alias! { @with_dollar![$] $($t)* })}
-
using
#[macro_rules_attribute]
to be able to use the defined macros as attributes.-
otherwise one would have to use the macros as:
cfg_my_combination! { fn main () { ... } }
-
By using something like ::paste
to concat identifiers into new ones, one would be able to reduce the "redundancy" at call site, but this involves an extra dependency that pulls the heavy ::syn
crate, and leasds to a more complex / convoluted make_cfg_alias!
macro definition, which is already quite unreadable because of its nested macro definitions...