(copy-pasting from IRLO)
Consider the code snippet
pub fn foo() {
// unused function!
}
fn main() {}
cargo check reports no errors or warnings. However, the same snippet using pub(crate) fn foo() gives a warning:
warning: function is never used: `foo`
--> src/main.rs:1:15
|
1 | pub(crate) fn foo() {
| ^^^
|
= note: `#[warn(dead_code)]` on by default
warning: 1 warning emitted
Given that binaries can't be used in anything else (as far as I'm aware?), would it make sense to treat pub as equivalent to pub(crate) in binaries? I don't believe there is any difference in semantics, but it certainly makes a difference regarding warnings.
CC @estebank, who suggested I file an issue.
Given that binaries can't be used in anything else
A dylib loaded by the binary could lookup the symbol using dlsym if it was #[no_mangle] I think.
You can build multiple crate types at once. Then this would break any non-binary crate types that are built at the same time.
What about just changing the lint instead? It could check if the only crate type being built is a binary, and then treat only fn main as the initially used function.
the target `foo` is a binary and can't have any crate-types set (currently "lib")
So this could only apply to _binary targets_, not the crate-type bin (if you have a library target that is set to be something like ["bin", "staticlib"]).
Changing the lint would certainly be sensible if totally merging the behavior causes issues. I believe this affects any item, not just functions. It would probably be worth checking whether any other lints have the same type of behavior.
A dylib loaded by the binary could lookup the symbol using
dlsymif it was#[no_mangle]I think.
In this case, #[no_mangle] itself should mark the function as used, so I don't think this would present any problems. The following library compiles without warnings on stable rustc:
#[no_mangle]
fn foo() {
}
It would make sense to do this for staticlibs and cydlibs as well.
Ideally it would be cool to go even further, to have unused lints across crates. Many crates are only used by crates inside the same project, and their pub items may or may not be used by those crates. I've built something based on save-analysis a while ago but discontinued its development. https://github.com/est31/warnalyzer
@est31 How would that work compiler-wise? My understanding is that workspaces are entirely a creation of cargo, and is no different than two unrelated crates to rustc.
@jhpratt it's a level above the compiler, kinda like cargo-udeps. It requires save-analysis of all crates in the workspace as input. in order to support "go to places that use this", save analysis contains (thing_a -> thing_b) relationships when e.g. the thing_a function uses the thing_b function. the tool uses that info to find things that aren't used by anything else. It currently only supports one binary crate, but that's only an implementation limitation.
Anyways, the warnalyzer tool is in prototype phase, needs porting to rust-analyzer, and will always require some kind of manual user input about which crates a library crate is to be used by. Treating pub in binaries as pub(crate) can always run on the other hand, so the change should be done as well. Just wanted to make sure you are aware of warnalyzer :).
I definitely put stuff as pub in a binary as a deliberate way to shut up the warning about potentially dead code exiting.
@Lokathor Just curious, why? Dead code warnings are useful.
Not while things are in development, or while things depend on cargo features, or when i might want to use it later, or when
Most helpful comment
You can build multiple crate types at once. Then this would break any non-binary crate types that are built at the same time.
What about just changing the lint instead? It could check if the only crate type being built is a binary, and then treat only
fn mainas the initially used function.