Cfg, keyword for "if multiple/more than one"

Hi, GitHub sent me here when I tried to create a feature request, if this is the wrong place to post this in I apologize

I am at the moment working on a program that has a features for multiple Linux distro's example.:

arch, manjaro, garuda, debian

To compile the program it always needs one feature enabled, but now I wanted to handle a case in which someone tries to compile it with more features but I can't seem to create a cfg which will allow me to basically do "if more than one -> allow compilation", I wanted to make a custom compile error if someone provides more of them so it's more clear, because when I don't do something like this the compiler just returns an error about duplicate struct and such which is not best for a just maintainer of the package and not a developer.

I think having some keyword like "multiple" or something like that to be able to do this would be useful.

#[cfg(multiple(feature = "manjaro", feature = "arch", feature = "garuda", feature = "debian"))]
compile_error!("You can't compile this program to support multiple distros at the same time! It must be compiled separately for each one!");

An option you have is to have a sentinel const for each of your feature gates: if multiple features are enabled, then you'd get a duplicated const error. The error message won't be as good as what you desire, but it will do the trick to preclude compilation.

2 Likes

That's clever, Thank you, I will probably use that for now but this keyword for it would be very nice instead of this trick

In the current stable Rust version (1.57.0), you can use a static assertion to get a compile_error-like error message: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=825e435532bd68f2b2d82ca8966e59e0

const _: () = {
    let enabled_features = {
        cfg!(feature = "manjaro") as u32 +
        cfg!(feature = "arch") as u32 +
        cfg!(feature = "garuda") as u32 + 
        cfg!(feature = "debian") as u32
    };

    match enabled_features {
        0 => panic!("\nNone of the distro features were enabled, exactly one must be."),
        1 => {}
        2.. => panic!("\nYou can't compile this program to support multiple distros at the same time! It must be compiled separately for each one!"),
    }
};
error[E0080]: evaluation of constant value failed
  --> src/lib.rs:10:14
   |
10 |         0 => panic!("\nNone of the distro features were enabled, exactly one must be."),
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '
None of the distro features were enabled, exactly one must be.', src/lib.rs:10:14
   |
   = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info)
6 Likes