rust-clippy icon indicating copy to clipboard operation
rust-clippy copied to clipboard

`use anyhow::Result;`treated as unused import if only tests use it

Open SichangHe opened this issue 3 years ago • 5 comments

Summary

If I add

use anyhow::Result;

and use Result<T> only in my tests, clippy thinks this import is unused.

Lint Name

unused_imports

Reproducer

This is all the code you need to have this false warning:

use anyhow::Result;

fn main() {
    println!("Hello, world!");
}

#[test]
fn test() -> Result<()> {
    Ok(())
}

The warning:

$ cargo clippy
warning: unused import: `anyhow::Result`
 --> blah/src/main.rs:1:5
  |
1 | use anyhow::Result;
  |     ^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: `blah` generated 1 warning

To show that this import is used, remove it:

fn main() {
    println!("Hello, world!");
}

#[test]
fn test() -> Result<()> {
    Ok(())
}

If you run the test, it shows an error:

$ cargo t
   Compiling blah
error[E0107]: this enum takes 2 generic arguments but 1 generic argument was supplied
   --> blah/src/main.rs:6:14
    |
6   | fn test() -> Result<()> {
    |              ^^^^^^ -- supplied 1 generic argument
    |              |
    |              expected 2 generic arguments
    |
note: enum defined here, with 2 generic parameters: `T`, `E`
   --> ~/.rustup/toolchains/stable-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/result.rs:504:10
    |
504 | pub enum Result<T, E> {
    |          ^^^^^^ -  -
help: add missing generic argument
    |
6   | fn test() -> Result<(), E> {
    |                       +++

For more information about this error, try `rustc --explain E0107`.
error: could not compile `blah` due to previous error

Version

rustc 1.62.1 (e092d0b6b 2022-07-16)
binary: rustc
commit-hash: e092d0b6b43f2de967af0887873151bb1c0b18d3
commit-date: 2022-07-16
host: aarch64-apple-darwin
release: 1.62.1
LLVM version: 14.0.5

Additional Labels

No response

SichangHe avatar Jul 24 '22 10:07 SichangHe

This warning is from rustc itself rather than Clippy. #[test] fns have #[cfg(test)] applied to them, so when not compiled in test mode the Result import is unused. The usual way to do tests is within a #[cfg(test)] module, with the imports also in the test module


fn main() {
    println!("Hello, world!");
}

#[cfg(test)]
mod tests {
    use anyhow::Result;

    #[test]
    fn test() -> Result<()> {
        Ok(())
    }
}

Alexendoo avatar Jul 24 '22 12:07 Alexendoo

So, it is a bug from rustc I guess.

SichangHe avatar Jul 24 '22 12:07 SichangHe

It's not a bug, the program when not compiling tests is essentially

use anyhow::Result;

fn main() {
    println!("Hello, world!");
}

Where the anyhow::Result import is unused. Test only imports should only be enabled when the tests themselves are enabled

Alexendoo avatar Jul 24 '22 12:07 Alexendoo

Good point. The import is unused from the point of building. It still looks wonky I guess.

Also, why are we not suggesting people to separate tests to a module? Is that too much restriction?

SichangHe avatar Jul 24 '22 12:07 SichangHe

It's a reasonable suggestion, we don't have a lint for it probably because of some combination of it being difficult (due to how clippy works with conditional compilation) and nobody taking the time to implement it

Alexendoo avatar Jul 24 '22 15:07 Alexendoo