You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Auto merge of #3824 - phansch:adding_lints, r=phansch
Add lint writing documentation
[Rendered](https://github.com/phansch/rust-clippy/blob/adding_lints/doc/adding_lints.md)
This adds a new documentation page that explains how to write Clippy
lints. It guides the reader through creating a `foo` function lint.
I plan to iterate a bit more on the prose of some sections, but I think the
general structure is fine now, so I'm looking forward to feedback =)
One thing I'm not sure about: I felt like this is too big for CONTRIBUTING.md
so I put it into a new `doc/` directory. I can imagine having more
documentation in the future, so we might even want to create a book using
mdbook instead? Or should everything go into CONTRIBUTING.md?
Further things left to do:
- [x] Link from CONTRIBUTING.md
- [x] Remove things covered in this guide from CONTRIBUTING.md
- [x] Section about `clippy::author` attribute
- [x] Run `remark-lint` on CI over the `doc` directory and fix things
@@ -73,121 +68,15 @@ an AST expression). `match_def_path()` in Clippy's `utils` module can also be us
73
68
74
69
## Writing code
75
70
76
-
Clippy depends on the current git master version of rustc, which can change rapidly. Make sure you're
77
-
working near rust-clippy's master, and use the `setup-toolchain.sh` script to configure the appropriate
78
-
toolchain for this directory.
79
-
80
-
[Llogiq's blog post on lints](https://llogiq.github.io/2015/06/04/workflows.html) is a nice primer
81
-
to lint-writing, though it does get into advanced stuff. Most lints consist of an implementation of
82
-
`LintPass` with one or more of its default methods overridden. See the existing lints for examples
83
-
of this.
71
+
Have a look at the [docs for writing lints](doc/adding_lints.md) for more details. [Llogiq's blog post on lints](https://llogiq.github.io/2015/06/04/workflows.html) is also a nice primer
72
+
to lint-writing, though it does get into advanced stuff and may be a bit
73
+
outdated.
84
74
85
75
If you want to add a new lint or change existing ones apart from bugfixing, it's
86
76
also a good idea to give the [stability guarantees][rfc_stability] and
87
77
[lint categories][rfc_lint_cats] sections of the [Clippy 1.0 RFC][clippy_rfc] a
88
78
quick read.
89
79
90
-
### Author lint
91
-
92
-
There is also the internal `author` lint to generate Clippy code that detects the offending pattern. It does not work for all of the Rust syntax, but can give a good starting point.
93
-
94
-
First, create a new UI test file in the `tests/ui/` directory with the pattern you want to match:
95
-
96
-
```rust
97
-
// ./tests/ui/my_lint.rs
98
-
fnmain() {
99
-
#[clippy::author]
100
-
letarr: [i32; 1] = [7]; // Replace line with the code you want to match
101
-
}
102
-
```
103
-
104
-
Now you run `TESTNAME=ui/my_lint cargo uitest` to produce
105
-
a `.stdout` file with the generated code:
106
-
107
-
```rust
108
-
// ./tests/ui/my_lint.stdout
109
-
110
-
if_chain! {
111
-
ifletExprKind::Array(refelements) =stmt.node;
112
-
ifelements.len() ==1;
113
-
ifletExprKind::Lit(reflit) =elements[0].node;
114
-
ifletLitKind::Int(7, _) =lit.node;
115
-
then {
116
-
// report your lint here
117
-
}
118
-
}
119
-
```
120
-
121
-
If the command was executed successfully, you can copy the code over to where you are implementing your lint.
122
-
123
-
### Documentation
124
-
125
-
Please document your lint with a doc comment akin to the following:
126
-
127
-
```rust
128
-
/// **What it does:** Checks for ... (describe what the lint matches).
129
-
///
130
-
/// **Why is this bad?** Supply the reason for linting the code.
131
-
///
132
-
/// **Known problems:** None. (Or describe where it could go wrong.)
133
-
///
134
-
/// **Example:**
135
-
///
136
-
/// ```rust
137
-
/// // Bad
138
-
/// Insert a short example of code that triggers the lint
139
-
///
140
-
/// // Good
141
-
/// Insert a short example of improved code that doesn't trigger the lint
142
-
/// ```
143
-
```
144
-
145
-
Once your lint is merged it will show up in the [lint list](https://rust-lang.github.io/rust-clippy/master/index.html)
146
-
147
-
### Running test suite
148
-
149
-
Use `cargo test` to run the whole testsuite.
150
-
151
-
If you don't want to wait for all tests to finish, you can also execute a single test file by using `TESTNAME` to specify the test to run:
Clippy uses UI tests. UI tests check that the output of the compiler is exactly as expected.
158
-
Of course there's little sense in writing the output yourself or copying it around.
159
-
Therefore you should use `tests/ui/update-all-references.sh` (after running
160
-
`cargo test`) and check whether the output looks as you expect with `git diff`. Commit all
161
-
`*.stderr` files, too.
162
-
163
-
If the lint you are working on is making use of structured suggestions, the
164
-
test file should include a `// run-rustfix` comment at the top. This will
165
-
additionally run [rustfix](https://github.com/rust-lang-nursery/rustfix) for
166
-
that test. Rustfix will apply the suggestions from the lint to the code of the
167
-
test file and compare that to the contents of a `.fixed` file.
168
-
169
-
Use `tests/ui/update-all-references.sh` to automatically generate the
170
-
`.fixed` file after running `cargo test`.
171
-
172
-
### Running rustfmt
173
-
174
-
[Rustfmt](https://github.com/rust-lang/rustfmt) is a tool for formatting Rust code according
175
-
to style guidelines. The code has to be formatted by `rustfmt` before a PR will be merged.
176
-
177
-
It can be installed via `rustup`:
178
-
```bash
179
-
rustup component add rustfmt
180
-
```
181
-
182
-
Use `cargo fmt --all` to format the whole codebase.
183
-
184
-
### Testing manually
185
-
186
-
Manually testing against an example file is useful if you have added some
187
-
`println!`s and test suite output becomes unreadable. To try Clippy with your
188
-
local modifications, run `env CLIPPY_TESTS=true cargo run --bin clippy-driver -- -L ./target/debug input.rs`
189
-
from the working copy root.
190
-
191
80
## How Clippy works
192
81
193
82
Clippy is a [rustc compiler plugin][compiler_plugin]. The main entry point is at [`src/lib.rs`][main_entry]. In there, the lint registration is delegated to the [`clippy_lints`][lint_crate] crate.
0 commit comments