Any Such Thing as `#[cfg]` Aliases?

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.");
}

image

This is achieved by:

  1. 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)* })}
    
  2. 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...

4 Likes