Is it possible to conditionally compile a code block inside a function?
Asked Answered
K

2

11

I'm wondering if something like this is possible

fn main() {
    #[cfg(foo)] {
        println!("using foo config");
    }

}

The context is some code that cannot adequately be tested with just unit tests. I'll often have to run a "demo" cfg which displays information. I'm looking for alternatives to manually commenting in/out some portions of code.

Kuban answered 24/6, 2014 at 21:6 Comment(0)
M
23

As of at least Rust 1.21.1, it's possible to do this as exactly as you said (however, only inside of functions):

fn main() {
    #[cfg(foo)]
    {
        println!("using foo config");
    }
}

Before this, it isn't possible to do this completely conditionally (i.e. avoiding the block being type checked entirely), doing that is covered by RFC #16. However, you can use the cfg macro which evaluates to either true or false based on the --cfg flags:

fn main() {
    if cfg!(foo) { // either `if true { ... }` or `if false { ... }`
        println!("using foo config");
    }
}

The body of the if always has name-resolution and type checking run, so may not always work.

Myrna answered 24/6, 2014 at 21:14 Comment(1)
Note that you can only use blocks like this inside a function, not at the top level of a file. There is some discussion as to why in this closed RFC issue: github.com/rust-lang/rfcs/pull/2377Admetus
F
2

You may interested in the crate cfg-if, or a simple macro will do:

macro_rules! conditional_compile {
    ($(#[$ATTR:meta])* { $CODE: tt }) => {
        {
            match 0 {
                $(#[$ATTR])*
                0 => $CODE,

                // suppress clippy warnning `single_match`.
                1 => (),
                _ => (),
            }
        }
    }
}

fn main() {
    conditional_compile{
        #[cfg(foo)]
        {{
            println!("using foo config");
            // Or something only exists in cfg foo, like a featured mod.
        }}
    }
}
Flamethrower answered 5/11, 2016 at 6:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.