17
17
use self :: TargetLint :: * ;
18
18
19
19
use std:: slice;
20
- use rustc_data_structures:: sync:: ReadGuard ;
20
+ use rustc_data_structures:: sync:: { ReadGuard , Lock , join } ;
21
21
use crate :: lint:: { EarlyLintPass , LateLintPass , EarlyLintPassObject , LateLintPassObject } ;
22
22
use crate :: lint:: { LintArray , Level , Lint , LintId , LintPass , LintBuffer } ;
23
23
use crate :: lint:: builtin:: BuiltinLintDiagnostics ;
@@ -55,8 +55,8 @@ pub struct LintStore {
55
55
/// This is only `None` while performing a lint pass.
56
56
pre_expansion_passes : Option < Vec < EarlyLintPassObject > > ,
57
57
early_passes : Option < Vec < EarlyLintPassObject > > ,
58
- late_passes : Option < Vec < LateLintPassObject > > ,
59
- late_module_passes : Option < Vec < LateLintPassObject > > ,
58
+ late_passes : Lock < Option < Vec < LateLintPassObject > > > ,
59
+ late_module_passes : Lock < Option < Vec < LateLintPassObject > > > ,
60
60
61
61
/// Lints indexed by name.
62
62
by_name : FxHashMap < String , TargetLint > ,
@@ -69,14 +69,6 @@ pub struct LintStore {
69
69
future_incompatible : FxHashMap < LintId , FutureIncompatibleInfo > ,
70
70
}
71
71
72
- pub struct LintSession < ' a , PassObject > {
73
- /// Reference to the store of registered lints.
74
- lints : ReadGuard < ' a , LintStore > ,
75
-
76
- /// Trait objects for each lint pass.
77
- passes : Option < Vec < PassObject > > ,
78
- }
79
-
80
72
/// Lints that are buffered up early on in the `Session` before the
81
73
/// `LintLevels` is calculated
82
74
#[ derive( PartialEq , RustcEncodable , RustcDecodable , Debug ) ]
@@ -151,8 +143,8 @@ impl LintStore {
151
143
lints : vec ! [ ] ,
152
144
pre_expansion_passes : Some ( vec ! [ ] ) ,
153
145
early_passes : Some ( vec ! [ ] ) ,
154
- late_passes : Some ( vec ! [ ] ) ,
155
- late_module_passes : Some ( vec ! [ ] ) ,
146
+ late_passes : Lock :: new ( Some ( vec ! [ ] ) ) ,
147
+ late_module_passes : Lock :: new ( Some ( vec ! [ ] ) ) ,
156
148
by_name : Default :: default ( ) ,
157
149
future_incompatible : Default :: default ( ) ,
158
150
lint_groups : Default :: default ( ) ,
@@ -208,9 +200,9 @@ impl LintStore {
208
200
self . push_pass ( sess, from_plugin, & pass) ;
209
201
if !register_only {
210
202
if per_module {
211
- self . late_module_passes . as_mut ( ) . unwrap ( ) . push ( pass) ;
203
+ self . late_module_passes . lock ( ) . as_mut ( ) . unwrap ( ) . push ( pass) ;
212
204
} else {
213
- self . late_passes . as_mut ( ) . unwrap ( ) . push ( pass) ;
205
+ self . late_passes . lock ( ) . as_mut ( ) . unwrap ( ) . push ( pass) ;
214
206
}
215
207
}
216
208
}
@@ -529,7 +521,7 @@ pub struct LateContext<'a, 'tcx: 'a> {
529
521
pub access_levels : & ' a AccessLevels ,
530
522
531
523
/// The store of registered lints and the lint levels.
532
- lint_sess : LintSession < ' tcx , LateLintPassObject > ,
524
+ lint_store : ReadGuard < ' a , LintStore > ,
533
525
534
526
last_node_with_lint_attrs : hir:: HirId ,
535
527
@@ -557,7 +549,7 @@ pub struct EarlyContext<'a> {
557
549
builder : LintLevelsBuilder < ' a > ,
558
550
559
551
/// The store of registered lints and the lint levels.
560
- lint_sess : LintSession < ' a , EarlyLintPassObject > ,
552
+ lint_store : ReadGuard < ' a , LintStore > ,
561
553
562
554
buffered : LintBuffer ,
563
555
}
@@ -578,8 +570,6 @@ pub trait LintContext<'tcx>: Sized {
578
570
579
571
fn sess ( & self ) -> & Session ;
580
572
fn lints ( & self ) -> & LintStore ;
581
- fn lint_sess ( & self ) -> & LintSession < ' tcx , Self :: PassObject > ;
582
- fn lint_sess_mut ( & mut self ) -> & mut LintSession < ' tcx , Self :: PassObject > ;
583
573
584
574
fn lookup_and_emit < S : Into < MultiSpan > > ( & self ,
585
575
lint : & ' static Lint ,
@@ -654,10 +644,7 @@ impl<'a> EarlyContext<'a> {
654
644
EarlyContext {
655
645
sess,
656
646
krate,
657
- lint_sess : LintSession {
658
- lints : sess. lint_store . borrow ( ) ,
659
- passes : None ,
660
- } ,
647
+ lint_store : sess. lint_store . borrow ( ) ,
661
648
builder : LintLevelSets :: builder ( sess) ,
662
649
buffered,
663
650
}
@@ -721,15 +708,7 @@ impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> {
721
708
}
722
709
723
710
fn lints ( & self ) -> & LintStore {
724
- & * self . lint_sess . lints
725
- }
726
-
727
- fn lint_sess ( & self ) -> & LintSession < ' tcx , Self :: PassObject > {
728
- & self . lint_sess
729
- }
730
-
731
- fn lint_sess_mut ( & mut self ) -> & mut LintSession < ' tcx , Self :: PassObject > {
732
- & mut self . lint_sess
711
+ & * self . lint_store
733
712
}
734
713
735
714
fn lookup < S : Into < MultiSpan > > ( & self ,
@@ -757,15 +736,7 @@ impl<'a> LintContext<'a> for EarlyContext<'a> {
757
736
}
758
737
759
738
fn lints ( & self ) -> & LintStore {
760
- & * self . lint_sess . lints
761
- }
762
-
763
- fn lint_sess ( & self ) -> & LintSession < ' a , Self :: PassObject > {
764
- & self . lint_sess
765
- }
766
-
767
- fn lint_sess_mut ( & mut self ) -> & mut LintSession < ' a , Self :: PassObject > {
768
- & mut self . lint_sess
739
+ & * self . lint_store
769
740
}
770
741
771
742
fn lookup < S : Into < MultiSpan > > ( & self ,
@@ -1269,17 +1240,12 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
1269
1240
) {
1270
1241
let access_levels = & tcx. privacy_access_levels ( LOCAL_CRATE ) ;
1271
1242
1272
- let store = & tcx. sess . lint_store ;
1273
-
1274
1243
let context = LateContext {
1275
1244
tcx,
1276
1245
tables : & ty:: TypeckTables :: empty ( None ) ,
1277
1246
param_env : ty:: ParamEnv :: empty ( ) ,
1278
1247
access_levels,
1279
- lint_sess : LintSession {
1280
- lints : store. borrow ( ) ,
1281
- passes : None ,
1282
- } ,
1248
+ lint_store : tcx. sess . lint_store . borrow ( ) ,
1283
1249
last_node_with_lint_attrs : tcx. hir ( ) . as_local_hir_id ( module_def_id) . unwrap ( ) ,
1284
1250
generics : None ,
1285
1251
only_module : true ,
@@ -1304,18 +1270,21 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
1304
1270
module_def_id : DefId ,
1305
1271
builtin_lints : T ,
1306
1272
) {
1307
- assert ! ( !tcx. sess. opts. debugging_opts. no_interleave_lints) ;
1273
+ if tcx. sess . opts . debugging_opts . no_interleave_lints {
1274
+ // These passes runs in late_lint_crate with -Z no_interleave_lints
1275
+ return ;
1276
+ }
1308
1277
1309
1278
late_lint_mod_pass ( tcx, module_def_id, builtin_lints) ;
1310
1279
1311
- let mut passes = tcx. sess . lint_store . borrow_mut ( ) . late_module_passes . take ( ) . unwrap ( ) ;
1280
+ let mut passes = tcx. sess . lint_store . borrow ( ) . late_module_passes . lock ( ) . take ( ) . unwrap ( ) ;
1312
1281
1313
1282
if !passes. is_empty ( ) {
1314
1283
late_lint_mod_pass ( tcx, module_def_id, LateLintPassObjects { lints : & mut passes[ ..] } ) ;
1315
1284
}
1316
1285
1317
1286
// Put the passes back in the session.
1318
- tcx. sess . lint_store . borrow_mut ( ) . late_module_passes = Some ( passes) ;
1287
+ * tcx. sess . lint_store . borrow ( ) . late_module_passes . lock ( ) = Some ( passes) ;
1319
1288
}
1320
1289
1321
1290
fn late_lint_pass_crate < ' tcx , T : for < ' a > LateLintPass < ' a , ' tcx > > (
@@ -1331,10 +1300,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
1331
1300
tables : & ty:: TypeckTables :: empty ( None ) ,
1332
1301
param_env : ty:: ParamEnv :: empty ( ) ,
1333
1302
access_levels,
1334
- lint_sess : LintSession {
1335
- passes : None ,
1336
- lints : tcx. sess . lint_store . borrow ( ) ,
1337
- } ,
1303
+ lint_store : tcx. sess . lint_store . borrow ( ) ,
1338
1304
last_node_with_lint_attrs : hir:: CRATE_HIR_ID ,
1339
1305
generics : None ,
1340
1306
only_module : false ,
@@ -1361,7 +1327,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
1361
1327
tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
1362
1328
builtin_lints : T
1363
1329
) {
1364
- let mut passes = tcx. sess . lint_store . borrow_mut ( ) . late_passes . take ( ) . unwrap ( ) ;
1330
+ let mut passes = tcx. sess . lint_store . borrow ( ) . late_passes . lock ( ) . take ( ) . unwrap ( ) ;
1365
1331
1366
1332
if !tcx. sess . opts . debugging_opts . no_interleave_lints {
1367
1333
if !passes. is_empty ( ) {
@@ -1376,34 +1342,40 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
1376
1342
} ) ;
1377
1343
}
1378
1344
1379
- let mut passes = tcx. sess . lint_store . borrow_mut ( ) . late_module_passes . take ( ) . unwrap ( ) ;
1380
-
1345
+ let mut passes = tcx. sess . lint_store . borrow ( ) . late_module_passes . lock ( ) . take ( ) . unwrap ( ) ;
1346
+
1381
1347
for pass in & mut passes {
1382
1348
time ( tcx. sess , & format ! ( "running late module lint: {}" , pass. name( ) ) , || {
1383
1349
late_lint_pass_crate ( tcx, LateLintPassObjects { lints : slice:: from_mut ( pass) } ) ;
1384
1350
} ) ;
1385
1351
}
1386
1352
1387
1353
// Put the passes back in the session.
1388
- tcx. sess . lint_store . borrow_mut ( ) . late_module_passes = Some ( passes) ;
1354
+ * tcx. sess . lint_store . borrow ( ) . late_module_passes . lock ( ) = Some ( passes) ;
1389
1355
}
1390
1356
1391
1357
// Put the passes back in the session.
1392
- tcx. sess . lint_store . borrow_mut ( ) . late_passes = Some ( passes) ;
1358
+ * tcx. sess . lint_store . borrow ( ) . late_passes . lock ( ) = Some ( passes) ;
1393
1359
}
1394
1360
1395
1361
/// Performs lint checking on a crate.
1396
1362
pub fn check_crate < ' tcx , T : for < ' a > LateLintPass < ' a , ' tcx > > (
1397
1363
tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
1398
- builtin_lints : T ,
1364
+ builtin_lints : impl FnOnce ( ) -> T + Send ,
1399
1365
) {
1400
- // Run per-module lints
1401
- for & module in tcx. hir ( ) . krate ( ) . modules . keys ( ) {
1402
- tcx. ensure ( ) . lint_mod ( tcx. hir ( ) . local_def_id ( module) ) ;
1403
- }
1404
-
1405
- // Run whole crate non-incremental lints
1406
- late_lint_crate ( tcx, builtin_lints) ;
1366
+ join ( || {
1367
+ time ( tcx. sess , "crate lints" , || {
1368
+ // Run whole crate non-incremental lints
1369
+ late_lint_crate ( tcx, builtin_lints ( ) ) ;
1370
+ } ) ;
1371
+ } , || {
1372
+ time ( tcx. sess , "module lints" , || {
1373
+ // Run per-module lints
1374
+ for & module in tcx. hir ( ) . krate ( ) . modules . keys ( ) {
1375
+ tcx. ensure ( ) . lint_mod ( tcx. hir ( ) . local_def_id ( module) ) ;
1376
+ }
1377
+ } ) ;
1378
+ } ) ;
1407
1379
}
1408
1380
1409
1381
struct EarlyLintPassObjects < ' a > {
0 commit comments