Alexandros Katechis
Alexandros Katechis

Reputation: 1022

Cargo test warns for unused code after saving file

I'm starting to grasp Rust modules, but I have the following in a crate's src directory. If I make a small modification (add some whitespace or rename the test function), save and then immediately run cargo test I get a warning for an unused function, but if I wait a few seconds, and run it again, it runs with no warnings.

lib.rs

mod greet;

#[test]
pub fn it_greets_the_world_correctly() {
    assert_eq!("Hello, world!", greet::greet("world"));
}

greet.rs

pub fn greet(name: &str) -> String {
    format!("Hello, {}!", name)
}

But when I run cargo test I get the following:

$ cargo test
   Compiling hello v0.1.0 (file:///F:/workspace/hello_rust)
src\greet.rs:1:1: 3:2 warning: function is never used: `greet`, #[warn(dead_code)] on by default
src\greet.rs:1 pub fn greet (name: &str) -> String {
src\greet.rs:2   format!("Hello, {}!", name)
src\greet.rs:3 }
     Running target\debug\hello-111b9369d8889475.exe

running 1 test
test it_greets_the_world_correctly ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests hello

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

and then a few seconds later...

$ cargo test
     Running target\debug\hello-111b9369d8889475.exe

running 1 test
test it_greets_the_world_correctly ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

   Doc-tests hello

running 0 tests

test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured

I'm not interested in suppressing the warning, I'm curious as to how Rust can possibly think the function is not being used when it's obviously called, since the test passes in both runs of the test.

Upvotes: 2

Views: 1141

Answers (2)

Shepmaster
Shepmaster

Reputation: 430671

Check the output closely:

$ cargo test
   Compiling hello v0.1.0 (file:///F:/workspace/hello_rust)
     Running target\debug\hello-111b9369d8889475.exe
$ cargo test
     Running target\debug\hello-111b9369d8889475.exe

When you execute cargo test the second time, nothing has changed with your code. Because nothing has changed, the code doesn't need to be recompiled.

Compiler warnings like unused functions are only generated when the compiler runs. If the compiler doesn't run, there won't be any warnings.

Changing the code will trigger a recompilation.


The followup question is, why does it think the function is unused? Simon Whitehead's answer covers that. Even though the function is marked pub, the module it's in is not public. That means it's impossible to call the function outside of the library. Since there are no calls to it inside the library, it's unused.

Upvotes: 1

Simon Whitehead
Simon Whitehead

Reputation: 65079

Using cargo test --verbose will give you some answers.

Firstly cargo test will compile everything for the lib with --crate-type lib. This is what is causing your warning. greet::greet is not actually called in your library code.

Next, cargo test will run rustc --crate-type lib --test against the library as a separate step. This one does call greet::greet, and so you get no warning.

Now, if you touch the files again and change the test to this:

assert_eq!("Hello, world!", "Hello, world!");

You'll note you get two warnings of the same thing ... because both steps don't reference the greet::greet function (the library doesn't call it.. and the tests don't call it).

I think this is a valid warning and is what you want: The warning is saying you have a method that isn't called in your library code.. even if a test calls it. I think, in a larger codebase, you would want to be warned and clean up your tests that are now testing functions that aren't used in the main codebase.

Upvotes: 2

Related Questions