]> git.lizzy.rs Git - rust.git/blob - CONTRIBUTING.md
Move parts of CONTRIBUTING.md to the book
[rust.git] / CONTRIBUTING.md
1 # Contributing to Clippy
2
3 Hello fellow Rustacean! Great to see your interest in compiler internals and lints!
4
5 **First**: if you're unsure or afraid of _anything_, just ask or submit the issue or pull request anyway. You won't be
6 yelled at for giving it your best effort. The worst that can happen is that you'll be politely asked to change
7 something. We appreciate any sort of contributions, and don't want a wall of rules to get in the way of that.
8
9 Clippy welcomes contributions from everyone. There are many ways to contribute to Clippy and the following document
10 explains how you can contribute and how to get started.  If you have any questions about contributing or need help with
11 anything, feel free to ask questions on issues or visit the `#clippy` on [Zulip].
12
13 All contributors are expected to follow the [Rust Code of Conduct].
14
15 - [Contributing to Clippy](#contributing-to-clippy)
16   - [The Clippy book](#the-clippy-book)
17   - [High level approach](#high-level-approach)
18   - [Finding something to fix/improve](#finding-something-to-fiximprove)
19   - [Writing code](#writing-code)
20   - [Getting code-completion for rustc internals to work](#getting-code-completion-for-rustc-internals-to-work)
21     - [IntelliJ Rust](#intellij-rust)
22     - [Rust Analyzer](#rust-analyzer)
23   - [How Clippy works](#how-clippy-works)
24   - [Issue and PR triage](#issue-and-pr-triage)
25   - [Bors and Homu](#bors-and-homu)
26   - [Contributions](#contributions)
27
28 [Zulip]: https://rust-lang.zulipchat.com/#narrow/stream/clippy
29 [Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct
30
31 ## The Clippy book
32
33 If you're new to Clippy and don't know where to start the [Clippy book] includes
34 a developer guide and is a good place to start your journey.
35
36 <!-- FIXME: Link to the deployed book, once it is deployed through CI -->
37 [Clippy book]: book/src
38
39 ## High level approach
40
41 1. Find something to fix/improve
42 2. Change code (likely some file in `clippy_lints/src/`)
43 3. Follow the instructions in the [Basics docs](book/src/development/basics.md)
44    to get set up
45 4. Run `cargo test` in the root directory and wiggle code until it passes
46 5. Open a PR (also can be done after 2. if you run into problems)
47
48 ## Finding something to fix/improve
49
50 All issues on Clippy are mentored, if you want help simply ask @Manishearth, @flip1995, @phansch
51 or @llogiq directly by mentioning them in the issue or over on [Zulip]. This list may be out of date.
52 All currently active mentors can be found [here](https://github.com/rust-lang/highfive/blob/master/highfive/configs/rust-lang/rust-clippy.json#L3)
53
54 Some issues are easier than others. The [`good-first-issue`] label can be used to find the easy
55 issues. You can use `@rustbot claim` to assign the issue to yourself.
56
57 There are also some abandoned PRs, marked with [`S-inactive-closed`].
58 Pretty often these PRs are nearly completed and just need some extra steps
59 (formatting, addressing review comments, ...) to be merged. If you want to
60 complete such a PR, please leave a comment in the PR and open a new one based
61 on it.
62
63 Issues marked [`T-AST`] involve simple matching of the syntax tree structure,
64 and are generally easier than [`T-middle`] issues, which involve types
65 and resolved paths.
66
67 [`T-AST`] issues will generally need you to match against a predefined syntax structure.
68 To figure out how this syntax structure is encoded in the AST, it is recommended to run
69 `rustc -Z unpretty=ast-tree` on an example of the structure and compare with the [nodes in the AST docs].
70 Usually the lint will end up to be a nested series of matches and ifs, [like so][deep-nesting].
71 But we can make it nest-less by using [let chains], [like this][nest-less].
72
73 [`E-medium`] issues are generally pretty easy too, though it's recommended you work on an [`good-first-issue`]
74 first. Sometimes they are only somewhat involved code wise, but not difficult per-se.
75 Note that [`E-medium`] issues may require some knowledge of Clippy internals or some
76 debugging to find the actual problem behind the issue.
77
78 [`T-middle`] issues can be more involved and require verifying types. The [`ty`] module contains a
79 lot of methods that are useful, though one of the most useful would be `expr_ty` (gives the type of
80 an AST expression). `match_def_path()` in Clippy's `utils` module can also be useful.
81
82 [`good-first-issue`]: https://github.com/rust-lang/rust-clippy/labels/good-first-issue
83 [`S-inactive-closed`]: https://github.com/rust-lang/rust-clippy/pulls?q=is%3Aclosed+label%3AS-inactive-closed
84 [`T-AST`]: https://github.com/rust-lang/rust-clippy/labels/T-AST
85 [`T-middle`]: https://github.com/rust-lang/rust-clippy/labels/T-middle
86 [`E-medium`]: https://github.com/rust-lang/rust-clippy/labels/E-medium
87 [`ty`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty
88 [nodes in the AST docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast/ast/
89 [deep-nesting]: https://github.com/rust-lang/rust-clippy/blob/5e4f0922911536f80d9591180fa604229ac13939/clippy_lints/src/mem_forget.rs#L31-L45
90 [let chains]: https://github.com/rust-lang/rust/pull/94927
91 [nest-less]: https://github.com/rust-lang/rust-clippy/blob/5e4f0922911536f80d9591180fa604229ac13939/clippy_lints/src/bit_mask.rs#L133-L159
92
93 ## Getting code-completion for rustc internals to work
94
95 ### IntelliJ Rust
96 Unfortunately, [`IntelliJ Rust`][IntelliJ_rust_homepage] does not (yet?) understand how Clippy uses compiler-internals
97 using `extern crate` and it also needs to be able to read the source files of the rustc-compiler which are not
98 available via a `rustup` component at the time of writing.
99 To work around this, you need to have a copy of the [rustc-repo][rustc_repo] available which can be obtained via
100 `git clone https://github.com/rust-lang/rust/`.
101 Then you can run a `cargo dev` command to automatically make Clippy use the rustc-repo via path-dependencies
102 which `IntelliJ Rust` will be able to understand.
103 Run `cargo dev setup intellij --repo-path <repo-path>` where `<repo-path>` is a path to the rustc repo
104 you just cloned.
105 The command will add path-dependencies pointing towards rustc-crates inside the rustc repo to
106 Clippy's `Cargo.toml`s and should allow `IntelliJ Rust` to understand most of the types that Clippy uses.
107 Just make sure to remove the dependencies again before finally making a pull request!
108
109 [rustc_repo]: https://github.com/rust-lang/rust/
110 [IntelliJ_rust_homepage]: https://intellij-rust.github.io/
111
112 ### Rust Analyzer
113 As of [#6869][6869], [`rust-analyzer`][ra_homepage] can understand that Clippy uses compiler-internals
114 using `extern crate` when `package.metadata.rust-analyzer.rustc_private` is set to `true` in Clippy's `Cargo.toml.`
115 You will require a `nightly` toolchain with the `rustc-dev` component installed.
116 Make sure that in the `rust-analyzer` configuration, you set
117 ```
118 { "rust-analyzer.rustcSource": "discover" }
119 ```
120 and
121 ```
122 { "rust-analyzer.updates.channel": "nightly" }
123 ```
124 You should be able to see information on things like `Expr` or `EarlyContext` now if you hover them, also
125 a lot more type hints.
126 This will work with `rust-analyzer 2021-03-15` shipped in nightly `1.52.0-nightly (107896c32 2021-03-15)` or later.
127
128 [ra_homepage]: https://rust-analyzer.github.io/
129 [6869]: https://github.com/rust-lang/rust-clippy/pull/6869
130
131 ## How Clippy works
132
133 [`clippy_lints/src/lib.rs`][lint_crate_entry] imports all the different lint modules and registers in the [`LintStore`].
134 For example, the [`else_if_without_else`][else_if_without_else] lint is registered like this:
135
136 ```rust
137 // ./clippy_lints/src/lib.rs
138
139 // ...
140 pub mod else_if_without_else;
141 // ...
142
143 pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: &Conf) {
144     // ...
145     store.register_early_pass(|| box else_if_without_else::ElseIfWithoutElse);
146     // ...
147
148     store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
149         // ...
150         LintId::of(&else_if_without_else::ELSE_IF_WITHOUT_ELSE),
151         // ...
152     ]);
153 }
154 ```
155
156 The [`rustc_lint::LintStore`][`LintStore`] provides two methods to register lints:
157 [register_early_pass][reg_early_pass] and [register_late_pass][reg_late_pass]. Both take an object
158 that implements an [`EarlyLintPass`][early_lint_pass] or [`LateLintPass`][late_lint_pass] respectively. This is done in
159 every single lint. It's worth noting that the majority of `clippy_lints/src/lib.rs` is autogenerated by `cargo dev
160 update_lints`. When you are writing your own lint, you can use that script to save you some time.
161
162 ```rust
163 // ./clippy_lints/src/else_if_without_else.rs
164
165 use rustc_lint::{EarlyLintPass, EarlyContext};
166
167 // ...
168
169 pub struct ElseIfWithoutElse;
170
171 // ...
172
173 impl EarlyLintPass for ElseIfWithoutElse {
174     // ... the functions needed, to make the lint work
175 }
176 ```
177
178 The difference between `EarlyLintPass` and `LateLintPass` is that the methods of the `EarlyLintPass` trait only provide
179 AST information. The methods of the `LateLintPass` trait are executed after type checking and contain type information
180 via the `LateContext` parameter.
181
182 That's why the `else_if_without_else` example uses the `register_early_pass` function. Because the
183 [actual lint logic][else_if_without_else] does not depend on any type information.
184
185 [lint_crate_entry]: https://github.com/rust-lang/rust-clippy/blob/master/clippy_lints/src/lib.rs
186 [else_if_without_else]: https://github.com/rust-lang/rust-clippy/blob/4253aa7137cb7378acc96133c787e49a345c2b3c/clippy_lints/src/else_if_without_else.rs
187 [`LintStore`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html
188 [reg_early_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html#method.register_early_pass
189 [reg_late_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html#method.register_late_pass
190 [early_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.EarlyLintPass.html
191 [late_lint_pass]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/trait.LateLintPass.html
192
193 ## Issue and PR triage
194
195 Clippy is following the [Rust triage procedure][triage] for issues and pull
196 requests.
197
198 However, we are a smaller project with all contributors being volunteers
199 currently. Between writing new lints, fixing issues, reviewing pull requests and
200 responding to issues there may not always be enough time to stay on top of it
201 all.
202
203 Our highest priority is fixing [crashes][l-crash] and [bugs][l-bug], for example
204 an ICE in a popular crate that many other crates depend on. We don't
205 want Clippy to crash on your code and we want it to be as reliable as the
206 suggestions from Rust compiler errors.
207
208 We have prioritization labels and a sync-blocker label, which are described below.
209 - [P-low][p-low]: Requires attention (fix/response/evaluation) by a team member but isn't urgent.
210 - [P-medium][p-medium]: Should be addressed by a team member until the next sync.
211 - [P-high][p-high]: Should be immediately addressed and will require an out-of-cycle sync or a backport.
212 - [L-sync-blocker][l-sync-blocker]: An issue that "blocks" a sync.
213 Or rather: before the sync this should be addressed,
214 e.g. by removing a lint again, so it doesn't hit beta/stable.
215
216 ## Bors and Homu
217
218 We use a bot powered by [Homu][homu] to help automate testing and landing of pull
219 requests in Clippy. The bot's username is @bors.
220
221 You can find the Clippy bors queue [here][homu_queue].
222
223 If you have @bors permissions, you can find an overview of the available
224 commands [here][homu_instructions].
225
226 [triage]: https://forge.rust-lang.org/release/triage-procedure.html
227 [l-crash]: https://github.com/rust-lang/rust-clippy/labels/L-crash
228 [l-bug]: https://github.com/rust-lang/rust-clippy/labels/L-bug
229 [p-low]: https://github.com/rust-lang/rust-clippy/labels/P-low
230 [p-medium]: https://github.com/rust-lang/rust-clippy/labels/P-medium
231 [p-high]: https://github.com/rust-lang/rust-clippy/labels/P-high
232 [l-sync-blocker]: https://github.com/rust-lang/rust-clippy/labels/L-sync-blocker
233 [homu]: https://github.com/rust-lang/homu
234 [homu_instructions]: https://bors.rust-lang.org/
235 [homu_queue]: https://bors.rust-lang.org/queue/clippy
236
237 ## Contributions
238
239 Contributions to Clippy should be made in the form of GitHub pull requests. Each pull request will
240 be reviewed by a core contributor (someone with permission to land patches) and either landed in the
241 main tree or given feedback for changes that would be required.
242
243 All code in this repository is under the [Apache-2.0] or the [MIT] license.
244
245 <!-- adapted from https://github.com/servo/servo/blob/master/CONTRIBUTING.md -->
246
247 [Apache-2.0]: https://www.apache.org/licenses/LICENSE-2.0
248 [MIT]: https://opensource.org/licenses/MIT