Skip to content

Add AdHocCalls and pass self to build_controller as Box<Self> #50844

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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);
}