8

I noticed that in order for a piece of code to not be classified as dead, it has to be reachable from all binaries. Example:

Cargo.toml:
[[bin]]
name = "main_one"
path = "src/main_one.rs"
[[bin]]
name = "main_two"
path = "src/main_two.rs"

main_one.rs:
mod utils;
fn main() {
    print!("Hello, ");
    utils::function_in_question();
}


main_two.rs:
mod utils;
fn main() {
    print!("Hello, ");
    // utils::function_in_question();
}


utils.rs:
pub fn function_in_question() {
    println!("world!");
}

This reports function_in_question as dead code, even though it's reachable from main_one.rs. Uncommenting it fixes this issue. Works also if it's present only in main_two.rs.

Although there is some rationale behind this behavior, it is annyoing to have VSCode complain about this all the time + the output of Clippy is spammed by these warnings. Is there a solution to at least surpress dead code detection globally? Restructuring the whole project with cargo workspaces should be avoided.

Vilda
  • 1,675
  • 1
  • 20
  • 50
  • 1
    To silence warnings globally refer to [this answer](https://stackoverflow.com/a/25877389/2766908). – pretzelhammer Feb 14 '21 at 13:30
  • @pretzelhammer Ok, adding #![allow(dead_code)] to the top of every binary entry point file silences the warnings. I however agree with your comment on this not being a solid solution. – Vilda Feb 14 '21 at 13:43
  • 2
    Add `#![allow(dead_code]` to the top of your main source files, not `Cargo.toml`. And yes, as I said earlier, I'd still like to see an answer with a proper solution to this problem, as globally silencing an otherwise useful warning just avoids the problem (and creates another in the process). – pretzelhammer Feb 14 '21 at 13:45

1 Answers1

12

This happens because you're not compiling utils.rs just once -- you're compiling it twice, first as part of main_one and then as part of main_two.

The pattern I am familiar with is to put common items into lib.rs, which is by default compiled into a library crate with the same name as your project. Then, instead of including them in each binary with mod, just use the library crate.

# Cargo.toml
[package]
name = "my_crate" # <- will be the name of the library crate
version = "0.1.0"

[dependencies]

# No need for [[bin]] sections if you put the binary sources in src/bin
// src/lib.rs
pub fn function_in_question() {
    println!("world!");
}
// src/bin/main_one.rs
fn main() {
    print!("Hello, ");
    my_crate::function_in_question();
}
// src/bin/main_two.rs
fn main() {
    print!("Hello, ");
    // my_crate::function_in_question();
}

The library crate will be compiled only once, and because function_in_question is part of the crate's public API, you will see no dead code warnings.

Note that you do not need [[bin]] sections in Cargo.toml if you put the binary files in src/bin; see this question for more.

trent
  • 25,033
  • 7
  • 51
  • 90