Skip to content

Commit 685faa2

Browse files
committed
Auto merge of #50844 - bjorn3:adhoc_compiller_calls, r=nrc
Add AdHocCalls and pass self to build_controller as Box<Self> This makes it easier to write custom drivers.
2 parents 4a9c58c + cc5c1a0 commit 685faa2

File tree

3 files changed

+110
-34
lines changed

3 files changed

+110
-34
lines changed

src/librustc_driver/driver.rs

+69
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,75 @@ impl<'a> CompileController<'a> {
414414
}
415415
}
416416

417+
/// This implementation makes it easier to create a custom driver when you only want to hook
418+
/// into callbacks from `CompileController`.
419+
///
420+
/// # Example
421+
///
422+
/// ```no_run
423+
/// # extern crate rustc_driver;
424+
/// # use rustc_driver::driver::CompileController;
425+
/// let mut controller = CompileController::basic();
426+
/// controller.after_analysis.callback = Box::new(move |_state| {});
427+
/// rustc_driver::run_compiler(&[], Box::new(controller), None, None);
428+
/// ```
429+
impl<'a> ::CompilerCalls<'a> for CompileController<'a> {
430+
fn early_callback(
431+
&mut self,
432+
matches: &::getopts::Matches,
433+
sopts: &config::Options,
434+
cfg: &ast::CrateConfig,
435+
descriptions: &::errors::registry::Registry,
436+
output: ::ErrorOutputType,
437+
) -> Compilation {
438+
::RustcDefaultCalls.early_callback(
439+
matches,
440+
sopts,
441+
cfg,
442+
descriptions,
443+
output,
444+
)
445+
}
446+
fn no_input(
447+
&mut self,
448+
matches: &::getopts::Matches,
449+
sopts: &config::Options,
450+
cfg: &ast::CrateConfig,
451+
odir: &Option<PathBuf>,
452+
ofile: &Option<PathBuf>,
453+
descriptions: &::errors::registry::Registry,
454+
) -> Option<(Input, Option<PathBuf>)> {
455+
::RustcDefaultCalls.no_input(
456+
matches,
457+
sopts,
458+
cfg,
459+
odir,
460+
ofile,
461+
descriptions,
462+
)
463+
}
464+
fn late_callback(
465+
&mut self,
466+
codegen_backend: &::CodegenBackend,
467+
matches: &::getopts::Matches,
468+
sess: &Session,
469+
cstore: &::CrateStore,
470+
input: &Input,
471+
odir: &Option<PathBuf>,
472+
ofile: &Option<PathBuf>,
473+
) -> Compilation {
474+
::RustcDefaultCalls
475+
.late_callback(codegen_backend, matches, sess, cstore, input, odir, ofile)
476+
}
477+
fn build_controller(
478+
self: Box<Self>,
479+
_: &Session,
480+
_: &::getopts::Matches
481+
) -> CompileController<'a> {
482+
*self
483+
}
484+
}
485+
417486
pub struct PhaseController<'a> {
418487
pub stop: Compilation,
419488
// If true then the compiler will try to run the callback even if the phase

src/librustc_driver/lib.rs

+26-22
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ fn get_codegen_sysroot(backend_name: &str) -> fn() -> Box<CodegenBackend> {
454454
// See comments on CompilerCalls below for details about the callbacks argument.
455455
// The FileLoader provides a way to load files from sources other than the file system.
456456
pub fn run_compiler<'a>(args: &[String],
457-
callbacks: &mut (CompilerCalls<'a> + sync::Send),
457+
callbacks: Box<CompilerCalls<'a> + sync::Send + 'a>,
458458
file_loader: Option<Box<FileLoader + Send + Sync + 'static>>,
459459
emitter_dest: Option<Box<Write + Send>>)
460460
-> (CompileResult, Option<Session>)
@@ -478,7 +478,7 @@ fn run_compiler_with_pool<'a>(
478478
matches: getopts::Matches,
479479
sopts: config::Options,
480480
cfg: ast::CrateConfig,
481-
callbacks: &mut (CompilerCalls<'a> + sync::Send),
481+
mut callbacks: Box<CompilerCalls<'a> + sync::Send + 'a>,
482482
file_loader: Option<Box<FileLoader + Send + Sync + 'static>>,
483483
emitter_dest: Option<Box<Write + Send>>
484484
) -> (CompileResult, Option<Session>) {
@@ -642,12 +642,12 @@ impl Compilation {
642642
}
643643
}
644644

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

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

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

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

702702
// Create a CompilController struct for controlling the behaviour of
703703
// compilation.
704-
fn build_controller(&mut self, _: &Session, _: &getopts::Matches) -> CompileController<'a>;
704+
fn build_controller(
705+
self: Box<Self>,
706+
_: &Session,
707+
_: &getopts::Matches
708+
) -> CompileController<'a>;
705709
}
706710

707-
// CompilerCalls instance for a regular rustc build.
711+
/// CompilerCalls instance for a regular rustc build.
708712
#[derive(Copy, Clone)]
709713
pub struct RustcDefaultCalls;
710714

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

881-
fn build_controller(&mut self,
885+
fn build_controller(self: Box<Self>,
882886
sess: &Session,
883887
matches: &getopts::Matches)
884888
-> CompileController<'a> {
@@ -1693,7 +1697,7 @@ pub fn main() {
16931697
}))
16941698
.collect::<Vec<_>>();
16951699
run_compiler(&args,
1696-
&mut RustcDefaultCalls,
1700+
Box::new(RustcDefaultCalls),
16971701
None,
16981702
None)
16991703
});

src/test/run-pass-fulldeps/compiler-calls.rs

+15-12
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,19 @@ use syntax::ast;
3131

3232
use std::path::PathBuf;
3333

34-
struct TestCalls {
35-
count: u32
34+
struct TestCalls<'a> {
35+
count: &'a mut u32
3636
}
3737

38-
impl<'a> CompilerCalls<'a> for TestCalls {
38+
impl<'a> CompilerCalls<'a> for TestCalls<'a> {
3939
fn early_callback(&mut self,
4040
_: &getopts::Matches,
4141
_: &config::Options,
4242
_: &ast::CrateConfig,
4343
_: &errors::registry::Registry,
4444
_: config::ErrorOutputType)
4545
-> Compilation {
46-
self.count *= 2;
46+
*self.count *= 2;
4747
Compilation::Continue
4848
}
4949

@@ -56,13 +56,13 @@ impl<'a> CompilerCalls<'a> for TestCalls {
5656
_: &Option<PathBuf>,
5757
_: &Option<PathBuf>)
5858
-> Compilation {
59-
self.count *= 3;
59+
*self.count *= 3;
6060
Compilation::Stop
6161
}
6262

6363
fn some_input(&mut self, input: Input, input_path: Option<PathBuf>)
6464
-> (Input, Option<PathBuf>) {
65-
self.count *= 5;
65+
*self.count *= 5;
6666
(input, input_path)
6767
}
6868

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

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

8888

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

0 commit comments

Comments
 (0)