Skip to content

Commit

Permalink
Remove LintSession and run incremental and whole crate lints in parallel
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Mar 28, 2019
1 parent 41316f0 commit cd32f9b
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 68 deletions.
106 changes: 39 additions & 67 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>,
Expand All @@ -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)]
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -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,

Expand Down Expand Up @@ -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,
}
Expand All @@ -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,
Expand Down Expand Up @@ -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,
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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>>(
Expand All @@ -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,
Expand All @@ -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() {
Expand All @@ -1376,34 +1342,40 @@ 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) });
});
}

// 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> {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
});
});
}, {
Expand Down

0 comments on commit cd32f9b

Please sign in to comment.