Skip to content

Commit 920112d

Browse files
committed
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
2 parents ccfbfb8 + 34685a5 commit 920112d

File tree

4 files changed

+455
-117
lines changed

4 files changed

+455
-117
lines changed

CONTRIBUTING.md

+3-114
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,6 @@ All contributors are expected to follow the [Rust Code of Conduct](http://www.ru
1414
* [Getting started](#getting-started)
1515
* [Finding something to fix/improve](#finding-something-to-fiximprove)
1616
* [Writing code](#writing-code)
17-
* [Author lint](#author-lint)
18-
* [Documentation](#documentation)
19-
* [Running test suite](#running-test-suite)
20-
* [Running rustfmt](#running-rustfmt)
21-
* [Testing manually](#testing-manually)
2217
* [How Clippy works](#how-clippy-works)
2318
* [Fixing nightly build failures](#fixing-build-failures-caused-by-rust)
2419
* [Issue and PR Triage](#issue-and-pr-triage)
@@ -73,121 +68,15 @@ an AST expression). `match_def_path()` in Clippy's `utils` module can also be us
7368

7469
## Writing code
7570

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.
8474

8575
If you want to add a new lint or change existing ones apart from bugfixing, it's
8676
also a good idea to give the [stability guarantees][rfc_stability] and
8777
[lint categories][rfc_lint_cats] sections of the [Clippy 1.0 RFC][clippy_rfc] a
8878
quick read.
8979

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-
fn main() {
99-
#[clippy::author]
100-
let arr: [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-
if let ExprKind::Array(ref elements) = stmt.node;
112-
if elements.len() == 1;
113-
if let ExprKind::Lit(ref lit) = elements[0].node;
114-
if let LitKind::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:
152-
153-
```bash
154-
TESTNAME=ui/empty_line_after_outer_attr cargo uitest
155-
```
156-
157-
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-
19180
## How Clippy works
19281

19382
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.

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,13 @@ script:
107107
- cargo clippy
108108
# if you want the build job to fail when encountering warnings, use
109109
- cargo clippy -- -D warnings
110-
# in order to also check tests and none-default crate features, use
110+
# in order to also check tests and non-default crate features, use
111111
- cargo clippy --all-targets --all-features -- -D warnings
112112
- cargo test
113113
# etc.
114114
```
115115

116-
It might happen that Clippy is not available for a certain nightly release.
116+
If you are on nightly, It might happen that Clippy is not available for a certain nightly release.
117117
In this case you can try to conditionally install Clippy from the git repo.
118118

119119
```yaml

ci/base-tests.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ echo "Running clippy base tests"
44

55
PATH=$PATH:./node_modules/.bin
66
if [ "$TRAVIS_OS_NAME" == "linux" ]; then
7-
remark -f *.md > /dev/null
7+
remark -f *.md -f doc/*.md > /dev/null
88
fi
99
# build clippy in debug mode and run tests
1010
cargo build --features debugging

0 commit comments

Comments
 (0)