]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/context.rs
Auto merge of #43710 - zackmdavis:field_init_shorthand_power_slam, r=Mark-Simulacrum
[rust.git] / src / librustc_trans / context.rs
index 0413b0ea5c81ccdd00ce045caeb321807daab706..8c6bd302e4bfdb51fd495938024285a04b8ba25c 100644 (file)
 use rustc::traits;
 use debuginfo;
 use callee;
+use back::symbol_export::ExportedSymbols;
 use base;
 use declare;
 use monomorphize::Instance;
 
 use partitioning::CodegenUnit;
+use trans_item::TransItem;
 use type_::Type;
 use rustc_data_structures::base_n;
+use rustc::session::config::{self, NoDebugInfo, OutputFilenames};
+use rustc::session::Session;
 use rustc::ty::subst::Substs;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::layout::{LayoutTyper, TyLayout};
-use rustc::session::config::{self, NoDebugInfo};
-use rustc::session::Session;
-use rustc::util::nodemap::{NodeSet, DefIdMap, FxHashMap};
+use rustc::ty::layout::{LayoutCx, LayoutError, LayoutTyper, TyLayout};
+use rustc::util::nodemap::{DefIdMap, FxHashMap, FxHashSet};
 
 use std::ffi::{CStr, CString};
 use std::cell::{Cell, RefCell};
 use std::ptr;
 use std::iter;
 use std::str;
+use std::sync::Arc;
 use std::marker::PhantomData;
 use syntax::ast;
 use syntax::symbol::InternedString;
@@ -76,11 +79,12 @@ pub fn extend(&mut self, stats: Stats) {
 /// crate, so it must not contain references to any LLVM data structures
 /// (aside from metadata-related ones).
 pub struct SharedCrateContext<'a, 'tcx: 'a> {
-    exported_symbols: NodeSet,
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     check_overflow: bool,
 
     use_dll_storage_attrs: bool,
+
+    output_filenames: &'a OutputFilenames,
 }
 
 /// The local portion of a `CrateContext`.  There is one `LocalCrateContext`
@@ -92,6 +96,13 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
     llcx: ContextRef,
     stats: Stats,
     codegen_unit: CodegenUnit<'tcx>,
+
+    /// The translation items of the whole crate.
+    crate_trans_items: Arc<FxHashSet<TransItem<'tcx>>>,
+
+    /// Information about which symbols are exported from the crate.
+    exported_symbols: Arc<ExportedSymbols>,
+
     /// Cache instances of monomorphic and polymorphic items
     instances: RefCell<FxHashMap<Instance<'tcx>, ValueRef>>,
     /// Cache generated vtables
@@ -263,8 +274,8 @@ pub unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (Cont
 
 impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
     pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
-               exported_symbols: NodeSet,
-               check_overflow: bool)
+               check_overflow: bool,
+               output_filenames: &'b OutputFilenames)
                -> SharedCrateContext<'b, 'tcx> {
         // An interesting part of Windows which MSVC forces our hand on (and
         // apparently MinGW didn't) is the usage of `dllimport` and `dllexport`
@@ -312,27 +323,23 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
         let use_dll_storage_attrs = tcx.sess.target.target.options.is_like_msvc;
 
         SharedCrateContext {
-            exported_symbols: exported_symbols,
-            tcx: tcx,
-            check_overflow: check_overflow,
-            use_dll_storage_attrs: use_dll_storage_attrs,
+            tcx,
+            check_overflow,
+            use_dll_storage_attrs,
+            output_filenames,
         }
     }
 
     pub fn type_needs_drop(&self, ty: Ty<'tcx>) -> bool {
-        ty.needs_drop(self.tcx, ty::ParamEnv::empty())
+        ty.needs_drop(self.tcx, ty::ParamEnv::empty(traits::Reveal::All))
     }
 
     pub fn type_is_sized(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_sized(self.tcx, ty::ParamEnv::empty(), DUMMY_SP)
+        ty.is_sized(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP)
     }
 
     pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool {
-        ty.is_freeze(self.tcx, ty::ParamEnv::empty(), DUMMY_SP)
-    }
-
-    pub fn exported_symbols<'a>(&'a self) -> &'a NodeSet {
-        &self.exported_symbols
+        ty.is_freeze(self.tcx, ty::ParamEnv::empty(traits::Reveal::All), DUMMY_SP)
     }
 
     pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
@@ -350,11 +357,17 @@ pub fn dep_graph<'a>(&'a self) -> &'a DepGraph {
     pub fn use_dll_storage_attrs(&self) -> bool {
         self.use_dll_storage_attrs
     }
