16
16
17
17
use crate :: context:: { EarlyContext , LintContext , LintStore } ;
18
18
use crate :: passes:: { EarlyLintPass , EarlyLintPassObject } ;
19
- use rustc_ast as ast ;
20
- use rustc_ast:: visit as ast_visit;
19
+ use rustc_ast:: ptr :: P ;
20
+ use rustc_ast:: visit:: { self as ast_visit, Visitor } ;
21
21
use rustc_ast:: AstLike ;
22
+ use rustc_ast:: { self as ast, walk_list} ;
22
23
use rustc_middle:: ty:: RegisteredTools ;
23
24
use rustc_session:: lint:: { BufferedEarlyLint , LintBuffer , LintPass } ;
24
25
use rustc_session:: Session ;
@@ -32,7 +33,7 @@ macro_rules! run_early_pass { ($cx:expr, $f:ident, $($args:expr),*) => ({
32
33
$cx. pass. $f( & $cx. context, $( $args) ,* ) ;
33
34
} ) }
34
35
35
- struct EarlyContextAndPass < ' a , T : EarlyLintPass > {
36
+ pub struct EarlyContextAndPass < ' a , T : EarlyLintPass > {
36
37
context : EarlyContext < ' a > ,
37
38
pass : T ,
38
39
}
@@ -326,14 +327,65 @@ macro_rules! early_lint_pass_impl {
326
327
327
328
crate :: early_lint_methods!( early_lint_pass_impl, [ ] ) ;
328
329
329
- fn early_lint_node (
330
+ /// Early lints work on different nodes - either on the crate root, or on freshly loaded modules.
331
+ /// This trait generalizes over those nodes.
332
+ pub trait EarlyCheckNode < ' a > : Copy {
333
+ fn id ( self ) -> ast:: NodeId ;
334
+ fn attrs < ' b > ( self ) -> & ' b [ ast:: Attribute ]
335
+ where
336
+ ' a : ' b ;
337
+ fn check < ' b > ( self , cx : & mut EarlyContextAndPass < ' b , impl EarlyLintPass > )
338
+ where
339
+ ' a : ' b ;
340
+ }
341
+
342
+ impl < ' a > EarlyCheckNode < ' a > for & ' a ast:: Crate {
343
+ fn id ( self ) -> ast:: NodeId {
344
+ ast:: CRATE_NODE_ID
345
+ }
346
+ fn attrs < ' b > ( self ) -> & ' b [ ast:: Attribute ]
347
+ where
348
+ ' a : ' b ,
349
+ {
350
+ & self . attrs
351
+ }
352
+ fn check < ' b > ( self , cx : & mut EarlyContextAndPass < ' b , impl EarlyLintPass > )
353
+ where
354
+ ' a : ' b ,
355
+ {
356
+ run_early_pass ! ( cx, check_crate, self ) ;
357
+ ast_visit:: walk_crate ( cx, self ) ;
358
+ run_early_pass ! ( cx, check_crate_post, self ) ;
359
+ }
360
+ }
361
+
362
+ impl < ' a > EarlyCheckNode < ' a > for ( ast:: NodeId , & ' a [ ast:: Attribute ] , & ' a [ P < ast:: Item > ] ) {
363
+ fn id ( self ) -> ast:: NodeId {
364
+ self . 0
365
+ }
366
+ fn attrs < ' b > ( self ) -> & ' b [ ast:: Attribute ]
367
+ where
368
+ ' a : ' b ,
369
+ {
370
+ self . 1
371
+ }
372
+ fn check < ' b > ( self , cx : & mut EarlyContextAndPass < ' b , impl EarlyLintPass > )
373
+ where
374
+ ' a : ' b ,
375
+ {
376
+ walk_list ! ( cx, visit_attribute, self . 1 ) ;
377
+ walk_list ! ( cx, visit_item, self . 2 ) ;
378
+ }
379
+ }
380
+
381
+ fn early_lint_node < ' a > (
330
382
sess : & Session ,
331
383
warn_about_weird_lints : bool ,
332
384
lint_store : & LintStore ,
333
385
registered_tools : & RegisteredTools ,
334
386
buffered : LintBuffer ,
335
387
pass : impl EarlyLintPass ,
336
- check_node : & ast :: Crate ,
388
+ check_node : impl EarlyCheckNode < ' a > ,
337
389
) -> LintBuffer {
338
390
let mut cx = EarlyContextAndPass {
339
391
context : EarlyContext :: new (
@@ -346,22 +398,18 @@ fn early_lint_node(
346
398
pass,
347
399
} ;
348
400
349
- cx. with_lint_attrs ( ast:: CRATE_NODE_ID , & check_node. attrs , |cx| {
350
- run_early_pass ! ( cx, check_crate, check_node) ;
351
- ast_visit:: walk_crate ( cx, check_node) ;
352
- run_early_pass ! ( cx, check_crate_post, check_node) ;
353
- } ) ;
401
+ cx. with_lint_attrs ( check_node. id ( ) , check_node. attrs ( ) , |cx| check_node. check ( cx) ) ;
354
402
cx. context . buffered
355
403
}
356
404
357
- pub fn check_ast_node (
405
+ pub fn check_ast_node < ' a > (
358
406
sess : & Session ,
359
407
pre_expansion : bool ,
360
408
lint_store : & LintStore ,
361
409
registered_tools : & RegisteredTools ,
362
410
lint_buffer : Option < LintBuffer > ,
363
411
builtin_lints : impl EarlyLintPass ,
364
- check_node : & ast :: Crate ,
412
+ check_node : impl EarlyCheckNode < ' a > ,
365
413
) {
366
414
let passes =
367
415
if pre_expansion { & lint_store. pre_expansion_passes } else { & lint_store. early_passes } ;
0 commit comments