diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index ff9f666af75..44c046131f1 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -1053,7 +1053,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, analysis: ty::CrateAnalysis, incremental_hashes_map: &IncrementalHashesMap, output_filenames: &OutputFilenames) - -> trans::OngoingCrateTranslation { + -> write::OngoingCrateTranslation { let time_passes = tcx.sess.time_passes(); time(time_passes, @@ -1071,7 +1071,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, /// Run LLVM itself, producing a bitcode file, assembly file or object file /// as a side effect. pub fn phase_5_run_llvm_passes(sess: &Session, - trans: trans::OngoingCrateTranslation, + trans: write::OngoingCrateTranslation, outputs: &OutputFilenames) -> (CompileResult, trans::CrateTranslation) { let trans = trans.join(sess, outputs); diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 83f7f574493..987d88c7c61 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -10,23 +10,25 @@ use back::lto; use back::link::{self, get_linker, remove}; +use back::linker::LinkerInfo; use back::symbol_export::ExportedSymbols; use rustc_incremental::{save_trans_partition, in_incr_comp_dir}; +use rustc::middle::cstore::{LinkMeta, EncodedMetadata}; use rustc::session::config::{self, OutputFilenames, OutputType, OutputTypes, Passes, SomePasses, AllPasses, Sanitizer}; use rustc::session::Session; use llvm; use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef}; use llvm::SMDiagnosticRef; -use {CrateTranslation, OngoingCrateTranslation, ModuleSource, ModuleTranslation, - CompiledModule, ModuleKind}; +use {CrateTranslation, ModuleSource, ModuleTranslation, CompiledModule, ModuleKind}; use rustc::hir::def_id::CrateNum; use rustc::util::common::{time, time_depth, set_time_depth, path2cstr}; -use rustc::util::fs::link_or_copy; +use rustc::util::fs::{link_or_copy, rename_or_copy_remove}; use errors::{self, Handler, Level, DiagnosticBuilder, FatalError}; use errors::emitter::{Emitter}; use syntax::ext::hygiene::Mark; use syntax_pos::MultiSpan; +use syntax_pos::symbol::Symbol; use context::{is_pie_binary, get_reloc_model}; use jobserver::{Client, Acquired}; use rustc_demangle; @@ -816,7 +818,7 @@ pub fn run_passes(sess: &Session, } loop { - shared_emitter_main.check(sess); + shared_emitter_main.check(sess, false); match trans_worker_receive.recv() { Err(_) => { @@ -837,7 +839,7 @@ pub fn run_passes(sess: &Session, let compiled_modules = coordinator_thread.join().unwrap(); // Just in case, check this on the way out. - shared_emitter_main.check(sess); + shared_emitter_main.check(sess, false); sess.diagnostic().abort_if_errors(); // If in incr. comp. mode, preserve the `.o` files for potential re-use @@ -1516,9 +1518,21 @@ impl Emitter for SharedEmitter { } impl SharedEmitterMain { - pub fn check(&self, sess: &Session) { + pub fn check(&self, sess: &Session, blocking: bool) { loop { - match self.receiver.try_recv() { + let message = if blocking { + match self.receiver.recv() { + Ok(message) => Ok(message), + Err(_) => Err(()), + } + } else { + match self.receiver.try_recv() { + Ok(message) => Ok(message), + Err(_) => Err(()), + } + }; + + match message { Ok(SharedEmitterMessage::Diagnostic(diag)) => { let handler = sess.diagnostic(); match diag.code { @@ -1555,3 +1569,62 @@ impl SharedEmitterMain { } } } + +pub struct OngoingCrateTranslation { + pub crate_name: Symbol, + pub link: LinkMeta, + pub metadata: EncodedMetadata, + pub exported_symbols: Arc, + pub no_builtins: bool, + pub windows_subsystem: Option, + pub linker_info: LinkerInfo, + pub no_integrated_as: bool, + + // This will be replaced by a Future. + pub result: ::std::cell::RefCell>, +} + +impl OngoingCrateTranslation { + pub fn join(self, + sess: &Session, + outputs: &OutputFilenames) + -> CrateTranslation { + + let result = self.result.borrow_mut().take().unwrap(); + + let trans = CrateTranslation { + crate_name: self.crate_name, + link: self.link, + metadata: self.metadata, + exported_symbols: self.exported_symbols, + no_builtins: self.no_builtins, + windows_subsystem: self.windows_subsystem, + linker_info: self.linker_info, + + modules: result.modules, + metadata_module: result.metadata_module, + allocator_module: result.allocator_module, + }; + + if self.no_integrated_as { + run_assembler(sess, outputs); + + // HACK the linker expects the object file to be named foo.0.o but + // `run_assembler` produces an object named just foo.o. Rename it if we + // are going to build an executable + if sess.opts.output_types.contains_key(&OutputType::Exe) { + let f = outputs.path(OutputType::Object); + rename_or_copy_remove(&f, + f.with_file_name(format!("{}.0.o", + f.file_stem().unwrap().to_string_lossy()))).unwrap(); + } + + // Remove assembly source, unless --save-temps was specified + if !sess.opts.cg.save_temps { + fs::remove_file(&outputs.temp_path(OutputType::Assembly, None)).unwrap(); + } + } + + trans + } +} diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 7ece92ef9dd..6eb38dc52ee 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -23,7 +23,6 @@ //! but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int, //! int) and rec(x=int, y=int, z=int) will have the same TypeRef. -use super::OngoingCrateTranslation; use super::ModuleLlvm; use super::ModuleSource; use super::ModuleTranslation; @@ -33,6 +32,7 @@ use assert_module_sources; use back::link; use back::linker::LinkerInfo; use back::symbol_export::{self, ExportedSymbols}; +use back::write::OngoingCrateTranslation; use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param}; use llvm; use metadata; diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs index 1df1bd272fd..62ff1535be9 100644 --- a/src/librustc_trans/lib.rs +++ b/src/librustc_trans/lib.rs @@ -35,11 +35,7 @@ #![feature(conservative_impl_trait)] use rustc::dep_graph::WorkProduct; -use rustc::session::Session; -use rustc::session::config::{OutputType, OutputFilenames}; -use rustc::util::fs::rename_or_copy_remove; use syntax_pos::symbol::Symbol; -use std::fs; use std::sync::Arc; extern crate flate2; @@ -229,63 +225,4 @@ pub struct CrateTranslation { pub linker_info: back::linker::LinkerInfo } -pub struct OngoingCrateTranslation { - pub crate_name: Symbol, - pub link: rustc::middle::cstore::LinkMeta, - pub metadata: rustc::middle::cstore::EncodedMetadata, - pub exported_symbols: Arc, - pub no_builtins: bool, - pub windows_subsystem: Option, - pub linker_info: back::linker::LinkerInfo, - pub no_integrated_as: bool, - - // This will be replaced by a Future. - pub result: ::std::cell::RefCell>, -} - -impl OngoingCrateTranslation { - pub fn join(self, - sess: &Session, - outputs: &OutputFilenames) - -> CrateTranslation { - - let result = self.result.borrow_mut().take().unwrap(); - - let trans = CrateTranslation { - crate_name: self.crate_name, - link: self.link, - metadata: self.metadata, - exported_symbols: self.exported_symbols, - no_builtins: self.no_builtins, - windows_subsystem: self.windows_subsystem, - linker_info: self.linker_info, - - modules: result.modules, - metadata_module: result.metadata_module, - allocator_module: result.allocator_module, - }; - - if self.no_integrated_as { - back::write::run_assembler(sess, outputs); - - // HACK the linker expects the object file to be named foo.0.o but - // `run_assembler` produces an object named just foo.o. Rename it if we - // are going to build an executable - if sess.opts.output_types.contains_key(&OutputType::Exe) { - let f = outputs.path(OutputType::Object); - rename_or_copy_remove(&f, - f.with_file_name(format!("{}.0.o", - f.file_stem().unwrap().to_string_lossy()))).unwrap(); - } - - // Remove assembly source, unless --save-temps was specified - if !sess.opts.cg.save_temps { - fs::remove_file(&outputs.temp_path(OutputType::Assembly, None)).unwrap(); - } - } - - trans - } -} - __build_diagnostic_array! { librustc_trans, DIAGNOSTICS }