RFC 2476: Clippy 1.0

tools (lint)

Summary

Release Clippy 1.0, in preparation for it being shipped via rustup and eventually available via Rust Stable.

Motivation

See also: The Future of Clippy

Clippy, the linter for Rust, has been a nightly-only plugin to Rust for many years. In that time, it's grown big, but it's nightly-only nature makes it pretty hard to use.

The eventual plan is to integrate it in Rustup à la Rustfmt/RLS so that you can simply fetch prebuilt binaries for your system and cargo clippy Just Works ™️. In preparation for this, we'd like to nail down various things about its lints and their categorization.

Guide-level explanation

Usage and lint philosophy

We expect Clippy to be used via cargo clippy.

Clippy aims to follow the general Rust style. It may be somewhat opiniated in some situations.

In general Clippy is intended to be used with a liberal sprinkling of #[allow()] and #[warn()]; it is okay to disagree with Clippy's choices. This is a weaker philosophy than that behind rustc's lints, where usually flipping one is an indication of a very specialized situation.

Lint attributes

Currently to allow/deny Clippy lints you have to #[cfg_attr(clippy, allow(lintname))] which is somewhat tedious.

The compiler should support something like #[allow(clippy::lintname)] which won't attempt to warn about nonexistant lints at all when not running Clippy.

Stability guarantees

Clippy will have the same idea of lint stability as rustc; essentially we do not guarantee stability under #[deny(lintname)]. This is not a problem since deny only affects the current crate (dependencies have their lints capped) so at most you’ll be forced to slap on an #[allow()] for your own crate following a Rust upgrade.

This means that we will never remove lints. We may recategorize lints, and we may "deprecate" them. Deprecation "removes" them by removing their functionality and marking them as deprecated, which may cause further warnings but cannot cause a compiler error.

It also means that we won't make fundamentally large changes to lints. You can expect that turning on a lint will keep it behaving mostly similarly over time, unless it is removed. The kinds of changes we will make are:

When fixing false negatives this will usually be fixing things that can be understood as comfortably within the scope of the lint as documented/named. For example, a lint on having the type Box<Vec<_>> may be changed to also catch Box<Vec<T>> where T is generic, but will not be changed to also catch Box<String> (which can be linted on for the same reasons).

An exception to this is the "nursery" lints — Clippy has a lint category for unpolished lints called the "nursery" which are allow-by-default. These may experience radical changes, however they will never be entirely "removed" either.

Pre-1.0 we may also flush out all of the deprecated lints.

The configuration file for clippy, clippy.toml, is not stabilized in this RFC. Instead, we propose to require clippy.toml users set a clippy_toml_is_unstable_and_may_go_away option.

The interface and existence of cargo-clippy is also not stabilized in this RFC. We will continue shipping it with rustup, but it may be replaced in the future with a combined cargo lint command.

Lint audit and categories

A couple months ago we did a lint audit to recategorize all the Clippy lints. The Reference-Level explanation below contains a list of all of these lints as currently categorized.

The categories we came up with are:

Lints can only belong to one lint group at a time, and the lint group defines the lint level. There is a bunch of overlap between the style and complexity groups -- a lot of style issues are also complexity issues and vice versa. We separate these groups so that people can opt in to the complexity lints without having to opt in to Clippy's style.

Compiler uplift

The compiler has historically had a "no new lints" policy, partly with the desire that lints would incubate outside of the compiler (so usually in Clippy). This feels like a good time to look into uplifting these lints.

This RFC does not yet propose lints to be uplifted, but the intention is that the RFC discussion will bring up lints that the community feels should be uplifted and we can list them here.

Such an uplift may change the lint level; correctness lints are Deny by default in Clippy but would probably switch to Warn if uplifted since the compiler is more conservative here (Using Clippy is in itself an opt-in to a "please annoy me more" mode).

We'd also like to establish a rough policy for future lints here: Some correctness lints should probably belong in the compiler, whereas style/complexity/etc lints should probably belong in Clippy. Lints may be incubated in Clippy, of course.

I don't think the compler will want all correctness lints here, however if the lint is about a common enough situation where it being not a bug is an exceedingly rare case (i.e. very low false positive frequency) it should probably belong in the compiler.

What lints belong in clippy?

Essentially, we consider the categorization itself to be a definition of boundaries -- if it doesn't fit in the categories, it doesn't fit in clippy (or needs an RFC for, specifically).

In itself this isn't complete, we explicitly have a "pedantic" group that's kinda ill defined.

The rules for the main categories (style/complexity/correctness/perf -- things which are warn or deny by default) are:

For the other categories (these are allow by default):

Reference-level explanation

Lint categorization

This categorization can be browsed online.

Please leave comments on thoughts about these lints -- if their categorization is correct, if they should exist at all, and if we should be uplifting them to the compiler.

For ease of review, the lints below are as they were listed in the original RFC. The proposed changes are:

correctness (Deny)

style (Warn)

complexity (Warn)

perf (Warn)

pedantic (Allow)

nursery (Allow)

restriction (Allow)

Rationale and alternatives

We don't particularly need a 1.0, however it's good to have a milestone here, and a general idea of stability as we move forward in this process.

It's also good to have some community involvement in the lint design/categorization process since Clippy lints both reflect and affect the general style of the community.

Unresolved questions

Through the process of this RFC we hope to determine if there are lints which need to be uplifted, recategorized, or removed.