+
+    pub fn output_filenames(&self) -> &OutputFilenames {
+        self.output_filenames
+    }
 }
 
 impl<'a, 'tcx> LocalCrateContext<'a, 'tcx> {
     pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
-               codegen_unit: CodegenUnit<'tcx>)
+               codegen_unit: CodegenUnit<'tcx>,
+               crate_trans_items: Arc<FxHashSet<TransItem<'tcx>>>,
+               exported_symbols: Arc<ExportedSymbols>,)
                -> LocalCrateContext<'a, 'tcx> {
         unsafe {
             // Append ".rs" to LLVM module identifier.
@@ -382,10 +395,12 @@ pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
             };
 
             let local_ccx = LocalCrateContext {
-                llmod: llmod,
-                llcx: llcx,
+                llmod,
+                llcx,
                 stats: Stats::default(),
-                codegen_unit: codegen_unit,
+                codegen_unit,
+                crate_trans_items,
+                exported_symbols,
                 instances: RefCell::new(FxHashMap()),
                 vtables: RefCell::new(FxHashMap()),
                 const_cstr_cache: RefCell::new(FxHashMap()),
@@ -401,7 +416,7 @@ pub fn new(shared: &SharedCrateContext<'a, 'tcx>,
                 int_type: Type::from_ref(ptr::null_mut()),
                 opaque_vec_type: Type::from_ref(ptr::null_mut()),
                 str_slice_type: Type::from_ref(ptr::null_mut()),
-                dbg_cx: dbg_cx,
+                dbg_cx,
                 eh_personality: Cell::new(None),
                 eh_unwind_resume: Cell::new(None),
                 rust_try_fn: Cell::new(None),
@@ -447,7 +462,7 @@ fn dummy_ccx(shared: &'a SharedCrateContext<'a, 'tcx>,
                  -> CrateContext<'a, 'tcx> {
         assert!(local_ccxs.len() == 1);
         CrateContext {
-            shared: shared,
+            shared,
             local_ccx: &local_ccxs[0]
         }
     }
@@ -496,6 +511,14 @@ pub fn codegen_unit(&self) -> &CodegenUnit<'tcx> {
         &self.local().codegen_unit
     }
 
+    pub fn crate_trans_items(&self) -> &FxHashSet<TransItem<'tcx>> {
+        &self.local().crate_trans_items
+    }
+
+    pub fn exported_symbols(&self) -> &ExportedSymbols {
+        &self.local().exported_symbols
+    }
+
     pub fn td(&self) -> llvm::TargetDataRef {
         unsafe { llvm::LLVMRustGetModuleDataLayout(self.llmod()) }
     }
@@ -709,41 +732,27 @@ fn data_layout(&self) -> &ty::layout::TargetDataLayout {
     }
 }
 
-impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a SharedCrateContext<'a, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
-        self.tcx
-    }
-}
-
 impl<'a, 'tcx> ty::layout::HasDataLayout for &'a CrateContext<'a, 'tcx> {
     fn data_layout(&self) -> &ty::layout::TargetDataLayout {
         &self.shared.tcx.data_layout
     }
 }
 
-impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a CrateContext<'a, 'tcx> {
-    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
-        self.shared.tcx
-    }
-}
-
 impl<'a, 'tcx> LayoutTyper<'tcx> for &'a SharedCrateContext<'a, 'tcx> {
     type TyLayout = TyLayout<'tcx>;
 
-    fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
-        if let Some(&layout) = self.tcx().layout_cache.borrow().get(&ty) {
-            return TyLayout { ty: ty, layout: layout, variant_index: None };
-        }
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
+        self.tcx
+    }
 
-        self.tcx().infer_ctxt((), traits::Reveal::All).enter(|infcx| {
-            infcx.layout_of(ty).unwrap_or_else(|e| {
-                match e {
-                    ty::layout::LayoutError::SizeOverflow(_) =>
-                        self.sess().fatal(&e.to_string()),
-                    _ => bug!("failed to get layout for `{}`: {}", ty, e)
-                }
+    fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
+        let param_env = ty::ParamEnv::empty(traits::Reveal::All);
+        LayoutCx::new(self.tcx, param_env)
+            .layout_of(ty)
+            .unwrap_or_else(|e| match e {
+                LayoutError::SizeOverflow(_) => self.sess().fatal(&e.to_string()),
+                _ => bug!("failed to get layout for `{}`: {}", ty, e)
             })
-        })
     }
 
     fn normalize_projections(self, ty: Ty<'tcx>) -> Ty<'tcx> {
@@ -754,6 +763,10 @@ fn normalize_projections(self, ty: Ty<'tcx>) -> Ty<'tcx> {
 impl<'a, 'tcx> LayoutTyper<'tcx> for &'a CrateContext<'a, 'tcx> {
     type TyLayout = TyLayout<'tcx>;
 
+    fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
+        self.shared.tcx
+    }
+
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
         self.shared.layout_of(ty)
     }