1717use self :: TargetLint :: * ;
1818
1919use std:: slice;
20- use rustc_data_structures:: sync:: ReadGuard ;
20+ use rustc_data_structures:: sync:: { ReadGuard , Lock , join } ;
2121use crate :: lint:: { EarlyLintPass , LateLintPass , EarlyLintPassObject , LateLintPassObject } ;
2222use crate :: lint:: { LintArray , Level , Lint , LintId , LintPass , LintBuffer } ;
2323use crate :: lint:: builtin:: BuiltinLintDiagnostics ;
@@ -55,8 +55,8 @@ pub struct LintStore {
5555 /// This is only `None` while performing a lint pass.
5656 pre_expansion_passes : Option < Vec < EarlyLintPassObject > > ,
5757 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 > > > ,
6060
6161 /// Lints indexed by name.
6262 by_name : FxHashMap < String , TargetLint > ,
@@ -69,14 +69,6 @@ pub struct LintStore {
6969 future_incompatible : FxHashMap < LintId , FutureIncompatibleInfo > ,
7070}
7171
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-
8072/// Lints that are buffered up early on in the `Session` before the
8173/// `LintLevels` is calculated
8274#[ derive( PartialEq , RustcEncodable , RustcDecodable , Debug ) ]
@@ -151,8 +143,8 @@ impl LintStore {
151143 lints : vec ! [ ] ,
152144 pre_expansion_passes : Some ( vec ! [ ] ) ,
153145 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 ! [ ] ) ) ,
156148 by_name : Default :: default ( ) ,
157149 future_incompatible : Default :: default ( ) ,
158150 lint_groups : Default :: default ( ) ,
@@ -208,9 +200,9 @@ impl LintStore {
208200 self . push_pass ( sess, from_plugin, & pass) ;
209201 if !register_only {
210202 if per_module {
211- self . late_module_passes . as_mut ( ) . unwrap ( ) . push ( pass) ;
203+ self . late_module_passes . lock ( ) . as_mut ( ) . unwrap ( ) . push ( pass) ;
212204 } else {
213- self . late_passes . as_mut ( ) . unwrap ( ) . push ( pass) ;
205+ self . late_passes . lock ( ) . as_mut ( ) . unwrap ( ) . push ( pass) ;
214206 }
215207 }
216208 }
@@ -529,7 +521,7 @@ pub struct LateContext<'a, 'tcx: 'a> {
529521 pub access_levels : & ' a AccessLevels ,
530522
531523 /// The store of registered lints and the lint levels.
532- lint_sess : LintSession < ' tcx , LateLintPassObject > ,
524+ lint_store : ReadGuard < ' a , LintStore > ,
533525
534526 last_node_with_lint_attrs : hir:: HirId ,
535527
@@ -557,7 +549,7 @@ pub struct EarlyContext<'a> {
557549 builder : LintLevelsBuilder < ' a > ,
558550
559551 /// The store of registered lints and the lint levels.
560- lint_sess : LintSession < ' a , EarlyLintPassObject > ,
552+ lint_store : ReadGuard < ' a , LintStore > ,
561553
562554 buffered : LintBuffer ,
563555}
@@ -578,8 +570,6 @@ pub trait LintContext<'tcx>: Sized {
578570
579571 fn sess ( & self ) -> & Session ;
580572 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 > ;
583573
584574 fn lookup_and_emit < S : Into < MultiSpan > > ( & self ,
585575 lint : & ' static Lint ,
@@ -654,10 +644,7 @@ impl<'a> EarlyContext<'a> {
654644 EarlyContext {
655645 sess,
656646 krate,
657- lint_sess : LintSession {
658- lints : sess. lint_store . borrow ( ) ,
659- passes : None ,
660- } ,
647+ lint_store : sess. lint_store . borrow ( ) ,
661648 builder : LintLevelSets :: builder ( sess) ,
662649 buffered,
663650 }
@@ -721,15 +708,7 @@ impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> {
721708 }
722709
723710 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
733712 }
734713
735714 fn lookup < S : Into < MultiSpan > > ( & self ,
@@ -757,15 +736,7 @@ impl<'a> LintContext<'a> for EarlyContext<'a> {
757736 }
758737
759738 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
769740 }
770741
771742 fn lookup < S : Into < MultiSpan > > ( & self ,
@@ -1269,17 +1240,12 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
12691240) {
12701241 let access_levels = & tcx. privacy_access_levels ( LOCAL_CRATE ) ;
12711242
1272- let store = & tcx. sess . lint_store ;
1273-
12741243 let context = LateContext {
12751244 tcx,
12761245 tables : & ty:: TypeckTables :: empty ( None ) ,
12771246 param_env : ty:: ParamEnv :: empty ( ) ,
12781247 access_levels,
1279- lint_sess : LintSession {
1280- lints : store. borrow ( ) ,
1281- passes : None ,
1282- } ,
1248+ lint_store : tcx. sess . lint_store . borrow ( ) ,
12831249 last_node_with_lint_attrs : tcx. hir ( ) . as_local_hir_id ( module_def_id) . unwrap ( ) ,
12841250 generics : None ,
12851251 only_module : true ,
@@ -1304,18 +1270,21 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
13041270 module_def_id : DefId ,
13051271 builtin_lints : T ,
13061272) {
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+ }
13081277
13091278 late_lint_mod_pass ( tcx, module_def_id, builtin_lints) ;
13101279
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 ( ) ;
13121281
13131282 if !passes. is_empty ( ) {
13141283 late_lint_mod_pass ( tcx, module_def_id, LateLintPassObjects { lints : & mut passes[ ..] } ) ;
13151284 }
13161285
13171286 // 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) ;
13191288}
13201289
13211290fn 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>>(
13311300 tables : & ty:: TypeckTables :: empty ( None ) ,
13321301 param_env : ty:: ParamEnv :: empty ( ) ,
13331302 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 ( ) ,
13381304 last_node_with_lint_attrs : hir:: CRATE_HIR_ID ,
13391305 generics : None ,
13401306 only_module : false ,
@@ -1361,7 +1327,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
13611327 tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
13621328 builtin_lints : T
13631329) {
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 ( ) ;
13651331
13661332 if !tcx. sess . opts . debugging_opts . no_interleave_lints {
13671333 if !passes. is_empty ( ) {
@@ -1376,34 +1342,40 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
13761342 } ) ;
13771343 }
13781344
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+
13811347 for pass in & mut passes {
13821348 time ( tcx. sess , & format ! ( "running late module lint: {}" , pass. name( ) ) , || {
13831349 late_lint_pass_crate ( tcx, LateLintPassObjects { lints : slice:: from_mut ( pass) } ) ;
13841350 } ) ;
13851351 }
13861352
13871353 // 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) ;
13891355 }
13901356
13911357 // 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) ;
13931359}
13941360
13951361/// Performs lint checking on a crate.
13961362pub fn check_crate < ' tcx , T : for < ' a > LateLintPass < ' a , ' tcx > > (
13971363 tcx : TyCtxt < ' _ , ' tcx , ' tcx > ,
1398- builtin_lints : T ,
1364+ builtin_lints : impl FnOnce ( ) -> T + Send ,
13991365) {
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+ } ) ;
14071379}
14081380
14091381struct EarlyLintPassObjects < ' a > {
0 commit comments