]> git.lizzy.rs Git - rust.git/commitdiff
Moved Backend interface into rustc_codegen_utils
authorDenis Merigoux <denis.merigoux@gmail.com>
Mon, 1 Oct 2018 08:32:09 +0000 (10:32 +0200)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Fri, 16 Nov 2018 12:40:16 +0000 (14:40 +0200)
18 files changed:
src/librustc_codegen_llvm/back/lto.rs
src/librustc_codegen_llvm/back/write.rs
src/librustc_codegen_llvm/base.rs
src/librustc_codegen_llvm/interfaces/asm.rs
src/librustc_codegen_llvm/interfaces/backend.rs [deleted file]
src/librustc_codegen_llvm/interfaces/builder.rs
src/librustc_codegen_llvm/interfaces/debuginfo.rs
src/librustc_codegen_llvm/interfaces/declare.rs
src/librustc_codegen_llvm/interfaces/intrinsic.rs
src/librustc_codegen_llvm/interfaces/misc.rs
src/librustc_codegen_llvm/interfaces/mod.rs
src/librustc_codegen_llvm/interfaces/statics.rs
src/librustc_codegen_llvm/interfaces/type_.rs
src/librustc_codegen_llvm/lib.rs
src/librustc_codegen_utils/common.rs
src/librustc_codegen_utils/interfaces/backend.rs [new file with mode: 0644]
src/librustc_codegen_utils/interfaces/mod.rs [new file with mode: 0644]
src/librustc_codegen_utils/lib.rs

index 5eb2e28a2a86fbef6403cee079fdbe75ed02e72c..de69531fa8bffd5625b47255b10f10f2f7b06ae3 100644 (file)
@@ -24,7 +24,8 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_codegen_utils::symbol_export;
 use time_graph::Timeline;
-use {ModuleCodegen, ModuleLlvm, ModuleKind};
+use ModuleLlvm;
+use rustc_codegen_utils::{ModuleCodegen, ModuleKind};
 
 use libc;
 
index 72820f967afa338f13d75b3c6897ad40f3b9506d..d96dd93e3e2c3a5ee1fd220dd25c30d813b79413 100644 (file)
@@ -26,8 +26,8 @@
 use time_graph::{self, TimeGraph, Timeline};
 use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
 use llvm_util;
-use {CodegenResults, ModuleCodegen, CompiledModule, ModuleKind, ModuleLlvm,
-     CachedModuleCodegen};
+use {CodegenResults, ModuleLlvm};
+use rustc_codegen_utils::{ModuleCodegen, ModuleKind, CachedModuleCodegen, CompiledModule};
 use CrateInfo;
 use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
 use rustc::ty::TyCtxt;
index 5a11bade27488d935c93effcfc1a934667c23b85..d8f5c25714f664339b8ef8cd8a512198be716a1e 100644 (file)
@@ -24,9 +24,7 @@
 //!     int) and rec(x=int, y=int, z=int) will have the same llvm::Type.
 
 use super::ModuleLlvm;
-use super::ModuleCodegen;
-use super::ModuleKind;
-use super::CachedModuleCodegen;
+use rustc_codegen_utils::{ModuleCodegen, ModuleKind, CachedModuleCodegen};
 use super::LlvmCodegenBackend;
 
 use abi;
@@ -1197,25 +1195,3 @@ pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
         Visibility::Protected => llvm::Visibility::Protected,
     }
 }
-
-// FIXME(mw): Anything that is produced via DepGraph::with_task() must implement
-//            the HashStable trait. Normally DepGraph::with_task() calls are
-//            hidden behind queries, but CGU creation is a special case in two
-//            ways: (1) it's not a query and (2) CGU are output nodes, so their
-//            Fingerprints are not actually needed. It remains to be clarified
-//            how exactly this case will be handled in the red/green system but
-//            for now we content ourselves with providing a no-op HashStable
-//            implementation for CGUs.
-mod temp_stable_hash_impls {
-    use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher,
-                                               HashStable};
-    use {ModuleCodegen, ModuleLlvm};
-
-    impl<HCX> HashStable<HCX> for ModuleCodegen<ModuleLlvm> {
-        fn hash_stable<W: StableHasherResult>(&self,
-                                              _: &mut HCX,
-                                              _: &mut StableHasher<W>) {
-            // do nothing
-        }
-    }
-}
index 33c751cc1d974f2e446a47b58af3c8bf5f8e1af0..ffe9679fcd6cbc8c358fc4bf43ece9ac4b726120 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::backend::Backend;
+use super::Backend;
 use super::HasCodegen;
 use mir::place::PlaceRef;
 use rustc::hir::{GlobalAsm, InlineAsm};
