Create lint store during plugin registration

Remove lint store from Session
This commit is contained in:
Mark Rousskov 2019-10-09 09:53:13 -04:00
parent da56d1d201
commit dab3bd6cda
12 changed files with 83 additions and 103 deletions

View file

@ -3483,6 +3483,7 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_interface",
"rustc_lint",
"rustc_metadata",
"rustc_mir",
"rustc_plugin",

View file

@ -35,7 +35,7 @@
use errors::DiagnosticBuilder;
use std::slice;
use std::default::Default as StdDefault;
use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter};
use rustc_data_structures::sync::{ParallelIterator, join, par_iter};
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
use syntax::ast;
use syntax::util::lev_distance::find_best_match_for_name;
@ -452,7 +452,7 @@ pub struct LateContext<'a, 'tcx> {
pub access_levels: &'a AccessLevels,
/// The store of registered lints and the lint levels.
lint_store: ReadGuard<'a, LintStore>,
lint_store: &'tcx LintStore,
last_node_with_lint_attrs: hir::HirId,
@ -1320,7 +1320,7 @@ fn late_lint_mod_pass<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(
tables: &ty::TypeckTables::empty(None),
param_env: ty::ParamEnv::empty(),
access_levels,
lint_store: tcx.sess.lint_store.borrow(),
lint_store: &tcx.lint_store,
last_node_with_lint_attrs: tcx.hir().as_local_hir_id(module_def_id).unwrap(),
generics: None,
only_module: true,
@ -1352,7 +1352,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
let mut passes: Vec<_> = tcx.lint_store.late_module_passes
.iter().map(|pass| (pass)()).collect();
if !passes.is_empty() {
@ -1370,7 +1370,7 @@ fn late_lint_pass_crate<'tcx, T: for<'a> LateLintPass<'a, 'tcx>>(tcx: TyCtxt<'tc
tables: &ty::TypeckTables::empty(None),
param_env: ty::ParamEnv::empty(),
access_levels,
lint_store: tcx.sess.lint_store.borrow(),
lint_store: &tcx.lint_store,
last_node_with_lint_attrs: hir::CRATE_HIR_ID,
generics: None,
only_module: false,
@ -1394,7 +1394,7 @@ 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()
let mut passes = tcx.lint_store
.late_passes.iter().map(|p| (p)()).collect::<Vec<_>>();
if !tcx.sess.opts.debugging_opts.no_interleave_lints {
@ -1410,7 +1410,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
let mut passes: Vec<_> = tcx.lint_store.late_module_passes
.iter().map(|pass| (pass)()).collect();
for pass in &mut passes {
@ -1571,7 +1571,7 @@ impl Decodable for LintId {
fn decode<D: Decoder>(d: &mut D) -> Result<LintId, D::Error> {
let s = d.read_str()?;
ty::tls::with(|tcx| {
match tcx.sess.lint_store.borrow().find_lints(&s) {
match tcx.lint_store.find_lints(&s) {
Ok(ids) => {
if ids.len() != 0 {
panic!("invalid lint-id `{}`", s);

View file

@ -777,11 +777,11 @@ pub fn maybe_lint_level_root(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap {
assert_eq!(cnum, LOCAL_CRATE);
let store = tcx.sess.lint_store.borrow();
let store = &tcx.lint_store;
let mut builder = LintLevelMapBuilder {
levels: LintLevelSets::builder(tcx.sess, &store),
tcx: tcx,
store: &*store,
store: store,
};
let krate = tcx.hir().krate();

View file

@ -14,7 +14,7 @@
use rustc_data_structures::base_n;
use rustc_data_structures::sync::{
self, Lrc, Lock, OneThread, Once, RwLock, AtomicU64, AtomicUsize, Ordering,
self, Lrc, Lock, OneThread, Once, AtomicU64, AtomicUsize, Ordering,
Ordering::SeqCst,
};
@ -77,9 +77,11 @@ pub struct Session {
/// if the value stored here has been affected by path remapping.
pub working_dir: (PathBuf, bool),
// FIXME: `lint_store` and `buffered_lints` are not thread-safe,
// but are only used in a single thread.
pub lint_store: RwLock<lint::LintStore>,
/// This is intended to be used from a single thread.
///
/// FIXME: there was a previous comment about this not being thread safe,
/// but it's not clear how or why that's the case. The LintBuffer itself is certainly thread
/// safe at least from a "Rust safety" standpoint.
pub buffered_lints: Lock<Option<lint::LintBuffer>>,
/// Set of `(DiagnosticId, Option<Span>, message)` tuples tracking
@ -1213,7 +1215,6 @@ fn build_session_(
sysroot,
local_crate_source_file,
working_dir,
lint_store: RwLock::new(lint::LintStore::new()),
buffered_lints: Lock::new(Some(Default::default())),
one_time_diagnostics: Default::default(),
plugin_llvm_passes: OneThread::new(RefCell::new(Vec::new())),

View file

@ -1035,6 +1035,8 @@ pub struct GlobalCtxt<'tcx> {
pub sess: &'tcx Session,
pub lint_store: Lrc<lint::LintStore>,
pub dep_graph: DepGraph,
pub prof: SelfProfilerRef,
@ -1199,6 +1201,7 @@ pub fn lift<T: ?Sized + Lift<'tcx>>(self, value: &T) -> Option<T::Lifted> {
/// reference to the context, to allow formatting values that need it.
pub fn create_global_ctxt(
s: &'tcx Session,
lint_store: Lrc<lint::LintStore>,
cstore: &'tcx CrateStoreDyn,
local_providers: ty::query::Providers<'tcx>,
extern_providers: ty::query::Providers<'tcx>,
@ -1268,6 +1271,7 @@ pub fn create_global_ctxt(
GlobalCtxt {
sess: s,
lint_store,
cstore,
arena: WorkerLocal::new(|_| Arena::default()),
interners,

View file

@ -16,6 +16,7 @@ log = "0.4"
env_logger = { version = "0.7", default-features = false }
rustc = { path = "../librustc" }
rustc_target = { path = "../librustc_target" }
rustc_lint = { path = "../librustc_lint" }
rustc_data_structures = { path = "../librustc_data_structures" }
errors = { path = "../librustc_errors", package = "rustc_errors" }
rustc_metadata = { path = "../librustc_metadata" }

View file

@ -202,9 +202,13 @@ pub fn run_compiler(
interface::run_compiler(config, |compiler| {
let sopts = &compiler.session().opts;
if sopts.describe_lints {
let lint_store = rustc_lint::new_lint_store(
sopts.debugging_opts.no_interleave_lints,
compiler.session().unstable_options(),
);
describe_lints(
compiler.session(),
&*compiler.session().lint_store.borrow(),
&lint_store,
false
);
return;
@ -321,12 +325,14 @@ pub fn run_compiler(
return sess.compile_status();
}
compiler.register_plugins()?;
{
let (_, _, lint_store) = &*compiler.register_plugins()?.peek();
// Lint plugins are registered; now we can process command line flags.
if sess.opts.describe_lints {
describe_lints(&sess, &sess.lint_store.borrow(), true);
return sess.compile_status();
// Lint plugins are registered; now we can process command line flags.
if sess.opts.describe_lints {
describe_lints(&sess, &lint_store, true);
return sess.compile_status();
}
}
compiler.expansion()?;

View file

@ -117,6 +117,7 @@ fn count_nodes(krate: &ast::Crate) -> usize {
/// Returns `None` if we're aborting after handling -W help.
pub fn configure_and_expand(
sess: Lrc<Session>,
lint_store: Lrc<lint::LintStore>,
cstore: Lrc<CStore>,
krate: ast::Crate,
crate_name: &str,
@ -134,6 +135,7 @@ pub fn configure_and_expand(
let resolver_arenas = Resolver::arenas();
let res = configure_and_expand_inner(
sess,
&lint_store,
&*cstore,
krate,
&crate_name,
@ -227,7 +229,7 @@ pub fn register_plugins<'a>(
cstore: &'a CStore,
mut krate: ast::Crate,
crate_name: &str,
) -> Result<(ast::Crate, PluginInfo)> {
) -> Result<(ast::Crate, PluginInfo, Lrc<lint::LintStore>)> {
krate = time(sess, "attributes injection", || {
syntax_ext::cmdline_attrs::inject(
krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr
@ -278,7 +280,12 @@ pub fn register_plugins<'a>(
)
});
let mut registry = Registry::new(sess, krate.span);
let mut lint_store = rustc_lint::new_lint_store(
sess.opts.debugging_opts.no_interleave_lints,
sess.unstable_options(),
);
let mut registry = Registry::new(sess, &mut lint_store, krate.span);
time(sess, "plugin registration", || {
for registrar in registrars {
@ -289,36 +296,20 @@ pub fn register_plugins<'a>(
let Registry {
syntax_exts,
early_lint_passes,
late_lint_passes,
lints,
lint_groups,
llvm_passes,
attributes,
..
} = registry;
let mut ls = sess.lint_store.borrow_mut();
ls.register_lints(&lints);
for pass in early_lint_passes {
ls.register_early_pass(pass);
}
for pass in late_lint_passes {
ls.register_late_pass(pass);
}
for (name, (to, deprecated_name)) in lint_groups {
ls.register_group(true, name, deprecated_name, to);
}
*sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
*sess.plugin_attributes.borrow_mut() = attributes;
Ok((krate, PluginInfo { syntax_exts }))
Ok((krate, PluginInfo { syntax_exts }, Lrc::new(lint_store)))
}
fn configure_and_expand_inner<'a>(
sess: &'a Session,
lint_store: &'a lint::LintStore,
cstore: &'a CStore,
mut krate: ast::Crate,
crate_name: &str,
@ -329,7 +320,7 @@ fn configure_and_expand_inner<'a>(
time(sess, "pre-AST-expansion lint checks", || {
lint::check_ast_crate(
sess,
&*sess.lint_store.borrow(),
lint_store,
&krate,
true,
rustc_lint::BuiltinCombinedPreExpansionLintPass::new());
@ -539,6 +530,7 @@ fn configure_and_expand_inner<'a>(
pub fn lower_to_hir(
sess: &Session,
lint_store: &lint::LintStore,
cstore: &CStore,
resolver: &mut Resolver<'_>,
dep_graph: &DepGraph,
@ -559,7 +551,7 @@ pub fn lower_to_hir(
time(sess, "early lint checks", || {
lint::check_ast_crate(
sess,
&*sess.lint_store.borrow(),
lint_store,
&krate,
false,
rustc_lint::BuiltinCombinedEarlyLintPass::new(),
@ -826,6 +818,7 @@ pub fn enter<F, R>(&mut self, f: F) -> R
pub fn create_global_ctxt(
compiler: &Compiler,
lint_store: Lrc<lint::LintStore>,
mut hir_forest: hir::map::Forest,
defs: hir::map::Definitions,
resolutions: Resolutions,
@ -863,6 +856,7 @@ pub fn create_global_ctxt(
let gcx = TyCtxt::create_global_ctxt(
sess,
lint_store,
cstore,
local_providers,
extern_providers,

View file

@ -2,9 +2,11 @@
use crate::passes::{self, BoxedResolver, ExpansionResult, BoxedGlobalCtxt, PluginInfo};
use rustc_incremental::DepGraphFuture;
use rustc_data_structures::sync::Lrc;
use rustc::session::config::{OutputFilenames, OutputType};
use rustc::util::common::{time, ErrorReported};
use rustc::hir;
use rustc::lint::LintStore;
use rustc::hir::def_id::LOCAL_CRATE;
use rustc::ty::steal::Steal;
use rustc::dep_graph::DepGraph;
@ -74,8 +76,8 @@ pub(crate) struct Queries {
dep_graph_future: Query<Option<DepGraphFuture>>,
parse: Query<ast::Crate>,
crate_name: Query<String>,
register_plugins: Query<(ast::Crate, PluginInfo)>,
expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>)>,
register_plugins: Query<(ast::Crate, PluginInfo, Lrc<LintStore>)>,
expansion: Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>,
dep_graph: Query<DepGraph>,
lower_to_hir: Query<(Steal<hir::map::Forest>, ExpansionResult)>,
prepare_outputs: Query<OutputFilenames>,
@ -106,7 +108,7 @@ pub fn parse(&self) -> Result<&Query<ast::Crate>> {
})
}
pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo)>> {
pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo, Lrc<LintStore>)>> {
self.queries.register_plugins.compute(|| {
let crate_name = self.crate_name()?.peek().clone();
let krate = self.parse()?.take();
@ -148,17 +150,20 @@ pub fn crate_name(&self) -> Result<&Query<String>> {
pub fn expansion(
&self
) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>)>> {
) -> Result<&Query<(ast::Crate, Steal<Rc<RefCell<BoxedResolver>>>, Lrc<LintStore>)>> {
self.queries.expansion.compute(|| {
let crate_name = self.crate_name()?.peek().clone();
let (krate, plugin_info) = self.register_plugins()?.take();
let (krate, plugin_info, lint_store) = self.register_plugins()?.take();
passes::configure_and_expand(
self.sess.clone(),
lint_store.clone(),
self.cstore().clone(),
krate,
&crate_name,
plugin_info,
).map(|(krate, resolver)| (krate, Steal::new(Rc::new(RefCell::new(resolver)))))
).map(|(krate, resolver)| {
(krate, Steal::new(Rc::new(RefCell::new(resolver))), lint_store)
})
})
}
@ -185,9 +190,11 @@ pub fn lower_to_hir(&self) -> Result<&Query<(Steal<hir::map::Forest>, ExpansionR
let peeked = expansion_result.peek();
let krate = &peeked.0;
let resolver = peeked.1.steal();
let lint_store = &peeked.2;
let hir = Steal::new(resolver.borrow_mut().access(|resolver| {
passes::lower_to_hir(
self.session(),
lint_store,
self.cstore(),
resolver,
&*self.dep_graph()?.peek(),
@ -212,11 +219,13 @@ pub fn global_ctxt(&self) -> Result<&Query<BoxedGlobalCtxt>> {
self.queries.global_ctxt.compute(|| {
let crate_name = self.crate_name()?.peek().clone();
let outputs = self.prepare_outputs()?.peek().clone();
let lint_store = self.expansion()?.peek().2.clone();
let hir = self.lower_to_hir()?;
let hir = hir.peek();
let (ref hir_forest, ref expansion) = *hir;
Ok(passes::create_global_ctxt(
self,
lint_store,
hir_forest.steal(),
expansion.defs.steal(),
expansion.resolutions.steal(),

View file

@ -13,7 +13,6 @@
use rustc_data_structures::thin_vec::ThinVec;
use rustc_data_structures::fx::{FxHashSet, FxHashMap};
use rustc_errors::registry::Registry;
use rustc_lint;
use rustc_metadata::dynamic_lib::DynamicLibrary;
use rustc_mir;
use rustc_passes;
@ -108,12 +107,6 @@ pub fn create_session(
let codegen_backend = get_codegen_backend(&sess);
rustc_lint::register_builtins(&mut sess.lint_store.get_mut(),
sess.opts.debugging_opts.no_interleave_lints);
if sess.unstable_options() {
rustc_lint::register_internals(&mut sess.lint_store.get_mut());
}
let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg));
add_configuration(&mut cfg, &sess, &*codegen_backend);
sess.parse_sess.config = cfg;

View file

@ -189,10 +189,21 @@ macro_rules! declare_combined_late_pass {
late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLintPass]);
pub fn new_lint_store(no_interleave_lints: bool, internal_lints: bool) -> lint::LintStore {
let mut lint_store = lint::LintStore::new();
register_builtins(&mut lint_store, no_interleave_lints);
if internal_lints {
register_internals(&mut lint_store);
}
lint_store
}
/// Tell the `LintStore` about all the built-in lints (the ones
/// defined in this crate and the ones defined in
/// `rustc::lint::builtin`).
pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) {
fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) {
macro_rules! add_lint_group {
($name:expr, $($lint:ident),*) => (
store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]);
@ -327,7 +338,7 @@ macro_rules! register_passes {
"converted into hard error, see https://github.com/rust-lang/rust/issues/46205");
}
pub fn register_internals(store: &mut lint::LintStore) {
fn register_internals(store: &mut lint::LintStore) {
store.register_lints(&DefaultHashTypes::get_lints());
store.register_early_pass(|| box DefaultHashTypes::new());
store.register_lints(&LintPassImpl::get_lints());

View file

@ -1,8 +1,7 @@
//! Used by plugin crates to tell `rustc` about the plugins they provide.
use rustc::lint::{EarlyLintPassObject, LateLintPassObject, LintId, Lint};
use rustc::lint::LintStore;
use rustc::session::Session;
use rustc::util::nodemap::FxHashMap;
use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension};
use syntax_expand::base::MacroExpanderFn;
@ -26,6 +25,8 @@ pub struct Registry<'a> {
/// from the plugin registrar.
pub sess: &'a Session,
pub lint_store: &'a mut LintStore,
#[doc(hidden)]
pub args_hidden: Option<Vec<ast::NestedMetaItem>>,
@ -35,18 +36,6 @@ pub struct Registry<'a> {
#[doc(hidden)]
pub syntax_exts: Vec<NamedSyntaxExtension>,
#[doc(hidden)]
pub early_lint_passes: Vec<fn() -> EarlyLintPassObject>,
#[doc(hidden)]
pub late_lint_passes: Vec<fn() -> LateLintPassObject>,
#[doc(hidden)]
pub lints: Vec<&'static Lint>,
#[doc(hidden)]
pub lint_groups: FxHashMap<&'static str, (Vec<LintId>, Option<&'static str>)>,
#[doc(hidden)]
pub llvm_passes: Vec<String>,
@ -56,16 +45,13 @@ pub struct Registry<'a> {
impl<'a> Registry<'a> {
#[doc(hidden)]
pub fn new(sess: &'a Session, krate_span: Span) -> Registry<'a> {
pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> {
Registry {
sess,
lint_store,
args_hidden: None,
krate_span,
syntax_exts: vec![],
lints: vec![],
early_lint_passes: vec![],
late_lint_passes: vec![],
lint_groups: FxHashMap::default(),
llvm_passes: vec![],
attributes: vec![],
}
@ -103,32 +89,6 @@ pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
self.register_syntax_extension(Symbol::intern(name), ext);
}
/// Register a compiler lint pass.
pub fn register_lints(&mut self, lints: &[&'static Lint]) {
self.lints.extend(lints);
}
/// Register a compiler lint pass.
pub fn register_early_lint_pass(&mut self, lint_pass: fn() -> EarlyLintPassObject) {
self.early_lint_passes.push(lint_pass);
}
/// Register a compiler lint pass.
pub fn register_late_lint_pass(&mut self, lint_pass: fn() -> LateLintPassObject) {
self.late_lint_passes.push(lint_pass);
}
/// Register a lint group.
pub fn register_lint_group(
&mut self,
name: &'static str,
deprecated_name: Option<&'static str>,
to: Vec<&'static Lint>
) {
self.lint_groups.insert(name,
(to.into_iter().map(|x| LintId::of(x)).collect(),
deprecated_name));
}
/// Register an LLVM pass.
///
/// Registration with LLVM itself is handled through static C++ objects with