Catch-all for configuration flags `#[cfg(foo = ?)]`?

Imagine a crate which relies on configuration flags to change its behavior for some reason. We can write the following code:

pub fn foo() {
    cfg_if::cfg_if!(
        if #[cfg(foo_backend = "bar")] {
            foo_bar()
        } else if #[cfg(foo_backend = "baz")] {
            foo_baz()
        } else {
            foo_default()
        }
    )
}

But it can be easy to make a typo while specifying backend name. Ideally, the code would emit a compilation error for an unknown configuration flag value, but I couldn't find a way to specify a catch-all for #[cfg(foo_backend = ???)]. Am I missing something or Rust simply does not have a way to specify this?

Rustc recently gained the ability to check cfgs for validity: Checking Conditional Configurations - The rustc book

In this case, I think that would look like this in Cargo.toml:

[lints.rust.unexpected_cfgs]
level = "error"
check-cfg = ['cfg(foo_backend, values("bar", "baz"))']

I haven't tried that though so not sure.

If you expect to need to do this cfg_if a lot, then I'd make another macro that wraps this one and hardcodes the names.

1 Like

IIUC this lint does not help in any way when user makes a typo, e.g. RUSTFLAGS='--cfg foo_backend="bat"'.

Oh, I thought you meant making a typo in the code. Yeah, there's nothing you can do about that. You would need to add a value that users should specify instead of leaving it blank, so that you can use the else for errors.

I think putting a panic in a const block in the else block will cause a compiler error.

        pub fn foo() {
            cfg_if! {
                if #[cfg(foo_backend = "bar")] {
                    foo_bar()
                } else if #[cfg(foo_backend = "baz")] {
                    foo_baz()
                } else {
                    const { panic!("unknown foo_backend") }
                }
            }
        }
1 Like

The idea is that the configuration flag is used to overwrite default behavior, so raising compilation error in the default branch is not acceptable. (And we don't need const panic for this, since we already have the compile_error! macro.)

You're right, and I misunderstood.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.