diff --git a/src/librustc_codegen_llvm/interfaces/backend.rs b/src/librustc_codegen_llvm/interfaces/backend.rs
deleted file mode 100644 (file)
index d21e397..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2018 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.
-
-use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout};
-use rustc::ty::Ty;
-
-use super::CodegenObject;
-use rustc::middle::allocator::AllocatorKind;
-use rustc::middle::cstore::EncodedMetadata;
-use rustc::mir::mono::Stats;
-use rustc::session::Session;
-use rustc::ty::TyCtxt;
-use std::any::Any;
-use std::sync::mpsc::Receiver;
-use syntax_pos::symbol::InternedString;
-use time_graph::TimeGraph;
-use ModuleCodegen;
-
-pub trait BackendTypes {
-    type Value: CodegenObject;
-    type BasicBlock: Copy;
-    type Type: CodegenObject;
-    type Context;
-    type Funclet;
-
-    type DIScope: Copy;
-}
-
-pub trait Backend<'tcx>:
-    BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
-{
-}
-
-impl<'tcx, T> Backend<'tcx> for T where
-    Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
-{}
-
-pub trait BackendMethods {
-    type Module;
-    type OngoingCodegen;
-
-    fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Module;
-    fn write_metadata<'b, 'gcx>(
-        &self,
-        tcx: TyCtxt<'b, 'gcx, 'gcx>,
-        metadata: &Self::Module,
-    ) -> EncodedMetadata;
-    fn codegen_allocator(&self, tcx: TyCtxt, mods: &Self::Module, kind: AllocatorKind);
-
-    fn start_async_codegen(
-        &self,
-        tcx: TyCtxt,
-        time_graph: Option<TimeGraph>,
-        metadata: EncodedMetadata,
-        coordinator_receive: Receiver<Box<dyn Any + Send>>,
-        total_cgus: usize,
-    ) -> Self::OngoingCodegen;
-    fn submit_pre_codegened_module_to_llvm(
-        &self,
-        codegen: &Self::OngoingCodegen,
-        tcx: TyCtxt,
-        module: ModuleCodegen<Self::Module>,
-    );
-    fn codegen_aborted(codegen: Self::OngoingCodegen);
-    fn codegen_finished(&self, codegen: &Self::OngoingCodegen, tcx: TyCtxt);
-    fn check_for_errors(&self, codegen: &Self::OngoingCodegen, sess: &Session);
-    fn wait_for_signal_to_codegen_item(&self, codegen: &Self::OngoingCodegen);
-    fn compile_codegen_unit<'a, 'tcx: 'a>(
-        &self,
-        tcx: TyCtxt<'a, 'tcx, 'tcx>,
-        cgu_name: InternedString,
-    ) -> Stats;
-}
index 61e60d55e09814d338c07e229bb4779fb41c44d6..74a31975a390e0b3f2ea95ad055610a3ff5dfd58 100644 (file)
@@ -213,7 +213,8 @@ fn select(
     fn set_cleanup(&self, landing_pad: Self::Value);
     fn resume(&self, exn: Self::Value) -> Self::Value;
     fn cleanup_pad(&self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet;
-    fn cleanup_ret(&self, funclet: &Self::Funclet, unwind: Option<Self::BasicBlock>) -> Self::Value;
+    fn cleanup_ret(&self, funclet: &Self::Funclet, unwind: Option<Self::BasicBlock>)
+        -> Self::Value;
     fn catch_pad(&self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet;
     fn catch_ret(&self, funclet: &Self::Funclet, unwind: Self::BasicBlock) -> Self::Value;
     fn catch_switch(
index 4e24e12bc6861e27eca89e0d8b574b6b25461716..24f6cb85c7bd02c190cdb6f7b64d9488a754dc2d 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::backend::Backend;
+use super::Backend;
 use super::HasCodegen;
 use debuginfo::{FunctionDebugContext, MirDebugScope, VariableAccess, VariableKind};
 use monomorphize::Instance;
index 5c9aedd1a3becc5fb52fd08ced9f25ca5ab06bb7..373220fd345e8b82cfa1c5a65a00effa45e5df6c 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::backend::Backend;
+use super::Backend;
 use monomorphize::Instance;
 use rustc::hir::def_id::DefId;
 use rustc::mir::mono::{Linkage, Visibility};
index 5f2994c1a83019d66ba8b0c05847f6bbfd2b027a..1ea377b5a1d020c7808494fdcead598a9f6567ed 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::backend::Backend;
+use super::Backend;
 use super::HasCodegen;
 use abi::FnType;
 use mir::operand::OperandRef;
index 2557b51b76de294ee0bb6330cf43d478648329b9..6e6af597a763f1617c11136bc68b921d70635bc6 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::backend::Backend;
+use super::Backend;
 use libc::c_uint;
 use monomorphize::partitioning::CodegenUnit;
 use rustc::mir::mono::Stats;
index f1040020aff23ba369cc77b0b5182eee9c08740f..61aa7e29326ba39bd83ed2f312ba13650b1e4451 100644 (file)
@@ -10,7 +10,6 @@
 
 mod abi;
 mod asm;
-mod backend;
 mod builder;
 mod consts;
 mod debuginfo;
@@ -22,7 +21,6 @@
 
 pub use self::abi::{AbiBuilderMethods, AbiMethods};
 pub use self::asm::{AsmBuilderMethods, AsmMethods};
-pub use self::backend::{Backend, BackendMethods, BackendTypes};
 pub use self::builder::BuilderMethods;
 pub use self::consts::ConstMethods;
 pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
@@ -33,8 +31,7 @@
 pub use self::type_::{
     ArgTypeMethods, BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMethods,
 };
-
-use std::fmt;
+pub use rustc_codegen_utils::interfaces::{Backend, BackendMethods, BackendTypes, CodegenObject};
 
 pub trait CodegenMethods<'tcx>:
     Backend<'tcx>
@@ -76,6 +73,3 @@ pub trait HasCodegen<'tcx>: Backend<'tcx> {
             DIScope = Self::DIScope,
         >;
 }
-
-pub trait CodegenObject: Copy + PartialEq + fmt::Debug {}
-impl<T: Copy + PartialEq + fmt::Debug> CodegenObject for T {}
index 0feb9d5255f5ce748cf78eb7c5839b977969977d..27748a8dd427f82a835e2a49b6adca4305d3689e 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::backend::Backend;
+use super::Backend;
 use rustc::hir::def_id::DefId;
 use rustc::ty::layout::Align;
 
index a03bcac5ecd8e59b73954de9d83ad24d7bef0e55..775ca2d2d0268dd77a342d67917e40aacfc2fbf0 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use super::backend::Backend;
+use super::Backend;
 use super::HasCodegen;
 use mir::place::PlaceRef;
 use rustc::ty::layout::TyLayout;
index 395fbae6aad8f16e5a4e8b664215aa77544e1f5d..e8f488ab04c17ef33eb950c1cf387d1197f86066 100644 (file)
@@ -37,7 +37,6 @@
 #![feature(static_nobundle)]
 
 use back::write::create_target_machine;
-use rustc::dep_graph::WorkProduct;
 use syntax_pos::symbol::Symbol;
 
 #[macro_use] extern crate bitflags;
@@ -67,7 +66,6 @@
 extern crate tempfile;
 extern crate memmap;
 
-use back::bytecode::RLIB_BYTECODE_EXTENSION;
 use interfaces::*;
 use time_graph::TimeGraph;
 use std::sync::mpsc::Receiver;
@@ -93,7 +91,7 @@
 use rustc::util::nodemap::{FxHashSet, FxHashMap};
 use rustc::util::profiling::ProfileCategory;
 use rustc_mir::monomorphize;
-use rustc_codegen_utils::{CompiledModule, ModuleKind};
+use rustc_codegen_utils::{ModuleCodegen, CompiledModule};
 use rustc_codegen_utils::codegen_backend::CodegenBackend;
 use rustc_data_structures::svh::Svh;
 
@@ -329,56 +327,6 @@ pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
     LlvmCodegenBackend::new()
 }
 
-pub struct ModuleCodegen<M> {
-    /// The name of the module. When the crate may be saved between
-    /// compilations, incremental compilation requires that name be
-    /// unique amongst **all** crates.  Therefore, it should contain
-    /// something unique to this crate (e.g., a module path) as well
-    /// as the crate name and disambiguator.
-    /// We currently generate these names via CodegenUnit::build_cgu_name().
-    name: String,
-    module_llvm: M,
-    kind: ModuleKind,
-}
-
-struct CachedModuleCodegen {
-    name: String,
-    source: WorkProduct,
-}
-
-impl ModuleCodegen<ModuleLlvm> {
-    fn into_compiled_module(self,
-                            emit_obj: bool,
-                            emit_bc: bool,
-                            emit_bc_compressed: bool,
-                            outputs: &OutputFilenames) -> CompiledModule {
-        let object = if emit_obj {
-            Some(outputs.temp_path(OutputType::Object, Some(&self.name)))
-        } else {
-            None
-        };
-        let bytecode = if emit_bc {
-            Some(outputs.temp_path(OutputType::Bitcode, Some(&self.name)))
-        } else {
-            None
-        };
-        let bytecode_compressed = if emit_bc_compressed {
-            Some(outputs.temp_path(OutputType::Bitcode, Some(&self.name))
-                        .with_extension(RLIB_BYTECODE_EXTENSION))
-        } else {
-            None
-        };
-
-        CompiledModule {
-            name: self.name.clone(),
-            kind: self.kind,
-            object,
-            bytecode,
-            bytecode_compressed,
-        }
-    }
-}
-
 pub struct ModuleLlvm {
     llcx: &'static mut llvm::Context,
     llmod_raw: *const llvm::Module,
index c274fa4345ab5d7a65f4f299a9c2406b6aa3a614..3f4389913ae49bad346b661eb61f8c050520f68f 100644 (file)
@@ -113,3 +113,25 @@ pub enum TypeKind {
     X86_MMX,
     Token,
 }
+
+// FIXME(mw): Anything that is produced via DepGraph::with_task() must implement
+//            the HashStable trait. Normally DepGraph::with_task() calls are
+//            hidden behind queries, but CGU creation is a special case in two
+//            ways: (1) it's not a query and (2) CGU are output nodes, so their
+//            Fingerprints are not actually needed. It remains to be clarified
+//            how exactly this case will be handled in the red/green system but
+//            for now we content ourselves with providing a no-op HashStable
+//            implementation for CGUs.
+mod temp_stable_hash_impls {
+    use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher,
+                                               HashStable};
+    use ModuleCodegen;
+
+    impl<HCX, M> HashStable<HCX> for ModuleCodegen<M> {
+        fn hash_stable<W: StableHasherResult>(&self,
+                                              _: &mut HCX,
+                                              _: &mut StableHasher<W>) {
+            // do nothing
+        }
+    }
+}
diff --git a/src/librustc_codegen_utils/interfaces/backend.rs b/src/librustc_codegen_utils/interfaces/backend.rs
new file mode 100644 (file)
index 0000000..3cdb1c6
--- /dev/null
@@ -0,0 +1,80 @@
+// Copyright 2018 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.
+
+use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout};
+use rustc::ty::Ty;
+
+use super::CodegenObject;
+use rustc::middle::allocator::AllocatorKind;
+use rustc::middle::cstore::EncodedMetadata;
+use rustc::mir::mono::Stats;
+use rustc::session::Session;
+use rustc::ty::TyCtxt;
+use rustc::util::time_graph::TimeGraph;
+use std::any::Any;
+use std::sync::mpsc::Receiver;
+use syntax_pos::symbol::InternedString;
+use ModuleCodegen;
+
+pub trait BackendTypes {
+    type Value: CodegenObject;
+    type BasicBlock: Copy;
+    type Type: CodegenObject;
+    type Context;
+    type Funclet;
+
+    type DIScope: Copy;
+}
+
+pub trait Backend<'tcx>:
+    BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+{
+}
+
+impl<'tcx, T> Backend<'tcx> for T where
+    Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf<Ty = Ty<'tcx>, TyLayout = TyLayout<'tcx>>
+{}
+
+pub trait BackendMethods {
+    type Module;
+    type OngoingCodegen;
+
+    fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Module;
+    fn write_metadata<'b, 'gcx>(
+        &self,
+        tcx: TyCtxt<'b, 'gcx, 'gcx>,
+        metadata: &Self::Module,
+    ) -> EncodedMetadata;
+    fn codegen_allocator(&self, tcx: TyCtxt, mods: &Self::Module, kind: AllocatorKind);
+
+    fn start_async_codegen(
+        &self,
+        tcx: TyCtxt,
+        time_graph: Option<TimeGraph>,
+        metadata: EncodedMetadata,
+        coordinator_receive: Receiver<Box<dyn Any + Send>>,
+        total_cgus: usize,
+    ) -> Self::OngoingCodegen;
+    fn submit_pre_codegened_module_to_llvm(
+        &self,
+        codegen: &Self::OngoingCodegen,
+        tcx: TyCtxt,
+        module: ModuleCodegen<Self::Module>,
+    );
+    fn codegen_aborted(codegen: Self::OngoingCodegen);
+    fn codegen_finished(&self, codegen: &Self::OngoingCodegen, tcx: TyCtxt);
+    fn check_for_errors(&self, codegen: &Self::OngoingCodegen, sess: &Session);
+    fn wait_for_signal_to_codegen_item(&self, codegen: &Self::OngoingCodegen);
+    fn compile_codegen_unit<'a, 'tcx: 'a>(
+        &self,
+        tcx: TyCtxt<'a, 'tcx, 'tcx>,
+        cgu_name: InternedString,
+    ) -> Stats;
+}
diff --git a/src/librustc_codegen_utils/interfaces/mod.rs b/src/librustc_codegen_utils/interfaces/mod.rs
new file mode 100644 (file)
index 0000000..f958dba
--- /dev/null
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+mod backend;
+
+pub use self::backend::{Backend, BackendMethods, BackendTypes};
+
+use std::fmt;
+
+pub trait CodegenObject: Copy + PartialEq + fmt::Debug {}
+impl<T: Copy + PartialEq + fmt::Debug> CodegenObject for T {}
index 2141a763d165a328bcaf6b88faba71f40f8b1468..4fb182e4f05402e1aae56228fc814a37de76508c 100644 (file)
@@ -21,6 +21,7 @@
 #![feature(custom_attribute)]
 #![feature(nll)]
 #![allow(unused_attributes)]
+#![allow(dead_code)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 
 
 use rustc::session::Session;
 use rustc::ty::TyCtxt;
+use rustc::dep_graph::WorkProduct;
+use rustc::session::config::{OutputFilenames, OutputType};
 
 pub mod command;
+pub mod interfaces;
 pub mod link;
 pub mod linker;
 pub mod codegen_backend;
 pub mod symbol_names_test;
 pub mod common;
 
-/// check for the #[rustc_error] annotation, which forces an
-/// error in codegen. This is used to write compile-fail tests
-/// that actually test that compilation succeeds without
-/// reporting an error.
-pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
-    if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() {
-        let main_def_id = tcx.hir.local_def_id(id);
+pub struct ModuleCodegen<M> {
+    /// The name of the module. When the crate may be saved between
+    /// compilations, incremental compilation requires that name be
+    /// unique amongst **all** crates.  Therefore, it should contain
+    /// something unique to this crate (e.g., a module path) as well
+    /// as the crate name and disambiguator.
+    /// We currently generate these names via CodegenUnit::build_cgu_name().
+    pub name: String,
+    pub module_llvm: M,
+    pub kind: ModuleKind,
+}
 
-        if tcx.has_attr(main_def_id, "rustc_error") {
-            tcx.sess.span_fatal(span, "compilation successful");
+pub const RLIB_BYTECODE_EXTENSION: &str = "bc.z";
+
+impl<M> ModuleCodegen<M> {
+    pub fn into_compiled_module(self,
+                            emit_obj: bool,
+                            emit_bc: bool,
+                            emit_bc_compressed: bool,
+                            outputs: &OutputFilenames) -> CompiledModule {
+        let object = if emit_obj {
+            Some(outputs.temp_path(OutputType::Object, Some(&self.name)))
+        } else {
+            None
+        };
+        let bytecode = if emit_bc {
+            Some(outputs.temp_path(OutputType::Bitcode, Some(&self.name)))
+        } else {
+            None
+        };
+        let bytecode_compressed = if emit_bc_compressed {
+            Some(outputs.temp_path(OutputType::Bitcode, Some(&self.name))
+                    .with_extension(RLIB_BYTECODE_EXTENSION))
+        } else {
+            None
+        };
+
+        CompiledModule {
+            name: self.name.clone(),
+            kind: self.kind,
+            object,
+            bytecode,
+            bytecode_compressed,
         }
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq)]
-pub enum ModuleKind {
-    Regular,
-    Metadata,
-    Allocator,
-}
-
 #[derive(Debug)]
 pub struct CompiledModule {
     pub name: String,
@@ -86,6 +116,32 @@ pub struct CompiledModule {
     pub bytecode_compressed: Option<PathBuf>,
 }
 
+pub struct CachedModuleCodegen {
+    pub name: String,
+    pub source: WorkProduct,
+}
+
+#[derive(Copy, Clone, Debug, PartialEq)]
+pub enum ModuleKind {
+    Regular,
+    Metadata,
+    Allocator,
+}
+
+/// check for the #[rustc_error] annotation, which forces an
+/// error in codegen. This is used to write compile-fail tests
+/// that actually test that compilation succeeds without
+/// reporting an error.
+pub fn check_for_rustc_errors_attr(tcx: TyCtxt) {
+    if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() {
+        let main_def_id = tcx.hir.local_def_id(id);
+
+        if tcx.has_attr(main_def_id, "rustc_error") {
+            tcx.sess.span_fatal(span, "compilation successful");
+        }
+    }
+}
+
 pub fn find_library(name: &str, search_paths: &[PathBuf], sess: &Session)
                     -> PathBuf {
     // On Windows, static libraries sometimes show up as libfoo.a and other