[Feature Request]: Add Automatic ignoring of dead_code for functions called behind cfg targets

For example, I have the target locked code:

    #[cfg(all(target_family="wasm", target_os="emscripten"))] {
        unsafe {
            let webgl_context_result: i32 = create_webgl_context();
            debug!("WebGL Context Created With Value {:?}...", emscripten::read_emscripten_result(webgl_context_result));
        }
    }

The function which turns the int to an enum value is:

#[allow(dead_code)]
pub fn read_emscripten_result(value: i32) -> String {
    match value.try_into() {
        Ok(EmscriptenResult::Success) => String::from("Success"),
        Ok(EmscriptenResult::Deferred) => String::from("Deferred"),
        Ok(EmscriptenResult::NotSupported) => String::from("NotSupported"),
        Ok(EmscriptenResult::FailedNotDeferred) => String::from("FailedNotDeferred"),
        Ok(EmscriptenResult::InvalidTarget) => String::from("InvalidTarget"),
        Ok(EmscriptenResult::UnknownTarget) => String::from("UnknownTarget"),
        Ok(EmscriptenResult::InvalidParam) => String::from("InvalidParam"),
        Ok(EmscriptenResult::Failed) => String::from("Failed"),
        Ok(EmscriptenResult::NoData) => String::from("NoData"),
        Ok(EmscriptenResult::TimedOut) => String::from("TimedOut"),
        Err(_) => String::from("Unknown"),
    }
}

I currently have to put #[allow(dead_code)] in order for Rust to not warn about the code when building for non-emscripten targets. The code itself isn't dead, it just doesn't get called in all circumstances and it would be nice if I could set some kind of flag (e.g. in cargo.toml or at the top of main.rs and lib.rs) which tells Rust not to treat those specific pieces of code as dead unless they are actually dead in all circumstances.

Edit: I do know that in this particular case, I could lock this behind a target too, but I've had cases where I had to do this for every function in a file as it caused problems with breaking imports if I put a file wide lock.

Sounds like the lint is working as intended. After expanding all cfg and macros, your code is dead. Why would you expect it to work otherwise?

Properly gating such functions behind the respective cfg directives is indeed the proper solution. You can also extract them into a submodule, and put a cfg guard on the module itself.

Note that you can also put cfg directives on your import statements.

5 Likes

I generally handle this issue with an internal mod wasm {} (named for whatever the condition is), then guard that and a pub use wasm::*;. Eventually, if those internal modules get too big to be inline this turns into the classic:

some_feature.rs
some_feature/macos.rs
some_feature/wasm.rs
some_feature/windows.rs
...
1 Like

Another workaround is to use:

#[cfg_attr(not(all(target_family="wasm", target_os="emscripten")), allow(dead_code))]

so that at least you don't lose the benefits of the dead_code lint during the build where it matters.

1 Like

To add: this isn't just pedantry. By cfg-gating more code, you reduce the amount of work the compiler needs to perform, speeding up compile times.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.