| use std::any::Any; | 
 | use std::sync::Arc; | 
 |  | 
 | use rustc_codegen_ssa::CodegenResults; | 
 | use rustc_codegen_ssa::traits::CodegenBackend; | 
 | use rustc_data_structures::svh::Svh; | 
 | use rustc_errors::timings::TimingSection; | 
 | use rustc_hir::def_id::LOCAL_CRATE; | 
 | use rustc_metadata::EncodedMetadata; | 
 | use rustc_middle::dep_graph::DepGraph; | 
 | use rustc_middle::ty::TyCtxt; | 
 | use rustc_session::Session; | 
 | use rustc_session::config::{self, OutputFilenames, OutputType}; | 
 |  | 
 | use crate::errors::FailedWritingFile; | 
 | use crate::passes; | 
 |  | 
 | pub struct Linker { | 
 |     dep_graph: DepGraph, | 
 |     output_filenames: Arc<OutputFilenames>, | 
 |     // Only present when incr. comp. is enabled. | 
 |     crate_hash: Option<Svh>, | 
 |     metadata: EncodedMetadata, | 
 |     ongoing_codegen: Box<dyn Any>, | 
 | } | 
 |  | 
 | impl Linker { | 
 |     pub fn codegen_and_build_linker( | 
 |         tcx: TyCtxt<'_>, | 
 |         codegen_backend: &dyn CodegenBackend, | 
 |     ) -> Linker { | 
 |         let (ongoing_codegen, metadata) = passes::start_codegen(codegen_backend, tcx); | 
 |  | 
 |         Linker { | 
 |             dep_graph: tcx.dep_graph.clone(), | 
 |             output_filenames: Arc::clone(tcx.output_filenames(())), | 
 |             crate_hash: if tcx.needs_crate_hash() { | 
 |                 Some(tcx.crate_hash(LOCAL_CRATE)) | 
 |             } else { | 
 |                 None | 
 |             }, | 
 |             metadata, | 
 |             ongoing_codegen, | 
 |         } | 
 |     } | 
 |  | 
 |     pub fn link(self, sess: &Session, codegen_backend: &dyn CodegenBackend) { | 
 |         let (codegen_results, mut work_products) = sess.time("finish_ongoing_codegen", || { | 
 |             codegen_backend.join_codegen(self.ongoing_codegen, sess, &self.output_filenames) | 
 |         }); | 
 |         sess.timings.end_section(sess.dcx(), TimingSection::Codegen); | 
 |  | 
 |         if sess.opts.incremental.is_some() | 
 |             && let Some(path) = self.metadata.path() | 
 |             && let Some((id, product)) = | 
 |                 rustc_incremental::copy_cgu_workproduct_to_incr_comp_cache_dir( | 
 |                     sess, | 
 |                     "metadata", | 
 |                     &[("rmeta", path)], | 
 |                     &[], | 
 |                 ) | 
 |         { | 
 |             work_products.insert(id, product); | 
 |         } | 
 |  | 
 |         sess.dcx().abort_if_errors(); | 
 |  | 
 |         let _timer = sess.timer("link"); | 
 |  | 
 |         sess.time("serialize_work_products", || { | 
 |             rustc_incremental::save_work_product_index(sess, &self.dep_graph, work_products) | 
 |         }); | 
 |  | 
 |         let prof = sess.prof.clone(); | 
 |         prof.generic_activity("drop_dep_graph").run(move || drop(self.dep_graph)); | 
 |  | 
 |         // Now that we won't touch anything in the incremental compilation directory | 
 |         // any more, we can finalize it (which involves renaming it) | 
 |         rustc_incremental::finalize_session_directory(sess, self.crate_hash); | 
 |  | 
 |         if !sess | 
 |             .opts | 
 |             .output_types | 
 |             .keys() | 
 |             .any(|&i| i == OutputType::Exe || i == OutputType::Metadata) | 
 |         { | 
 |             return; | 
 |         } | 
 |  | 
 |         if sess.opts.unstable_opts.no_link { | 
 |             let rlink_file = self.output_filenames.with_extension(config::RLINK_EXT); | 
 |             CodegenResults::serialize_rlink( | 
 |                 sess, | 
 |                 &rlink_file, | 
 |                 &codegen_results, | 
 |                 &self.metadata, | 
 |                 &*self.output_filenames, | 
 |             ) | 
 |             .unwrap_or_else(|error| { | 
 |                 sess.dcx().emit_fatal(FailedWritingFile { path: &rlink_file, error }) | 
 |             }); | 
 |             return; | 
 |         } | 
 |  | 
 |         let _timer = sess.prof.verbose_generic_activity("link_crate"); | 
 |         let _timing = sess.timings.section_guard(sess.dcx(), TimingSection::Linking); | 
 |         codegen_backend.link(sess, codegen_results, self.metadata, &self.output_filenames) | 
 |     } | 
 | } |