From aa4ee2cc0f722467da4c4b0d19ad365a4be1e5d5 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:23:16 -0400 Subject: [PATCH] Move to storing constructor functions inside LintStore This stops storing the pass objects and instead stores constructor functions. The primary effect is that LintStore no longer has any interior mutability. --- src/librustc/lint/context.rs | 56 +++++++++++++++++------------------- src/librustc/lint/mod.rs | 3 -- 2 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 73d8bb11b71..6e67c0315cf 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -35,7 +35,7 @@ use crate::util::common::time; use errors::DiagnosticBuilder; use std::slice; use std::default::Default as StdDefault; -use rustc_data_structures::sync::{ReadGuard, Lock, ParallelIterator, join, par_iter}; +use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; use syntax::edition; @@ -52,12 +52,17 @@ pub struct LintStore { /// added by a plugin. lints: Vec<&'static Lint>, - /// Trait objects for each lint pass. - /// This is only `None` while performing a lint pass. - pre_expansion_passes: Option>, - early_passes: Option>, - late_passes: Lock>>, - late_module_passes: Vec, + /// Constructor functions for each variety of lint pass. + /// + /// These should only be called once, but since we want to avoid locks or + /// interior mutability, we don't enforce this (and lints should, in theory, + /// be compatible with being constructed more than once, though not + /// necessarily in a sane manner. This is safe though.) + pre_expansion_passes: Vec EarlyLintPassObject>, + early_passes: Vec EarlyLintPassObject>, + late_passes: Vec LateLintPassObject>, + /// This is unique in that we construct them per-module, so not once. + late_module_passes: Vec LateLintPassObject>, /// Lints indexed by name. by_name: FxHashMap, @@ -142,9 +147,9 @@ impl LintStore { pub fn new() -> LintStore { LintStore { lints: vec![], - pre_expansion_passes: Some(vec![]), - early_passes: Some(vec![]), - late_passes: Lock::new(Some(vec![])), + pre_expansion_passes: vec![], + early_passes: vec![], + late_passes: vec![], late_module_passes: vec![], by_name: Default::default(), future_incompatible: Default::default(), @@ -169,19 +174,19 @@ impl LintStore { } pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.early_passes.as_mut().unwrap().push((pass)()); + self.early_passes.push(pass); } pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.pre_expansion_passes.as_mut().unwrap().push((pass)()); + self.pre_expansion_passes.push(pass); } pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_passes.lock().as_mut().unwrap().push((pass)()); + self.late_passes.push(pass); } pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_module_passes.push((pass)()); + self.late_module_passes.push(pass); } // Helper method for register_early/late_pass @@ -1374,7 +1379,7 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>( late_lint_mod_pass(tcx, module_def_id, builtin_lints); let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes - .iter().map(|pass| pass.fresh_late_pass()).collect(); + .iter().map(|pass| (pass)()).collect(); if !passes.is_empty() { late_lint_mod_pass(tcx, module_def_id, LateLintPassObjects { lints: &mut passes[..] }); @@ -1415,7 +1420,8 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc } fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) { - let mut passes = tcx.sess.lint_store.borrow().late_passes.lock().take().unwrap(); + let mut passes = tcx.sess.lint_store.borrow() + .late_passes.iter().map(|p| (p)()).collect::>(); if !tcx.sess.opts.debugging_opts.no_interleave_lints { if !passes.is_empty() { @@ -1431,7 +1437,7 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b } let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes - .iter().map(|pass| pass.fresh_late_pass()).collect(); + .iter().map(|pass| (pass)()).collect(); for pass in &mut passes { time(tcx.sess, &format!("running late module lint: {}", pass.name()), || { @@ -1439,9 +1445,6 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b }); } } - - // Put the passes back in the session. - *tcx.sess.lint_store.borrow().late_passes.lock() = Some(passes); } /// Performs lint checking on a crate. @@ -1525,14 +1528,14 @@ pub fn check_ast_crate( pre_expansion: bool, builtin_lints: T, ) { - let (mut passes, mut buffered) = if pre_expansion { + let (mut passes, mut buffered): (Vec<_>, _) = if pre_expansion { ( - sess.lint_store.borrow_mut().pre_expansion_passes.take().unwrap(), + sess.lint_store.borrow().pre_expansion_passes.iter().map(|p| (p)()).collect(), LintBuffer::default(), ) } else { ( - sess.lint_store.borrow_mut().early_passes.take().unwrap(), + sess.lint_store.borrow().early_passes.iter().map(|p| (p)()).collect(), sess.buffered_lints.borrow_mut().take().unwrap(), ) }; @@ -1561,13 +1564,6 @@ pub fn check_ast_crate( } } - // Put the lint store levels and passes back in the session. - if pre_expansion { - sess.lint_store.borrow_mut().pre_expansion_passes = Some(passes); - } else { - sess.lint_store.borrow_mut().early_passes = Some(passes); - } - // All of the buffered lints should have been emitted at this point. // If not, that means that we somehow buffered a lint for a node id // that was not lint-checked (perhaps it doesn't exist?). This is a bug. diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 1b34808ef30..63c4013e1d3 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -286,9 +286,6 @@ macro_rules! expand_lint_pass_methods { macro_rules! declare_late_lint_pass { ([], [$hir:tt], [$($methods:tt)*]) => ( pub trait LateLintPass<'a, $hir>: LintPass { - fn fresh_late_pass(&self) -> LateLintPassObject { - panic!() - } expand_lint_pass_methods!(&LateContext<'a, $hir>, [$($methods)*]); } )