Skip to content

Commit aa4ee2c

Browse files
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.
1 parent 2454512 commit aa4ee2c

File tree

2 files changed

+26
-33
lines changed

2 files changed

+26
-33
lines changed

src/librustc/lint/context.rs

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use crate::util::common::time;
3535
use errors::DiagnosticBuilder;
3636
use std::slice;
3737
use std::default::Default as StdDefault;
38-
use rustc_data_structures::sync::{ReadGuard, Lock, ParallelIterator, join, par_iter};
38+
use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter};
3939
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
4040
use syntax::ast;
4141
use syntax::edition;
@@ -52,12 +52,17 @@ pub struct LintStore {
5252
/// added by a plugin.
5353
lints: Vec<&'static Lint>,
5454

55-
/// Trait objects for each lint pass.
56-
/// This is only `None` while performing a lint pass.
57-
pre_expansion_passes: Option<Vec<EarlyLintPassObject>>,
58-
early_passes: Option<Vec<EarlyLintPassObject>>,
59-
late_passes: Lock<Option<Vec<LateLintPassObject>>>,
60-
late_module_passes: Vec<LateLintPassObject>,
55+
/// Constructor functions for each variety of lint pass.
56+
///
57+
/// These should only be called once, but since we want to avoid locks or
58+
/// interior mutability, we don't enforce this (and lints should, in theory,
59+
/// be compatible with being constructed more than once, though not
60+
/// necessarily in a sane manner. This is safe though.)
61+
pre_expansion_passes: Vec<fn() -> EarlyLintPassObject>,
62+
early_passes: Vec<fn() -> EarlyLintPassObject>,
63+
late_passes: Vec<fn() -> LateLintPassObject>,
64+
/// This is unique in that we construct them per-module, so not once.
65+
late_module_passes: Vec<fn() -> LateLintPassObject>,
6166

6267
/// Lints indexed by name.
6368
by_name: FxHashMap<String, TargetLint>,
@@ -142,9 +147,9 @@ impl LintStore {
142147
pub fn new() -> LintStore {
143148
LintStore {
144149
lints: vec![],
145-
pre_expansion_passes: Some(vec![]),
146-
early_passes: Some(vec![]),
147-
late_passes: Lock::new(Some(vec![])),
150+
pre_expansion_passes: vec![],
151+
early_passes: vec![],
152+
late_passes: vec![],
148153
late_module_passes: vec![],
149154
by_name: Default::default(),
150155
future_incompatible: Default::default(),
@@ -169,19 +174,19 @@ impl LintStore {
169174
}
170175

171176
pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) {
172-
self.early_passes.as_mut().unwrap().push((pass)());
177+
self.early_passes.push(pass);
173178
}
174179

175180
pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) {
176-
self.pre_expansion_passes.as_mut().unwrap().push((pass)());
181+
self.pre_expansion_passes.push(pass);
177182
}
178183

179184
pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) {
180-
self.late_passes.lock().as_mut().unwrap().push((pass)());
185+
self.late_passes.push(pass);
181186
}
182187

183188
pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) {
184-
self.late_module_passes.push((pass)());
189+
self.late_module_passes.push(pass);
185190
}
186191

187192
// Helper method for register_early/late_pass
@@ -1374,7 +1379,7 @@ pub fn late_lint_mod<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
13741379
late_lint_mod_pass(tcx, module_def_id, builtin_lints);
13751380

13761381
let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes
1377-
.iter().map(|pass| pass.fresh_late_pass()).collect();
1382+
.iter().map(|pass| (pass)()).collect();
13781383

13791384
if !passes.is_empty() {
13801385
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
14151420
}
14161421

14171422
fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, builtin_lints: T) {
1418-
let mut passes = tcx.sess.lint_store.borrow().late_passes.lock().take().unwrap();
1423+
let mut passes = tcx.sess.lint_store.borrow()
1424+
.late_passes.iter().map(|p| (p)()).collect::<Vec<_>>();
14191425

14201426
if !tcx.sess.opts.debugging_opts.no_interleave_lints {
14211427
if !passes.is_empty() {
@@ -1431,17 +1437,14 @@ fn late_lint_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tcx>, b
14311437
}
14321438

14331439
let mut passes: Vec<_> = tcx.sess.lint_store.borrow().late_module_passes
1434-
.iter().map(|pass| pass.fresh_late_pass()).collect();
1440+
.iter().map(|pass| (pass)()).collect();
14351441

14361442
for pass in &mut passes {
14371443
time(tcx.sess, &format!("running late module lint: {}", pass.name()), || {
14381444
late_lint_pass_crate(tcx, LateLintPassObjects { lints: slice::from_mut(pass) });
14391445
});
14401446
}
14411447
}
1442-
1443-
// Put the passes back in the session.
1444-
*tcx.sess.lint_store.borrow().late_passes.lock() = Some(passes);
14451448
}
14461449

14471450
/// Performs lint checking on a crate.
@@ -1525,14 +1528,14 @@ pub fn check_ast_crate<T: EarlyLintPass>(
15251528
pre_expansion: bool,
15261529
builtin_lints: T,
15271530
) {
1528-
let (mut passes, mut buffered) = if pre_expansion {
1531+
let (mut passes, mut buffered): (Vec<_>, _) = if pre_expansion {
15291532
(
1530-
sess.lint_store.borrow_mut().pre_expansion_passes.take().unwrap(),
1533+
sess.lint_store.borrow().pre_expansion_passes.iter().map(|p| (p)()).collect(),
15311534
LintBuffer::default(),
15321535
)
15331536
} else {
15341537
(
1535-
sess.lint_store.borrow_mut().early_passes.take().unwrap(),
1538+
sess.lint_store.borrow().early_passes.iter().map(|p| (p)()).collect(),
15361539
sess.buffered_lints.borrow_mut().take().unwrap(),
15371540
)
15381541
};
@@ -1561,13 +1564,6 @@ pub fn check_ast_crate<T: EarlyLintPass>(
15611564
}
15621565
}
15631566

1564-
// Put the lint store levels and passes back in the session.
1565-
if pre_expansion {
1566-
sess.lint_store.borrow_mut().pre_expansion_passes = Some(passes);
1567-
} else {
1568-
sess.lint_store.borrow_mut().early_passes = Some(passes);
1569-
}
1570-
15711567
// All of the buffered lints should have been emitted at this point.
15721568
// If not, that means that we somehow buffered a lint for a node id
15731569
// that was not lint-checked (perhaps it doesn't exist?). This is a bug.

src/librustc/lint/mod.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,9 +286,6 @@ macro_rules! expand_lint_pass_methods {
286286
macro_rules! declare_late_lint_pass {
287287
([], [$hir:tt], [$($methods:tt)*]) => (
288288
pub trait LateLintPass<'a, $hir>: LintPass {
289-
fn fresh_late_pass(&self) -> LateLintPassObject {
290-
panic!()
291-
}
292289
expand_lint_pass_methods!(&LateContext<'a, $hir>, [$($methods)*]);
293290
}
294291
)

0 commit comments

Comments
 (0)