1
1
# Lints
2
+
2
3
This page documents some of the machinery around lint registration and how we
3
4
run lints in the compiler.
4
5
@@ -8,18 +9,26 @@ everything rotates. It's not available during the early parts of compilation
8
9
lints, which can only happen after plugin registration.
9
10
10
11
## Lints vs. lint passes
12
+
11
13
There are two parts to the linting mechanism within the compiler: lints and
12
14
lint passes. Unfortunately, a lot of the documentation we have refers to both
13
15
of these as just "lints."
14
16
15
17
First, we have the lint declarations themselves: this is where the name and
16
18
default lint level and other metadata come from. These are normally defined by
17
19
way of the [ ` declare_lint! ` ] macro, which boils down to a static with type
18
- ` &rustc_session::lint::Lint ` .
20
+ [ ` &rustc_lint_defs::Lint ` ] .
21
+
22
+ First, we have the lint declarations themselves,
23
+ and this is where the name and default lint level and other metadata come from.
24
+ These are normally defined by way of the [ ` declare_lint! ` ] macro,
25
+ which boils down to a static with type [ ` &rustc_lint_defs::Lint ` ]
26
+ (although this may change in the future,
27
+ as the macro is somewhat unwieldy to add new fields to,
28
+ like all macros).
19
29
20
- As of <!-- date-check --> February 2022, we lint against direct declarations
21
- without the use of the macro today (although this may change in the future, as
22
- the macro is somewhat unwieldy to add new fields to, like all macros).
30
+ As of <!-- date-check --> Aug 2022,
31
+ we lint against direct declarations without the use of the macro.
23
32
24
33
Lint declarations don't carry any "state" - they are merely global identifiers
25
34
and descriptions of lints. We assert at runtime that they are not registered
@@ -34,8 +43,10 @@ lints are emitted as part of other work (e.g., type checking, etc.).
34
43
## Registration
35
44
36
45
### High-level overview
37
- In [ ` rustc_interface::register_plugins ` ] the [ ` LintStore ` ] is created and all
38
- lints are registered.
46
+
47
+ In [ ` rustc_interface::register_plugins ` ] ,
48
+ the [ ` LintStore ` ] is created,
49
+ and all lints are registered.
39
50
40
51
There are four 'sources' of lints:
41
52
@@ -61,6 +72,7 @@ then invoke the lint pass methods. The lint pass methods take `&mut self` so
61
72
they can keep track of state internally.
62
73
63
74
#### Internal lints
75
+
64
76
These are lints used just by the compiler or plugins like ` clippy ` . They can be
65
77
found in ` rustc_lint::internal ` .
66
78
@@ -73,16 +85,20 @@ function which is called when constructing a new lint store inside
73
85
[ ` rustc_lint::new_lint_store ` ] .
74
86
75
87
### Builtin Lints
76
- These are primarily described in two places: ` rustc_session::lint::builtin ` and
77
- ` rustc_lint::builtin ` . Often the first provides the definitions for the lints
78
- themselves, and the latter provides the lint pass definitions (and
79
- implementations), but this is not always true.
80
88
81
- The builtin lint registration happens in the [ ` rustc_lint::register_builtins ` ]
82
- function. Just like with internal lints, this happens inside of
83
- [ ` rustc_lint::new_lint_store ` ] .
89
+ These are primarily described in two places,
90
+ ` rustc_lint_defs::builtin ` and ` rustc_lint::builtin ` .
91
+ Often the first provides the definitions for the lints themselves,
92
+ and the latter provides the lint pass definitions (and implementations),
93
+ but this is not always true.
94
+
95
+ The builtin lint registration happens in
96
+ the [ ` rustc_lint::register_builtins ` ] function.
97
+ Just like with internal lints,
98
+ this happens inside of [ ` rustc_lint::new_lint_store ` ] .
84
99
85
100
#### Plugin lints
101
+
86
102
This is one of the primary use cases remaining for plugins/drivers. Plugins are
87
103
given access to the mutable ` LintStore ` during registration (which happens
88
104
inside of [ ` rustc_interface::register_plugins ` ] ) and they can call any
@@ -94,6 +110,7 @@ diagnostics and help text; otherwise plugin lints are mostly just as first
94
110
class as rustc builtin lints.
95
111
96
112
#### Driver lints
113
+
97
114
These are the lints provided by drivers via the ` rustc_interface::Config `
98
115
[ ` register_lints ` ] field, which is a callback. Drivers should, if finding it
99
116
already set, call the function currently set within the callback they add. The
@@ -102,6 +119,7 @@ best way for drivers to get access to this is by overriding the
102
119
structure.
103
120
104
121
## Compiler lint passes are combined into one pass
122
+
105
123
Within the compiler, for performance reasons, we usually do not register dozens
106
124
of lint passes. Instead, we have a single lint pass of each variety (e.g.,
107
125
` BuiltinCombinedModuleLateLintPass ` ) which will internally call all of the
@@ -121,3 +139,4 @@ approach, it is beneficial to do so for performance reasons.
121
139
[ `declare_lint!` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/macro.declare_lint.html
122
140
[ `declare_tool_lint!` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/macro.declare_tool_lint.html
123
141
[ `register_lints` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Config.html#structfield.register_lints
142
+ [ `&rustc_lint_defs::Lint` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/struct.Lint.html
0 commit comments