Rust and ClippyApr 25, 2017
I’ve been dipping my toes in Rust lately and I’m finding it a competent programming language. It’s a nice middle ground between C/C++ and a programming language that requires you to know Category Theory in order to start using it (cough… Haskell cough…).
When you start using Rust you quickly find out that it’s a good idea to something called Clippy. It is a fantastic tool that helps you write better and more idiomatic Rust code. I’m sure its name is a reference to this guy on the right, just a little less obnoxious.
Having Clippy on your side is like having an experienced Rust developer telling you that the code you are writing is of questionable quality, even though it compiles just fine.
There’s one catch though, you can’t use it on stable Rust releases. 1
Clippy, in fact, is implemented as a compiler plugin and, as such, it depends on unstable
APIs that are available only on nightly releases of the Rust toolchain.
I don’t like to run nightly or beta releases as my daily driver for a couple of reasons:
- I don’t want to risk depending on features that will ever be available only on nightly Rust or that will change wildly between snapshots. 2
- Being a beginner, I want to judge Rust on the merit of what’s available in stable releases right now, not on the prospect of what will be available later, if at all. In a project I decided to use serde’s codegen before “macros 1.1” were stabilized in Rust 1.15.
Sometimes Clippy fails to build even with the latest nightly compiler, so the first thing I usually do is to browse its CHANGELOG file and find out which release has been compiled with which compiler and use that.
For example, given this excerpt:
0.0.124 — 2017-04-16
- Update to rustc 1.18.0-nightly (d5cf1cb64 2017-04-15)
0.0.123 — 2017-04-07
- Fix various false positives
I would pick Clippy version 0.0.124 and build it with the 2017-04-23 nightly compiler.
Starting with a working
rustup I would then run:
rustup toolchain add nightly-2017-04-15 rustup run nightly-2017-04-15 cargo install --force --vers 0.0.124
If the selected version still fails to compile, I just pick the previous one until I find one that works.
Since I always keep the stable toolchain as default, running
cargo clippy as-is will result in an error:
0 19:40:53 lvillani@oculus ~/D/borg-hive (master=) $ cargo clippy dyld: Library not loaded: @rpath/librustc_driver-8dacd42830809d58.dylib Referenced from: /Users/lvillani/.cargo/bin/cargo-clippy Reason: image not found error: An unknown error occurred To learn more, run the command again with --verbose.
Since we have
rustup, running Clippy with the nightly toolchain we installed before is easy:
rustup run nightly-2017-04-15 cargo clippy
If, for some reason, running
cargo build with the stable toolchain after Clippy ends up
recompiling all dependencies, just tell Cargo to put its output files in a separate directory like
env CARGO_TARGET_DIR=./target/clippy rustup run nightly-2017-04-15 cargo clippy
This is especially useful if you then want to remove only the output files generated by a Clippy run.
Most nightly features are behind a feature-gate, which means that you won’t accidentally use them. sometimes, though, rustc may change behavior without you noticing. For example, struct field reordering has been recently enabled, breaking programs that relied on previous behavior (I’m just making an example, excluding the fact that Rust doesn’t specify an ABI and people shouldn’t rely on the compiler’s behavior in this case). I prefer to know about behavior changes by reading release notes published with each new stable release instead of having to wade through commit logs. ↩