From 4ec97fb04422b0792a352f06e4ce7ae3bbeffeea Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 19 Jul 2014 01:29:57 -0700 Subject: [PATCH 1/5] rustc: Make `monitor` public. It's harder to run rustc correctly without it. --- src/librustc/driver/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/driver/mod.rs b/src/librustc/driver/mod.rs index e433c3df8644c..ee490ad43ebad 100644 --- a/src/librustc/driver/mod.rs +++ b/src/librustc/driver/mod.rs @@ -418,7 +418,7 @@ pub fn list_metadata(sess: &Session, path: &Path, /// /// The diagnostic emitter yielded to the procedure should be used for reporting /// errors of the compiler. -fn monitor(f: proc():Send) { +pub fn monitor(f: proc():Send) { // FIXME: This is a hack for newsched since it doesn't support split stacks. // rustc needs a lot of stack! When optimizations are disabled, it needs // even *more* stack than usual as well. From a23262651a6a09698ba08aa937c425499843be19 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 19 Jul 2014 21:11:26 -0700 Subject: [PATCH 2/5] rustc: Extract --crate-type parsing to its own function Helpful for users of rustc as a library. --- src/librustc/driver/config.rs | 43 +++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index ee611293475f9..4752997a3fcea 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -593,24 +593,10 @@ fn parse_cfgspecs(cfgspecs: Vec ) -> ast::CrateConfig { } pub fn build_session_options(matches: &getopts::Matches) -> Options { - let mut crate_types: Vec = Vec::new(); + let unparsed_crate_types = matches.opt_strs("crate-type"); - for unparsed_crate_type in unparsed_crate_types.iter() { - for part in unparsed_crate_type.as_slice().split(',') { - let new_part = match part { - "lib" => default_lib_output(), - "rlib" => CrateTypeRlib, - "staticlib" => CrateTypeStaticlib, - "dylib" => CrateTypeDylib, - "bin" => CrateTypeExecutable, - _ => { - early_error(format!("unknown crate type: `{}`", - part).as_slice()) - } - }; - crate_types.push(new_part) - } - } + let crate_types = parse_crate_types_from_list(unparsed_crate_types) + .unwrap_or_else(|e| early_error(e.as_slice())); let parse_only = matches.opt_present("parse-only"); let no_trans = matches.opt_present("no-trans"); @@ -804,6 +790,29 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } } +pub fn parse_crate_types_from_list(crate_types_list_list: Vec) -> Result, String> { + + let mut crate_types: Vec = Vec::new(); + for unparsed_crate_type in crate_types_list_list.iter() { + for part in unparsed_crate_type.as_slice().split(',') { + let new_part = match part { + "lib" => default_lib_output(), + "rlib" => CrateTypeRlib, + "staticlib" => CrateTypeStaticlib, + "dylib" => CrateTypeDylib, + "bin" => CrateTypeExecutable, + _ => { + return Err(format!("unknown crate type: `{}`", + part)); + } + }; + crate_types.push(new_part) + } + } + + return Ok(crate_types); +} + impl fmt::Show for CrateType { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { From df102ef3574b6804e8a0ab82a10bd580a88c3f48 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 19 Jul 2014 21:54:37 -0700 Subject: [PATCH 3/5] rustc: Pass optional additional plugins to compile_input This provides a way for clients of the rustc library to add their own features to the pipeline. --- src/librustc/driver/driver.rs | 14 +++++++++----- src/librustc/driver/mod.rs | 2 +- src/librustc/middle/typeck/infer/test.rs | 2 +- src/librustc/plugin/load.rs | 18 ++++++++++++++++-- src/librustdoc/core.rs | 2 +- src/librustdoc/test.rs | 4 ++-- 6 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 81ace4d015c85..311d9fb93a121 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -69,7 +69,8 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &Input, outdir: &Option, - output: &Option) { + output: &Option, + addl_plugins: Option) { // We need nested scopes here, because the intermediate results can keep // large chunks of memory alive and we want to free them as soon as // possible to keep the peak memory usage low @@ -85,7 +86,8 @@ pub fn compile_input(sess: Session, let id = link::find_crate_name(Some(&sess), krate.attrs.as_slice(), input); let (expanded_crate, ast_map) - = match phase_2_configure_and_expand(&sess, krate, id.as_slice()) { + = match phase_2_configure_and_expand(&sess, krate, id.as_slice(), + addl_plugins) { None => return, Some(p) => p, }; @@ -186,7 +188,8 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input) /// Returns `None` if we're aborting after handling -W help. pub fn phase_2_configure_and_expand(sess: &Session, mut krate: ast::Crate, - crate_name: &str) + crate_name: &str, + addl_plugins: Option) -> Option<(ast::Crate, syntax::ast_map::Map)> { let time_passes = sess.time_passes(); @@ -212,9 +215,10 @@ pub fn phase_2_configure_and_expand(sess: &Session, krate = time(time_passes, "configuration 1", krate, |krate| front::config::strip_unconfigured_items(krate)); + let mut addl_plugins = Some(addl_plugins); let Plugins { macros, registrars } = time(time_passes, "plugin loading", (), |_| - plugin::load::load_plugins(sess, &krate)); + plugin::load::load_plugins(sess, &krate, addl_plugins.take_unwrap())); let mut registry = Registry::new(&krate); @@ -697,7 +701,7 @@ pub fn pretty_print_input(sess: Session, PpmExpanded | PpmExpandedIdentified | PpmTyped | PpmFlowGraph(_) => { let (krate, ast_map) = match phase_2_configure_and_expand(&sess, krate, - id.as_slice()) { + id.as_slice(), None) { None => return, Some(p) => p, }; diff --git a/src/librustc/driver/mod.rs b/src/librustc/driver/mod.rs index ee490ad43ebad..a5df63a9e23fa 100644 --- a/src/librustc/driver/mod.rs +++ b/src/librustc/driver/mod.rs @@ -124,7 +124,7 @@ fn run_compiler(args: &[String]) { return; } - driver::compile_input(sess, cfg, &input, &odir, &ofile); + driver::compile_input(sess, cfg, &input, &odir, &ofile, None); } /// Prints version information and returns None on success or an error diff --git a/src/librustc/middle/typeck/infer/test.rs b/src/librustc/middle/typeck/infer/test.rs index c8f6836b20596..637af96b6321a 100644 --- a/src/librustc/middle/typeck/infer/test.rs +++ b/src/librustc/middle/typeck/infer/test.rs @@ -117,7 +117,7 @@ fn test_env(_test_name: &str, let input = driver::StrInput(source_string.to_string()); let krate = driver::phase_1_parse_input(&sess, krate_config, &input); let (krate, ast_map) = - driver::phase_2_configure_and_expand(&sess, krate, "test") + driver::phase_2_configure_and_expand(&sess, krate, "test", None) .expect("phase 2 aborted"); // run just enough stuff to build a tcx: diff --git a/src/librustc/plugin/load.rs b/src/librustc/plugin/load.rs index 499cffa42aac9..4f38c74893e46 100644 --- a/src/librustc/plugin/load.rs +++ b/src/librustc/plugin/load.rs @@ -66,10 +66,24 @@ impl<'a> PluginLoader<'a> { } /// Read plugin metadata and dynamically load registrar functions. -pub fn load_plugins(sess: &Session, krate: &ast::Crate) -> Plugins { +pub fn load_plugins(sess: &Session, krate: &ast::Crate, + addl_plugins: Option) -> Plugins { let mut loader = PluginLoader::new(sess); visit::walk_crate(&mut loader, krate, ()); - loader.plugins + + let mut plugins = loader.plugins; + + match addl_plugins { + Some(addl_plugins) => { + // Add in the additional plugins requested by the frontend + let Plugins { macros: addl_macros, registrars: addl_registrars } = addl_plugins; + plugins.macros.push_all_move(addl_macros); + plugins.registrars.push_all_move(addl_registrars); + } + None => () + } + + return plugins; } // note that macros aren't expanded yet, and therefore macros can't add plugins. diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index e62c8b63a2940..b1c715ae5b36a 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -121,7 +121,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet, cfgs: Vec) &input); let (krate, ast_map) - = phase_2_configure_and_expand(&sess, krate, name.as_slice()) + = phase_2_configure_and_expand(&sess, krate, name.as_slice(), None) .expect("phase_2_configure_and_expand aborted in rustdoc!"); let driver::driver::CrateAnalysis { diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 055019aa481ff..8fe28d1eab824 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -69,7 +69,7 @@ pub fn run(input: &str, })); let krate = driver::phase_1_parse_input(&sess, cfg, &input); let (krate, _) = driver::phase_2_configure_and_expand(&sess, krate, - "rustdoc-test") + "rustdoc-test", None) .expect("phase_2_configure_and_expand aborted in rustdoc!"); let ctx = box(GC) core::DocContext { @@ -166,7 +166,7 @@ fn runtest(test: &str, cratename: &str, libs: HashSet, should_fail: bool, let out = Some(outdir.path().clone()); let cfg = config::build_configuration(&sess); let libdir = sess.target_filesearch().get_lib_path(); - driver::compile_input(sess, cfg, &input, &out, &None); + driver::compile_input(sess, cfg, &input, &out, &None, None); if no_run { return } From 7d87b53b769d7df528d93f40deabcb0a8f1fce43 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 19 Jul 2014 22:40:39 -0700 Subject: [PATCH 4/5] rustc: Allow the crate linked to as 'std' to be customized This adds the alt_std_name field to the Session's Options type. I'm using this in an external tool to control which libraries a crate links to. --- src/librustc/driver/config.rs | 3 +++ src/librustc/front/std_inject.rs | 9 ++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index 4752997a3fcea..890093a10ecc7 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -97,6 +97,7 @@ pub struct Options { pub color: ColorConfig, pub externs: HashMap>, pub crate_name: Option, + pub alt_std_name: Option } /// Some reasonable defaults @@ -124,6 +125,7 @@ pub fn basic_options() -> Options { color: Auto, externs: HashMap::new(), crate_name: None, + alt_std_name: None, } } @@ -787,6 +789,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { color: color, externs: externs, crate_name: crate_name, + alt_std_name: None } } diff --git a/src/librustc/front/std_inject.rs b/src/librustc/front/std_inject.rs index 351c9a6b77167..940112325fdf4 100644 --- a/src/librustc/front/std_inject.rs +++ b/src/librustc/front/std_inject.rs @@ -60,9 +60,16 @@ struct StandardLibraryInjector<'a> { impl<'a> fold::Folder for StandardLibraryInjector<'a> { fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate { + + // The name to use in `extern crate std = "name";` + let actual_crate_name = match self.sess.opts.alt_std_name { + Some(ref s) => token::intern_and_get_ident(s.as_slice()), + None => token::intern_and_get_ident("std"), + }; + let mut vis = vec!(ast::ViewItem { node: ast::ViewItemExternCrate(token::str_to_ident("std"), - None, + Some((actual_crate_name, ast::CookedStr)), ast::DUMMY_NODE_ID), attrs: vec!( attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_list_item( From d9c60f485323483a80fb2b358429fd2d187e63df Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 20 Jul 2014 16:32:46 -0700 Subject: [PATCH 5/5] Address review feedback --- src/librustc/driver/config.rs | 7 +++++-- src/librustc/driver/driver.rs | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index 890093a10ecc7..2d200c82a94a2 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -97,6 +97,9 @@ pub struct Options { pub color: ColorConfig, pub externs: HashMap>, pub crate_name: Option, + /// An optional name to use as the crate for std during std injection, + /// written `extern crate std = "name"`. Default to "std". Used by + /// out-of-tree drivers. pub alt_std_name: Option } @@ -793,10 +796,10 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { } } -pub fn parse_crate_types_from_list(crate_types_list_list: Vec) -> Result, String> { +pub fn parse_crate_types_from_list(list_list: Vec) -> Result, String> { let mut crate_types: Vec = Vec::new(); - for unparsed_crate_type in crate_types_list_list.iter() { + for unparsed_crate_type in list_list.iter() { for part in unparsed_crate_type.as_slice().split(',') { let new_part = match part { "lib" => default_lib_output(), diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index 311d9fb93a121..9796aab51fb6b 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -181,6 +181,7 @@ pub fn phase_1_parse_input(sess: &Session, cfg: ast::CrateConfig, input: &Input) // modified /// Run the "early phases" of the compiler: initial `cfg` processing, +/// loading compiler plugins (including those from `addl_plugins`), /// syntax expansion, secondary `cfg` expansion, synthesis of a test /// harness if one is to be provided and injection of a dependency on the /// standard library and prelude.