DEV Community

ANKDDEV
ANKDDEV

Posted on

Useful Clippy lints

Introduction

Hello! Rust has very useful tool, named Cargo. It helps you compile code, run program, run tests and benches, format code using cargo fmt and lint it using clippy. In this post we'll talk abou Clippy.

What is Clippy

Clippy is a linter for Rust code. Linter is a static analysis tool, used to prevent errors, bugs, styling mistakes, etc. Clippy includes many lints, or rules, you can enable them and Clippy will show warning or error when you violate this lint.

How to install Clippy

Assume that you already installed Rust, just run following command:

rustup component add clippy
Enter fullscreen mode Exit fullscreen mode

This will download and install Clippy for your current toolchain. Then, you can run Clippy using this commands:

# Check for issues
cargo clippy
# Fix some issues
cargo clippy --fix
Enter fullscreen mode Exit fullscreen mode

How to enable or disable lints

Command line

In CLI interface of Clippy you can enable or disable specific lint by adding to command -A/W/D clippy::lint_name, where:

  • A - allow violation of lint
  • W - print warning when you violate lint
  • D - deny code if you vioalte lint and show error Example usage:
cargo clippy -- -Aclippy::style -Wclippy::double_neg -Dclippy::perf
Enter fullscreen mode Exit fullscreen mode

This will:

  • allow violation of clippy::style
  • print warning when violating clippy::double_neg
  • and deny code that violate clippy::perf For CI all warnings can be elevated to errors which will in turn fail the build and cause Clippy to exit with a code other than 0.
cargo clippy -- -Dwarnings
Enter fullscreen mode Exit fullscreen mode

This will deny code that generate any Clippy warnings.

Cargo.toml

You can define levels for lints in your Cargo.toml like this:

[lints.clippy]
enum_glob_use = "deny"
Enter fullscreen mode Exit fullscreen mode

This will deny any code that violates clippy::enum_glob_use

In code

You can add attributes to your code to allow/warn/deny Clippy lints:

  • the whole set of warn-by-default lints using the clippy lint group (#![allow(clippy::all)])
  • all lints using both the clippy and clippy::pedantic lint groups (#![warn(clippy::all, clippy::pedantic)]. Note that clippy::pedantic contains some very aggressive lints prone to false positives.
  • only some lints (#![deny(clippy::single_match, clippy::box_vec)], etc.)
  • allow/warn/deny can be limited to a single function or module using #[allow(...)], etc. # Useful lints groups Clippy includes some groups of lints, that are allowed by default. ## clippy::pedantic The first group is the pedantic group. This group contains really opinionated lints, that may have some intentional false positives in order to prevent false negatives. So while this group is ready to be used in production, you can expect to sprinkle multiple #[allow(..)]s in your code. If you find any false positives, you're still welcome to report them to us for future improvements. ## clippy::restriction The second group is the restriction group. This group contains lints that "restrict" the language in some way. For example the clippy::unwrap lint from this group won't allow you to use .unwrap() in your code. You may want to look through the lints in this group and enable the ones that fit your need.

Note: You shouldn't enable the whole lint group, but cherry-pick lints from this group. Some lints in this group will even contradict other Clippy lints!

Useful lints

Here's list of some useful lints, that I usually use in my projects

clippy::dbg_macro

While dbg!() macro is very useful for testing purposes, you shouldn't include it into production builds of software.

clippy::else_if_without_else

Checks for usage of if expressions with an else if branch, but without a final else branch. Some coding guidelines require final else branch (e.g., MISRA-C:2004 Rule 14.10).

clippy::exit

Detects calls to the std::process::exit() function which terminates the program. exit() immediately terminates the program with no information other than an exit code. This provides no means to troubleshoot a problem, and may be an unexpected side effect.

Codebases may use this lint to require that all exits are performed either by panicking (which produces a message, a code location, and optionally a backtrace) or by returning from main() (which is a single place to look).

clippy::explicit_into_iter_loop

Checks for loops on y.into_iter() where y will do (e.g. it is Vec or slice), and suggests the latter.

clippy::explicit_iter_loop

Like lint above.

clippy::if_not_else

Checks for usage of ! or != in an if condition with an else branch. Negations reduce the readability of statements.
Example:

if !v.is_empty() {
    a()
} else {
    b()
}
Enter fullscreen mode Exit fullscreen mode

sould be rewritten as:

if v.is_empty() {
    b()
} else {
    a()
}
Enter fullscreen mode Exit fullscreen mode

clippy::implicit_return

Checks for missing return statements at the end of a block.
Omitting the return keyword whenever possible is idiomatic Rust code, but:

  • Programmers coming from other languages might prefer the expressiveness of return.
  • It’s possible to miss the last returning statement because the only difference is a missing ;.
  • Especially in bigger code with multiple return paths, having a return keyword makes it easier to find the corresponding statements. ## clippy::infinite_loop Checks for infinite loops in a function where the return type is not ! and lint accordingly. Making the return type ! serves as documentation that the function does not return. If the function is not intended to loop infinitely, then this lint may detect a bug. ## clippy::manual_let_else Warn of cases where let...else could be used. let...else provides a standard construct for this pattern that people can easily recognize. It’s also more compact. ## clippy::match_bool Checks for matches where match expression is a bool. It suggests to replace the expression with an if...else block. ## clippy::mem_forget Checks for usage of std::mem::forget(t) where t is Drop or has a field that implements Drop. std::mem::forget(t) prevents t from running its destructor, possibly causing leaks. It is not possible to detect all means of creating leaks, but it may be desirable to prohibit the simple ones. ## clippy::missing_panics_doc Checks the doc comments of publicly visible functions that may panic and warns if there is no # Panics section. ## clippy::panic This macro, or panics in general, may be unwanted in production code. ## clippy::pub_use Restricts the usage of pub use .... A project may wish to limit pub use instances to prevent unintentional exports, or to encourage placing exported items directly in public modules. ## clippy::similar_names Checks for names that are very similar and thus confusing.

Note: this lint looks for similar names throughout each scope. To allow it, you need to allow it on the scope level, not on the name that is reported.

clippy::todo

Checks for usage of todo!. The todo! macro indicates the presence of unfinished code, so it should not be present in production code.

clippy::too_many_lines

Checks for functions with a large amount of lines. Functions with a lot of lines are harder to understand due to having to look at a larger amount of code to understand what the function is doing. Consider splitting the body of the function into multiple functions.
By default it is 100 lines

clippy::wildcard_imports

Checks for wildcard imports use _::*. wildcard imports can pollute the namespace. This is especially bad if you try to import something through a wildcard, that already has been imported by name from a different source.

Conclusion

In this post I wrote some useful Clippy lints, that I usually use.
Write feedback on comments, see my projects on GitHub, subscribe to my Telegram chhannel about Rust. Thanks for reading this!

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Eliminate Context Switching and Maximize Productivity

Pieces.app

Pieces Copilot is your personalized workflow assistant, working alongside your favorite apps. Ask questions about entire repositories, generate contextualized code, save and reuse useful snippets, and streamline your development process.

Learn more