]>
Commit | Line | Data |
---|---|---|
ea8adc8c XL |
1 | # rust-clippy |
2 | ||
3 | [![Build Status](https://travis-ci.org/rust-lang-nursery/rust-clippy.svg?branch=master)](https://travis-ci.org/rust-lang-nursery/rust-clippy) | |
4 | [![Windows build status](https://ci.appveyor.com/api/projects/status/github/rust-lang-nursery/rust-clippy?svg=true)](https://ci.appveyor.com/project/rust-lang-nursery/rust-clippy) | |
5 | [![Current Version](http://meritbadge.herokuapp.com/clippy)](https://crates.io/crates/clippy) | |
6 | [![License: MPL-2.0](https://img.shields.io/crates/l/clippy.svg)](#License) | |
7 | ||
abe05a73 | 8 | A collection of lints to catch common mistakes and improve your [Rust](https://github.com/rust-lang/rust) code. |
ea8adc8c | 9 | |
abe05a73 | 10 | [There are 208 lints included in this crate!](https://rust-lang-nursery.github.io/rust-clippy/master/index.html) |
ea8adc8c XL |
11 | |
12 | More to come, please [file an issue](https://github.com/rust-lang-nursery/rust-clippy/issues) if you have ideas! | |
13 | ||
14 | Table of contents: | |
15 | ||
16 | * [Usage instructions](#usage) | |
17 | * [Configuration](#configuration) | |
18 | * [License](#license) | |
19 | ||
20 | ## Usage | |
21 | ||
22 | Since this is a tool for helping the developer of a library or application | |
23 | write better code, it is recommended not to include clippy as a hard dependency. | |
24 | Options include using it as an optional dependency, as a cargo subcommand, or | |
25 | as an included feature during build. All of these options are detailed below. | |
26 | ||
27 | As a general rule clippy will only work with the *latest* Rust nightly for now. | |
28 | ||
29 | ### Optional dependency | |
30 | ||
31 | If you want to make clippy an optional dependency, you can do the following: | |
32 | ||
33 | In your `Cargo.toml`: | |
34 | ||
35 | ```toml | |
36 | [dependencies] | |
37 | clippy = {version = "*", optional = true} | |
38 | ||
39 | [features] | |
40 | default = [] | |
41 | ``` | |
42 | ||
43 | And, in your `main.rs` or `lib.rs`: | |
44 | ||
45 | ```rust | |
46 | #![cfg_attr(feature="clippy", feature(plugin))] | |
47 | ||
48 | #![cfg_attr(feature="clippy", plugin(clippy))] | |
49 | ``` | |
50 | ||
51 | Then build by enabling the feature: `cargo build --features "clippy"` | |
52 | ||
53 | Instead of adding the `cfg_attr` attributes you can also run clippy on demand: | |
54 | `cargo rustc --features clippy -- -Z no-trans -Z extra-plugins=clippy` | |
55 | (the `-Z no trans`, while not necessary, will stop the compilation process after | |
56 | typechecking (and lints) have completed, which can significantly reduce the runtime). | |
57 | ||
58 | ### As a cargo subcommand (`cargo clippy`) | |
59 | ||
60 | An alternate way to use clippy is by installing clippy through cargo as a cargo | |
61 | subcommand. | |
62 | ||
63 | ```terminal | |
64 | cargo install clippy | |
65 | ``` | |
66 | ||
67 | Now you can run clippy by invoking `cargo clippy`, or | |
68 | `rustup run nightly cargo clippy` directly from a directory that is usually | |
69 | compiled with stable. | |
70 | ||
71 | In case you are not using rustup, you need to set the environment flag | |
72 | `SYSROOT` during installation so clippy knows where to find `librustc` and | |
73 | similar crates. | |
74 | ||
75 | ```terminal | |
76 | SYSROOT=/path/to/rustc/sysroot cargo install clippy | |
77 | ``` | |
78 | ||
79 | ### Running clippy from the command line without installing | |
80 | ||
81 | To have cargo compile your crate with clippy without needing `#![plugin(clippy)]` | |
82 | in your code, you can use: | |
83 | ||
84 | ```terminal | |
85 | cargo rustc -- -L /path/to/clippy_so/dir/ -Z extra-plugins=clippy | |
86 | ``` | |
87 | ||
88 | *[Note](https://github.com/rust-lang-nursery/rust-clippy/wiki#a-word-of-warning):* | |
89 | Be sure that clippy was compiled with the same version of rustc that cargo invokes here! | |
90 | ||
91 | ### As a Compiler Plugin | |
92 | ||
93 | *Note:* This is not a recommended installation method. | |
94 | ||
95 | Since stable Rust is backwards compatible, you should be able to | |
96 | compile your stable programs with nightly Rust with clippy plugged in to | |
97 | circumvent this. | |
98 | ||
99 | Add in your `Cargo.toml`: | |
100 | ||
101 | ```toml | |
102 | [dependencies] | |
103 | clippy = "*" | |
104 | ``` | |
105 | ||
106 | You then need to add `#![feature(plugin)]` and `#![plugin(clippy)]` to the top | |
107 | of your crate entry point (`main.rs` or `lib.rs`). | |
108 | ||
109 | Sample `main.rs`: | |
110 | ||
111 | ```rust | |
112 | #![feature(plugin)] | |
113 | ||
114 | #![plugin(clippy)] | |
115 | ||
116 | ||
117 | fn main(){ | |
118 | let x = Some(1u8); | |
119 | match x { | |
120 | Some(y) => println!("{:?}", y), | |
121 | _ => () | |
122 | } | |
123 | } | |
124 | ``` | |
125 | ||
126 | Produces this warning: | |
127 | ||
128 | ```terminal | |
129 | src/main.rs:8:5: 11:6 warning: you seem to be trying to use match for destructuring a single type. Consider using `if let`, #[warn(single_match)] on by default | |
130 | src/main.rs:8 match x { | |
131 | src/main.rs:9 Some(y) => println!("{:?}", y), | |
132 | src/main.rs:10 _ => () | |
133 | src/main.rs:11 } | |
134 | src/main.rs:8:5: 11:6 help: Try | |
135 | if let Some(y) = x { println!("{:?}", y) } | |
136 | ``` | |
137 | ||
138 | ## Configuration | |
139 | ||
140 | Some lints can be configured in a `clippy.toml` file. It contains basic `variable = value` mapping eg. | |
141 | ||
142 | ```toml | |
143 | blacklisted-names = ["toto", "tata", "titi"] | |
144 | cyclomatic-complexity-threshold = 30 | |
145 | ``` | |
146 | ||
147 | See the wiki for more information about which lints can be configured and the | |
148 | meaning of the variables. | |
149 | ||
150 | You can also specify the path to the configuration file with: | |
151 | ||
152 | ```rust | |
153 | #![plugin(clippy(conf_file="path/to/clippy's/configuration"))] | |
154 | ``` | |
155 | ||
156 | To deactivate the “for further information visit *wiki-link*” message you can | |
157 | define the `CLIPPY_DISABLE_DOCS_LINKS` environment variable. | |
158 | ||
159 | ### Allowing/denying lints | |
160 | ||
161 | You can add options to `allow`/`warn`/`deny`: | |
162 | ||
163 | * the whole set of `Warn` lints using the `clippy` lint group (`#![deny(clippy)]`) | |
164 | ||
165 | * all lints using both the `clippy` and `clippy_pedantic` lint groups (`#![deny(clippy)]`, | |
166 | `#![deny(clippy_pedantic)]`). Note that `clippy_pedantic` contains some very aggressive | |
167 | lints prone to false positives. | |
168 | ||
169 | * only some lints (`#![deny(single_match, box_vec)]`, etc) | |
170 | ||
171 | * `allow`/`warn`/`deny` can be limited to a single function or module using `#[allow(...)]`, etc | |
172 | ||
173 | Note: `deny` produces errors instead of warnings. | |
174 | ||
175 | For convenience, `cargo clippy` automatically defines a `cargo-clippy` | |
176 | features. This lets you set lints level and compile with or without clippy | |
177 | transparently: | |
178 | ||
179 | ```rust | |
180 | #[cfg_attr(feature = "cargo-clippy", allow(needless_lifetimes))] | |
181 | ``` | |
182 | ||
abe05a73 XL |
183 | ## Updating rustc |
184 | ||
185 | Sometimes, rustc moves forward without clippy catching up. Therefore updating | |
186 | rustc may leave clippy a non-functional state until we fix the resulting | |
187 | breakage. | |
188 | ||
189 | You can use the [rust-update](rust-update) script to update rustc only if | |
190 | clippy would also update correctly. | |
191 | ||
ea8adc8c XL |
192 | ## License |
193 | ||
194 | Licensed under [MPL](https://www.mozilla.org/MPL/2.0/). | |
195 | If you're having issues with the license, let me know and I'll try to change it to something more permissive. |