Skip to content

Commit af38579

Browse files
committed
Move internal documentation to book
1 parent 853d7ee commit af38579

File tree

12 files changed

+263
-1835
lines changed

12 files changed

+263
-1835
lines changed

book/src/development/adding_lints.md

Lines changed: 76 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,24 @@ because that's clearly a non-descriptive name.
1111
- [Setup](#setup)
1212
- [Getting Started](#getting-started)
1313
- [Testing](#testing)
14+
- [Cargo lints](#cargo-lints)
1415
- [Rustfix tests](#rustfix-tests)
1516
- [Edition 2018 tests](#edition-2018-tests)
1617
- [Testing manually](#testing-manually)
1718
- [Lint declaration](#lint-declaration)
19+
- [Lint registration](#lint-registration)
1820
- [Lint passes](#lint-passes)
1921
- [Emitting a lint](#emitting-a-lint)
2022
- [Adding the lint logic](#adding-the-lint-logic)
2123
- [Specifying the lint's minimum supported Rust version (MSRV)](#specifying-the-lints-minimum-supported-rust-version-msrv)
2224
- [Author lint](#author-lint)
25+
- [Print HIR lint](#print-hir-lint)
2326
- [Documentation](#documentation)
2427
- [Running rustfmt](#running-rustfmt)
2528
- [Debugging](#debugging)
2629
- [PR Checklist](#pr-checklist)
2730
- [Adding configuration to a lint](#adding-configuration-to-a-lint)
28-
- [Cheatsheet](#cheatsheet)
31+
- [Cheat Sheet](#cheat-sheet)
2932

3033
## Setup
3134

@@ -42,9 +45,9 @@ take a look at our [lint naming guidelines][lint_naming]. To get started on this
4245
lint you can run `cargo dev new_lint --name=foo_functions --pass=early
4346
--category=pedantic` (category will default to nursery if not provided). This
4447
command will create two files: `tests/ui/foo_functions.rs` and
45-
`clippy_lints/src/foo_functions.rs`, as well as run `cargo dev update_lints` to
46-
register the new lint. For cargo lints, two project hierarchies (fail/pass) will
47-
be created by default under `tests/ui-cargo`.
48+
`clippy_lints/src/foo_functions.rs`, as well as
49+
[registering the lint](#lint-registration). For cargo lints, two project
50+
hierarchies (fail/pass) will be created by default under `tests/ui-cargo`.
4851

4952
Next, we'll open up these files and add our lint!
5053

@@ -155,7 +158,7 @@ Manually testing against an example file can be useful if you have added some
155158
your local modifications, run
156159

157160
```
158-
env __CLIPPY_INTERNAL_TESTS=true cargo run --bin clippy-driver -- -L ./target/debug input.rs
161+
cargo dev lint input.rs
159162
```
160163

161164
from the working copy root. With tests in place, let's have a look at
@@ -179,17 +182,15 @@ the auto-generated lint declaration to have a real description, something like t
179182

180183
```rust
181184
declare_clippy_lint! {
182-
/// **What it does:**
185+
/// ### What it does
183186
///
184-
/// **Why is this bad?**
185-
///
186-
/// **Known problems:** None.
187-
///
188-
/// **Example:**
187+
/// ### Why is this bad?
189188
///
189+
/// ### Example
190190
/// ```rust
191191
/// // example code
192192
/// ```
193+
#[clippy::version = "1.29.0"]
193194
pub FOO_FUNCTIONS,
194195
pedantic,
195196
"function named `foo`, which is not a descriptive name"
@@ -200,6 +201,10 @@ declare_clippy_lint! {
200201
section. This is the default documentation style and will be displayed
201202
[like this][example_lint_page]. To render and open this documentation locally
202203
in a browser, run `cargo dev serve`.
204+
* The `#[clippy::version]` attribute will be rendered as part of the lint documentation.
205+
The value should be set to the current Rust version that the lint is developed in,
206+
it can be retrieved by running `rustc -vV` in the rust-clippy directory. The version
207+
is listed under *release*. (Use the version without the `-nightly`) suffix.
203208
* `FOO_FUNCTIONS` is the name of our lint. Be sure to follow the
204209
[lint naming guidelines][lint_naming] here when naming your lint.
205210
In short, the name should state the thing that is being checked for and
@@ -222,32 +227,34 @@ declare_lint_pass!(FooFunctions => [FOO_FUNCTIONS]);
222227
impl EarlyLintPass for FooFunctions {}
223228
```
224229

225-
Normally after declaring the lint, we have to run `cargo dev update_lints`,
226-
which updates some files, so Clippy knows about the new lint. Since we used
227-
`cargo dev new_lint ...` to generate the lint declaration, this was done
228-
automatically. While `update_lints` automates most of the things, it doesn't
229-
automate everything. We will have to register our lint pass manually in the
230-
`register_plugins` function in `clippy_lints/src/lib.rs`:
230+
[declare_clippy_lint]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L60
231+
[example_lint_page]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
232+
[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
233+
[category_level_mapping]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L110
234+
235+
## Lint registration
236+
237+
When using `cargo dev new_lint`, the lint is automatically registered and
238+
nothing more has to be done.
239+
240+
When declaring a new lint by hand and `cargo dev update_lints` is used, the lint
241+
pass may have to be registered manually in the `register_plugins` function in
242+
`clippy_lints/src/lib.rs`:
231243

232244
```rust
233-
store.register_early_pass(|| box foo_functions::FooFunctions);
245+
store.register_early_pass(|| Box::new(foo_functions::FooFunctions));
234246
```
235247

236248
As one may expect, there is a corresponding `register_late_pass` method
237249
available as well. Without a call to one of `register_early_pass` or
238250
`register_late_pass`, the lint pass in question will not be run.
239251

240-
One reason that `cargo dev` does not automate this step is that multiple lints
241-
can use the same lint pass, so registering the lint pass may already be done
242-
when adding a new lint. Another reason that this step is not automated is that
243-
the order that the passes are registered determines the order the passes
244-
actually run, which in turn affects the order that any emitted lints are output
245-
in.
246-
247-
[declare_clippy_lint]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L60
248-
[example_lint_page]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure
249-
[lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
250-
[category_level_mapping]: https://github.com/rust-lang/rust-clippy/blob/557f6848bd5b7183f55c1e1522a326e9e1df6030/clippy_lints/src/lib.rs#L110
252+
One reason that `cargo dev update_lints` does not automate this step is that
253+
multiple lints can use the same lint pass, so registering the lint pass may
254+
already be done when adding a new lint. Another reason that this step is not
255+
automated is that the order that the passes are registered determines the order
256+
the passes actually run, which in turn affects the order that any emitted lints
257+
are output in.
251258

252259
## Lint passes
253260

@@ -425,7 +432,7 @@ The project's MSRV can then be matched against the feature MSRV in the LintPass
425432
using the `meets_msrv` utility function.
426433

427434
``` rust
428-
if !meets_msrv(self.msrv.as_ref(), &msrvs::STR_STRIP_PREFIX) {
435+
if !meets_msrv(self.msrv, msrvs::STR_STRIP_PREFIX) {
429436
return;
430437
}
431438
```
@@ -478,6 +485,19 @@ you are implementing your lint.
478485

479486
[author_example]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=9a12cb60e5c6ad4e3003ac6d5e63cf55
480487

488+
## Print HIR lint
489+
490+
To implement a lint, it's helpful to first understand the internal representation
491+
that rustc uses. Clippy has the `#[clippy::dump]` attribute that prints the
492+
[_High-Level Intermediate Representation (HIR)_] of the item, statement, or
493+
expression that the attribute is attached to. To attach the attribute to expressions
494+
you often need to enable `#![feature(stmt_expr_attributes)]`.
495+
496+
[Here][print_hir_example] you can find an example, just select _Tools_ and run _Clippy_.
497+
498+
[_High-Level Intermediate Representation (HIR)_]: https://rustc-dev-guide.rust-lang.org/hir.html
499+
[print_hir_example]: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=daf14db3a7f39ca467cd1b86c34b9afb
500+
481501
## Documentation
482502

483503
The final thing before submitting our PR is to add some documentation to our
@@ -487,21 +507,23 @@ Please document your lint with a doc comment akin to the following:
487507

488508
```rust
489509
declare_clippy_lint! {
490-
/// **What it does:** Checks for ... (describe what the lint matches).
510+
/// ### What it does
511+
/// Checks for ... (describe what the lint matches).
491512
///
492-
/// **Why is this bad?** Supply the reason for linting the code.
513+
/// ### Why is this bad?
514+
/// Supply the reason for linting the code.
493515
///
494-
/// **Known problems:** None. (Or describe where it could go wrong.)
495-
///
496-
/// **Example:**
516+
/// ### Example
497517
///
498518
/// ```rust,ignore
499-
/// // Bad
500-
/// Insert a short example of code that triggers the lint
501-
///
502-
/// // Good
503-
/// Insert a short example of improved code that doesn't trigger the lint
519+
/// // A short example of code that triggers the lint
504520
/// ```
521+
///
522+
/// Use instead:
523+
/// ```rust,ignore
524+
/// // A short example of improved code that doesn't trigger the lint
525+
/// ```
526+
#[clippy::version = "1.29.0"]
505527
pub FOO_FUNCTIONS,
506528
pedantic,
507529
"function named `foo`, which is not a descriptive name"
@@ -558,14 +580,16 @@ directory. Adding a configuration to a lint can be useful for thresholds or to c
558580
behavior that can be seen as a false positive for some users. Adding a configuration is done
559581
in the following steps:
560582

561-
1. Adding a new configuration entry to [clippy_utils::conf](/clippy_utils/src/conf.rs)
583+
1. Adding a new configuration entry to [clippy_lints::utils::conf](/clippy_lints/src/utils/conf.rs)
562584
like this:
563585
```rust
564-
/// Lint: LINT_NAME. <The configuration field doc comment>
586+
/// Lint: LINT_NAME.
587+
///
588+
/// <The configuration field doc comment>
565589
(configuration_ident: Type = DefaultValue),
566590
```
567-
The configuration value and identifier should usually be the same. The doc comment will be
568-
automatically added to the lint documentation.
591+
The doc comment is automatically added to the documentation of the listed lints. The default
592+
value will be formatted using the `Debug` implementation of the type.
569593
2. Adding the configuration value to the lint impl struct:
570594
1. This first requires the definition of a lint impl struct. Lint impl structs are usually
571595
generated with the `declare_lint_pass!` macro. This struct needs to be defined manually
@@ -626,14 +650,14 @@ in the following steps:
626650
with the configuration value and a rust file that should be linted by Clippy. The test can
627651
otherwise be written as usual.
628652

629-
## Cheatsheet
653+
## Cheat Sheet
630654

631655
Here are some pointers to things you are likely going to need for every lint:
632656

633657
* [Clippy utils][utils] - Various helper functions. Maybe the function you need
634-
is already in here (`implements_trait`, `match_def_path`, `snippet`, etc)
658+
is already in here ([`is_type_diagnostic_item`], [`implements_trait`], [`snippet`], etc)
635659
* [Clippy diagnostics][diagnostics]
636-
* [The `if_chain` macro][if_chain]
660+
* [Let chains][let-chains]
637661
* [`from_expansion`][from_expansion] and [`in_external_macro`][in_external_macro]
638662
* [`Span`][span]
639663
* [`Applicability`][applicability]
@@ -657,8 +681,11 @@ documentation currently. This is unfortunate, but in most cases you can probably
657681
get away with copying things from existing similar lints. If you are stuck,
658682
don't hesitate to ask on [Zulip] or in the issue/PR.
659683

660-
[utils]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_utils/src/lib.rs
661-
[if_chain]: https://docs.rs/if_chain/*/if_chain/
684+
[utils]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/index.html
685+
[`is_type_diagnostic_item`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/ty/fn.is_type_diagnostic_item.html
686+
[`implements_trait`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/ty/fn.implements_trait.html
687+
[`snippet`]: https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/source/fn.snippet.html
688+
[let-chains]: https://github.com/rust-lang/rust/pull/94927
662689
[from_expansion]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html#method.from_expansion
663690
[in_external_macro]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/lint/fn.in_external_macro.html
664691
[span]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.Span.html

book/src/development/basics.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -91,15 +91,18 @@ cargo dev fmt
9191
cargo dev update_lints
9292
# create a new lint and register it
9393
cargo dev new_lint
94+
# automatically formatting all code before each commit
95+
cargo dev setup git-hook
9496
# (experimental) Setup Clippy to work with IntelliJ-Rust
95-
cargo dev ide_setup
97+
cargo dev setup intellij
9698
```
99+
More about intellij command usage and reasons [here](../CONTRIBUTING.md#intellij-rust)
97100

98101
## lintcheck
99102
`cargo lintcheck` will build and run clippy on a fixed set of crates and generate a log of the results.
100-
You can `git diff` the updated log against its previous version and
103+
You can `git diff` the updated log against its previous version and
101104
see what impact your lint made on a small set of crates.
102-
If you add a new lint, please audit the resulting warnings and make sure
105+
If you add a new lint, please audit the resulting warnings and make sure
103106
there are no false positives and that the suggestions are valid.
104107

105108
Refer to the tools [README] for more details.
@@ -167,6 +170,5 @@ rustup component add clippy
167170
> [proxies](https://rust-lang.github.io/rustup/concepts/proxies.html). That is, `~/.cargo/bin/cargo-clippy` and
168171
> `~/.cargo/bin/clippy-driver` should be hard or soft links to `~/.cargo/bin/rustup`. You can repair these by running
169172
> `rustup update`.
170-
171-
173+
172174
[glossary]: https://rustc-dev-guide.rust-lang.org/appendix/glossary.html

0 commit comments

Comments
 (0)