Skip to content

Commit

Permalink
Update API to be more compatible with plugin needs
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Mark-Simulacrum committed Oct 17, 2019
1 parent b761367 commit 6be0a70
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 13 deletions.
30 changes: 17 additions & 13 deletions src/librustc/lint/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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>,
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -259,6 +261,7 @@ pub fn run_compiler(
stderr: None,
crate_name: None,
lint_caps: Default::default(),
register_lints: None,
};

callbacks.config(&mut config);
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_interface/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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(|| {
Expand Down
3 changes: 3 additions & 0 deletions src/librustc_interface/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>)> {
Expand Down Expand Up @@ -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", || {
Expand Down
7 changes: 7 additions & 0 deletions src/librustc_interface/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
);
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
1 change: 1 addition & 0 deletions src/test/run-make-fulldeps/issue-19371/foo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand Down

0 comments on commit 6be0a70

Please sign in to comment.