Skip to content

Commit

Permalink
Auto merge of #50844 - bjorn3:adhoc_compiller_calls, r=nrc
Browse files Browse the repository at this point in the history
Add AdHocCalls and pass self to build_controller as Box<Self>

This makes it easier to write custom drivers.
  • Loading branch information
bors committed Jun 6, 2018
2 parents 4a9c58c + cc5c1a0 commit 685faa2
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 34 deletions.
69 changes: 69 additions & 0 deletions src/librustc_driver/driver.rs
Expand Up @@ -414,6 +414,75 @@ impl<'a> CompileController<'a> {
}
}

/// This implementation makes it easier to create a custom driver when you only want to hook
/// into callbacks from `CompileController`.
///
/// # Example
///
/// ```no_run
/// # extern crate rustc_driver;
/// # use rustc_driver::driver::CompileController;
/// let mut controller = CompileController::basic();
/// controller.after_analysis.callback = Box::new(move |_state| {});
/// rustc_driver::run_compiler(&[], Box::new(controller), None, None);
/// ```
impl<'a> ::CompilerCalls<'a> for CompileController<'a> {
fn early_callback(
&mut self,
matches: &::getopts::Matches,
sopts: &config::Options,
cfg: &ast::CrateConfig,
descriptions: &::errors::registry::Registry,
output: ::ErrorOutputType,
) -> Compilation {
::RustcDefaultCalls.early_callback(
matches,
sopts,
cfg,
descriptions,
output,
)
}
fn no_input(
&mut self,
matches: &::getopts::Matches,
sopts: &config::Options,
cfg: &ast::CrateConfig,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>,
descriptions: &::errors::registry::Registry,
) -> Option<(Input, Option<PathBuf>)> {
::RustcDefaultCalls.no_input(
matches,
sopts,
cfg,
odir,
ofile,
descriptions,
)
}
fn late_callback(
&mut self,
codegen_backend: &::CodegenBackend,
matches: &::getopts::Matches,
sess: &Session,
cstore: &::CrateStore,
input: &Input,
odir: &Option<PathBuf>,
ofile: &Option<PathBuf>,
) -> Compilation {
::RustcDefaultCalls
.late_callback(codegen_backend, matches, sess, cstore, input, odir, ofile)
}
fn build_controller(
self: Box<Self>,
_: &Session,
_: &::getopts::Matches
) -> CompileController<'a> {
*self
}
}

pub struct PhaseController<'a> {
pub stop: Compilation,
// If true then the compiler will try to run the callback even if the phase
Expand Down
48 changes: 26 additions & 22 deletions src/librustc_driver/lib.rs
Expand Up @@ -454,7 +454,7 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<CodegenBackend> {
// See comments on CompilerCalls below for details about the callbacks argument.
// The FileLoader provides a way to load files from sources other than the file system.
pub fn run_compiler<'a>(args: &[String],
callbacks: &mut (CompilerCalls<'a> + sync::Send),
callbacks: Box<CompilerCalls<'a> + sync::Send + 'a>,
file_loader: Option<Box<FileLoader + Send + Sync + 'static>>,
emitter_dest: Option<Box<Write + Send>>)
-> (CompileResult, Option<Session>)
Expand All @@ -478,7 +478,7 @@ fn run_compiler_with_pool<'a>(
matches: getopts::Matches,
sopts: config::Options,
cfg: ast::CrateConfig,
callbacks: &mut (CompilerCalls<'a> + sync::Send),
mut callbacks: Box<CompilerCalls<'a> + sync::Send + 'a>,
file_loader: Option<Box<FileLoader + Send + Sync + 'static>>,
emitter_dest: Option<Box<Write + Send>>
) -> (CompileResult, Option<Session>) {
Expand Down Expand Up @@ -642,12 +642,12 @@ impl Compilation {
}
}

// A trait for customising the compilation process. Offers a number of hooks for
// executing custom code or customising input.
/// A trait for customising the compilation process. Offers a number of hooks for
/// executing custom code or customising input.
pub trait CompilerCalls<'a> {
// Hook for a callback early in the process of handling arguments. This will
// be called straight after options have been parsed but before anything
// else (e.g., selecting input and output).
/// Hook for a callback early in the process of handling arguments. This will
/// be called straight after options have been parsed but before anything
/// else (e.g., selecting input and output).
fn early_callback(&mut self,
_: &getopts::Matches,
_: &config::Options,
Expand All @@ -658,9 +658,9 @@ pub trait CompilerCalls<'a> {
Compilation::Continue
}

// Hook for a callback late in the process of handling arguments. This will
// be called just before actual compilation starts (and before build_controller
// is called), after all arguments etc. have been completely handled.
/// Hook for a callback late in the process of handling arguments. This will
/// be called just before actual compilation starts (and before build_controller
/// is called), after all arguments etc. have been completely handled.
fn late_callback(&mut self,
_: &CodegenBackend,
_: &getopts::Matches,
Expand All @@ -673,21 +673,21 @@ pub trait CompilerCalls<'a> {
Compilation::Continue
}

// Called after we extract the input from the arguments. Gives the implementer
// an opportunity to change the inputs or to add some custom input handling.
// The default behaviour is to simply pass through the inputs.
/// Called after we extract the input from the arguments. Gives the implementer
/// an opportunity to change the inputs or to add some custom input handling.
/// The default behaviour is to simply pass through the inputs.
fn some_input(&mut self,
input: Input,
input_path: Option<PathBuf>)
-> (Input, Option<PathBuf>) {
(input, input_path)
}

// Called after we extract the input from the arguments if there is no valid
// input. Gives the implementer an opportunity to supply alternate input (by
// returning a Some value) or to add custom behaviour for this error such as
// emitting error messages. Returning None will cause compilation to stop
// at this point.
/// Called after we extract the input from the arguments if there is no valid
/// input. Gives the implementer an opportunity to supply alternate input (by
/// returning a Some value) or to add custom behaviour for this error such as
/// emitting error messages. Returning None will cause compilation to stop
/// at this point.
fn no_input(&mut self,
_: &getopts::Matches,
_: &config::Options,
Expand All @@ -701,10 +701,14 @@ pub trait CompilerCalls<'a> {

// Create a CompilController struct for controlling the behaviour of
// compilation.
fn build_controller(&mut self, _: &Session, _: &getopts::Matches) -> CompileController<'a>;
fn build_controller(
self: Box<Self>,
_: &Session,
_: &getopts::Matches
) -> CompileController<'a>;
}

// CompilerCalls instance for a regular rustc build.
/// CompilerCalls instance for a regular rustc build.
#[derive(Copy, Clone)]
pub struct RustcDefaultCalls;

Expand Down Expand Up @@ -878,7 +882,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
.and_then(|| RustcDefaultCalls::list_metadata(sess, cstore, matches, input))
}

