about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Rousskov <mark.simulacrum@gmail.com>2019-10-10 19:33:00 -0400
committerMark Rousskov <mark.simulacrum@gmail.com>2019-10-17 19:41:21 -0400
commit6be0a7081a9aafc4e0b39cae266fbed5eabd8993 (patch)
tree6029a490136be5982d68ee7a68a5fd46e48f03cb
parentb761367d52b30c86a7d404a64a3b2dd854cd7418 (diff)
downloadrust-6be0a7081a9aafc4e0b39cae266fbed5eabd8993.tar.gz
rust-6be0a7081a9aafc4e0b39cae266fbed5eabd8993.zip
Update API to be more compatible with plugin needs
Move to using Box<dyn Fn() -> ...> 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.
-rw-r--r--src/librustc/lint/context.rs30
-rw-r--r--src/librustc_driver/lib.rs3
-rw-r--r--src/librustc_interface/interface.rs4
-rw-r--r--src/librustc_interface/passes.rs3
-rw-r--r--src/librustc_interface/queries.rs7
-rw-r--r--src/librustdoc/core.rs1
-rw-r--r--src/librustdoc/test.rs1
-rw-r--r--src/test/run-make-fulldeps/issue-19371/foo.rs1
8 files changed, 37 insertions, 13 deletions
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 8208cc26ed3..2a0cdba50cb 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<fn() -> EarlyLintPassObject>,
-    early_passes: Vec<fn() -> EarlyLintPassObject>,
-    late_passes: Vec<fn() -> LateLintPassObject>,
+    pre_expansion_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
+    early_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
+    late_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
     /// This is unique in that we construct them per-module, so not once.
-    late_module_passes: Vec<fn() -> LateLintPassObject>,
+    late_module_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
 
     /// Lints indexed by name.
     by_name: FxHashMap<String, TargetLint>,
@@ -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 8793b7f5130..2cf1552ed96 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -106,6 +106,7 @@ pub fn abort_on_err<T>(result: Result<T, ErrorReported>, 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 b26bd75c974..34ec3c862a3 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<CStore>,
     pub(crate) crate_name: Option<String>,
+    pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
 }
 
 impl Compiler {
@@ -80,6 +81,8 @@ pub struct Config {
 
     pub crate_name: Option<String>,
     pub lint_caps: FxHashMap<lint::LintId, lint::Level>,
+
+    pub register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
 }
 
 pub fn run_compiler_in_existing_thread_pool<F, R>(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 f9efd00f698..2044b73db8a 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<lint::LintStore>)> {
@@ -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 bb1221ead98..84648ca8326 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 2a468d679a8..be6404b8697 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 0be6340df96..03e37967c4b 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 e290f7fa6b1..9582137eae9 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| {