A hundred lints

28 January 2016

clippy just reached a hundred lints. Besides the obvious partying, this is a good time to look at the lints, and see what we’ve come up with so far.

When Manish started clippy, he had about 5 lints, most of them fairly trivial. I added my own eq_op lint, which was a bit more complex (and, as it turned out later, wrong), and we both followed up with a heap of lints each. Others joined us, we got automated testing, a CONTRIBUTION.md and even more heaps of lints. But what do we lint against? What do we lint for?

Reasons to lint

There are a few overarching themes that most of the lints follow:

Likely Errors – some patterns are usually programmer errors, e.g. bad_bit_mask , cmp_nan , eq_op , empty_loop , match_overlapping_arm , ineffective_bit_mask , min_max , modulo_one , nonsensical_open_options , out_of_bounds_indexing , range_step_by_zero , unit_cmp and others

, , , , , , , , , , , and others Readability – a good many lints suggest readability improvements, such as approx_constant , block_in_if_condition_stmt , collapsible_if , cyclomatic_complexity , filter_next , len_zero , let_and_return , needless_return , no_effect , temporary_assignment , type_complexity , unused_lifetimes

, , , , , , , , , , , Performance – As Rust is touted as a systems language, we have some lints to avoid patterns that produce suboptimal code. Examples are box_vec , boxed_local , cmp_owned , extend_from_slice , linkedlist , mutex_atomic , or_fun_call , redundant_closure , str_to_string , string_to_string

, , , , , , , , , Being a good citizen, this is enforced by unstable_as_mut_slice , zero_width_space and others.

There are a few things to note here.

First, the reasons may at times be contrary. For example, extend is certainly shorter and thus probably more readable than extend_from_slice , but the latter can be faster.

Second, I’d like to repeat my statement from my November 2015 talk that we’re pretty stable for a Rust compiler plugin – we haven’t had a rustup which broke the build for at least five days now, and usually only need to change stuff every two weeks or so. Most of my June blog entry is still valid, although some things moved around a bit.

Third, most lints are pretty good in that they have had no reported false positives for some time. This is mostly because most of our lints are pretty simple, so there is little room for error. This is great because picking the low-hanging fruit gives us a lot of bang for very little buck.

Fourth, while most lints (81 to be exact) warn by default, three deny by default and sixteen are allow ed. The reasons may be different in each case, but the broad rule of thumb is that we welcome any allow lint, but to warn we want to be fairly sure that there is a good benefit to warning and every coder should at least think twice if the thing linted doesn’t apply to their code. Ẁe only deny stuff that either cannot be possibly correct, e.g. bad bit masks that make the comparison useless or that is actively misleading like a zero-width space in the code – whoever does this is just plain evil.

Regarding the allow ed lints, those are either lints for special cases, e.g. against all forms of numerical truncation, against shadowing (I found too many matches in the wild which would have swamped the compiler output, so it stays on allow ), against String addition, needless mutexes etc. Some of them simply aren’t tested sufficiently to make them warn because they could still have false positives.

Now what?

We’re not done yet. Clippy will get more lints and the lints we have will become better with time (and effort – so I hereby invite everyone to join us!). It will also probably become even more opinionated (as we already invariably are), which may or may not be a good thing. To see if we are on the right track, Manish has opened a “RFC” issue, so if you think we do something wrong, or could do something better, this is the place to chime in.

Finally, since 2016 was touted as the year of IDE integration for Rust, I’d really like to explore how clippy could fit into this – especially given that we often have suggestions that could be automatically (or semi-automatically) applied.