about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2019-01-31 03:04:39 +0100
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2019-03-28 16:29:08 +0100
commitcd32f9bccaaf021a3327fc28df3401dc32a644e1 (patch)
treee3a0d91455b194e227c65849ca511003d58f5221
parent41316f0449025394fdca6606d3fdb3b8f37a9872 (diff)
downloadrust-cd32f9bccaaf021a3327fc28df3401dc32a644e1.tar.gz
rust-cd32f9bccaaf021a3327fc28df3401dc32a644e1.zip
Remove LintSession and run incremental and whole crate lints in parallel
-rw-r--r--src/librustc/lint/context.rs106
-rw-r--r--src/librustc_interface/passes.rs2
2 files changed, 40 insertions, 68 deletions
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index e0bd795c342..49e3eee4e52 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -17,7 +17,7 @@
 use self::TargetLint::*;
 
 use std::slice;
-use rustc_data_structures::sync::ReadGuard;
+use rustc_data_structures::sync::{ReadGuard, Lock, join};
 use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject};
 use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer};
 use crate::lint::builtin::BuiltinLintDiagnostics;
@@ -55,8 +55,8 @@ pub struct LintStore {
     /// This is only `None` while performing a lint pass.
     pre_expansion_passes: Option<Vec<EarlyLintPassObject>>,
     early_passes: Option<Vec<EarlyLintPassObject>>,
-    late_passes: Option<Vec<LateLintPassObject>>,
-    late_module_passes: Option<Vec<LateLintPassObject>>,
+    late_passes: Lock<Option<Vec<LateLintPassObject>>>,
+    late_module_passes: Lock<Option<Vec<LateLintPassObject>>>,
 
     /// Lints indexed by name.
     by_name: FxHashMap<String, TargetLint>,
@@ -69,14 +69,6 @@ pub struct LintStore {
     future_incompatible: FxHashMap<LintId, FutureIncompatibleInfo>,
 }
 
-pub struct LintSession<'a, PassObject> {
-    /// Reference to the store of registered lints.
-    lints: ReadGuard<'a, LintStore>,
-
-    /// Trait objects for each lint pass.
-    passes: Option<Vec<PassObject>>,
-}
-
 /// Lints that are buffered up early on in the `Session` before the
 /// `LintLevels` is calculated
 #[derive(PartialEq, RustcEncodable, RustcDecodable, Debug)]
@@ -151,8 +143,8 @@ impl LintStore {
             lints: vec![],
             pre_expansion_passes: Some(vec![]),
             early_passes: Some(vec![]),
-            late_passes: Some(vec![]),
-            late_module_passes: Some(vec![]),
+            late_passes: Lock::new(Some(vec![])),
+            late_module_passes: Lock::new(Some(vec![])),
             by_name: Default::default(),
             future_incompatible: Default::default(),
             lint_groups: Default::default(),
@@ -208,9 +200,9 @@ impl LintStore {
         self.push_pass(sess, from_plugin, &pass);
         if !register_only {
             if per_module {
-                self.late_module_passes.as_mut().unwrap().push(pass);
+                self.late_module_passes.lock().as_mut().unwrap().push(pass);
             } else {
-                self.late_passes.as_mut().unwrap().push(pass);
+                self.late_passes.lock().as_mut().unwrap().push(pass);
             }
         }
     }
@@ -529,7 +521,7 @@ pub struct LateContext<'a, 'tcx: 'a> {
     pub access_levels: &'a AccessLevels,
 
     /// The store of registered lints and the lint levels.
-    lint_sess: LintSession<'tcx, LateLintPassObject>,
+    lint_store: ReadGuard<'a, LintStore>,
 
     last_node_with_lint_attrs: hir::HirId,
 
@@ -557,7 +549,7 @@ pub struct EarlyContext<'a> {
     builder: LintLevelsBuilder<'a>,
 
     /// The store of registered lints and the lint levels.
-    lint_sess: LintSession<'a, EarlyLintPassObject>,
+    lint_store: ReadGuard<'a, LintStore>,
 
     buffered: LintBuffer,
 }
@@ -578,8 +570,6 @@ pub trait LintContext<'tcx>: Sized {
 
     fn sess(&self) -> &Session;
     fn lints(&self) -> &LintStore;
