Skip to content

Commit 6be0a70

Browse files
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.
1 parent b761367 commit 6be0a70

File tree

8 files changed

+37
-13
lines changed

8 files changed

+37
-13
lines changed

src/librustc/lint/context.rs

+17-13
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use crate::util::common::time;
3535
use errors::DiagnosticBuilder;
3636
use std::slice;
3737
use std::default::Default as StdDefault;
38-
use rustc_data_structures::sync::{ParallelIterator, join, par_iter};
38+
use rustc_data_structures::sync::{self, ParallelIterator, join, par_iter};
3939
use rustc_serialize::{Decoder, Decodable, Encoder, Encodable};
4040
use syntax::ast;
4141
use syntax::util::lev_distance::find_best_match_for_name;
@@ -57,11 +57,11 @@ pub struct LintStore {
5757
/// interior mutability, we don't enforce this (and lints should, in theory,
5858
/// be compatible with being constructed more than once, though not
5959
/// necessarily in a sane manner. This is safe though.)
60-
pre_expansion_passes: Vec<fn() -> EarlyLintPassObject>,
61-
early_passes: Vec<fn() -> EarlyLintPassObject>,
62-
late_passes: Vec<fn() -> LateLintPassObject>,
60+
pre_expansion_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
61+
early_passes: Vec<Box<dyn Fn() -> EarlyLintPassObject + sync::Send + sync::Sync>>,
62+
late_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
6363
/// This is unique in that we construct them per-module, so not once.
64-
late_module_passes: Vec<fn() -> LateLintPassObject>,
64+
late_module_passes: Vec<Box<dyn Fn() -> LateLintPassObject + sync::Send + sync::Sync>>,
6565

6666
/// Lints indexed by name.
6767
by_name: FxHashMap<String, TargetLint>,
@@ -155,20 +155,24 @@ impl LintStore {
155155
.collect()
156156
}
157157

158-
pub fn register_early_pass(&mut self, pass: fn() -> EarlyLintPassObject) {
159-
self.early_passes.push(pass);
158+
pub fn register_early_pass(&mut self,
159+
pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) {
160+
self.early_passes.push(Box::new(pass));
160161
}
161162

162-
pub fn register_pre_expansion_pass(&mut self, pass: fn() -> EarlyLintPassObject) {
163-
self.pre_expansion_passes.push(pass);
163+
pub fn register_pre_expansion_pass(&mut self,
164+
pass: impl Fn() -> EarlyLintPassObject + 'static + sync::Send + sync::Sync) {
165+
self.pre_expansion_passes.push(Box::new(pass));
164166
}
165167

166-
pub fn register_late_pass(&mut self, pass: fn() -> LateLintPassObject) {
167-
self.late_passes.push(pass);
168+
pub fn register_late_pass(&mut self,
169+
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) {
170+
self.late_passes.push(Box::new(pass));
168171
}
169172

170-
pub fn register_late_mod_pass(&mut self, pass: fn() -> LateLintPassObject) {
171-
self.late_module_passes.push(pass);
173+
pub fn register_late_mod_pass(&mut self,
174+
pass: impl Fn() -> LateLintPassObject + 'static + sync::Send + sync::Sync) {
175+
self.late_module_passes.push(Box::new(pass));
172176
}
173177

174178
// Helper method for register_early/late_pass

src/librustc_driver/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ pub fn abort_on_err<T>(result: Result<T, ErrorReported>, sess: &Session) -> T {
106106
pub trait Callbacks {
107107
/// Called before creating the compiler instance
108108
fn config(&mut self, _config: &mut interface::Config) {}
109+
fn extra_lints(&mut self, _ls: &mut lint::LintStore) {}
109110
/// Called after parsing. Return value instructs the compiler whether to
110111
/// continue the compilation afterwards (defaults to `Compilation::Continue`)
111112
fn after_parsing(&mut self, _compiler: &interface::Compiler) -> Compilation {
@@ -182,6 +183,7 @@ pub fn run_compiler(
182183
stderr: None,
183184
crate_name: None,
184185
lint_caps: Default::default(),
186+
register_lints: None,
185187
};
186188
callbacks.config(&mut config);
187189
config
@@ -259,6 +261,7 @@ pub fn run_compiler(
259261
stderr: None,
260262
crate_name: None,
261263
lint_caps: Default::default(),
264+
register_lints: None,
262265
};
263266

264267
callbacks.config(&mut config);

src/librustc_interface/interface.rs

+4
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub struct Compiler {
3434
pub(crate) queries: Queries,
3535
pub(crate) cstore: Lrc<CStore>,
3636
pub(crate) crate_name: Option<String>,
37+
pub(crate) register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
3738
}
3839

3940
impl Compiler {
@@ -80,6 +81,8 @@ pub struct Config {
8081

8182
pub crate_name: Option<String>,
8283
pub lint_caps: FxHashMap<lint::LintId, lint::Level>,
84+
85+
pub register_lints: Option<Box<dyn Fn(&Session, &mut lint::LintStore) + Send + Sync>>,
8386
}
8487

8588
pub fn run_compiler_in_existing_thread_pool<F, R>(config: Config, f: F) -> R
@@ -108,6 +111,7 @@ where
108111
output_file: config.output_file,
109112
queries: Default::default(),
110113
crate_name: config.crate_name,
114+
register_lints: config.register_lints,
111115
};
112116

113117
let _sess_abort_error = OnDrop(|| {

src/librustc_interface/passes.rs

+3
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ pub struct PluginInfo {
227227
pub fn register_plugins<'a>(
228228
sess: &'a Session,
229229
cstore: &'a CStore,
230+
register_lints: impl Fn(&Session, &mut lint::LintStore),
230231
mut krate: ast::Crate,
231232
crate_name: &str,
232233
) -> Result<(ast::Crate, PluginInfo, Lrc<lint::LintStore>)> {
@@ -285,6 +286,8 @@ pub fn register_plugins<'a>(
285286
sess.unstable_options(),
286287
);
287288

289+
(register_lints)(&sess, &mut lint_store);
290+
288291
let mut registry = Registry::new(sess, &mut lint_store, krate.span);
289292

290293
time(sess, "plugin registration", || {

src/librustc_interface/queries.rs

+7
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use rustc_data_structures::sync::Lrc;
66
use rustc::session::config::{OutputFilenames, OutputType};
77
use rustc::util::common::{time, ErrorReported};
88
use rustc::hir;
9+
use rustc::lint;
10+
use rustc::session::Session;
911
use rustc::lint::LintStore;
1012
use rustc::hir::def_id::LOCAL_CRATE;
1113
use rustc::ty::steal::Steal;
@@ -113,9 +115,14 @@ impl Compiler {
113115
let crate_name = self.crate_name()?.peek().clone();
114116
let krate = self.parse()?.take();
115117

118+
let empty: &(dyn Fn(&Session, &mut lint::LintStore) + Sync + Send) = &|_, _| {};
116119
let result = passes::register_plugins(
117120
self.session(),
118121
self.cstore(),
122+
self.register_lints
123+
.as_ref()
124+
.map(|p| &**p)
125+
.unwrap_or_else(|| empty),
119126
krate,
120127
&crate_name,
121128
);

src/librustdoc/core.rs

+1
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ pub fn run_core(options: RustdocOptions) -> (clean::Crate, RenderInfo, RenderOpt
338338
stderr: None,
339339
crate_name,
340340
lint_caps,
341+
register_lints: None,
341342
};
342343

343344
interface::run_compiler_in_existing_thread_pool(config, |compiler| {

src/librustdoc/test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ pub fn run(options: Options) -> i32 {
7777
stderr: None,
7878
crate_name: options.crate_name.clone(),
7979
lint_caps: Default::default(),
80+
register_lints: None,
8081
};
8182

8283
let mut test_args = options.test_args.clone();

src/test/run-make-fulldeps/issue-19371/foo.rs

+1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
5959
stderr: None,
6060
crate_name: None,
6161
lint_caps: Default::default(),
62+
register_lints: None,
6263
};
6364

6465
interface::run_compiler(config, |compiler| {

0 commit comments

Comments
 (0)