@@ -268,3 +268,41 @@ For example,
268
268
This defines the ` nonstandard_style ` group which turns on the listed lints. A
269
269
user can turn on these lints with a ` !#[warn(nonstandard_style)] ` attribute in
270
270
the source code, or by passing ` -W nonstandard-style ` on the command line.
271
+
272
+ ### Linting early in the compiler
273
+
274
+ On occasion, you may need to define a lint that runs before the linting system
275
+ has been initialized (e.g. during parsing or macro expansion). This is
276
+ problematic because we need to have computed lint levels to know whether we
277
+ should emit a warning or an error or nothing at all.
278
+
279
+ To solve this problem, we buffer the lints until the linting system is
280
+ processed. [ ` Session ` ] [ sessbl ] and [ ` ParseSess ` ] [ parsebl ] both have
281
+ ` buffer_lint ` methods that allow you to buffer a lint for later. The linting
282
+ system automatically takes care of handling buffered lints later.
283
+
284
+ [ sessbl ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc/session/struct.Session.html#method.buffer_lint
285
+ [ parsebl ] : https://doc.rust-lang.org/nightly/nightly-rustc/syntax/parse/struct.ParseSess.html#method.buffer_lint
286
+
287
+ Thus, to define a lint that runs early in the compilation, one defines a lint
288
+ like normal but invokes the lint with ` buffer_lint ` .
289
+
290
+ #### Linting even earlier in the compiler
291
+
292
+ The parser (` libsyntax ` ) is interesting in that it cannot have dependencies on
293
+ any of the other ` librustc* ` crates. In particular, it cannot depend on
294
+ ` librustc::lint ` or ` librustc_lint ` , where all of the compiler linting
295
+ infrastructure is defined. That's troublesome!
296
+
297
+ To solve this, ` libsyntax ` defines its own buffered lint type, which
298
+ ` ParseSess::buffer_lint ` uses. After macro expansion, these buffered lints are
299
+ then dumped into the ` Session::buffered_lints ` used by the rest of the compiler.
300
+
301
+ Usage for buffered lints in ` libsyntax ` is pretty much the same as the rest of
302
+ the compiler with one exception because we cannot import the ` LintId ` s for
303
+ lints we want to emit. Instead, the [ ` BufferedEarlyLintId ` ] type is used. If you
304
+ are defining a new lint, you will want to add an entry to this enum. Then, add
305
+ an appropriate mapping to the body of [ ` Lint::from_parser_lint_id ` ] [ fplid ] .
306
+
307
+ [ `BufferedEarlyLintId` ] : https://doc.rust-lang.org/nightly/nightly-rustc/syntax/early_buffered_lints/struct.BufferedEarlyLintId.html
308
+ [ fplid ] : https://doc.rust-lang.org/nightly/nightly-rustc/rustc/lint/struct.Lint.html#from_parser_lint_id
0 commit comments