@@ -17,7 +17,7 @@ use rustc_ast as ast;
17
17
use rustc_ast_pretty:: pprust;
18
18
use rustc_data_structures:: {
19
19
fx:: FxIndexMap ,
20
- sync:: { join , Lock , Lrc } ,
20
+ sync:: Lrc ,
21
21
} ;
22
22
use rustc_errors:: { Diag , DiagMessage , LintDiagnostic , MultiSpan } ;
23
23
use rustc_feature:: { Features , GateIssue } ;
@@ -162,9 +162,9 @@ fn lint_expectations(tcx: TyCtxt<'_>, (): ()) -> Vec<(LintExpectationId, LintExp
162
162
pub fn lints_that_can_emit ( tcx : TyCtxt < ' _ > , ( ) : ( ) ) -> Lrc < ( Vec < String > , Vec < String > ) > {
163
163
let mut visitor = LintLevelMinimum :: new ( tcx) ;
164
164
visitor. process_opts ( ) ;
165
- visitor . lint_level_minimums ( ) ;
165
+ tcx . hir ( ) . walk_attributes ( & mut visitor ) ;
166
166
167
- Lrc :: new ( ( visitor. lints_to_emit . into_inner ( ) , visitor. lints_allowed . into_inner ( ) ) )
167
+ Lrc :: new ( ( visitor. lints_to_emit , visitor. lints_allowed ) )
168
168
}
169
169
170
170
#[ instrument( level = "trace" , skip( tcx) , ret) ]
@@ -474,49 +474,77 @@ impl<'tcx> Visitor<'tcx> for LintLevelsBuilder<'_, QueryMapExpectationsWrapper<'
474
474
struct LintLevelMinimum < ' tcx > {
475
475
tcx : TyCtxt < ' tcx > ,
476
476
/// The actual list of detected lints.
477
- lints_to_emit : Lock < Vec < String > > ,
478
- lints_allowed : Lock < Vec < String > > ,
477
+ lints_to_emit : Vec < String > ,
478
+ lints_allowed : Vec < String > ,
479
479
}
480
480
481
481
impl < ' tcx > LintLevelMinimum < ' tcx > {
482
482
pub fn new ( tcx : TyCtxt < ' tcx > ) -> Self {
483
483
Self {
484
484
tcx,
485
485
// That magic number is the current number of lints + some more for possible future lints
486
- lints_to_emit : Lock :: new ( Vec :: with_capacity ( 230 ) ) ,
487
- lints_allowed : Lock :: new ( Vec :: with_capacity ( 100 ) ) ,
486
+ lints_to_emit : Vec :: with_capacity ( 230 ) ,
487
+ lints_allowed : Vec :: with_capacity ( 100 ) ,
488
488
}
489
489
}
490
490
491
491
fn process_opts ( & mut self ) {
492
492
for ( lint, level) in & self . tcx . sess . opts . lint_opts {
493
493
if * level == Level :: Allow {
494
- self . lints_allowed . with_lock ( |lints_allowed| lints_allowed . push ( lint. to_string ( ) ) ) ;
494
+ self . lints_allowed . push ( lint. clone ( ) ) ;
495
495
} else {
496
- self . lints_to_emit . with_lock ( |lints_to_emit| lints_to_emit . push ( lint. to_string ( ) ) ) ;
496
+ self . lints_to_emit . push ( lint. to_string ( ) ) ;
497
497
}
498
498
}
499
499
}
500
+ }
501
+
502
+ impl < ' tcx > Visitor < ' tcx > for LintLevelMinimum < ' tcx > {
503
+ type NestedFilter = nested_filter:: All ;
504
+
505
+ fn nested_visit_map ( & mut self ) -> Self :: Map {
506
+ self . tcx . hir ( )
507
+ }
500
508
501
- fn lint_level_minimums ( & mut self ) {
502
- join (
503
- || {
504
- self . tcx . sess . psess . lints_that_can_emit . with_lock ( |vec| {
505
- for lint_symbol in vec {
506
- self . lints_to_emit
507
- . with_lock ( |lints_to_emit| lints_to_emit. push ( lint_symbol. to_string ( ) ) ) ;
509
+ fn visit_attribute ( & mut self , attribute : & ' tcx ast:: Attribute ) {
510
+ if let Some ( meta) = attribute. meta ( ) {
511
+ if [ sym:: warn, sym:: deny, sym:: forbid, sym:: expect]
512
+ . iter ( )
513
+ . any ( |kind| meta. has_name ( * kind) )
514
+ {
515
+ // SAFETY: Lint attributes are always a metalist inside a
516
+ // metalist (even with just one lint).
517
+ for meta_list in meta. meta_item_list ( ) . unwrap ( ) {
518
+ // If it's a tool lint (e.g. clippy::my_clippy_lint)
519
+ if let ast:: NestedMetaItem :: MetaItem ( meta_item) = meta_list {
520
+ if meta_item. path . segments . len ( ) == 1 {
521
+ self . lints_to_emit . push (
522
+ // SAFETY: Lint attributes can only have literals
523
+ meta_list. ident ( ) . unwrap ( ) . name . as_str ( ) . to_string ( ) ,
524
+ ) ;
525
+ } else {
526
+ self . lints_to_emit
527
+ . push ( meta_item. path . segments [ 1 ] . ident . name . as_str ( ) . to_string ( ) ) ;
528
+ }
508
529
}
509
- } ) ;
510
- } ,
511
- || {
512
- self . tcx . sess . psess . lints_allowed . with_lock ( |vec| {
513
- for lint_symbol in vec {
514
- self . lints_allowed
515
- . with_lock ( |lints_allowed| lints_allowed. push ( lint_symbol. to_string ( ) ) ) ;
530
+ }
531
+ // We handle #![allow]s differently, as these remove checking rather than adding.
532
+ } else if meta. has_name ( sym:: allow)
533
+ && let ast:: AttrStyle :: Inner = attribute. style
534
+ {
535
+ for meta_list in meta. meta_item_list ( ) . unwrap ( ) {
536
+ // If it's a tool lint (e.g. clippy::my_clippy_lint)
537
+ if let ast:: NestedMetaItem :: MetaItem ( meta_item) = meta_list {
538
+ if meta_item. path . segments . len ( ) == 1 {
539
+ self . lints_allowed . push ( meta_list. name_or_empty ( ) . as_str ( ) . to_string ( ) )
540
+ } else {
541
+ self . lints_allowed
542
+ . push ( meta_item. path . segments [ 1 ] . ident . name . as_str ( ) . to_string ( ) ) ;
543
+ }
516
544
}
517
- } ) ;
518
- } ,
519
- ) ;
545
+ }
546
+ }
547
+ }
520
548
}
521
549
}
522
550
0 commit comments