From 47a443c50dbeee88cadc78e5c938f3e6d04d6f6b Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 23 Sep 2019 20:13:02 -0400 Subject: [PATCH 01/18] Duplicate lint specifications are always bug! Replace early_error and sess.err with bug!, in all cases. If the compiler we're running with, including plugins, is registering something twice, that's a (compiler/plugin) programmer error -- we should not try to be nice at the cost of developer ergononomics (hiding the stacktrace of the second registration is bad). This also is basically a static bug in ~all cases so it should not be a detriment to users, including with plugins. --- src/librustc/lint/context.rs | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index fa73a3c6c4628..002c3f6623514 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -218,16 +218,7 @@ impl LintStore { let id = LintId::of(lint); if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { - let msg = format!("duplicate specification of lint {}", lint.name_lower()); - match (sess, from_plugin) { - // We load builtin lints first, so a duplicate is a compiler bug. - // Use early_error when handling -W help with no crate. - (None, _) => early_error(config::ErrorOutputType::default(), &msg[..]), - (Some(_), false) => bug!("{}", msg), - - // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[..]), - } + bug!("duplicate specification of lint {}", lint.name_lower()) } } } @@ -300,16 +291,7 @@ impl LintStore { } if !new { - let msg = format!("duplicate specification of lint group {}", name); - match (sess, from_plugin) { - // We load builtin lints first, so a duplicate is a compiler bug. - // Use early_error when handling -W help with no crate. - (None, _) => early_error(config::ErrorOutputType::default(), &msg[..]), - (Some(_), false) => bug!("{}", msg), - - // A duplicate name from a plugin is a user error. - (Some(sess), true) => sess.err(&msg[..]), - } + bug!("duplicate specification of lint group {}", name); } } From 577d442fe8337338b873d3df1ab5132de6a1af83 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 23 Sep 2019 20:26:11 -0400 Subject: [PATCH 02/18] De-propagate optional session from lint registration This is straight up removing dead code, but is a separate commit from the previous to avoid conflating clean up and important changes. --- src/librustc/lint/context.rs | 17 ++++--------- src/librustc_interface/passes.rs | 6 ++--- src/librustc_interface/util.rs | 5 ++-- src/librustc_lint/lib.rs | 42 +++++++++++++------------------- 4 files changed, 28 insertions(+), 42 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 002c3f6623514..dc16de822ebcd 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -26,7 +26,7 @@ use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; -use crate::session::{config, early_error, Session}; +use crate::session::Session; use crate::ty::{self, print::Printer, subst::GenericArg, TyCtxt, Ty}; use crate::ty::layout::{LayoutError, LayoutOf, TyLayout}; use crate::util::nodemap::FxHashMap; @@ -169,11 +169,10 @@ impl LintStore { } pub fn register_early_pass(&mut self, - sess: Option<&Session>, from_plugin: bool, register_only: bool, pass: EarlyLintPassObject) { - self.push_pass(sess, from_plugin, &pass); + self.push_pass(from_plugin, &pass); if !register_only { self.early_passes.as_mut().unwrap().push(pass); } @@ -181,24 +180,22 @@ impl LintStore { pub fn register_pre_expansion_pass( &mut self, - sess: Option<&Session>, from_plugin: bool, register_only: bool, pass: EarlyLintPassObject, ) { - self.push_pass(sess, from_plugin, &pass); + self.push_pass(from_plugin, &pass); if !register_only { self.pre_expansion_passes.as_mut().unwrap().push(pass); } } pub fn register_late_pass(&mut self, - sess: Option<&Session>, from_plugin: bool, register_only: bool, per_module: bool, pass: LateLintPassObject) { - self.push_pass(sess, from_plugin, &pass); + self.push_pass(from_plugin, &pass); if !register_only { if per_module { self.late_module_passes.push(pass); @@ -210,7 +207,6 @@ impl LintStore { // Helper method for register_early/late_pass fn push_pass(&mut self, - sess: Option<&Session>, from_plugin: bool, pass: &Box

) { for lint in pass.get_lints() { @@ -224,14 +220,13 @@ impl LintStore { } pub fn register_future_incompatible(&mut self, - sess: Option<&Session>, lints: Vec) { for edition in edition::ALL_EDITIONS { let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) .collect::>(); if !lints.is_empty() { - self.register_group(sess, false, edition.lint_name(), None, lints) + self.register_group(false, edition.lint_name(), None, lints) } } @@ -242,7 +237,6 @@ impl LintStore { } self.register_group( - sess, false, "future_incompatible", None, @@ -268,7 +262,6 @@ impl LintStore { pub fn register_group( &mut self, - sess: Option<&Session>, from_plugin: bool, name: &'static str, deprecated_name: Option<&'static str>, diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 89de5714695de..280ac45803b7e 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,14 +299,14 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(Some(sess), true, false, pass); + ls.register_early_pass(true, false, pass); } for pass in late_lint_passes { - ls.register_late_pass(Some(sess), true, false, false, pass); + ls.register_late_pass(true, false, false, pass); } for (name, (to, deprecated_name)) in lint_groups { - ls.register_group(Some(sess), true, name, deprecated_name, to); + ls.register_group(true, name, deprecated_name, to); } *sess.plugin_llvm_passes.borrow_mut() = llvm_passes; diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 0c272f0c4563b..005f1a44acd6a 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -108,9 +108,10 @@ pub fn create_session( let codegen_backend = get_codegen_backend(&sess); - rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&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.borrow_mut(), Some(&sess)); + rustc_lint::register_internals(&mut sess.lint_store.get_mut()); } let mut cfg = config::build_configuration(&sess, config::to_crate_config(cfg)); diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 0e054013cd779..5c70e9f8a1a30 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -41,7 +41,6 @@ use rustc::lint::builtin::{ PRIVATE_DOC_TESTS, parser::ILL_FORMED_ATTRIBUTE_INPUT, }; -use rustc::session; use rustc::hir; use rustc::hir::def_id::DefId; use rustc::ty::query::Providers; @@ -51,7 +50,6 @@ use syntax::ast; use syntax::edition::Edition; use syntax_pos::Span; -use session::Session; use lint::LintId; use lint::FutureIncompatibleInfo; @@ -198,16 +196,16 @@ late_lint_mod_passes!(declare_combined_late_pass, [BuiltinCombinedModuleLateLint /// 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, sess: Option<&Session>) { +pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) { macro_rules! add_lint_group { - ($sess:ident, $name:expr, $($lint:ident),*) => ( - store.register_group($sess, false, $name, None, vec![$(LintId::of($lint)),*]); + ($name:expr, $($lint:ident),*) => ( + store.register_group(false, $name, None, vec![$(LintId::of($lint)),*]); ) } macro_rules! register_pass { ($method:ident, $constructor:expr, [$($args:expr),*]) => ( - store.$method(sess, false, false, $($args,)* box $constructor); + store.$method(false, false, $($args,)* box $constructor); ) } @@ -219,35 +217,32 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { ) } - if sess.map(|sess| sess.opts.debugging_opts.no_interleave_lints).unwrap_or(false) { + if no_interleave_lints { pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]); early_lint_passes!(register_passes, [register_early_pass, []]); late_lint_passes!(register_passes, [register_late_pass, [false]]); late_lint_mod_passes!(register_passes, [register_late_pass, [true]]); } else { store.register_pre_expansion_pass( - sess, false, true, box BuiltinCombinedPreExpansionLintPass::new() ); - store.register_early_pass(sess, false, true, box BuiltinCombinedEarlyLintPass::new()); + store.register_early_pass(false, true, box BuiltinCombinedEarlyLintPass::new()); store.register_late_pass( - sess, false, true, true, box BuiltinCombinedModuleLateLintPass::new() + false, true, true, box BuiltinCombinedModuleLateLintPass::new() ); store.register_late_pass( - sess, false, true, false, box BuiltinCombinedLateLintPass::new() + false, true, false, box BuiltinCombinedLateLintPass::new() ); } - add_lint_group!(sess, - "nonstandard_style", + add_lint_group!("nonstandard_style", NON_CAMEL_CASE_TYPES, NON_SNAKE_CASE, NON_UPPER_CASE_GLOBALS); - add_lint_group!(sess, - "unused", + add_lint_group!("unused", UNUSED_IMPORTS, UNUSED_VARIABLES, UNUSED_ASSIGNMENTS, @@ -267,8 +262,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { UNUSED_LABELS, UNUSED_PARENS); - add_lint_group!(sess, - "rust_2018_idioms", + add_lint_group!("rust_2018_idioms", BARE_TRAIT_OBJECTS, UNUSED_EXTERN_CRATES, ELLIPSIS_INCLUSIVE_RANGE_PATTERNS, @@ -284,8 +278,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { // MACRO_USE_EXTERN_CRATE, ); - add_lint_group!(sess, - "rustdoc", + add_lint_group!("rustdoc", INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS); @@ -298,7 +291,7 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { // and include the full URL, sort items in ascending order of issue numbers. // - Later, change lint to error // - Eventually, remove lint - store.register_future_incompatible(sess, vec![ + store.register_future_incompatible(vec![ FutureIncompatibleInfo { id: LintId::of(PRIVATE_IN_PUBLIC), reference: "issue #34537 ", @@ -498,12 +491,11 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) { "converted into hard error, see https://github.com/rust-lang/rust/issues/46205"); } -pub fn register_internals(store: &mut lint::LintStore, sess: Option<&Session>) { - store.register_early_pass(sess, false, false, box DefaultHashTypes::new()); - store.register_early_pass(sess, false, false, box LintPassImpl); - store.register_late_pass(sess, false, false, false, box TyTyKind); +pub fn register_internals(store: &mut lint::LintStore) { + store.register_early_pass(false, false, box DefaultHashTypes::new()); + store.register_early_pass(false, false, box LintPassImpl); + store.register_late_pass(false, false, false, box TyTyKind); store.register_group( - sess, false, "rustc::internal", None, From 2121b04751702359f3bf03847040a9907ec2f66f Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 24 Sep 2019 18:24:45 -0400 Subject: [PATCH 03/18] Handle lints, not passes in push_lints This extracts the call to get_lints() to callers. --- src/librustc/lint/context.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index dc16de822ebcd..c21c45b759c63 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -172,7 +172,7 @@ impl LintStore { from_plugin: bool, register_only: bool, pass: EarlyLintPassObject) { - self.push_pass(from_plugin, &pass); + self.push_lints(from_plugin, &pass.get_lints()); if !register_only { self.early_passes.as_mut().unwrap().push(pass); } @@ -184,7 +184,7 @@ impl LintStore { register_only: bool, pass: EarlyLintPassObject, ) { - self.push_pass(from_plugin, &pass); + self.push_lints(from_plugin, &pass.get_lints()); if !register_only { self.pre_expansion_passes.as_mut().unwrap().push(pass); } @@ -195,7 +195,7 @@ impl LintStore { register_only: bool, per_module: bool, pass: LateLintPassObject) { - self.push_pass(from_plugin, &pass); + self.push_lints(from_plugin, &pass.get_lints()); if !register_only { if per_module { self.late_module_passes.push(pass); @@ -206,10 +206,8 @@ impl LintStore { } // Helper method for register_early/late_pass - fn push_pass(&mut self, - from_plugin: bool, - pass: &Box

) { - for lint in pass.get_lints() { + fn push_lints(&mut self, from_plugin: bool, lints: &[&'static Lint]) { + for lint in lints { self.lints.push((lint, from_plugin)); let id = LintId::of(lint); From 748eccd48828e430b906ffa6bd3f6abdcc766dc9 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 16:52:53 -0400 Subject: [PATCH 04/18] Lints being from a plugin is dependent on the lint, not the registration --- src/librustc/lint/context.rs | 17 +++++++---------- src/librustc/lint/mod.rs | 5 +++++ src/librustc_driver/lib.rs | 5 ++--- src/librustc_interface/passes.rs | 4 ++-- src/librustc_lint/lib.rs | 15 +++++++-------- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index c21c45b759c63..37f577da8bba2 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -50,7 +50,7 @@ use syntax_pos::{MultiSpan, Span, symbol::Symbol}; pub struct LintStore { /// Registered lints. The bool is true if the lint was /// added by a plugin. - lints: Vec<(&'static Lint, bool)>, + lints: Vec<&'static Lint>, /// Trait objects for each lint pass. /// This is only `None` while performing a lint pass. @@ -152,7 +152,7 @@ impl LintStore { } } - pub fn get_lints<'t>(&'t self) -> &'t [(&'static Lint, bool)] { + pub fn get_lints<'t>(&'t self) -> &'t [&'static Lint] { &self.lints } @@ -169,10 +169,9 @@ impl LintStore { } pub fn register_early_pass(&mut self, - from_plugin: bool, register_only: bool, pass: EarlyLintPassObject) { - self.push_lints(from_plugin, &pass.get_lints()); + self.push_lints(&pass.get_lints()); if !register_only { self.early_passes.as_mut().unwrap().push(pass); } @@ -180,22 +179,20 @@ impl LintStore { pub fn register_pre_expansion_pass( &mut self, - from_plugin: bool, register_only: bool, pass: EarlyLintPassObject, ) { - self.push_lints(from_plugin, &pass.get_lints()); + self.push_lints(&pass.get_lints()); if !register_only { self.pre_expansion_passes.as_mut().unwrap().push(pass); } } pub fn register_late_pass(&mut self, - from_plugin: bool, register_only: bool, per_module: bool, pass: LateLintPassObject) { - self.push_lints(from_plugin, &pass.get_lints()); + self.push_lints(&pass.get_lints()); if !register_only { if per_module { self.late_module_passes.push(pass); @@ -206,9 +203,9 @@ impl LintStore { } // Helper method for register_early/late_pass - fn push_lints(&mut self, from_plugin: bool, lints: &[&'static Lint]) { + fn push_lints(&mut self, lints: &[&'static Lint]) { for lint in lints { - self.lints.push((lint, from_plugin)); + self.lints.push(lint); let id = LintId::of(lint); if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 7443cca822a99..455dc06a1efbd 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -76,6 +76,8 @@ pub struct Lint { /// `true` if this lint is reported even inside expansions of external macros. pub report_in_external_macro: bool, + + pub is_plugin: bool, } impl Lint { @@ -117,6 +119,7 @@ macro_rules! declare_lint { desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, + is_plugin: false, }; ); ($vis: vis $NAME: ident, $Level: ident, $desc: expr, @@ -128,6 +131,7 @@ macro_rules! declare_lint { desc: $desc, edition_lint_opts: Some(($lint_edition, $crate::lint::Level::$edition_level)), report_in_external_macro: false, + is_plugin: false, }; ); } @@ -156,6 +160,7 @@ macro_rules! declare_tool_lint { desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, + is_plugin: true, }; ); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index f33cb4e215d33..5af1e8faccc8f 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -835,8 +835,7 @@ Available lint options: "); - fn sort_lints(sess: &Session, lints: Vec<(&'static Lint, bool)>) -> Vec<&'static Lint> { - let mut lints: Vec<_> = lints.into_iter().map(|(x, _)| x).collect(); + fn sort_lints(sess: &Session, mut lints: Vec<&'static Lint>) -> Vec<&'static Lint> { // The sort doesn't case-fold but it's doubtful we care. lints.sort_by_cached_key(|x: &&Lint| (x.default_level(sess), x.name)); lints @@ -852,7 +851,7 @@ Available lint options: let (plugin, builtin): (Vec<_>, _) = lint_store.get_lints() .iter() .cloned() - .partition(|&(_, p)| p); + .partition(|&lint| lint.is_plugin); let plugin = sort_lints(sess, plugin); let builtin = sort_lints(sess, builtin); diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 280ac45803b7e..2684650c3a970 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,10 +299,10 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(true, false, pass); + ls.register_early_pass(false, pass); } for pass in late_lint_passes { - ls.register_late_pass(true, false, false, pass); + ls.register_late_pass(false, false, pass); } for (name, (to, deprecated_name)) in lint_groups { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 5c70e9f8a1a30..2c39ba024513e 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -205,7 +205,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_pass { ($method:ident, $constructor:expr, [$($args:expr),*]) => ( - store.$method(false, false, $($args,)* box $constructor); + store.$method(false, $($args,)* box $constructor); ) } @@ -224,16 +224,15 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) late_lint_mod_passes!(register_passes, [register_late_pass, [true]]); } else { store.register_pre_expansion_pass( - false, true, box BuiltinCombinedPreExpansionLintPass::new() ); - store.register_early_pass(false, true, box BuiltinCombinedEarlyLintPass::new()); + store.register_early_pass(true, box BuiltinCombinedEarlyLintPass::new()); store.register_late_pass( - false, true, true, box BuiltinCombinedModuleLateLintPass::new() + true, true, box BuiltinCombinedModuleLateLintPass::new() ); store.register_late_pass( - false, true, false, box BuiltinCombinedLateLintPass::new() + true, false, box BuiltinCombinedLateLintPass::new() ); } @@ -492,9 +491,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { - store.register_early_pass(false, false, box DefaultHashTypes::new()); - store.register_early_pass(false, false, box LintPassImpl); - store.register_late_pass(false, false, false, box TyTyKind); + store.register_early_pass(false, box DefaultHashTypes::new()); + store.register_early_pass(false, box LintPassImpl); + store.register_late_pass(false, false, box TyTyKind); store.register_group( false, "rustc::internal", From b060f3b84d98a0288cf51a6ab82be61e8f047c31 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 16:59:12 -0400 Subject: [PATCH 05/18] Split module and crate late pass registration --- src/librustc/lint/context.rs | 18 +++++++++--------- src/librustc_interface/passes.rs | 2 +- src/librustc_lint/lib.rs | 19 ++++++------------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 37f577da8bba2..c65acd98385fa 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -188,17 +188,17 @@ impl LintStore { } } - pub fn register_late_pass(&mut self, - register_only: bool, - per_module: bool, - pass: LateLintPassObject) { + pub fn register_late_pass(&mut self, register_only: bool, pass: LateLintPassObject) { self.push_lints(&pass.get_lints()); if !register_only { - if per_module { - self.late_module_passes.push(pass); - } else { - self.late_passes.lock().as_mut().unwrap().push(pass); - } + self.late_passes.lock().as_mut().unwrap().push(pass); + } + } + + pub fn register_late_mod_pass(&mut self, register_only: bool, pass: LateLintPassObject) { + self.push_lints(&pass.get_lints()); + if !register_only { + self.late_module_passes.push(pass); } } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 2684650c3a970..544dd26d01528 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -302,7 +302,7 @@ pub fn register_plugins<'a>( ls.register_early_pass(false, pass); } for pass in late_lint_passes { - ls.register_late_pass(false, false, pass); + ls.register_late_pass(false, pass); } for (name, (to, deprecated_name)) in lint_groups { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 2c39ba024513e..5b190740c101a 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -220,20 +220,13 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) if no_interleave_lints { pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]); early_lint_passes!(register_passes, [register_early_pass, []]); - late_lint_passes!(register_passes, [register_late_pass, [false]]); - late_lint_mod_passes!(register_passes, [register_late_pass, [true]]); + late_lint_passes!(register_passes, [register_late_pass, []]); + late_lint_mod_passes!(register_passes, [register_late_mod_pass, []]); } else { - store.register_pre_expansion_pass( - true, - box BuiltinCombinedPreExpansionLintPass::new() - ); + store.register_pre_expansion_pass(true, box BuiltinCombinedPreExpansionLintPass::new()); store.register_early_pass(true, box BuiltinCombinedEarlyLintPass::new()); - store.register_late_pass( - true, true, box BuiltinCombinedModuleLateLintPass::new() - ); - store.register_late_pass( - true, false, box BuiltinCombinedLateLintPass::new() - ); + store.register_late_mod_pass(true, box BuiltinCombinedModuleLateLintPass::new()); + store.register_late_pass(true, box BuiltinCombinedLateLintPass::new()); } add_lint_group!("nonstandard_style", @@ -493,7 +486,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) pub fn register_internals(store: &mut lint::LintStore) { store.register_early_pass(false, box DefaultHashTypes::new()); store.register_early_pass(false, box LintPassImpl); - store.register_late_pass(false, false, box TyTyKind); + store.register_late_pass(false, box TyTyKind); store.register_group( false, "rustc::internal", From e1079c82be514c6a9423acefd4457a7a08c0091c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 17:21:50 -0400 Subject: [PATCH 06/18] Split out just registration to separate function --- src/librustc/lint/context.rs | 40 +++++++++++--------------------- src/librustc_interface/passes.rs | 4 ++-- src/librustc_lint/lib.rs | 30 ++++++++++++------------ 3 files changed, 30 insertions(+), 44 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index c65acd98385fa..ff0b5a9e25b79 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -168,42 +168,28 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, - register_only: bool, - pass: EarlyLintPassObject) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.early_passes.as_mut().unwrap().push(pass); - } + pub fn register_early_pass(&mut self, pass: EarlyLintPassObject) { + self.register_lints(&pass.get_lints()); + self.early_passes.as_mut().unwrap().push(pass); } - pub fn register_pre_expansion_pass( - &mut self, - register_only: bool, - pass: EarlyLintPassObject, - ) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.pre_expansion_passes.as_mut().unwrap().push(pass); - } + pub fn register_pre_expansion_pass(&mut self, pass: EarlyLintPassObject) { + self.register_lints(&pass.get_lints()); + self.pre_expansion_passes.as_mut().unwrap().push(pass); } - pub fn register_late_pass(&mut self, register_only: bool, pass: LateLintPassObject) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.late_passes.lock().as_mut().unwrap().push(pass); - } + pub fn register_late_pass(&mut self, pass: LateLintPassObject) { + self.register_lints(&pass.get_lints()); + self.late_passes.lock().as_mut().unwrap().push(pass); } - pub fn register_late_mod_pass(&mut self, register_only: bool, pass: LateLintPassObject) { - self.push_lints(&pass.get_lints()); - if !register_only { - self.late_module_passes.push(pass); - } + pub fn register_late_mod_pass(&mut self, pass: LateLintPassObject) { + self.register_lints(&pass.get_lints()); + self.late_module_passes.push(pass); } // Helper method for register_early/late_pass - fn push_lints(&mut self, lints: &[&'static Lint]) { + pub fn register_lints(&mut self, lints: &[&'static Lint]) { for lint in lints { self.lints.push(lint); diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 544dd26d01528..4e879e508ab49 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,10 +299,10 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { - ls.register_early_pass(false, pass); + ls.register_early_pass(pass); } for pass in late_lint_passes { - ls.register_late_pass(false, pass); + ls.register_late_pass(pass); } for (name, (to, deprecated_name)) in lint_groups { diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 5b190740c101a..49ab34b830a9b 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -204,29 +204,29 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } macro_rules! register_pass { - ($method:ident, $constructor:expr, [$($args:expr),*]) => ( - store.$method(false, $($args,)* box $constructor); + ($method:ident, $constructor:expr) => ( + store.$method(box $constructor); ) } macro_rules! register_passes { - ([$method:ident, $args:tt], [$($passes:ident: $constructor:expr,)*]) => ( + ($method:ident, [$($passes:ident: $constructor:expr,)*]) => ( $( - register_pass!($method, $constructor, $args); + register_pass!($method, $constructor); )* ) } if no_interleave_lints { - pre_expansion_lint_passes!(register_passes, [register_pre_expansion_pass, []]); - early_lint_passes!(register_passes, [register_early_pass, []]); - late_lint_passes!(register_passes, [register_late_pass, []]); - late_lint_mod_passes!(register_passes, [register_late_mod_pass, []]); + pre_expansion_lint_passes!(register_passes, register_pre_expansion_pass); + early_lint_passes!(register_passes, register_early_pass); + late_lint_passes!(register_passes, register_late_pass); + late_lint_mod_passes!(register_passes, register_late_mod_pass); } else { - store.register_pre_expansion_pass(true, box BuiltinCombinedPreExpansionLintPass::new()); - store.register_early_pass(true, box BuiltinCombinedEarlyLintPass::new()); - store.register_late_mod_pass(true, box BuiltinCombinedModuleLateLintPass::new()); - store.register_late_pass(true, box BuiltinCombinedLateLintPass::new()); + store.register_lints(&BuiltinCombinedPreExpansionLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedEarlyLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedModuleLateLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedLateLintPass::new().get_lints()); } add_lint_group!("nonstandard_style", @@ -484,9 +484,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { - store.register_early_pass(false, box DefaultHashTypes::new()); - store.register_early_pass(false, box LintPassImpl); - store.register_late_pass(false, box TyTyKind); + store.register_early_pass(box DefaultHashTypes::new()); + store.register_early_pass(box LintPassImpl); + store.register_late_pass(box TyTyKind); store.register_group( false, "rustc::internal", From 68c07db80a90fd0fc3be03474555dc685864bcb6 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 17:36:44 -0400 Subject: [PATCH 07/18] No longer implicitly register lints when registering passes This is in preparation for on-demand constructing passes --- src/librustc/lint/context.rs | 4 ---- src/librustc_interface/passes.rs | 2 ++ src/librustc_lint/lib.rs | 7 ++++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index ff0b5a9e25b79..e04845d278a54 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -169,22 +169,18 @@ impl LintStore { } pub fn register_early_pass(&mut self, pass: EarlyLintPassObject) { - self.register_lints(&pass.get_lints()); self.early_passes.as_mut().unwrap().push(pass); } pub fn register_pre_expansion_pass(&mut self, pass: EarlyLintPassObject) { - self.register_lints(&pass.get_lints()); self.pre_expansion_passes.as_mut().unwrap().push(pass); } pub fn register_late_pass(&mut self, pass: LateLintPassObject) { - self.register_lints(&pass.get_lints()); self.late_passes.lock().as_mut().unwrap().push(pass); } pub fn register_late_mod_pass(&mut self, pass: LateLintPassObject) { - self.register_lints(&pass.get_lints()); self.late_module_passes.push(pass); } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 4e879e508ab49..951b0970754a2 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -299,9 +299,11 @@ pub fn register_plugins<'a>( let mut ls = sess.lint_store.borrow_mut(); for pass in early_lint_passes { + ls.register_lints(&pass.get_lints()); ls.register_early_pass(pass); } for pass in late_lint_passes { + ls.register_lints(&pass.get_lints()); ls.register_late_pass(pass); } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 49ab34b830a9b..3bb7de8b7f61c 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -205,7 +205,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_pass { ($method:ident, $constructor:expr) => ( - store.$method(box $constructor); + let obj = box $constructor; + store.register_lints(&obj.get_lints()); + store.$method(obj); ) } @@ -484,8 +486,11 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { + store.register_lints(&DefaultHashTypes::new().get_lints()); store.register_early_pass(box DefaultHashTypes::new()); + store.register_lints(&LintPassImpl.get_lints()); store.register_early_pass(box LintPassImpl); + store.register_lints(&TyTyKind.get_lints()); store.register_late_pass(box TyTyKind); store.register_group( false, From 7fef39791a093681c59f08181f96a0a2d63ab981 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:04:05 -0400 Subject: [PATCH 08/18] Make get_lints be a static function This moves from calling get_lints on instantiated pass objects to the raw object --- src/librustc/lint/context.rs | 10 +----- src/librustc/lint/mod.rs | 36 ++++++++----------- src/librustc_interface/passes.rs | 4 +-- src/librustc_lint/lib.rs | 20 +++++------ src/librustc_plugin/registry.rs | 9 +++++ src/librustdoc/core.rs | 7 ++-- .../lint_pass_impl_without_macro.rs | 10 +----- .../lint_pass_impl_without_macro.stderr | 3 +- 8 files changed, 42 insertions(+), 57 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index e04845d278a54..373ee2568a47c 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -22,7 +22,7 @@ use crate::hir::intravisit as hir_visit; use crate::hir::intravisit::Visitor; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject}; -use crate::lint::{LintArray, Level, Lint, LintId, LintPass, LintBuffer}; +use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; @@ -1307,10 +1307,6 @@ impl LintPass for LateLintPassObjects<'_> { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - panic!() - } } macro_rules! expand_late_lint_pass_impl_methods { @@ -1477,10 +1473,6 @@ impl LintPass for EarlyLintPassObjects<'_> { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - panic!() - } } macro_rules! expand_early_lint_pass_impl_methods { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 455dc06a1efbd..1b34808ef30ac 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -178,14 +178,6 @@ pub type LintArray = Vec<&'static Lint>; pub trait LintPass { fn name(&self) -> &'static str; - - /// Gets descriptions of the lints this `LintPass` object can emit. - /// - /// N.B., there is no enforcement that the object only emits lints it registered. - /// And some `rustc` internal `LintPass`es register lints to be emitted by other - /// parts of the compiler. If you want enforced access restrictions for your - /// `Lint`, make it a private `static` item in its own module. - fn get_lints(&self) -> LintArray; } /// Implements `LintPass for $name` with the given list of `Lint` statics. @@ -194,7 +186,9 @@ macro_rules! impl_lint_pass { ($name:ident => [$($lint:expr),* $(,)?]) => { impl LintPass for $name { fn name(&self) -> &'static str { stringify!($name) } - fn get_lints(&self) -> LintArray { $crate::lint_array!($($lint),*) } + } + impl $name { + pub fn get_lints() -> LintArray { $crate::lint_array!($($lint),*) } } }; } @@ -332,6 +326,12 @@ macro_rules! declare_combined_late_lint_pass { $($passes: $constructor,)* } } + + $v fn get_lints() -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&$passes::get_lints());)* + lints + } } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $name { @@ -342,12 +342,6 @@ macro_rules! declare_combined_late_lint_pass { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - let mut lints = Vec::new(); - $(lints.extend_from_slice(&self.$passes.get_lints());)* - lints - } } ) } @@ -459,6 +453,12 @@ macro_rules! declare_combined_early_lint_pass { $($passes: $constructor,)* } } + + $v fn get_lints() -> LintArray { + let mut lints = Vec::new(); + $(lints.extend_from_slice(&$passes::get_lints());)* + lints + } } impl EarlyLintPass for $name { @@ -469,12 +469,6 @@ macro_rules! declare_combined_early_lint_pass { fn name(&self) -> &'static str { panic!() } - - fn get_lints(&self) -> LintArray { - let mut lints = Vec::new(); - $(lints.extend_from_slice(&self.$passes.get_lints());)* - lints - } } ) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 951b0970754a2..fdea437d37fbc 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -291,6 +291,7 @@ pub fn register_plugins<'a>( syntax_exts, early_lint_passes, late_lint_passes, + lints, lint_groups, llvm_passes, attributes, @@ -298,12 +299,11 @@ pub fn register_plugins<'a>( } = registry; let mut ls = sess.lint_store.borrow_mut(); + ls.register_lints(&lints); for pass in early_lint_passes { - ls.register_lints(&pass.get_lints()); ls.register_early_pass(pass); } for pass in late_lint_passes { - ls.register_lints(&pass.get_lints()); ls.register_late_pass(pass); } diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 3bb7de8b7f61c..752396188afd1 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -204,9 +204,9 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } macro_rules! register_pass { - ($method:ident, $constructor:expr) => ( + ($method:ident, $ty:ident, $constructor:expr) => ( let obj = box $constructor; - store.register_lints(&obj.get_lints()); + store.register_lints(&$ty::get_lints()); store.$method(obj); ) } @@ -214,7 +214,7 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_passes { ($method:ident, [$($passes:ident: $constructor:expr,)*]) => ( $( - register_pass!($method, $constructor); + register_pass!($method, $passes, $constructor); )* ) } @@ -225,10 +225,10 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) late_lint_passes!(register_passes, register_late_pass); late_lint_mod_passes!(register_passes, register_late_mod_pass); } else { - store.register_lints(&BuiltinCombinedPreExpansionLintPass::new().get_lints()); - store.register_lints(&BuiltinCombinedEarlyLintPass::new().get_lints()); - store.register_lints(&BuiltinCombinedModuleLateLintPass::new().get_lints()); - store.register_lints(&BuiltinCombinedLateLintPass::new().get_lints()); + store.register_lints(&BuiltinCombinedPreExpansionLintPass::get_lints()); + store.register_lints(&BuiltinCombinedEarlyLintPass::get_lints()); + store.register_lints(&BuiltinCombinedModuleLateLintPass::get_lints()); + store.register_lints(&BuiltinCombinedLateLintPass::get_lints()); } add_lint_group!("nonstandard_style", @@ -486,11 +486,11 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) } pub fn register_internals(store: &mut lint::LintStore) { - store.register_lints(&DefaultHashTypes::new().get_lints()); + store.register_lints(&DefaultHashTypes::get_lints()); store.register_early_pass(box DefaultHashTypes::new()); - store.register_lints(&LintPassImpl.get_lints()); + store.register_lints(&LintPassImpl::get_lints()); store.register_early_pass(box LintPassImpl); - store.register_lints(&TyTyKind.get_lints()); + store.register_lints(&TyTyKind::get_lints()); store.register_late_pass(box TyTyKind); store.register_group( false, diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index b826dd9119838..a8076b57c86ac 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -41,6 +41,9 @@ pub struct Registry<'a> { #[doc(hidden)] pub late_lint_passes: Vec, + #[doc(hidden)] + pub lints: Vec<&'static Lint>, + #[doc(hidden)] pub lint_groups: FxHashMap<&'static str, (Vec, Option<&'static str>)>, @@ -59,6 +62,7 @@ impl<'a> Registry<'a> { args_hidden: None, krate_span, syntax_exts: vec![], + lints: vec![], early_lint_passes: vec![], late_lint_passes: vec![], lint_groups: FxHashMap::default(), @@ -99,6 +103,11 @@ impl<'a> Registry<'a> { 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: EarlyLintPassObject) { self.early_lint_passes.push(lint_pass); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 00265caa965ea..2a468d679a887 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -5,7 +5,7 @@ use rustc::hir::HirId; use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; use rustc::ty::{Ty, TyCtxt}; -use rustc::lint::{self, LintPass}; +use rustc::lint; use rustc::session::config::ErrorOutputType; use rustc::session::DiagnosticOutput; use rustc::util::nodemap::{FxHashMap, FxHashSet}; @@ -273,10 +273,9 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt whitelisted_lints.extend(lint_opts.iter().map(|(lint, _)| lint).cloned()); let lints = || { - lint::builtin::HardwiredLints - .get_lints() + lint::builtin::HardwiredLints::get_lints() .into_iter() - .chain(rustc_lint::SoftLints.get_lints().into_iter()) + .chain(rustc_lint::SoftLints::get_lints().into_iter()) }; let lint_opts = lints().filter_map(|lint| { diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs index 48dd5b122b5ac..0bfb32c6dc43b 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs @@ -6,7 +6,7 @@ extern crate rustc; use rustc::lint::{LintArray, LintPass}; -use rustc::{declare_lint, declare_lint_pass, impl_lint_pass, lint_array}; +use rustc::{declare_lint, declare_lint_pass, impl_lint_pass}; declare_lint! { pub TEST_LINT, @@ -17,10 +17,6 @@ declare_lint! { struct Foo; impl LintPass for Foo { //~ERROR implementing `LintPass` by hand - fn get_lints(&self) -> LintArray { - lint_array!(TEST_LINT) - } - fn name(&self) -> &'static str { "Foo" } @@ -31,10 +27,6 @@ macro_rules! custom_lint_pass_macro { struct Custom; impl LintPass for Custom { //~ERROR implementing `LintPass` by hand - fn get_lints(&self) -> LintArray { - lint_array!(TEST_LINT) - } - fn name(&self) -> &'static str { "Custom" } diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index b439ae2cd148d..b7cff343395e9 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -12,7 +12,7 @@ LL | #![deny(rustc::lint_pass_impl_without_macro)] = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: implementing `LintPass` by hand - --> $DIR/lint_pass_impl_without_macro.rs:33:14 + --> $DIR/lint_pass_impl_without_macro.rs:29:14 | LL | impl LintPass for Custom { | ^^^^^^^^ @@ -23,4 +23,3 @@ LL | custom_lint_pass_macro!(); = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: aborting due to 2 previous errors - From 24545128ebf7e19536e1384f64b89a18742471b0 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:10:41 -0400 Subject: [PATCH 09/18] Take lint passes as constructor functions --- src/librustc/lint/context.rs | 16 ++++++++-------- src/librustc_lint/lib.rs | 9 ++++----- src/librustc_plugin/registry.rs | 8 ++++---- src/test/ui-fulldeps/auxiliary/lint-for-crate.rs | 3 ++- .../lint_pass_impl_without_macro.stderr | 1 + 5 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 373ee2568a47c..73d8bb11b719c 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -168,20 +168,20 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, pass: EarlyLintPassObject) { - self.early_passes.as_mut().unwrap().push(pass); + pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) { + self.early_passes.as_mut().unwrap().push((pass)()); } - pub fn register_pre_expansion_pass(&mut self, pass: EarlyLintPassObject) { - self.pre_expansion_passes.as_mut().unwrap().push(pass); + pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) { + self.pre_expansion_passes.as_mut().unwrap().push((pass)()); } - pub fn register_late_pass(&mut self, pass: LateLintPassObject) { - self.late_passes.lock().as_mut().unwrap().push(pass); + pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) { + self.late_passes.lock().as_mut().unwrap().push((pass)()); } - pub fn register_late_mod_pass(&mut self, pass: LateLintPassObject) { - self.late_module_passes.push(pass); + pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) { + self.late_module_passes.push((pass)()); } // Helper method for register_early/late_pass diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 752396188afd1..0026c2317d156 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -205,9 +205,8 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) macro_rules! register_pass { ($method:ident, $ty:ident, $constructor:expr) => ( - let obj = box $constructor; store.register_lints(&$ty::get_lints()); - store.$method(obj); + store.$method(|| box $constructor); ) } @@ -487,11 +486,11 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) pub fn register_internals(store: &mut lint::LintStore) { store.register_lints(&DefaultHashTypes::get_lints()); - store.register_early_pass(box DefaultHashTypes::new()); + store.register_early_pass(|| box DefaultHashTypes::new()); store.register_lints(&LintPassImpl::get_lints()); - store.register_early_pass(box LintPassImpl); + store.register_early_pass(|| box LintPassImpl); store.register_lints(&TyTyKind::get_lints()); - store.register_late_pass(box TyTyKind); + store.register_late_pass(|| box TyTyKind); store.register_group( false, "rustc::internal", diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index a8076b57c86ac..44318bf06aaaf 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -36,10 +36,10 @@ pub struct Registry<'a> { pub syntax_exts: Vec, #[doc(hidden)] - pub early_lint_passes: Vec, + pub early_lint_passes: Vec EarlyLintPassObject>, #[doc(hidden)] - pub late_lint_passes: Vec, + pub late_lint_passes: Vec LateLintPassObject>, #[doc(hidden)] pub lints: Vec<&'static Lint>, @@ -109,12 +109,12 @@ impl<'a> Registry<'a> { } /// Register a compiler lint pass. - pub fn register_early_lint_pass(&mut self, lint_pass: EarlyLintPassObject) { + 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: LateLintPassObject) { + pub fn register_late_lint_pass(&mut self, lint_pass: fn() -> LateLintPassObject) { self.late_lint_passes.push(lint_pass); } /// Register a lint group. diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index 000e10392e827..ba5b5d1906aea 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -32,5 +32,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box Pass); + reg.register_lint(&[&CRATE_NOT_OKAY]); + reg.register_late_lint_pass(|| box Pass); } diff --git a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr index b7cff343395e9..0dbdf4f5aa9e2 100644 --- a/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr +++ b/src/test/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.stderr @@ -23,3 +23,4 @@ LL | custom_lint_pass_macro!(); = help: try using `declare_lint_pass!` or `impl_lint_pass!` instead error: aborting due to 2 previous errors + From aa4ee2cc0f722467da4c4b0d19ad365a4be1e5d5 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 7 Oct 2019 18:23:16 -0400 Subject: [PATCH 10/18] 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 73d8bb11b719c..6e67c0315cf23 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 1b34808ef30ac..63c4013e1d317 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)*]); } ) From c1abc30660c0c0b081a42d0a476d81ba04e6d16b Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 8 Oct 2019 18:47:08 -0400 Subject: [PATCH 11/18] Make declare_lint take any amount of boolean fields --- src/librustc/lint/builtin.rs | 8 ++++---- src/librustc/lint/mod.rs | 23 +++++++++++++++++------ src/librustc_lint/builtin.rs | 4 ++-- src/librustc_lint/unused.rs | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 983e3a9922ec2..29cc326fab64d 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -22,7 +22,7 @@ declare_lint! { pub CONST_ERR, Deny, "constant evaluation detected erroneous expression", - report_in_external_macro: true + report_in_external_macro } declare_lint! { @@ -71,7 +71,7 @@ declare_lint! { pub UNREACHABLE_CODE, Warn, "detects unreachable code paths", - report_in_external_macro: true + report_in_external_macro } declare_lint! { @@ -211,7 +211,7 @@ declare_lint! { pub DEPRECATED, Warn, "detects use of deprecated items", - report_in_external_macro: true + report_in_external_macro } declare_lint! { @@ -381,7 +381,7 @@ declare_lint! { pub DEPRECATED_IN_FUTURE, Allow, "detects use of items that will be deprecated in a future version", - report_in_external_macro: true + report_in_external_macro } declare_lint! { diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 63c4013e1d317..76e6a28008a37 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -81,6 +81,17 @@ pub struct Lint { } impl Lint { + pub const fn default_fields_for_macro() -> Self { + Lint { + name: "", + default_level: Level::Forbid, + desc: "", + edition_lint_opts: None, + is_plugin: false, + report_in_external_macro: false, + } + } + /// Returns the `rust::lint::Lint` for a `syntax::early_buffered_lints::BufferedEarlyLintId`. pub fn from_parser_lint_id(lint_id: BufferedEarlyLintId) -> &'static Self { match lint_id { @@ -107,19 +118,19 @@ impl Lint { #[macro_export] macro_rules! declare_lint { ($vis: vis $NAME: ident, $Level: ident, $desc: expr) => ( - declare_lint!{$vis $NAME, $Level, $desc, false} + declare_lint!( + $vis $NAME, $Level, $desc, + ); ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, report_in_external_macro: $rep: expr) => ( - declare_lint!{$vis $NAME, $Level, $desc, $rep} - ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $external: expr) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $($v:ident),*) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, desc: $desc, edition_lint_opts: None, - report_in_external_macro: $external, is_plugin: false, + $($v: true,)* + ..$crate::lint::Lint::default_fields_for_macro() }; ); ($vis: vis $NAME: ident, $Level: ident, $desc: expr, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 9a16d0a0715f7..2997e1d2ca942 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -280,7 +280,7 @@ declare_lint! { pub MISSING_DOCS, Allow, "detects missing documentation for public members", - report_in_external_macro: true + report_in_external_macro } pub struct MissingDoc { @@ -1374,7 +1374,7 @@ declare_lint! { UNNAMEABLE_TEST_ITEMS, Warn, "detects an item that cannot be named being marked as `#[test_case]`", - report_in_external_macro: true + report_in_external_macro } pub struct UnnameableTestItems { diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 3b3995832cb4c..2ff8147149bb8 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -25,7 +25,7 @@ declare_lint! { pub UNUSED_MUST_USE, Warn, "unused result of a type flagged as `#[must_use]`", - report_in_external_macro: true + report_in_external_macro } declare_lint! { From 7abb1fafcec155c4b596147fda4aff5a5cda62f3 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 8 Oct 2019 21:49:21 -0400 Subject: [PATCH 12/18] Remove side table of future incompatibility info Moves this information to a direct field of Lint, which is where it belongs. --- src/librustc/lint/builtin.rs | 161 +++++++++++++++++++++++++++++------ src/librustc/lint/context.rs | 63 +++++--------- src/librustc/lint/mod.rs | 20 ++++- src/librustc_lint/builtin.rs | 13 ++- src/librustc_lint/lib.rs | 157 ---------------------------------- 5 files changed, 183 insertions(+), 231 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 29cc326fab64d..4c1093e00ceed 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -4,11 +4,12 @@ //! compiler code, rather than using their own custom pass. Those //! lints are all available in `rustc_lint::builtin`. -use crate::lint::{LintPass, LateLintPass, LintArray}; +use crate::lint::{LintPass, LateLintPass, LintArray, FutureIncompatibleInfo}; use crate::middle::stability; use crate::session::Session; use errors::{Applicability, DiagnosticBuilder, pluralise}; use syntax::ast; +use syntax::edition::Edition; use syntax::source_map::Span; use syntax::symbol::Symbol; @@ -125,7 +126,11 @@ declare_lint! { declare_lint! { pub PRIVATE_IN_PUBLIC, Warn, - "detect private items in public interfaces not caught by the old implementation" + "detect private items in public interfaces not caught by the old implementation", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #34537 ", + edition: None, + }; } declare_lint! { @@ -137,13 +142,21 @@ declare_lint! { declare_lint! { pub PUB_USE_OF_PRIVATE_EXTERN_CRATE, Deny, - "detect public re-exports of private extern crates" + "detect public re-exports of private extern crates", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #34537 ", + edition: None, + }; } declare_lint! { pub INVALID_TYPE_PARAM_DEFAULT, Deny, - "type parameter default erroneously allowed in invalid location" + "type parameter default erroneously allowed in invalid location", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #36887 ", + edition: None, + }; } declare_lint! { @@ -155,56 +168,92 @@ declare_lint! { declare_lint! { pub SAFE_EXTERN_STATICS, Deny, - "safe access to extern statics was erroneously allowed" + "safe access to extern statics was erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #36247 ", + edition: None, + }; } declare_lint! { pub SAFE_PACKED_BORROWS, Warn, - "safe borrows of fields of packed structs were was erroneously allowed" + "safe borrows of fields of packed structs were was erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #46043 ", + edition: None, + }; } declare_lint! { pub PATTERNS_IN_FNS_WITHOUT_BODY, Warn, - "patterns in functions without body were erroneously allowed" + "patterns in functions without body were erroneously allowed", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #35203 ", + edition: None, + }; } declare_lint! { pub LEGACY_DIRECTORY_OWNERSHIP, Deny, "non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \ - not named `mod.rs`" + not named `mod.rs`", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #37872 ", + edition: None, + }; } declare_lint! { pub LEGACY_CONSTRUCTOR_VISIBILITY, Deny, - "detects use of struct constructors that would be invisible with new visibility rules" + "detects use of struct constructors that would be invisible with new visibility rules", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #39207 ", + edition: None, + }; } declare_lint! { pub MISSING_FRAGMENT_SPECIFIER, Deny, - "detects missing fragment specifiers in unused `macro_rules!` patterns" + "detects missing fragment specifiers in unused `macro_rules!` patterns", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #40107 ", + edition: None, + }; } declare_lint! { pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES, Deny, - "detects parenthesized generic parameters in type and module names" + "detects parenthesized generic parameters in type and module names", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #42238 ", + edition: None, + }; } declare_lint! { pub LATE_BOUND_LIFETIME_ARGUMENTS, Warn, - "detects generic lifetime arguments in path segments with late bound lifetime parameters" + "detects generic lifetime arguments in path segments with late bound lifetime parameters", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #42868 ", + edition: None, + }; } declare_lint! { pub ORDER_DEPENDENT_TRAIT_OBJECTS, Deny, - "trait-object types were treated as different depending on marker-trait order" + "trait-object types were treated as different depending on marker-trait order", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #56484 ", + edition: None, + }; } declare_lint! { @@ -247,7 +296,11 @@ declare_lint! { declare_lint! { pub TYVAR_BEHIND_RAW_POINTER, Warn, - "raw pointer to an inference variable" + "raw pointer to an inference variable", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #46906 ", + edition: Some(Edition::Edition2018), + }; } declare_lint! { @@ -266,19 +319,33 @@ declare_lint! { pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, Allow, "fully qualified paths that start with a module name \ - instead of `crate`, `self`, or an extern crate name" + instead of `crate`, `self`, or an extern crate name", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #53130 ", + edition: Some(Edition::Edition2018), + }; } declare_lint! { pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, Warn, - "floating-point literals cannot be used in patterns" + "floating-point literals cannot be used in patterns", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #41620 ", + edition: None, + }; } declare_lint! { pub UNSTABLE_NAME_COLLISIONS, Warn, - "detects name collision with an existing but unstable method" + "detects name collision with an existing but unstable method", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #48919 ", + edition: None, + // Note: this item represents future incompatibility of all unstable functions in the + // standard library, and thus should never be removed or changed to an error. + }; } declare_lint! { @@ -296,7 +363,11 @@ declare_lint! { declare_lint! { pub DUPLICATE_MACRO_EXPORTS, Deny, - "detects duplicate macro exports" + "detects duplicate macro exports", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #35896 ", + edition: Some(Edition::Edition2018), + }; } declare_lint! { @@ -320,13 +391,21 @@ declare_lint! { declare_lint! { pub WHERE_CLAUSES_OBJECT_SAFETY, Warn, - "checks the object safety of where clauses" + "checks the object safety of where clauses", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #51443 ", + edition: None, + }; } declare_lint! { pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, Warn, - "detects proc macro derives using inaccessible names from parent modules" + "detects proc macro derives using inaccessible names from parent modules", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #50504 ", + edition: None, + }; } declare_lint! { @@ -340,7 +419,11 @@ declare_lint! { pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, Deny, "macro-expanded `macro_export` macros from the current crate \ - cannot be referred to by absolute paths" + cannot be referred to by absolute paths", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #52234 ", + edition: None, + }; } declare_lint! { @@ -353,7 +436,11 @@ declare_lint! { pub INDIRECT_STRUCTURAL_MATCH, // defaulting to allow until rust-lang/rust#62614 is fixed. Allow, - "pattern with const indirectly referencing non-`#[structural_match]` type" + "pattern with const indirectly referencing non-`#[structural_match]` type", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #62411 ", + edition: None, + }; } /// Some lints that are buffered from `libsyntax`. See `syntax::early_buffered_lints`. @@ -361,7 +448,11 @@ pub mod parser { declare_lint! { pub ILL_FORMED_ATTRIBUTE_INPUT, Warn, - "ill-formed attribute inputs that were previously accepted and used in practice" + "ill-formed attribute inputs that were previously accepted and used in practice", + @future_incompatible = super::FutureIncompatibleInfo { + reference: "issue #57571 ", + edition: None, + }; } declare_lint! { @@ -387,25 +478,41 @@ declare_lint! { declare_lint! { pub AMBIGUOUS_ASSOCIATED_ITEMS, Deny, - "ambiguous associated items" + "ambiguous associated items", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #57644 ", + edition: None, + }; } declare_lint! { pub NESTED_IMPL_TRAIT, Warn, - "nested occurrence of `impl Trait` type" + "nested occurrence of `impl Trait` type", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #59014 ", + edition: None, + }; } declare_lint! { pub MUTABLE_BORROW_RESERVATION_CONFLICT, Warn, - "reservation of a two-phased borrow conflicts with other shared borrows" + "reservation of a two-phased borrow conflicts with other shared borrows", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #59159 ", + edition: None, + }; } declare_lint! { pub SOFT_UNSTABLE, Deny, - "a feature gate that doesn't break dependent crates" + "a feature gate that doesn't break dependent crates", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #64266 ", + edition: None, + }; } declare_lint_pass! { diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 6e67c0315cf23..97b9f21163dbe 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -22,7 +22,7 @@ use crate::hir::intravisit as hir_visit; use crate::hir::intravisit::Visitor; use crate::hir::map::{definitions::DisambiguatedDefPathData, DefPathData}; use crate::lint::{EarlyLintPass, LateLintPass, EarlyLintPassObject, LateLintPassObject}; -use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer}; +use crate::lint::{Level, Lint, LintId, LintPass, LintBuffer, FutureIncompatibleInfo}; use crate::lint::builtin::BuiltinLintDiagnostics; use crate::lint::levels::{LintLevelSets, LintLevelsBuilder}; use crate::middle::privacy::AccessLevels; @@ -38,7 +38,6 @@ use std::default::Default as StdDefault; use rustc_data_structures::sync::{ReadGuard, ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; -use syntax::edition; use syntax::util::lev_distance::find_best_match_for_name; use syntax::visit as ast_visit; use syntax_pos::{MultiSpan, Span, symbol::Symbol}; @@ -69,10 +68,6 @@ pub struct LintStore { /// Map of registered lint groups to what lints they expand to. lint_groups: FxHashMap<&'static str, LintGroup>, - - /// Extra info for future incompatibility lints, describing the - /// issue or RFC that caused the incompatibility. - future_incompatible: FxHashMap, } /// Lints that are buffered up early on in the `Session` before the @@ -86,18 +81,6 @@ pub struct BufferedEarlyLint { pub diagnostic: BuiltinLintDiagnostics, } -/// Extra information for a future incompatibility lint. See the call -/// to `register_future_incompatible` in `librustc_lint/lib.rs` for -/// guidelines. -pub struct FutureIncompatibleInfo { - pub id: LintId, - /// e.g., a URL for an issue/PR/RFC or error code - pub reference: &'static str, - /// If this is an edition fixing lint, the edition in which - /// this lint becomes obsolete - pub edition: Option, -} - /// The target of the `by_name` map, which accounts for renaming/deprecation. enum TargetLint { /// A direct lint target @@ -152,7 +135,6 @@ impl LintStore { late_passes: vec![], late_module_passes: vec![], by_name: Default::default(), - future_incompatible: Default::default(), lint_groups: Default::default(), } } @@ -198,36 +180,31 @@ impl LintStore { if self.by_name.insert(lint.name_lower(), Id(id)).is_some() { bug!("duplicate specification of lint {}", lint.name_lower()) } - } - } - pub fn register_future_incompatible(&mut self, - lints: Vec) { + if let Some(FutureIncompatibleInfo { edition, .. }) = lint.future_incompatible { + if let Some(edition) = edition { + self.lint_groups.entry(edition.lint_name()) + .or_insert(LintGroup { + lint_ids: vec![], + from_plugin: lint.is_plugin, + depr: None, + }) + .lint_ids.push(id); + } - for edition in edition::ALL_EDITIONS { - let lints = lints.iter().filter(|f| f.edition == Some(*edition)).map(|f| f.id) - .collect::>(); - if !lints.is_empty() { - self.register_group(false, edition.lint_name(), None, lints) + self.lint_groups.entry("future_incompatible") + .or_insert(LintGroup { + lint_ids: vec![], + from_plugin: lint.is_plugin, + depr: None, + }) + .lint_ids.push(id); } } - - let mut future_incompatible = Vec::with_capacity(lints.len()); - for lint in lints { - future_incompatible.push(lint.id); - self.future_incompatible.insert(lint.id, lint); - } - - self.register_group( - false, - "future_incompatible", - None, - future_incompatible, - ); } - pub fn future_incompatible(&self, id: LintId) -> Option<&FutureIncompatibleInfo> { - self.future_incompatible.get(&id) + pub fn future_incompatible(&self, id: LintId) -> Option { + id.lint.future_incompatible } pub fn register_group_alias( diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index 76e6a28008a37..ba7ec0ed6e484 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -45,7 +45,7 @@ use syntax_pos::Span; pub use crate::lint::context::{LateContext, EarlyContext, LintContext, LintStore, check_crate, check_ast_crate, late_lint_mod, CheckLintNameResult, - FutureIncompatibleInfo, BufferedEarlyLint,}; + BufferedEarlyLint,}; /// Specification of a single lint. #[derive(Copy, Clone, Debug)] @@ -77,9 +77,21 @@ pub struct Lint { /// `true` if this lint is reported even inside expansions of external macros. pub report_in_external_macro: bool, + pub future_incompatible: Option, + pub is_plugin: bool, } +/// Extra information for a future incompatibility lint. +#[derive(Copy, Clone, Debug)] +pub struct FutureIncompatibleInfo { + /// e.g., a URL for an issue/PR/RFC or error code + pub reference: &'static str, + /// If this is an edition fixing lint, the edition in which + /// this lint becomes obsolete + pub edition: Option, +} + impl Lint { pub const fn default_fields_for_macro() -> Self { Lint { @@ -89,6 +101,7 @@ impl Lint { edition_lint_opts: None, is_plugin: false, report_in_external_macro: false, + future_incompatible: None, } } @@ -122,7 +135,8 @@ macro_rules! declare_lint { $vis $NAME, $Level, $desc, ); ); - ($vis: vis $NAME: ident, $Level: ident, $desc: expr, $($v:ident),*) => ( + ($vis: vis $NAME: ident, $Level: ident, $desc: expr, + $(@future_incompatible = $fi:expr;)? $($v:ident),*) => ( $vis static $NAME: &$crate::lint::Lint = &$crate::lint::Lint { name: stringify!($NAME), default_level: $crate::lint::$Level, @@ -130,6 +144,7 @@ macro_rules! declare_lint { edition_lint_opts: None, is_plugin: false, $($v: true,)* + $(future_incompatible: Some($fi),)* ..$crate::lint::Lint::default_fields_for_macro() }; ); @@ -171,6 +186,7 @@ macro_rules! declare_tool_lint { desc: $desc, edition_lint_opts: None, report_in_external_macro: $external, + future_incompatible: None, is_plugin: true, }; ); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 2997e1d2ca942..bce04471cec48 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -27,6 +27,7 @@ use rustc::hir::def::{Res, DefKind}; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::ty::{self, Ty, TyCtxt, layout::VariantIdx}; use rustc::{lint, util}; +use rustc::lint::FutureIncompatibleInfo; use hir::Node; use util::nodemap::HirIdSet; use lint::{LateContext, LintContext, LintArray}; @@ -601,7 +602,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDebugImplementations { declare_lint! { pub ANONYMOUS_PARAMETERS, Allow, - "detects anonymous parameters" + "detects anonymous parameters", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #41686 ", + edition: Some(Edition::Edition2018), + }; } declare_lint_pass!( @@ -1423,7 +1428,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnnameableTestItems { declare_lint! { pub KEYWORD_IDENTS, Allow, - "detects edition keywords being used as an identifier" + "detects edition keywords being used as an identifier", + @future_incompatible = FutureIncompatibleInfo { + reference: "issue #49716 ", + edition: Some(Edition::Edition2018), + }; } declare_lint_pass!( diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index 0026c2317d156..c83074c95ca0a 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -33,13 +33,11 @@ use rustc::lint; use rustc::lint::{EarlyContext, LateContext, LateLintPass, EarlyLintPass, LintPass, LintArray}; use rustc::lint::builtin::{ BARE_TRAIT_OBJECTS, - ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS, INTRA_DOC_LINK_RESOLUTION_FAILURE, MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS, - parser::ILL_FORMED_ATTRIBUTE_INPUT, }; use rustc::hir; use rustc::hir::def_id::DefId; @@ -47,11 +45,9 @@ use rustc::ty::query::Providers; use rustc::ty::TyCtxt; use syntax::ast; -use syntax::edition::Edition; use syntax_pos::Span; use lint::LintId; -use lint::FutureIncompatibleInfo; use redundant_semicolon::*; use nonstandard_style::*; @@ -276,159 +272,6 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) MISSING_DOC_CODE_EXAMPLES, PRIVATE_DOC_TESTS); - // Guidelines for creating a future incompatibility lint: - // - // - Create a lint defaulting to warn as normal, with ideally the same error - // message you would normally give - // - Add a suitable reference, typically an RFC or tracking issue. Go ahead - // and include the full URL, sort items in ascending order of issue numbers. - // - Later, change lint to error - // - Eventually, remove lint - store.register_future_incompatible(vec![ - FutureIncompatibleInfo { - id: LintId::of(PRIVATE_IN_PUBLIC), - reference: "issue #34537 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(PUB_USE_OF_PRIVATE_EXTERN_CRATE), - reference: "issue #34537 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY), - reference: "issue #35203 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(DUPLICATE_MACRO_EXPORTS), - reference: "issue #35896 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(KEYWORD_IDENTS), - reference: "issue #49716 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(SAFE_EXTERN_STATICS), - reference: "issue #36247 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(INVALID_TYPE_PARAM_DEFAULT), - reference: "issue #36887 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(LEGACY_DIRECTORY_OWNERSHIP), - reference: "issue #37872 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(LEGACY_CONSTRUCTOR_VISIBILITY), - reference: "issue #39207 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(MISSING_FRAGMENT_SPECIFIER), - reference: "issue #40107 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ILLEGAL_FLOATING_POINT_LITERAL_PATTERN), - reference: "issue #41620 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ANONYMOUS_PARAMETERS), - reference: "issue #41686 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES), - reference: "issue #42238 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(LATE_BOUND_LIFETIME_ARGUMENTS), - reference: "issue #42868 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(SAFE_PACKED_BORROWS), - reference: "issue #46043 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ORDER_DEPENDENT_TRAIT_OBJECTS), - reference: "issue #56484 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(TYVAR_BEHIND_RAW_POINTER), - reference: "issue #46906 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(UNSTABLE_NAME_COLLISIONS), - reference: "issue #48919 ", - edition: None, - // Note: this item represents future incompatibility of all unstable functions in the - // standard library, and thus should never be removed or changed to an error. - }, - FutureIncompatibleInfo { - id: LintId::of(ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE), - reference: "issue #53130 ", - edition: Some(Edition::Edition2018), - }, - FutureIncompatibleInfo { - id: LintId::of(WHERE_CLAUSES_OBJECT_SAFETY), - reference: "issue #51443 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(PROC_MACRO_DERIVE_RESOLUTION_FALLBACK), - reference: "issue #50504 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS), - reference: "issue #52234 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(ILL_FORMED_ATTRIBUTE_INPUT), - reference: "issue #57571 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(AMBIGUOUS_ASSOCIATED_ITEMS), - reference: "issue #57644 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(NESTED_IMPL_TRAIT), - reference: "issue #59014 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(MUTABLE_BORROW_RESERVATION_CONFLICT), - reference: "issue #59159 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(INDIRECT_STRUCTURAL_MATCH), - reference: "issue #62411 ", - edition: None, - }, - FutureIncompatibleInfo { - id: LintId::of(SOFT_UNSTABLE), - reference: "issue #64266 ", - edition: None, - }, - ]); - // Register renamed and removed lints. store.register_renamed("single_use_lifetime", "single_use_lifetimes"); store.register_renamed("elided_lifetime_in_path", "elided_lifetimes_in_paths"); From c4475c753b252060dbc76a73b83159484992bf06 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 8 Oct 2019 21:51:18 -0400 Subject: [PATCH 13/18] Access future incompatibility information directly Avoid querying LintStore when not necessary --- src/librustc/lint/context.rs | 4 ---- src/librustc/lint/mod.rs | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 97b9f21163dbe..4146606d443ec 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -203,10 +203,6 @@ impl LintStore { } } - pub fn future_incompatible(&self, id: LintId) -> Option { - id.lint.future_incompatible - } - pub fn register_group_alias( &mut self, lint_name: &'static str, diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index ba7ec0ed6e484..e3219b717905a 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -672,9 +672,8 @@ pub fn struct_lint_level<'a>(sess: &'a Session, }; // Check for future incompatibility lints and issue a stronger warning. - let lints = sess.lint_store.borrow(); let lint_id = LintId::of(lint); - let future_incompatible = lints.future_incompatible(lint_id); + let future_incompatible = lint.future_incompatible; // If this code originates in a foreign macro, aka something that this crate // did not itself author, then it's likely that there's nothing this crate From da56d1d20113355047f5e6e3d5686ea1c7589d99 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 9 Oct 2019 08:46:11 -0400 Subject: [PATCH 14/18] Remove all borrows of lint store from Session from librustc Access through tcx is fine -- by that point, the lint store is frozen, but direct access through Session will go away in future commits, as lint store is still mutable in early stages of Session, and will be removed completely. --- src/librustc/lint/context.rs | 21 +++++++++++++-------- src/librustc/lint/levels.rs | 16 +++++++--------- src/librustc/lint/mod.rs | 15 +++++++++------ src/librustc_interface/passes.rs | 9 ++++++++- 4 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 4146606d443ec..515d4d3cd7272 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -480,7 +480,7 @@ pub struct EarlyContext<'a> { builder: LintLevelsBuilder<'a>, /// The store of registered lints and the lint levels. - lint_store: ReadGuard<'a, LintStore>, + lint_store: &'a LintStore, buffered: LintBuffer, } @@ -569,14 +569,15 @@ pub trait LintContext: Sized { impl<'a> EarlyContext<'a> { fn new( sess: &'a Session, + lint_store: &'a LintStore, krate: &'a ast::Crate, buffered: LintBuffer, ) -> EarlyContext<'a> { EarlyContext { sess, krate, - lint_store: sess.lint_store.borrow(), - builder: LintLevelSets::builder(sess), + lint_store, + builder: LintLevelSets::builder(sess, lint_store), buffered, } } @@ -611,7 +612,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { f: F) where F: FnOnce(&mut Self) { - let push = self.context.builder.push(attrs); + let push = self.context.builder.push(attrs, &self.context.lint_store); self.check_id(id); self.enter_attrs(attrs); f(self); @@ -1473,12 +1474,13 @@ early_lint_methods!(early_lint_pass_impl, []); fn early_lint_crate( sess: &Session, + lint_store: &LintStore, krate: &ast::Crate, pass: T, buffered: LintBuffer, ) -> LintBuffer { let mut cx = EarlyContextAndPass { - context: EarlyContext::new(sess, krate, buffered), + context: EarlyContext::new(sess, lint_store, krate, buffered), pass, }; @@ -1497,28 +1499,30 @@ fn early_lint_crate( pub fn check_ast_crate( sess: &Session, + lint_store: &LintStore, krate: &ast::Crate, pre_expansion: bool, builtin_lints: T, ) { let (mut passes, mut buffered): (Vec<_>, _) = if pre_expansion { ( - sess.lint_store.borrow().pre_expansion_passes.iter().map(|p| (p)()).collect(), + lint_store.pre_expansion_passes.iter().map(|p| (p)()).collect(), LintBuffer::default(), ) } else { ( - sess.lint_store.borrow().early_passes.iter().map(|p| (p)()).collect(), + lint_store.early_passes.iter().map(|p| (p)()).collect(), sess.buffered_lints.borrow_mut().take().unwrap(), ) }; if !sess.opts.debugging_opts.no_interleave_lints { - buffered = early_lint_crate(sess, krate, builtin_lints, buffered); + buffered = early_lint_crate(sess, lint_store, krate, builtin_lints, buffered); if !passes.is_empty() { buffered = early_lint_crate( sess, + lint_store, krate, EarlyLintPassObjects { lints: &mut passes[..] }, buffered, @@ -1529,6 +1533,7 @@ pub fn check_ast_crate( buffered = time(sess, &format!("running lint: {}", pass.name()), || { early_lint_crate( sess, + lint_store, krate, EarlyLintPassObjects { lints: slice::from_mut(pass) }, buffered, diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs index 60b1b192d10db..36c7c5b20fded 100644 --- a/src/librustc/lint/levels.rs +++ b/src/librustc/lint/levels.rs @@ -3,7 +3,7 @@ use std::cmp; use crate::hir::HirId; use crate::ich::StableHashingContext; use crate::lint::builtin; -use crate::lint::context::CheckLintNameResult; +use crate::lint::context::{LintStore, CheckLintNameResult}; use crate::lint::{self, Lint, LintId, Level, LintSource}; use crate::session::Session; use crate::util::nodemap::FxHashMap; @@ -35,21 +35,20 @@ enum LintSet { } impl LintLevelSets { - pub fn new(sess: &Session) -> LintLevelSets { + pub fn new(sess: &Session, lint_store: &LintStore) -> LintLevelSets { let mut me = LintLevelSets { list: Vec::new(), lint_cap: Level::Forbid, }; - me.process_command_line(sess); + me.process_command_line(sess, lint_store); return me } - pub fn builder(sess: &Session) -> LintLevelsBuilder<'_> { - LintLevelsBuilder::new(sess, LintLevelSets::new(sess)) + pub fn builder<'a>(sess: &'a Session, store: &LintStore) -> LintLevelsBuilder<'a> { + LintLevelsBuilder::new(sess, LintLevelSets::new(sess, store)) } - fn process_command_line(&mut self, sess: &Session) { - let store = sess.lint_store.borrow(); + fn process_command_line(&mut self, sess: &Session, store: &LintStore) { let mut specs = FxHashMap::default(); self.lint_cap = sess.opts.lint_cap.unwrap_or(Level::Forbid); @@ -186,9 +185,8 @@ impl<'a> LintLevelsBuilder<'a> { /// #[allow] /// /// Don't forget to call `pop`! - pub fn push(&mut self, attrs: &[ast::Attribute]) -> BuilderPush { + pub fn push(&mut self, attrs: &[ast::Attribute], store: &LintStore) -> BuilderPush { let mut specs = FxHashMap::default(); - let store = self.sess.lint_store.borrow(); let sess = self.sess; let bad_attr = |span| { struct_span_err!(sess, span, E0452, "malformed lint attribute input") diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index e3219b717905a..ea06884d2c425 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -777,13 +777,15 @@ 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 mut builder = LintLevelMapBuilder { - levels: LintLevelSets::builder(tcx.sess), + levels: LintLevelSets::builder(tcx.sess, &store), tcx: tcx, + store: &*store, }; let krate = tcx.hir().krate(); - let push = builder.levels.push(&krate.attrs); + let push = builder.levels.push(&krate.attrs, &store); builder.levels.register_id(hir::CRATE_HIR_ID); for macro_def in &krate.exported_macros { builder.levels.register_id(macro_def.hir_id); @@ -794,19 +796,20 @@ fn lint_levels(tcx: TyCtxt<'_>, cnum: CrateNum) -> &LintLevelMap { tcx.arena.alloc(builder.levels.build_map()) } -struct LintLevelMapBuilder<'tcx> { +struct LintLevelMapBuilder<'a, 'tcx> { levels: levels::LintLevelsBuilder<'tcx>, tcx: TyCtxt<'tcx>, + store: &'a LintStore, } -impl LintLevelMapBuilder<'tcx> { +impl LintLevelMapBuilder<'_, '_> { fn with_lint_attrs(&mut self, id: hir::HirId, attrs: &[ast::Attribute], f: F) where F: FnOnce(&mut Self) { - let push = self.levels.push(attrs); + let push = self.levels.push(attrs, self.store); if push.changed { self.levels.register_id(id); } @@ -815,7 +818,7 @@ impl LintLevelMapBuilder<'tcx> { } } -impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'tcx> { +impl intravisit::Visitor<'tcx> for LintLevelMapBuilder<'_, 'tcx> { fn nested_visit_map<'this>(&'this mut self) -> intravisit::NestedVisitorMap<'this, 'tcx> { intravisit::NestedVisitorMap::All(&self.tcx.hir()) } diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index fdea437d37fbc..2fd7b2507a786 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -329,6 +329,7 @@ fn configure_and_expand_inner<'a>( time(sess, "pre-AST-expansion lint checks", || { lint::check_ast_crate( sess, + &*sess.lint_store.borrow(), &krate, true, rustc_lint::BuiltinCombinedPreExpansionLintPass::new()); @@ -556,7 +557,13 @@ pub fn lower_to_hir( }); time(sess, "early lint checks", || { - lint::check_ast_crate(sess, &krate, false, rustc_lint::BuiltinCombinedEarlyLintPass::new()) + lint::check_ast_crate( + sess, + &*sess.lint_store.borrow(), + &krate, + false, + rustc_lint::BuiltinCombinedEarlyLintPass::new(), + ) }); // Discard hygiene data, which isn't required after lowering to HIR. From dab3bd6cda23064e6726bd046c903096ef03cbd0 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 9 Oct 2019 09:53:13 -0400 Subject: [PATCH 15/18] Create lint store during plugin registration Remove lint store from Session --- Cargo.lock | 1 + src/librustc/lint/context.rs | 16 +++++----- src/librustc/lint/mod.rs | 4 +-- src/librustc/session/mod.rs | 11 +++---- src/librustc/ty/context.rs | 4 +++ src/librustc_driver/Cargo.toml | 1 + src/librustc_driver/lib.rs | 18 +++++++---- src/librustc_interface/passes.rs | 38 ++++++++++------------- src/librustc_interface/queries.rs | 21 +++++++++---- src/librustc_interface/util.rs | 7 ----- src/librustc_lint/lib.rs | 15 ++++++++-- src/librustc_plugin/registry.rs | 50 ++++--------------------------- 12 files changed, 83 insertions(+), 103 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a5a7521abde13..04181e197258d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3483,6 +3483,7 @@ dependencies = [ "rustc_data_structures", "rustc_errors", "rustc_interface", + "rustc_lint", "rustc_metadata", "rustc_mir", "rustc_plugin", diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 515d4d3cd7272..8208cc26ed30c 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, 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::>(); 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: &mut D) -> Result { 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); diff --git a/src/librustc/lint/mod.rs b/src/librustc/lint/mod.rs index ea06884d2c425..3c35bdae66e9d 100644 --- a/src/librustc/lint/mod.rs +++ b/src/librustc/lint/mod.rs @@ -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(); diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index b65bf2230b39d..bd2460cfab116 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -14,7 +14,7 @@ use crate::util::common::{duration_to_secs_str, ErrorReported}; 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, + /// 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>, /// Set of `(DiagnosticId, Option, 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())), diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 256194cfb00ef..a70ff37b7a04c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1035,6 +1035,8 @@ pub struct GlobalCtxt<'tcx> { pub sess: &'tcx Session, + pub lint_store: Lrc, + pub dep_graph: DepGraph, pub prof: SelfProfilerRef, @@ -1199,6 +1201,7 @@ impl<'tcx> TyCtxt<'tcx> { /// reference to the context, to allow formatting values that need it. pub fn create_global_ctxt( s: &'tcx Session, + lint_store: Lrc, cstore: &'tcx CrateStoreDyn, local_providers: ty::query::Providers<'tcx>, extern_providers: ty::query::Providers<'tcx>, @@ -1268,6 +1271,7 @@ impl<'tcx> TyCtxt<'tcx> { GlobalCtxt { sess: s, + lint_store, cstore, arena: WorkerLocal::new(|_| Arena::default()), interners, diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index aa74966d0ab4c..a9e4e6db1c75f 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -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" } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 5af1e8faccc8f..8793b7f5130a0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -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()?; diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 2fd7b2507a786..f9efd00f6983c 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -117,6 +117,7 @@ declare_box_region_type!( /// Returns `None` if we're aborting after handling -W help. pub fn configure_and_expand( sess: Lrc, + lint_store: Lrc, cstore: Lrc, 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)> { 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 @@ impl BoxedGlobalCtxt { pub fn create_global_ctxt( compiler: &Compiler, + lint_store: Lrc, 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, diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index cd72dc9453c7e..bb1221ead98bc 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -2,9 +2,11 @@ use crate::interface::{Compiler, Result}; 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>, parse: Query, crate_name: Query, - register_plugins: Query<(ast::Crate, PluginInfo)>, - expansion: Query<(ast::Crate, Steal>>)>, + register_plugins: Query<(ast::Crate, PluginInfo, Lrc)>, + expansion: Query<(ast::Crate, Steal>>, Lrc)>, dep_graph: Query, lower_to_hir: Query<(Steal, ExpansionResult)>, prepare_outputs: Query, @@ -106,7 +108,7 @@ impl Compiler { }) } - pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo)>> { + pub fn register_plugins(&self) -> Result<&Query<(ast::Crate, PluginInfo, Lrc)>> { self.queries.register_plugins.compute(|| { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); @@ -148,17 +150,20 @@ impl Compiler { pub fn expansion( &self - ) -> Result<&Query<(ast::Crate, Steal>>)>> { + ) -> Result<&Query<(ast::Crate, Steal>>, Lrc)>> { 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 @@ impl Compiler { 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 @@ impl Compiler { 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(), diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 005f1a44acd6a..8f11dc9372728 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -13,7 +13,6 @@ use rustc_data_structures::fingerprint::Fingerprint; 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; diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs index c83074c95ca0a..3c2396f6cdb07 100644 --- a/src/librustc_lint/lib.rs +++ b/src/librustc_lint/lib.rs @@ -189,10 +189,21 @@ late_lint_passes!(declare_combined_late_pass, [pub BuiltinCombinedLateLintPass]) 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 @@ pub fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) "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()); diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 44318bf06aaaf..223956a4f5e3f 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -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>, @@ -35,18 +36,6 @@ pub struct Registry<'a> { #[doc(hidden)] pub syntax_exts: Vec, - #[doc(hidden)] - pub early_lint_passes: Vec EarlyLintPassObject>, - - #[doc(hidden)] - pub late_lint_passes: Vec LateLintPassObject>, - - #[doc(hidden)] - pub lints: Vec<&'static Lint>, - - #[doc(hidden)] - pub lint_groups: FxHashMap<&'static str, (Vec, Option<&'static str>)>, - #[doc(hidden)] pub llvm_passes: Vec, @@ -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 @@ impl<'a> Registry<'a> { 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 From b761367d52b30c86a7d404a64a3b2dd854cd7418 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 9 Oct 2019 15:41:17 -0400 Subject: [PATCH 16/18] Fix test fallout --- .../auxiliary/issue-40001-plugin.rs | 7 +++--- .../auxiliary/lint-for-crate-rpass.rs | 24 +++++++++---------- .../ui-fulldeps/auxiliary/lint-for-crate.rs | 6 ++--- .../auxiliary/lint-group-plugin-test.rs | 8 ++++--- .../ui-fulldeps/auxiliary/lint-plugin-test.rs | 6 ++--- .../ui-fulldeps/auxiliary/lint-tool-test.rs | 8 ++++--- 6 files changed, 31 insertions(+), 28 deletions(-) diff --git a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs index bb0ebf693d0be..6b914f501ca79 100644 --- a/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs +++ b/src/test/ui-fulldeps/auxiliary/issue-40001-plugin.rs @@ -15,15 +15,14 @@ use syntax::symbol::Symbol; use rustc::hir; use rustc::hir::intravisit; -use rustc::hir::map as hir_map; use hir::Node; use rustc::lint::{LateContext, LintPass, LintArray, LateLintPass, LintContext}; -use rustc::ty; -use syntax::{ast, source_map}; +use syntax::source_map; #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box MissingWhitelistedAttrPass); + reg.lint_store.register_lints(&[&MISSING_WHITELISTED_ATTR]); + reg.lint_store.register_late_pass(|| box MissingWhitelistedAttrPass); reg.register_attribute(Symbol::intern("whitelisted_attr"), Whitelisted); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs index 17386d7e1aa5f..6874c921c1cc1 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate-rpass.rs @@ -7,24 +7,20 @@ extern crate rustc_driver; extern crate syntax; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass}; use rustc_driver::plugin::Registry; use rustc::hir; use syntax::attr; use syntax::symbol::Symbol; macro_rules! fake_lint_pass { - ($struct:ident, $lints:expr, $($attr:expr),*) => { + ($struct:ident, $($attr:expr),*) => { struct $struct; impl LintPass for $struct { fn name(&self) -> &'static str { stringify!($struct) } - - fn get_lints(&self) -> LintArray { - $lints - } } impl<'a, 'tcx> LateLintPass<'a, 'tcx> for $struct { @@ -49,25 +45,29 @@ declare_lint!(CRATE_NOT_GREEN, Warn, "crate not marked with #![crate_green]"); fake_lint_pass! { PassOkay, - lint_array!(CRATE_NOT_OKAY), // Single lint Symbol::intern("rustc_crate_okay") } fake_lint_pass! { PassRedBlue, - lint_array!(CRATE_NOT_RED, CRATE_NOT_BLUE), // Multiple lints Symbol::intern("rustc_crate_red"), Symbol::intern("rustc_crate_blue") } fake_lint_pass! { PassGreyGreen, - lint_array!(CRATE_NOT_GREY, CRATE_NOT_GREEN, ), // Trailing comma Symbol::intern("rustc_crate_grey"), Symbol::intern("rustc_crate_green") } #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box PassOkay); - reg.register_late_lint_pass(box PassRedBlue); - reg.register_late_lint_pass(box PassGreyGreen); + reg.lint_store.register_lints(&[ + &CRATE_NOT_OKAY, + &CRATE_NOT_RED, + &CRATE_NOT_BLUE, + &CRATE_NOT_GREY, + &CRATE_NOT_GREEN, + ]); + reg.lint_store.register_late_pass(|| box PassOkay); + reg.lint_store.register_late_pass(|| box PassRedBlue); + reg.lint_store.register_late_pass(|| box PassGreyGreen); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs index ba5b5d1906aea..1cd3e7b28dba7 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-for-crate.rs @@ -7,7 +7,7 @@ extern crate rustc_driver; extern crate syntax; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray}; use rustc_driver::plugin::Registry; use rustc::hir; use syntax::attr; @@ -32,6 +32,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_lint(&[&CRATE_NOT_OKAY]); - reg.register_late_lint_pass(|| box Pass); + reg.lint_store.register_lints(&[&CRATE_NOT_OKAY]); + reg.lint_store.register_late_pass(|| box Pass); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs index a377b07bd3dd2..cb793b4349885 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-group-plugin-test.rs @@ -9,7 +9,7 @@ extern crate rustc; extern crate rustc_driver; use rustc::hir; -use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LintArray, LintId}; use rustc_driver::plugin::Registry; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); @@ -30,6 +30,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_late_lint_pass(box Pass); - reg.register_lint_group("lint_me", None, vec![TEST_LINT, PLEASE_LINT]); + reg.lint_store.register_lints(&[&TEST_LINT, &PLEASE_LINT]); + reg.lint_store.register_late_pass(|| box Pass); + reg.lint_store.register_group(true, "lint_me", None, + vec![LintId::of(&TEST_LINT), LintId::of(&PLEASE_LINT)]); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs index 02675191f785e..40c37eb570e2d 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-plugin-test.rs @@ -10,8 +10,7 @@ extern crate syntax; extern crate rustc; extern crate rustc_driver; -use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, - EarlyLintPassObject, LintArray}; +use rustc::lint::{EarlyContext, LintContext, LintPass, EarlyLintPass, LintArray}; use rustc_driver::plugin::Registry; use syntax::ast; declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); @@ -28,5 +27,6 @@ impl EarlyLintPass for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_early_lint_pass(box Pass as EarlyLintPassObject); + reg.lint_store.register_lints(&[&TEST_LINT]); + reg.lint_store.register_early_pass(|| box Pass); } diff --git a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs index 40f8d490ac87c..67135d595f448 100644 --- a/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint-tool-test.rs @@ -8,7 +8,7 @@ extern crate syntax; extern crate rustc; extern crate rustc_driver; -use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass}; +use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass, LintId}; use rustc_driver::plugin::Registry; use syntax::ast; declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff"); @@ -40,6 +40,8 @@ impl EarlyLintPass for Pass { #[plugin_registrar] pub fn plugin_registrar(reg: &mut Registry) { - reg.register_early_lint_pass(box Pass); - reg.register_lint_group("clippy::group", Some("clippy_group"), vec![TEST_LINT, TEST_GROUP]); + reg.lint_store.register_lints(&[&TEST_RUSTC_TOOL_LINT, &TEST_LINT, &TEST_GROUP]); + reg.lint_store.register_early_pass(|| box Pass); + reg.lint_store.register_group(true, "clippy::group", Some("clippy_group"), + vec![LintId::of(&TEST_LINT), LintId::of(&TEST_GROUP)]); } From 6be0a7081a9aafc4e0b39cae266fbed5eabd8993 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Thu, 10 Oct 2019 19:33:00 -0400 Subject: [PATCH 17/18] Update API to be more compatible with plugin needs Move to using Box ...> so that we can let plugins register state. This also adds a callback that'll get called from plugin registration so that Clippy and other tools can register lints without using the plugin API. The plugin API still works, but this new API is more compatible with drivers other than rustc. --- src/librustc/lint/context.rs | 30 +++++++++++-------- src/librustc_driver/lib.rs | 3 ++ src/librustc_interface/interface.rs | 4 +++ src/librustc_interface/passes.rs | 3 ++ src/librustc_interface/queries.rs | 7 +++++ src/librustdoc/core.rs | 1 + src/librustdoc/test.rs | 1 + src/test/run-make-fulldeps/issue-19371/foo.rs | 1 + 8 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 8208cc26ed30c..2a0cdba50cb5f 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::{ParallelIterator, join, par_iter}; +use rustc_data_structures::sync::{self, ParallelIterator, join, par_iter}; use rustc_serialize::{Decoder, Decodable, Encoder, Encodable}; use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; @@ -57,11 +57,11 @@ pub struct LintStore { /// 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>, + pre_expansion_passes: Vec EarlyLintPassObject + sync::Send + sync::Sync>>, + early_passes: Vec EarlyLintPassObject + sync::Send + sync::Sync>>, + late_passes: Vec LateLintPassObject + sync::Send + sync::Sync>>, /// This is unique in that we construct them per-module, so not once. - late_module_passes: Vec LateLintPassObject>, + late_module_passes: Vec LateLintPassObject + sync::Send + sync::Sync>>, /// Lints indexed by name. by_name: FxHashMap, @@ -155,20 +155,24 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.early_passes.push(pass); + pub fn register_early_pass(&mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + self.early_passes.push(Box::new(pass)); } - pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) { - self.pre_expansion_passes.push(pass); + pub fn register_pre_expansion_pass(&mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + self.pre_expansion_passes.push(Box::new(pass)); } - pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_passes.push(pass); + pub fn register_late_pass(&mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + self.late_passes.push(Box::new(pass)); } - pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) { - self.late_module_passes.push(pass); + pub fn register_late_mod_pass(&mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + self.late_module_passes.push(Box::new(pass)); } // Helper method for register_early/late_pass diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 8793b7f5130a0..2cf1552ed9683 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -106,6 +106,7 @@ pub fn abort_on_err(result: Result, sess: &Session) -> T { pub trait Callbacks { /// Called before creating the compiler instance fn config(&mut self, _config: &mut interface::Config) {} + fn extra_lints(&mut self, _ls: &mut lint::LintStore) {} /// Called after parsing. Return value instructs the compiler whether to /// continue the compilation afterwards (defaults to `Compilation::Continue`) fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation { @@ -182,6 +183,7 @@ pub fn run_compiler( stderr: None, crate_name: None, lint_caps: Default::default(), + register_lints: None, }; callbacks.config(&mut config); config @@ -259,6 +261,7 @@ pub fn run_compiler( stderr: None, crate_name: None, lint_caps: Default::default(), + register_lints: None, }; callbacks.config(&mut config); diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index b26bd75c974c6..34ec3c862a3e4 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -34,6 +34,7 @@ pub struct Compiler { pub(crate) queries: Queries, pub(crate) cstore: Lrc, pub(crate) crate_name: Option, + pub(crate) register_lints: Option>, } impl Compiler { @@ -80,6 +81,8 @@ pub struct Config { pub crate_name: Option, pub lint_caps: FxHashMap, + + pub register_lints: Option>, } pub fn run_compiler_in_existing_thread_pool(config: Config, f: F) -> R @@ -108,6 +111,7 @@ where output_file: config.output_file, queries: Default::default(), crate_name: config.crate_name, + register_lints: config.register_lints, }; let _sess_abort_error = OnDrop(|| { diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index f9efd00f6983c..2044b73db8aa9 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -227,6 +227,7 @@ pub struct PluginInfo { pub fn register_plugins<'a>( sess: &'a Session, cstore: &'a CStore, + register_lints: impl Fn(&Session, &mut lint::LintStore), mut krate: ast::Crate, crate_name: &str, ) -> Result<(ast::Crate, PluginInfo, Lrc)> { @@ -285,6 +286,8 @@ pub fn register_plugins<'a>( sess.unstable_options(), ); + (register_lints)(&sess, &mut lint_store); + let mut registry = Registry::new(sess, &mut lint_store, krate.span); time(sess, "plugin registration", || { diff --git a/src/librustc_interface/queries.rs b/src/librustc_interface/queries.rs index bb1221ead98bc..84648ca8326fb 100644 --- a/src/librustc_interface/queries.rs +++ b/src/librustc_interface/queries.rs @@ -6,6 +6,8 @@ use rustc_data_structures::sync::Lrc; use rustc::session::config::{OutputFilenames, OutputType}; use rustc::util::common::{time, ErrorReported}; use rustc::hir; +use rustc::lint; +use rustc::session::Session; use rustc::lint::LintStore; use rustc::hir::def_id::LOCAL_CRATE; use rustc::ty::steal::Steal; @@ -113,9 +115,14 @@ impl Compiler { let crate_name = self.crate_name()?.peek().clone(); let krate = self.parse()?.take(); + let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {}; let result = passes::register_plugins( self.session(), self.cstore(), + self.register_lints + .as_ref() + .map(|p| &**p) + .unwrap_or_else(|| empty), krate, &crate_name, ); diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 2a468d679a887..be6404b869760 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -338,6 +338,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt stderr: None, crate_name, lint_caps, + register_lints: None, }; interface::run_compiler_in_existing_thread_pool(config, |compiler| { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 0be6340df96e8..03e37967c4b58 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -77,6 +77,7 @@ pub fn run(options: Options) -> i32 { stderr: None, crate_name: options.crate_name.clone(), lint_caps: Default::default(), + register_lints: None, }; let mut test_args = options.test_args.clone(); diff --git a/src/test/run-make-fulldeps/issue-19371/foo.rs b/src/test/run-make-fulldeps/issue-19371/foo.rs index e290f7fa6b13a..9582137eae91c 100644 --- a/src/test/run-make-fulldeps/issue-19371/foo.rs +++ b/src/test/run-make-fulldeps/issue-19371/foo.rs @@ -59,6 +59,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) { stderr: None, crate_name: None, lint_caps: Default::default(), + register_lints: None, }; interface::run_compiler(config, |compiler| { From 4e8d1b229217c7c83ce96b44410ccae9470db973 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 22 Oct 2019 16:53:28 -0400 Subject: [PATCH 18/18] Add some documentation --- src/librustc/lint/context.rs | 24 ++++++++++++++++-------- src/librustc_driver/lib.rs | 1 + src/librustc_interface/interface.rs | 5 +++++ src/librustc_plugin/registry.rs | 1 + 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 2a0cdba50cb5f..595b715c02ef6 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -155,23 +155,31 @@ impl LintStore { .collect() } - pub fn register_early_pass(&mut self, - pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_early_pass( + &mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync + ) { self.early_passes.push(Box::new(pass)); } - pub fn register_pre_expansion_pass(&mut self, - pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_pre_expansion_pass( + &mut self, + pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync, + ) { self.pre_expansion_passes.push(Box::new(pass)); } - pub fn register_late_pass(&mut self, - pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_late_pass( + &mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync, + ) { self.late_passes.push(Box::new(pass)); } - pub fn register_late_mod_pass(&mut self, - pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) { + pub fn register_late_mod_pass( + &mut self, + pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync, + ) { self.late_module_passes.push(Box::new(pass)); } diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 2cf1552ed9683..a18ef014b4dc0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -106,6 +106,7 @@ pub fn abort_on_err(result: Result, sess: &Session) -> T { pub trait Callbacks { /// Called before creating the compiler instance fn config(&mut self, _config: &mut interface::Config) {} + /// Called early during compilation to allow other drivers to easily register lints. fn extra_lints(&mut self, _ls: &mut lint::LintStore) {} /// Called after parsing. Return value instructs the compiler whether to /// continue the compilation afterwards (defaults to `Compilation::Continue`) diff --git a/src/librustc_interface/interface.rs b/src/librustc_interface/interface.rs index 34ec3c862a3e4..3f832f95bd408 100644 --- a/src/librustc_interface/interface.rs +++ b/src/librustc_interface/interface.rs @@ -82,6 +82,11 @@ pub struct Config { pub crate_name: Option, pub lint_caps: FxHashMap, + /// This is a callback from the driver that is called when we're registering lints; + /// it is called during plugin registration when we have the LintStore in a non-shared state. + /// + /// Note that if you find a Some here you probably want to call that function in the new + /// function being registered. pub register_lints: Option>, } diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 223956a4f5e3f..2e23b8c870cfc 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -25,6 +25,7 @@ pub struct Registry<'a> { /// from the plugin registrar. pub sess: &'a Session, + /// The `LintStore` allows plugins to register new lints. pub lint_store: &'a mut LintStore, #[doc(hidden)]