Item 29: Listen to Clippy

"It looks like you're writing a letter. Would you like help?" – Microsoft Clippit

Item 31 describes the ecosystem of helpful tools available in the Rust toolbox, but one tool is sufficiently helpful and important to get promoted to an Item of its very own: Clippy.

Clippy is an additional component for Cargo that emits warnings about your Rust usage (cargo clippy ...), across a variety of categories:

  • Correctness: warn about common programming errors.
  • Idiom: warn about code constructs that aren't quite in standard Rust style.
  • Concision: point out variations on the code that are more compact.
  • Performance: suggest alternatives that avoid unnecessary processing or allocation.
  • Readability: describe alterations to the code that would make it easier for humans to read and understand.

For example, the following code builds fine:

    pub fn circle_area(radius: f64) -> f64 {
        let pi = 3.14;
        pi * radius * radius
    }

but Clippy points out that the local approximation to π is unnecessary and inaccurate:

error: approximate value of `f{32, 64}::consts::PI` found
 --> clippy/src/main.rs:5:18
  |
5 |         let pi = 3.14;
  |                  ^^^^
  |
  = note: `#[deny(clippy::approx_constant)]` on by default
  = help: consider using the constant directly
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#approx_constant

The linked webpage explains the problem, and points the way to a suitable modification of the code:

#![allow(unused)]
fn main() {
    pub fn circle_area(radius: f64) -> f64 {
        std::f64::consts::PI * radius * radius
    }
}

As shown above, each Clippy warning comes with a link to a webpage describing the error, which explains why the code is considered bad. This is vital, because it allows you to decide whether those reasons apply to your code, or whether there is some particular reason why the lint check isn't relevant. In some cases, the text also describes known problems with the lint, which might explain an otherwise confusing false positive.

If you decide that a lint warning isn't relevant for your code, you can disable it either for that particular item (#[allow(clippy::some-lint)]) or for the entire crate (#![allow(clippy::some-lint)]). However, it's usually better to take the cost of a minor refactoring of the code than to waste time and energy arguing about whether the warning is a genuine false positive.

Whether you choose to fix or disable the warnings, you should make your code Clippy warning free.

That way, when new warnings appear – whether because the code has been changed, or because Clippy has been upgraded to include new checks – they will be obvious. Clippy should also be enabled in your continuous integration system (Item 32).

Clippy's warnings are particularly helpful when you're learning Rust, because they reveal gotchas you might not have noticed, and help you become familiar with Rust idiom.

Many of the Items in this book also have corresponding Clippy warnings, when it's possible to mechanically check the relevant concern:

As the size of this list should make clear, it can be a valuable learning experience to read the list of Clippy lint warnings – including the pedantic or high-false-positive checks that are disabled by default. Even though you're unlikely to want to enable these warnings for your code, understanding the reasons why they were written in the first place will improve your understanding of Rust and its idiom.