fn build_controller(&mut self,
fn build_controller(self: Box<Self>,
sess: &Session,
matches: &getopts::Matches)
-> CompileController<'a> {
Expand Down Expand Up @@ -1693,7 +1697,7 @@ pub fn main() {
}))
.collect::<Vec<_>>();
run_compiler(&args,
&mut RustcDefaultCalls,
Box::new(RustcDefaultCalls),
None,
None)
});
Expand Down
27 changes: 15 additions & 12 deletions src/test/run-pass-fulldeps/compiler-calls.rs
Expand Up @@ -31,19 +31,19 @@ use syntax::ast;

use std::path::PathBuf;

struct TestCalls {
count: u32
struct TestCalls<'a> {
count: &'a mut u32
}

impl<'a> CompilerCalls<'a> for TestCalls {
impl<'a> CompilerCalls<'a> for TestCalls<'a> {
fn early_callback(&mut self,
_: &getopts::Matches,
_: &config::Options,
_: &ast::CrateConfig,
_: &errors::registry::Registry,
_: config::ErrorOutputType)
-> Compilation {
self.count *= 2;
*self.count *= 2;
Compilation::Continue
}

Expand All @@ -56,13 +56,13 @@ impl<'a> CompilerCalls<'a> for TestCalls {
_: &Option<PathBuf>,
_: &Option<PathBuf>)
-> Compilation {
self.count *= 3;
*self.count *= 3;
Compilation::Stop
}

fn some_input(&mut self, input: Input, input_path: Option<PathBuf>)
-> (Input, Option<PathBuf>) {
self.count *= 5;
*self.count *= 5;
(input, input_path)
}

Expand All @@ -77,7 +77,7 @@ impl<'a> CompilerCalls<'a> for TestCalls {
panic!("This shouldn't happen");
}

fn build_controller(&mut self,
fn build_controller(self: Box<Self>,
_: &Session,
_: &getopts::Matches)
-> driver::CompileController<'a> {
Expand All @@ -87,9 +87,12 @@ impl<'a> CompilerCalls<'a> for TestCalls {


fn main() {
let mut tc = TestCalls { count: 1 };
// we should never get use this filename, but lets make sure they are valid args.
let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
rustc_driver::run_compiler(&args, &mut tc, None, None);
assert_eq!(tc.count, 30);
let mut count = 1;
{
let tc = TestCalls { count: &mut count };
// we should never get use this filename, but lets make sure they are valid args.
let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
rustc_driver::run_compiler(&args, Box::new(tc), None, None);
}
assert_eq!(count, 30);
}

0 comments on commit 685faa2

Please sign in to comment.