-    fn lint_sess(&self) -> &LintSession<'tcx, Self::PassObject>;
-    fn lint_sess_mut(&mut self) -> &mut LintSession<'tcx, Self::PassObject>;
 
     fn lookup_and_emit<S: Into<MultiSpan>>(&self,
                                            lint: &'static Lint,
@@ -654,10 +644,7 @@ impl<'a> EarlyContext<'a> {
         EarlyContext {
             sess,
             krate,
-            lint_sess: LintSession {
-                lints: sess.lint_store.borrow(),
-                passes: None,
-            },
+            lint_store: sess.lint_store.borrow(),
             builder: LintLevelSets::builder(sess),
             buffered,
         }
@@ -721,15 +708,7 @@ impl<'a, 'tcx> LintContext<'tcx> for LateContext<'a, 'tcx> {
     }
 
     fn lints(&self) -> &LintStore {
-        &*self.lint_sess.lints
-    }
-
-    fn lint_sess(&self) -> &LintSession<'tcx, Self::PassObject> {
-        &self.lint_sess
-    }
-
-    fn lint_sess_mut(&mut self) -> &mut LintSession<'tcx, Self::PassObject> {
-        &mut self.lint_sess
+        &*self.lint_store
     }
 
     fn lookup<S: Into<MultiSpan>>(&self,
@@ -757,15 +736,7 @@ impl<'a> LintContext<'a> for EarlyContext<'a> {
     }
 
     fn lints(&self) -> &LintStore {
-        &*self.lint_sess.lints
-    }
-
-    fn lint_sess(&self) -> &LintSession<'a, Self::PassObject> {
-        &self.lint_sess
-    }
-
-    fn lint_sess_mut(&mut self) -> &mut LintSession<'a, Self::PassObject> {
-        &mut self.lint_sess
+        &*self.lint_store
     }
 
     fn lookup<S: Into<MultiSpan>>(&self,
@@ -1269,17 +1240,12 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
 ) {
     let access_levels = &tcx.privacy_access_levels(LOCAL_CRATE);
 
-    let store = &tcx.sess.lint_store;
-
     let context = LateContext {
         tcx,
         tables: &ty::TypeckTables::empty(None),
         param_env: ty::ParamEnv::empty(),
         access_levels,
-        lint_sess: LintSession {
-            lints: store.borrow(),
-            passes: None,
-        },
+        lint_store: tcx.sess.lint_store.borrow(),
         last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(),
         generics: None,
         only_module: true,
@@ -1304,18 +1270,21 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
     module_def_id: DefId,
     builtin_lints: T,
 ) {
-    assert!(!tcx.sess.opts.debugging_opts.no_interleave_lints);
+    if tcx.sess.opts.debugging_opts.no_interleave_lints {
+        // These passes runs in late_lint_crate with -Z no_interleave_lints
+        return;
+    }
 
     late_lint_mod_pass(tcx, module_def_id, builtin_lints);
 
-    let mut passes = tcx.sess.lint_store.borrow_mut().late_module_passes.take().unwrap();
+    let mut passes = tcx.sess.lint_store.borrow().late_module_passes.lock().take().unwrap();
 
     if !passes.is_empty() {
         late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] });
     }
 
     // Put the passes back in the session.
-    tcx.sess.lint_store.borrow_mut().late_module_passes = Some(passes);
+    *tcx.sess.lint_store.borrow().late_module_passes.lock() = Some(passes);
 }
 
 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>>(
         tables: &ty::TypeckTables::empty(None),
         param_env: ty::ParamEnv::empty(),
         access_levels,
-        lint_sess: LintSession {
-            passes: None,
-            lints: tcx.sess.lint_store.borrow(),
-        },
+        lint_store: tcx.sess.lint_store.borrow(),
         last_node_with_lint_attrs: hir::CRATE_HIR_ID,
         generics: None,
         only_module: false,
@@ -1361,7 +1327,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
     builtin_lints: T
 ) {
-    let mut passes = tcx.sess.lint_store.borrow_mut().late_passes.take().unwrap();
+    let mut passes = tcx.sess.lint_store.borrow().late_passes.lock().take().unwrap();
 
     if !tcx.sess.opts.debugging_opts.no_interleave_lints {
         if !passes.is_empty() {
@@ -1376,8 +1342,8 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
             });
         }
 
-        let mut passes = tcx.sess.lint_store.borrow_mut().late_module_passes.take().unwrap();
-            
+        let mut passes = tcx.sess.lint_store.borrow().late_module_passes.lock().take().unwrap();
+
         for pass in &mut passes {
             time(tcx.sess, &format!("running late module lint: {}", pass.name()), || {
                 late_lint_pass_crate(tcx, LateLintPassObjects { lints: slice::from_mut(pass) });
@@ -1385,25 +1351,31 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
         }
 
         // Put the passes back in the session.
-        tcx.sess.lint_store.borrow_mut().late_module_passes = Some(passes);
+        *tcx.sess.lint_store.borrow().late_module_passes.lock() = Some(passes);
     }
 
     // Put the passes back in the session.
-    tcx.sess.lint_store.borrow_mut().late_passes = Some(passes);
+    *tcx.sess.lint_store.borrow().late_passes.lock() = Some(passes);
 }
 
 /// Performs lint checking on a crate.
 pub fn check_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
     tcx: TyCtxt<'_, 'tcx, 'tcx>,
-    builtin_lints: T,
+    builtin_lints: impl FnOnce() -> T + Send,
 ) {
-    // Run per-module lints
-    for &module in tcx.hir().krate().modules.keys() {
-        tcx.ensure().lint_mod(tcx.hir().local_def_id(module));
-    }
-
-    // Run whole crate non-incremental lints
-    late_lint_crate(tcx, builtin_lints);
+    join(|| {
+        time(tcx.sess, "crate lints", || {
+            // Run whole crate non-incremental lints
+            late_lint_crate(tcx, builtin_lints());
+        });
+    }, || {
+        time(tcx.sess, "module lints", || {
+            // Run per-module lints
+            for &module in tcx.hir().krate().modules.keys() {
+                tcx.ensure().lint_mod(tcx.hir().local_def_id(module));
+            }
+        });
+    });
 }
 
 struct EarlyLintPassObjects<'a> {
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 6a6f56332a8..1547e15fd48 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -990,7 +990,7 @@ fn analysis<'tcx>(
                 });
             }, {
                 time(sess, "lint checking", || {
-                    lint::check_crate(tcx, rustc_lint::BuiltinCombinedLateLintPass::new());
+                    lint::check_crate(tcx, || rustc_lint::BuiltinCombinedLateLintPass::new());
                 });
             });
         }, {