mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Auto merge of #35340 - michaelwoerister:incr-comp-cli-args, r=nikomatsakis
Take commandline arguments into account for incr. comp. Implements the conservative strategy described in https://github.com/rust-lang/rust/issues/33727. From now one, every time a new commandline option is added, one has to specify if it influences the incremental compilation cache. I've tried to implement this as automatic as possible: One just has to added either the `[TRACKED]` or the `[UNTRACKED]` marker next to the field. The `Options`, `CodegenOptions`, and `DebuggingOptions` definitions in `session::config` show plenty of examples. The PR removes some cruft from `session::config::Options`, mostly unnecessary copies of flags also present in `DebuggingOptions` or `CodeGenOptions` in the same struct. One notable removal is the `cfg` field that contained the values passed via `--cfg` commandline arguments. I chose to remove it because (1) its content is only a subset of what later is stored in `hir::Crate::config` and it's pretty likely that reading the cfgs from `Options` would not be what you wanted, and (2) we could not incorporate it into the dep-tracking hash of the `Options` struct because of how the test framework works, leaving us with a piece of untracked but vital data. It is now recommended (just as before) to access the crate config via the `krate()` method in the HIR map. Because the `cfg` field is not present in the `Options` struct any more, some methods in the `CompilerCalls` trait now take the crate config as an explicit parameter -- which might constitute a breaking change for plugin authors.
This commit is contained in:
commit
f65d96fe3f
@ -269,7 +269,7 @@ impl LintId {
|
||||
}
|
||||
|
||||
/// Setting for how to handle a lint.
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug)]
|
||||
#[derive(Clone, Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
|
||||
pub enum Level {
|
||||
Allow, Warn, Deny, Forbid
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ pub enum LinkagePreference {
|
||||
}
|
||||
|
||||
enum_from_u32! {
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub enum NativeLibraryKind {
|
||||
NativeStatic, // native static library (.a archive)
|
||||
NativeFramework, // OSX-specific
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -363,7 +363,7 @@ pub fn build_session_with_codemap(sopts: config::Options,
|
||||
.map(|&(_, ref level)| *level != lint::Allow)
|
||||
.last()
|
||||
.unwrap_or(true);
|
||||
let treat_err_as_bug = sopts.treat_err_as_bug;
|
||||
let treat_err_as_bug = sopts.debugging_opts.treat_err_as_bug;
|
||||
|
||||
let emitter: Box<Emitter> = match sopts.error_format {
|
||||
config::ErrorOutputType::HumanReadable(color_config) => {
|
||||
|
@ -22,7 +22,7 @@ pub struct Iter<'a> {
|
||||
iter: slice::Iter<'a, (PathKind, PathBuf)>,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Debug)]
|
||||
#[derive(Eq, PartialEq, Clone, Copy, Debug, PartialOrd, Ord, Hash)]
|
||||
pub enum PathKind {
|
||||
Native,
|
||||
Crate,
|
||||
|
@ -15,7 +15,8 @@ use rustc::hir::lowering::lower_crate;
|
||||
use rustc_mir as mir;
|
||||
use rustc::mir::mir_map::MirMap;
|
||||
use rustc::session::{Session, CompileResult, compile_result_from_err_count};
|
||||
use rustc::session::config::{self, Input, OutputFilenames, OutputType};
|
||||
use rustc::session::config::{self, Input, OutputFilenames, OutputType,
|
||||
OutputTypes};
|
||||
use rustc::session::search_paths::PathKind;
|
||||
use rustc::lint;
|
||||
use rustc::middle::{self, dependency_format, stability, reachable};
|
||||
@ -42,7 +43,6 @@ use super::Compilation;
|
||||
|
||||
use serialize::json;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::ffi::{OsString, OsStr};
|
||||
use std::fs;
|
||||
@ -478,7 +478,7 @@ pub fn phase_1_parse_input<'a>(sess: &'a Session,
|
||||
cfg: ast::CrateConfig,
|
||||
input: &Input)
|
||||
-> PResult<'a, ast::Crate> {
|
||||
let continue_after_error = sess.opts.continue_parse_after_error;
|
||||
let continue_after_error = sess.opts.debugging_opts.continue_parse_after_error;
|
||||
sess.diagnostic().set_continue_after_error(continue_after_error);
|
||||
|
||||
let krate = time(sess.time_passes(), "parsing", || {
|
||||
@ -667,7 +667,10 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
|
||||
trace_mac: sess.opts.debugging_opts.trace_macros,
|
||||
should_test: sess.opts.test,
|
||||
};
|
||||
let mut loader = macro_import::MacroLoader::new(sess, &cstore, crate_name);
|
||||
let mut loader = macro_import::MacroLoader::new(sess,
|
||||
&cstore,
|
||||
crate_name,
|
||||
krate.config.clone());
|
||||
let mut ecx = syntax::ext::base::ExtCtxt::new(&sess.parse_sess,
|
||||
krate.config.clone(),
|
||||
cfg,
|
||||
@ -1024,11 +1027,10 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
|
||||
trans: &trans::CrateTranslation,
|
||||
outputs: &OutputFilenames) -> CompileResult {
|
||||
if sess.opts.cg.no_integrated_as {
|
||||
let mut map = HashMap::new();
|
||||
map.insert(OutputType::Assembly, None);
|
||||
let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]);
|
||||
time(sess.time_passes(),
|
||||
"LLVM passes",
|
||||
|| write::run_passes(sess, trans, &map, outputs));
|
||||
|| write::run_passes(sess, trans, &output_types, outputs));
|
||||
|
||||
write::run_assembler(sess, outputs);
|
||||
|
||||
|
@ -181,7 +181,7 @@ pub fn run_compiler_with_file_loader<'a, L>(args: &[String],
|
||||
None => return (Ok(()), None),
|
||||
};
|
||||
|
||||
let sopts = config::build_session_options(&matches);
|
||||
let (sopts, cfg) = config::build_session_options_and_crate_config(&matches);
|
||||
|
||||
if sopts.debugging_opts.debug_llvm {
|
||||
unsafe { llvm::LLVMRustSetDebug(1); }
|
||||
@ -191,6 +191,7 @@ pub fn run_compiler_with_file_loader<'a, L>(args: &[String],
|
||||
|
||||
do_or_return!(callbacks.early_callback(&matches,
|
||||
&sopts,
|
||||
&cfg,
|
||||
&descriptions,
|
||||
sopts.error_format),
|
||||
None);
|
||||
@ -198,7 +199,7 @@ pub fn run_compiler_with_file_loader<'a, L>(args: &[String],
|
||||
let (odir, ofile) = make_output(&matches);
|
||||
let (input, input_file_path) = match make_input(&matches.free) {
|
||||
Some((input, input_file_path)) => callbacks.some_input(input, input_file_path),
|
||||
None => match callbacks.no_input(&matches, &sopts, &odir, &ofile, &descriptions) {
|
||||
None => match callbacks.no_input(&matches, &sopts, &cfg, &odir, &ofile, &descriptions) {
|
||||
Some((input, input_file_path)) => (input, input_file_path),
|
||||
None => return (Ok(()), None),
|
||||
},
|
||||
@ -214,10 +215,11 @@ pub fn run_compiler_with_file_loader<'a, L>(args: &[String],
|
||||
cstore.clone(),
|
||||
codemap);
|
||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||
let mut cfg = config::build_configuration(&sess);
|
||||
let mut cfg = config::build_configuration(&sess, cfg);
|
||||
target_features::add_configuration(&mut cfg, &sess);
|
||||
|
||||
do_or_return!(callbacks.late_callback(&matches, &sess, &input, &odir, &ofile), Some(sess));
|
||||
do_or_return!(callbacks.late_callback(&matches, &sess, &cfg, &input, &odir, &ofile),
|
||||
Some(sess));
|
||||
|
||||
let plugins = sess.opts.debugging_opts.extra_plugins.clone();
|
||||
let control = callbacks.build_controller(&sess, &matches);
|
||||
@ -297,6 +299,7 @@ pub trait CompilerCalls<'a> {
|
||||
fn early_callback(&mut self,
|
||||
_: &getopts::Matches,
|
||||
_: &config::Options,
|
||||
_: &ast::CrateConfig,
|
||||
_: &errors::registry::Registry,
|
||||
_: ErrorOutputType)
|
||||
-> Compilation {
|
||||
@ -309,6 +312,7 @@ pub trait CompilerCalls<'a> {
|
||||
fn late_callback(&mut self,
|
||||
_: &getopts::Matches,
|
||||
_: &Session,
|
||||
_: &ast::CrateConfig,
|
||||
_: &Input,
|
||||
_: &Option<PathBuf>,
|
||||
_: &Option<PathBuf>)
|
||||
@ -334,6 +338,7 @@ pub trait CompilerCalls<'a> {
|
||||
fn no_input(&mut self,
|
||||
_: &getopts::Matches,
|
||||
_: &config::Options,
|
||||
_: &ast::CrateConfig,
|
||||
_: &Option<PathBuf>,
|
||||
_: &Option<PathBuf>,
|
||||
_: &errors::registry::Registry)
|
||||
@ -375,7 +380,7 @@ fn handle_explain(code: &str,
|
||||
}
|
||||
}
|
||||
|
||||
fn check_cfg(sopts: &config::Options,
|
||||
fn check_cfg(cfg: &ast::CrateConfig,
|
||||
output: ErrorOutputType) {
|
||||
let emitter: Box<Emitter> = match output {
|
||||
config::ErrorOutputType::HumanReadable(color_config) => {
|
||||
@ -386,7 +391,7 @@ fn check_cfg(sopts: &config::Options,
|
||||
let handler = errors::Handler::with_emitter(true, false, emitter);
|
||||
|
||||
let mut saw_invalid_predicate = false;
|
||||
for item in sopts.cfg.iter() {
|
||||
for item in cfg.iter() {
|
||||
if item.is_meta_item_list() {
|
||||
saw_invalid_predicate = true;
|
||||
handler.emit(&MultiSpan::new(),
|
||||
@ -404,7 +409,8 @@ fn check_cfg(sopts: &config::Options,
|
||||
impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
||||
fn early_callback(&mut self,
|
||||
matches: &getopts::Matches,
|
||||
sopts: &config::Options,
|
||||
_: &config::Options,
|
||||
cfg: &ast::CrateConfig,
|
||||
descriptions: &errors::registry::Registry,
|
||||
output: ErrorOutputType)
|
||||
-> Compilation {
|
||||
@ -413,13 +419,14 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
||||
return Compilation::Stop;
|
||||
}
|
||||
|
||||
check_cfg(sopts, output);
|
||||
check_cfg(cfg, output);
|
||||
Compilation::Continue
|
||||
}
|
||||
|
||||
fn no_input(&mut self,
|
||||
matches: &getopts::Matches,
|
||||
sopts: &config::Options,
|
||||
cfg: &ast::CrateConfig,
|
||||
odir: &Option<PathBuf>,
|
||||
ofile: &Option<PathBuf>,
|
||||
descriptions: &errors::registry::Registry)
|
||||
@ -440,7 +447,13 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
||||
descriptions.clone(),
|
||||
cstore.clone());
|
||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||
let should_stop = RustcDefaultCalls::print_crate_info(&sess, None, odir, ofile);
|
||||
let mut cfg = config::build_configuration(&sess, cfg.clone());
|
||||
target_features::add_configuration(&mut cfg, &sess);
|
||||
let should_stop = RustcDefaultCalls::print_crate_info(&sess,
|
||||
&cfg,
|
||||
None,
|
||||
odir,
|
||||
ofile);
|
||||
if should_stop == Compilation::Stop {
|
||||
return None;
|
||||
}
|
||||
@ -456,11 +469,12 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
||||
fn late_callback(&mut self,
|
||||
matches: &getopts::Matches,
|
||||
sess: &Session,
|
||||
cfg: &ast::CrateConfig,
|
||||
input: &Input,
|
||||
odir: &Option<PathBuf>,
|
||||
ofile: &Option<PathBuf>)
|
||||
-> Compilation {
|
||||
RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile)
|
||||
RustcDefaultCalls::print_crate_info(sess, cfg, Some(input), odir, ofile)
|
||||
.and_then(|| RustcDefaultCalls::list_metadata(sess, matches, input))
|
||||
}
|
||||
|
||||
@ -506,12 +520,14 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
|
||||
return control;
|
||||
}
|
||||
|
||||
if sess.opts.parse_only || sess.opts.debugging_opts.show_span.is_some() ||
|
||||
if sess.opts.debugging_opts.parse_only ||
|
||||
sess.opts.debugging_opts.show_span.is_some() ||
|
||||
sess.opts.debugging_opts.ast_json_noexpand {
|
||||
control.after_parse.stop = Compilation::Stop;
|
||||
}
|
||||
|
||||
if sess.opts.no_analysis || sess.opts.debugging_opts.ast_json {
|
||||
if sess.opts.debugging_opts.no_analysis ||
|
||||
sess.opts.debugging_opts.ast_json {
|
||||
control.after_hir_lowering.stop = Compilation::Stop;
|
||||
}
|
||||
|
||||
@ -577,6 +593,7 @@ impl RustcDefaultCalls {
|
||||
|
||||
|
||||
fn print_crate_info(sess: &Session,
|
||||
cfg: &ast::CrateConfig,
|
||||
input: Option<&Input>,
|
||||
odir: &Option<PathBuf>,
|
||||
ofile: &Option<PathBuf>)
|
||||
@ -629,9 +646,6 @@ impl RustcDefaultCalls {
|
||||
}
|
||||
}
|
||||
PrintRequest::Cfg => {
|
||||
let mut cfg = config::build_configuration(&sess);
|
||||
target_features::add_configuration(&mut cfg, &sess);
|
||||
|
||||
let allow_unstable_cfg = match get_unstable_features_setting() {
|
||||
UnstableFeatures::Disallow => false,
|
||||
_ => true,
|
||||
|
@ -158,6 +158,10 @@ impl<'a,'tcx> DefIdDirectoryBuilder<'a,'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
|
||||
self.tcx
|
||||
}
|
||||
|
||||
pub fn add(&mut self, def_id: DefId) -> DefPathIndex {
|
||||
debug!("DefIdDirectoryBuilder: def_id={:?}", def_id);
|
||||
let tcx = self.tcx;
|
||||
|
@ -101,8 +101,25 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
work_products_data: &[u8])
|
||||
-> Result<(), Error>
|
||||
{
|
||||
// Decode the list of work_products
|
||||
let mut work_product_decoder = Decoder::new(work_products_data, 0);
|
||||
let work_products = try!(<Vec<SerializedWorkProduct>>::decode(&mut work_product_decoder));
|
||||
|
||||
// Deserialize the directory and dep-graph.
|
||||
let mut dep_graph_decoder = Decoder::new(dep_graph_data, 0);
|
||||
let prev_commandline_args_hash = try!(u64::decode(&mut dep_graph_decoder));
|
||||
|
||||
if prev_commandline_args_hash != tcx.sess.opts.dep_tracking_hash() {
|
||||
// We can't reuse the cache, purge it.
|
||||
debug!("decode_dep_graph: differing commandline arg hashes");
|
||||
for swp in work_products {
|
||||
delete_dirty_work_product(tcx, swp);
|
||||
}
|
||||
|
||||
// No need to do any further work
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let directory = try!(DefIdDirectory::decode(&mut dep_graph_decoder));
|
||||
let serialized_dep_graph = try!(SerializedDepGraph::decode(&mut dep_graph_decoder));
|
||||
|
||||
@ -179,8 +196,6 @@ pub fn decode_dep_graph<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
// Add in work-products that are still clean, and delete those that are
|
||||
// dirty.
|
||||
let mut work_product_decoder = Decoder::new(work_products_data, 0);
|
||||
let work_products = try!(<Vec<SerializedWorkProduct>>::decode(&mut work_product_decoder));
|
||||
reconcile_work_products(tcx, work_products, &dirty_target_nodes);
|
||||
|
||||
dirty_clean::check_dirty_clean_annotations(tcx, &dirty_raw_source_nodes, &retraced);
|
||||
|
@ -105,6 +105,10 @@ pub fn encode_dep_graph(preds: &Predecessors,
|
||||
builder: &mut DefIdDirectoryBuilder,
|
||||
encoder: &mut Encoder)
|
||||
-> io::Result<()> {
|
||||
// First encode the commandline arguments hash
|
||||
let tcx = builder.tcx();
|
||||
try!(tcx.sess.opts.dep_tracking_hash().encode(encoder));
|
||||
|
||||
// Create a flat list of (Input, WorkProduct) edges for
|
||||
// serialization.
|
||||
let mut edges = vec![];
|
||||
|
@ -56,6 +56,7 @@ pub struct CrateReader<'a> {
|
||||
next_crate_num: ast::CrateNum,
|
||||
foreign_item_map: FnvHashMap<String, Vec<ast::NodeId>>,
|
||||
local_crate_name: String,
|
||||
local_crate_config: ast::CrateConfig,
|
||||
}
|
||||
|
||||
impl<'a> visit::Visitor for LocalCrateReader<'a> {
|
||||
@ -152,13 +153,16 @@ enum LoadResult {
|
||||
impl<'a> CrateReader<'a> {
|
||||
pub fn new(sess: &'a Session,
|
||||
cstore: &'a CStore,
|
||||
local_crate_name: &str) -> CrateReader<'a> {
|
||||
local_crate_name: &str,
|
||||
local_crate_config: ast::CrateConfig)
|
||||
-> CrateReader<'a> {
|
||||
CrateReader {
|
||||
sess: sess,
|
||||
cstore: cstore,
|
||||
next_crate_num: cstore.next_crate_num(),
|
||||
foreign_item_map: FnvHashMap(),
|
||||
local_crate_name: local_crate_name.to_owned(),
|
||||
local_crate_config: local_crate_config,
|
||||
}
|
||||
}
|
||||
|
||||
@ -561,7 +565,7 @@ impl<'a> CrateReader<'a> {
|
||||
// NB: Don't use parse::parse_tts_from_source_str because it parses with
|
||||
// quote_depth > 0.
|
||||
let mut p = parse::new_parser_from_source_str(&self.sess.parse_sess,
|
||||
self.sess.opts.cfg.clone(),
|
||||
self.local_crate_config.clone(),
|
||||
source_name.clone(),
|
||||
body);
|
||||
let lo = p.span.lo;
|
||||
@ -863,7 +867,7 @@ impl<'a> LocalCrateReader<'a> {
|
||||
LocalCrateReader {
|
||||
sess: sess,
|
||||
cstore: cstore,
|
||||
creader: CrateReader::new(sess, cstore, local_crate_name),
|
||||
creader: CrateReader::new(sess, cstore, local_crate_name, krate.config.clone()),
|
||||
krate: krate,
|
||||
definitions: defs,
|
||||
}
|
||||
|
@ -400,7 +400,7 @@ impl<'a> Context<'a> {
|
||||
if self.hash.is_none() {
|
||||
self.should_match_name = false;
|
||||
if let Some(s) = self.sess.opts.externs.get(self.crate_name) {
|
||||
return self.find_commandline_library(s);
|
||||
return self.find_commandline_library(s.iter());
|
||||
}
|
||||
self.should_match_name = true;
|
||||
}
|
||||
@ -661,7 +661,9 @@ impl<'a> Context<'a> {
|
||||
(t.options.staticlib_prefix.clone(), t.options.staticlib_suffix.clone())
|
||||
}
|
||||
|
||||
fn find_commandline_library(&mut self, locs: &[String]) -> Option<Library> {
|
||||
fn find_commandline_library<'b, LOCS> (&mut self, locs: LOCS) -> Option<Library>
|
||||
where LOCS: Iterator<Item=&'b String>
|
||||
{
|
||||
// First, filter out all libraries that look suspicious. We only accept
|
||||
// files which actually exist that have the correct naming scheme for
|
||||
// rlibs/dylibs.
|
||||
@ -670,7 +672,7 @@ impl<'a> Context<'a> {
|
||||
let mut rlibs = HashMap::new();
|
||||
let mut dylibs = HashMap::new();
|
||||
{
|
||||
let locs = locs.iter().map(|l| PathBuf::from(l)).filter(|loc| {
|
||||
let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| {
|
||||
if !loc.exists() {
|
||||
sess.err(&format!("extern location for {} does not exist: {}",
|
||||
self.crate_name, loc.display()));
|
||||
|
@ -29,10 +29,14 @@ pub struct MacroLoader<'a> {
|
||||
}
|
||||
|
||||
impl<'a> MacroLoader<'a> {
|
||||
pub fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> MacroLoader<'a> {
|
||||
pub fn new(sess: &'a Session,
|
||||
cstore: &'a CStore,
|
||||
crate_name: &str,
|
||||
crate_config: ast::CrateConfig)
|
||||
-> MacroLoader<'a> {
|
||||
MacroLoader {
|
||||
sess: sess,
|
||||
reader: CrateReader::new(sess, cstore, crate_name),
|
||||
reader: CrateReader::new(sess, cstore, crate_name, crate_config),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ pub fn load_plugins(sess: &Session,
|
||||
krate: &ast::Crate,
|
||||
crate_name: &str,
|
||||
addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
|
||||
let mut loader = PluginLoader::new(sess, cstore, crate_name);
|
||||
let mut loader = PluginLoader::new(sess, cstore, crate_name, krate.config.clone());
|
||||
|
||||
// do not report any error now. since crate attributes are
|
||||
// not touched by expansion, every use of plugin without
|
||||
@ -90,10 +90,14 @@ pub fn load_plugins(sess: &Session,
|
||||
}
|
||||
|
||||
impl<'a> PluginLoader<'a> {
|
||||
fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> PluginLoader<'a> {
|
||||
fn new(sess: &'a Session,
|
||||
cstore: &'a CStore,
|
||||
crate_name: &str,
|
||||
crate_config: ast::CrateConfig)
|
||||
-> PluginLoader<'a> {
|
||||
PluginLoader {
|
||||
sess: sess,
|
||||
reader: CrateReader::new(sess, cstore, crate_name),
|
||||
reader: CrateReader::new(sess, cstore, crate_name, crate_config),
|
||||
plugins: vec![],
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +190,8 @@ pub fn link_binary(sess: &Session,
|
||||
let mut out_filenames = Vec::new();
|
||||
for &crate_type in sess.crate_types.borrow().iter() {
|
||||
// Ignore executable crates if we have -Z no-trans, as they will error.
|
||||
if sess.opts.no_trans && crate_type == config::CrateTypeExecutable {
|
||||
if sess.opts.debugging_opts.no_trans &&
|
||||
crate_type == config::CrateTypeExecutable {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
use back::lto;
|
||||
use back::link::{get_linker, remove};
|
||||
use rustc_incremental::save_trans_partition;
|
||||
use session::config::{OutputFilenames, Passes, SomePasses, AllPasses};
|
||||
use session::config::{OutputFilenames, OutputTypes, Passes, SomePasses, AllPasses};
|
||||
use session::Session;
|
||||
use session::config::{self, OutputType};
|
||||
use llvm;
|
||||
@ -26,7 +26,6 @@ use errors::emitter::Emitter;
|
||||
use syntax_pos::MultiSpan;
|
||||
use context::{is_pie_binary, get_reloc_model};
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
@ -641,7 +640,7 @@ pub fn cleanup_llvm(trans: &CrateTranslation) {
|
||||
|
||||
pub fn run_passes(sess: &Session,
|
||||
trans: &CrateTranslation,
|
||||
output_types: &HashMap<OutputType, Option<PathBuf>>,
|
||||
output_types: &OutputTypes,
|
||||
crate_output: &OutputFilenames) {
|
||||
// It's possible that we have `codegen_units > 1` but only one item in
|
||||
// `trans.modules`. We could theoretically proceed and do LTO in that
|
||||
|
@ -2576,7 +2576,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
assert_module_sources::assert_module_sources(tcx, &modules);
|
||||
|
||||
// Skip crate items and just output metadata in -Z no-trans mode.
|
||||
if tcx.sess.opts.no_trans {
|
||||
if tcx.sess.opts.debugging_opts.no_trans {
|
||||
let linker_info = LinkerInfo::new(&shared_ccx, &[]);
|
||||
return CrateTranslation {
|
||||
modules: modules,
|
||||
|
@ -45,7 +45,6 @@ pub enum MaybeTyped<'a, 'tcx: 'a> {
|
||||
NotTyped(&'a session::Session)
|
||||
}
|
||||
|
||||
pub type Externs = HashMap<String, Vec<String>>;
|
||||
pub type ExternalPaths = HashMap<DefId, (Vec<String>, clean::TypeKind)>;
|
||||
|
||||
pub struct DocContext<'a, 'tcx: 'a> {
|
||||
@ -99,7 +98,7 @@ impl DocAccessLevels for AccessLevels<DefId> {
|
||||
|
||||
pub fn run_core(search_paths: SearchPaths,
|
||||
cfgs: Vec<String>,
|
||||
externs: Externs,
|
||||
externs: config::Externs,
|
||||
input: Input,
|
||||
triple: Option<String>) -> (clean::Crate, RenderInfo)
|
||||
{
|
||||
@ -120,7 +119,6 @@ pub fn run_core(search_paths: SearchPaths,
|
||||
lint_cap: Some(lint::Allow),
|
||||
externs: externs,
|
||||
target_triple: triple.unwrap_or(config::host_triple().to_string()),
|
||||
cfg: config::parse_cfgspecs(cfgs),
|
||||
// Ensure that rustdoc works even if rustc is feature-staged
|
||||
unstable_features: UnstableFeatures::Allow,
|
||||
..config::basic_options().clone()
|
||||
@ -139,7 +137,7 @@ pub fn run_core(search_paths: SearchPaths,
|
||||
codemap, cstore.clone());
|
||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||
|
||||
let mut cfg = config::build_configuration(&sess);
|
||||
let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs));
|
||||
target_features::add_configuration(&mut cfg, &sess);
|
||||
|
||||
let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));
|
||||
|
@ -51,7 +51,7 @@ extern crate rustc_errors as errors;
|
||||
|
||||
extern crate serialize as rustc_serialize; // used by deriving
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::default::Default;
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
@ -60,7 +60,8 @@ use std::sync::mpsc::channel;
|
||||
|
||||
use externalfiles::ExternalHtml;
|
||||
use rustc::session::search_paths::SearchPaths;
|
||||
use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options};
|
||||
use rustc::session::config::{ErrorOutputType, RustcOptGroup, nightly_options,
|
||||
Externs};
|
||||
|
||||
#[macro_use]
|
||||
pub mod externalfiles;
|
||||
@ -323,7 +324,7 @@ pub fn main_args(args: &[String]) -> isize {
|
||||
/// Looks inside the command line arguments to extract the relevant input format
|
||||
/// and files and then generates the necessary rustdoc output for formatting.
|
||||
fn acquire_input(input: &str,
|
||||
externs: core::Externs,
|
||||
externs: Externs,
|
||||
matches: &getopts::Matches) -> Result<Output, String> {
|
||||
match matches.opt_str("r").as_ref().map(|s| &**s) {
|
||||
Some("rust") => Ok(rust_input(input, externs, matches)),
|
||||
@ -335,10 +336,10 @@ fn acquire_input(input: &str,
|
||||
}
|
||||
|
||||
/// Extracts `--extern CRATE=PATH` arguments from `matches` and
|
||||
/// returns a `HashMap` mapping crate names to their paths or else an
|
||||
/// returns a map mapping crate names to their paths or else an
|
||||
/// error message.
|
||||
fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
|
||||
let mut externs = HashMap::new();
|
||||
fn parse_externs(matches: &getopts::Matches) -> Result<Externs, String> {
|
||||
let mut externs = BTreeMap::new();
|
||||
for arg in &matches.opt_strs("extern") {
|
||||
let mut parts = arg.splitn(2, '=');
|
||||
let name = parts.next().ok_or("--extern value must not be empty".to_string())?;
|
||||
@ -346,9 +347,9 @@ fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
|
||||
.ok_or("--extern value must be of the format `foo=bar`"
|
||||
.to_string())?;
|
||||
let name = name.to_string();
|
||||
externs.entry(name).or_insert(vec![]).push(location.to_string());
|
||||
externs.entry(name).or_insert_with(BTreeSet::new).insert(location.to_string());
|
||||
}
|
||||
Ok(externs)
|
||||
Ok(Externs::new(externs))
|
||||
}
|
||||
|
||||
/// Interprets the input file as a rust source file, passing it through the
|
||||
@ -356,7 +357,7 @@ fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
|
||||
/// generated from the cleaned AST of the crate.
|
||||
///
|
||||
/// This form of input will run all of the plug/cleaning passes
|
||||
fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matches) -> Output {
|
||||
fn rust_input(cratefile: &str, externs: Externs, matches: &getopts::Matches) -> Output {
|
||||
let mut default_passes = !matches.opt_present("no-defaults");
|
||||
let mut passes = matches.opt_strs("passes");
|
||||
let mut plugins = matches.opt_strs("plugins");
|
||||
|
@ -14,10 +14,10 @@ use std::io::prelude::*;
|
||||
use std::io;
|
||||
use std::path::{PathBuf, Path};
|
||||
|
||||
use core;
|
||||
use getopts;
|
||||
use testing;
|
||||
use rustc::session::search_paths::SearchPaths;
|
||||
use rustc::session::config::Externs;
|
||||
|
||||
use externalfiles::ExternalHtml;
|
||||
|
||||
@ -142,7 +142,7 @@ pub fn render(input: &str, mut output: PathBuf, matches: &getopts::Matches,
|
||||
}
|
||||
|
||||
/// Run any tests/code examples in the markdown file `input`.
|
||||
pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: core::Externs,
|
||||
pub fn test(input: &str, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
||||
mut test_args: Vec<String>) -> isize {
|
||||
let input_str = load_or_return!(input, 1, 2);
|
||||
|
||||
|
@ -26,7 +26,8 @@ use rustc_lint;
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::hir::map as hir_map;
|
||||
use rustc::session::{self, config};
|
||||
use rustc::session::config::{get_unstable_features_setting, OutputType};
|
||||
use rustc::session::config::{get_unstable_features_setting, OutputType,
|
||||
OutputTypes, Externs};
|
||||
use rustc::session::search_paths::{SearchPaths, PathKind};
|
||||
use rustc_back::dynamic_lib::DynamicLibrary;
|
||||
use rustc_back::tempdir::TempDir;
|
||||
@ -55,7 +56,7 @@ pub struct TestOptions {
|
||||
pub fn run(input: &str,
|
||||
cfgs: Vec<String>,
|
||||
libs: SearchPaths,
|
||||
externs: core::Externs,
|
||||
externs: Externs,
|
||||
mut test_args: Vec<String>,
|
||||
crate_name: Option<String>)
|
||||
-> isize {
|
||||
@ -89,8 +90,7 @@ pub fn run(input: &str,
|
||||
cstore.clone());
|
||||
rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
|
||||
|
||||
let mut cfg = config::build_configuration(&sess);
|
||||
cfg.extend(config::parse_cfgspecs(cfgs.clone()));
|
||||
let cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
|
||||
let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));
|
||||
let driver::ExpansionResult { defs, mut hir_forest, .. } = {
|
||||
phase_2_configure_and_expand(
|
||||
@ -172,7 +172,7 @@ fn scrape_test_config(krate: &::rustc::hir::Crate) -> TestOptions {
|
||||
}
|
||||
|
||||
fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
|
||||
externs: core::Externs,
|
||||
externs: Externs,
|
||||
should_panic: bool, no_run: bool, as_test_harness: bool,
|
||||
compile_fail: bool, mut error_codes: Vec<String>, opts: &TestOptions) {
|
||||
// the test harness wants its own `main` & top level functions, so
|
||||
@ -182,8 +182,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
|
||||
name: driver::anon_src(),
|
||||
input: test.to_owned(),
|
||||
};
|
||||
let mut outputs = HashMap::new();
|
||||
outputs.insert(OutputType::Exe, None);
|
||||
let outputs = OutputTypes::new(&[(OutputType::Exe, None)]);
|
||||
|
||||
let sessopts = config::Options {
|
||||
maybe_sysroot: Some(env::current_exe().unwrap().parent().unwrap()
|
||||
@ -247,8 +246,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
|
||||
let outdir = Mutex::new(TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir"));
|
||||
let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
|
||||
let mut control = driver::CompileController::basic();
|
||||
let mut cfg = config::build_configuration(&sess);
|
||||
cfg.extend(config::parse_cfgspecs(cfgs.clone()));
|
||||
let cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
|
||||
let out = Some(outdir.lock().unwrap().path().to_path_buf());
|
||||
|
||||
if no_run {
|
||||
@ -396,7 +394,7 @@ pub struct Collector {
|
||||
names: Vec<String>,
|
||||
cfgs: Vec<String>,
|
||||
libs: SearchPaths,
|
||||
externs: core::Externs,
|
||||
externs: Externs,
|
||||
cnt: usize,
|
||||
use_headers: bool,
|
||||
current_header: Option<String>,
|
||||
@ -405,7 +403,7 @@ pub struct Collector {
|
||||
}
|
||||
|
||||
impl Collector {
|
||||
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: core::Externs,
|
||||
pub fn new(cratename: String, cfgs: Vec<String>, libs: SearchPaths, externs: Externs,
|
||||
use_headers: bool, opts: TestOptions) -> Collector {
|
||||
Collector {
|
||||
tests: Vec::new(),
|
||||
|
@ -1194,7 +1194,7 @@ pub fn check_crate(krate: &ast::Crate,
|
||||
visit::walk_crate(&mut PostExpansionVisitor { context: &ctx }, krate);
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum UnstableFeatures {
|
||||
/// Hard errors for unstable features are active, as on
|
||||
/// beta/stable channels.
|
||||
|
30
src/test/incremental/commandline-args.rs
Normal file
30
src/test/incremental/commandline-args.rs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// Test that changing a tracked commandline argument invalidates
|
||||
// the cache while changing an untracked one doesn't.
|
||||
|
||||
// revisions:rpass1 rpass2 rpass3
|
||||
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#![rustc_partition_translated(module="commandline_args", cfg="rpass2")]
|
||||
#![rustc_partition_reused(module="commandline_args", cfg="rpass3")]
|
||||
|
||||
// Between revisions 1 and 2, we are changing the debuginfo-level, which should
|
||||
// invalidate the cache. Between revisions 2 and 3, we are adding `--verbose`
|
||||
// which should have no effect on the cache:
|
||||
//[rpass1] compile-flags: -C debuginfo=0
|
||||
//[rpass2] compile-flags: -C debuginfo=2
|
||||
//[rpass3] compile-flags: -C debuginfo=2 --verbose
|
||||
|
||||
pub fn main() {
|
||||
// empty
|
||||
}
|
@ -19,7 +19,8 @@ extern crate syntax;
|
||||
|
||||
use rustc::dep_graph::DepGraph;
|
||||
use rustc::session::{build_session, Session};
|
||||
use rustc::session::config::{basic_options, build_configuration, Input, OutputType};
|
||||
use rustc::session::config::{basic_options, build_configuration, Input,
|
||||
OutputType, OutputTypes};
|
||||
use rustc_driver::driver::{compile_input, CompileController, anon_src};
|
||||
use rustc_metadata::cstore::CStore;
|
||||
use rustc_errors::registry::Registry;
|
||||
@ -51,7 +52,7 @@ fn main() {
|
||||
|
||||
fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) {
|
||||
let mut opts = basic_options();
|
||||
opts.output_types.insert(OutputType::Exe, None);
|
||||
opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
|
||||
opts.maybe_sysroot = Some(sysroot);
|
||||
|
||||
let descriptions = Registry::new(&rustc::DIAGNOSTICS);
|
||||
@ -64,7 +65,7 @@ fn basic_sess(sysroot: PathBuf) -> (Session, Rc<CStore>) {
|
||||
|
||||
fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
|
||||
let (sess, cstore) = basic_sess(sysroot);
|
||||
let cfg = build_configuration(&sess);
|
||||
let cfg = build_configuration(&sess, vec![]);
|
||||
let control = CompileController::basic();
|
||||
|
||||
compile_input(&sess, &cstore,
|
||||
|
@ -24,6 +24,7 @@ extern crate rustc_errors as errors;
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::{self, Input};
|
||||
use rustc_driver::{driver, CompilerCalls, Compilation};
|
||||
use syntax::ast;
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
@ -35,6 +36,7 @@ impl<'a> CompilerCalls<'a> for TestCalls {
|
||||
fn early_callback(&mut self,
|
||||
_: &getopts::Matches,
|
||||
_: &config::Options,
|
||||
_: &ast::CrateConfig,
|
||||
_: &errors::registry::Registry,
|
||||
_: config::ErrorOutputType)
|
||||
-> Compilation {
|
||||
@ -45,6 +47,7 @@ impl<'a> CompilerCalls<'a> for TestCalls {
|
||||
fn late_callback(&mut self,
|
||||
_: &getopts::Matches,
|
||||
_: &Session,
|
||||
_: &ast::CrateConfig,
|
||||
_: &Input,
|
||||
_: &Option<PathBuf>,
|
||||
_: &Option<PathBuf>)
|
||||
@ -62,6 +65,7 @@ impl<'a> CompilerCalls<'a> for TestCalls {
|
||||
fn no_input(&mut self,
|
||||
_: &getopts::Matches,
|
||||
_: &config::Options,
|
||||
_: &ast::CrateConfig,
|
||||
_: &Option<PathBuf>,
|
||||
_: &Option<PathBuf>,
|
||||
_: &errors::registry::Registry)
|
||||
|
@ -2008,6 +2008,7 @@ actual:\n\
|
||||
// Add an extra flag pointing at the incremental directory.
|
||||
let mut revision_props = self.props.clone();
|
||||
revision_props.incremental_dir = Some(incremental_dir);
|
||||
revision_props.compile_flags.push(String::from("-Zincremental-info"));
|
||||
|
||||
let revision_cx = TestCx {
|
||||
config: self.config,
|
||||
|
Loading…
Reference in New Issue
Block a user