33This page documents some of the machinery around lint registration and how we
44run lints in the compiler.
55
6- The [ ` LintStore ` ] is the central piece of infrastructure, around which
7- everything rotates. The ` LintStore ` is held as part of the [ ` Session ` ] , and it
6+ The [ ` LintStore ` ] is the central piece of infrastructure, around which everything rotates.
7+ The ` LintStore ` is held as part of the [ ` Session ` ] , and it
88gets populated with the list of lints shortly after the ` Session ` is created.
99
1010## Lints vs. lint passes
1111
12- There are two parts to the linting mechanism within the compiler: lints and
13- lint passes. Unfortunately, a lot of the documentation we have refers to both
14- of these as just "lints."
12+ There are two parts to the linting mechanism within the compiler: lints and lint passes.
13+ Unfortunately, a lot of the documentation we have refers to both of these as just "lints."
1514
1615First, we have the lint declarations themselves,
1716and this is where the name and default lint level and other metadata come from.
@@ -24,10 +23,11 @@ like all macros).
2423we lint against direct declarations without the use of the macro.
2524
2625Lint declarations don't carry any "state" - they are merely global identifiers
27- and descriptions of lints. We assert at runtime that they are not registered
28- twice (by lint name).
26+ and descriptions of lints.
27+ We assert at runtime that they are not registered twice (by lint name).
2928
30- Lint passes are the meat of any lint. Notably, there is not a one-to-one
29+ Lint passes are the meat of any lint.
30+ Notably, there is not a one-to-one
3131relationship between lints and lint passes; a lint might not have any lint pass
3232that emits it, it could have many, or just one -- the compiler doesn't track
3333whether a pass is in any way associated with a particular lint, and frequently
@@ -44,36 +44,33 @@ and all lints are registered.
4444There are three 'sources' of lints:
4545
4646* internal lints: lints only used by the rustc codebase
47- * builtin lints: lints built into the compiler and not provided by some outside
48- source
49- * ` rustc_interface::Config ` [ ` register_lints ` ] : lints passed into the compiler
50- during construction
47+ * builtin lints: lints built into the compiler and not provided by some outside source
48+ * ` rustc_interface::Config ` [ ` register_lints ` ] : lints passed into the compiler during construction
5149
52- Lints are registered via the [ ` LintStore::register_lint ` ] function. This should
53- happen just once for any lint, or an ICE will occur.
50+ Lints are registered via the [ ` LintStore::register_lint ` ] function.
51+ This should happen just once for any lint, or an ICE will occur.
5452
55- Once the registration is complete, we "freeze" the lint store by placing it in
56- an ` Arc ` .
53+ Once the registration is complete, we "freeze" the lint store by placing it in an ` Arc ` .
5754
5855Lint passes are registered separately into one of the categories
59- (pre-expansion, early, late, late module). Passes are registered as a closure
56+ (pre-expansion, early, late, late module).
57+ Passes are registered as a closure
6058-- i.e., ` impl Fn() -> Box<dyn X> ` , where ` dyn X ` is either an early or late
61- lint pass trait object. When we run the lint passes, we run the closure and
62- then invoke the lint pass methods. The lint pass methods take ` &mut self ` so
63- they can keep track of state internally.
59+ lint pass trait object.
60+ When we run the lint passes, we run the closure and then invoke the lint pass methods.
61+ The lint pass methods take ` &mut self ` so they can keep track of state internally.
6462
6563#### Internal lints
6664
67- These are lints used just by the compiler or drivers like ` clippy ` . They can be
68- found in [ ` rustc_lint::internal ` ] .
65+ These are lints used just by the compiler or drivers like ` clippy ` .
66+ They can be found in [ ` rustc_lint::internal ` ] .
6967
7068An example of such a lint is the check that lint passes are implemented using
71- the ` declare_lint_pass! ` macro and not by hand. This is accomplished with the
72- ` LINT_PASS_IMPL_WITHOUT_MACRO ` lint.
69+ the ` declare_lint_pass! ` macro and not by hand.
70+ This is accomplished with the ` LINT_PASS_IMPL_WITHOUT_MACRO ` lint.
7371
7472Registration of these lints happens in the [ ` rustc_lint::register_internals ` ]
75- function which is called when constructing a new lint store inside
76- [ ` rustc_lint::new_lint_store ` ] .
73+ function which is called when constructing a new lint store inside [ ` rustc_lint::new_lint_store ` ] .
7774
7875#### Builtin Lints
7976
@@ -83,19 +80,18 @@ Often the first provides the definitions for the lints themselves,
8380and the latter provides the lint pass definitions (and implementations),
8481but this is not always true.
8582
86- The builtin lint registration happens in
87- the [ ` rustc_lint::register_builtins ` ] function.
83+ The builtin lint registration happens in the [ ` rustc_lint::register_builtins ` ] function.
8884Just like with internal lints,
8985this happens inside of [ ` rustc_lint::new_lint_store ` ] .
9086
9187#### Driver lints
9288
9389These are the lints provided by drivers via the ` rustc_interface::Config `
94- [ ` register_lints ` ] field, which is a callback. Drivers should, if finding it
95- already set, call the function currently set within the callback they add. The
96- best way for drivers to get access to this is by overriding the
97- ` Callbacks::config ` function which gives them direct access to the ` Config `
98- structure.
90+ [ ` register_lints ` ] field, which is a callback.
91+ Drivers should, if finding it
92+ already set, call the function currently set within the callback they add.
93+ The best way for drivers to get access to this is by overriding the
94+ ` Callbacks::config ` function which gives them direct access to the ` Config ` structure.
9995
10096## Compiler lint passes are combined into one pass
10197
@@ -105,8 +101,8 @@ of lint passes. Instead, we have a single lint pass of each variety (e.g.,
105101individual lint passes; this is because then we get the benefits of static over
106102dynamic dispatch for each of the (often empty) trait methods.
107103
108- Ideally, we'd not have to do this, since it adds to the complexity of
109- understanding the code. However, with the current type-erased lint store
104+ Ideally, we'd not have to do this, since it adds to the complexity of understanding the code.
105+ However, with the current type-erased lint store
110106approach, it is beneficial to do so for performance reasons.
111107
112108[ `LintStore` ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint/struct.LintStore.html
0 commit comments