]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_trans/trans_item.rs
avoid translating roots with predicates that do not hold
[rust.git] / src / librustc_trans / trans_item.rs
index de35d1b7dd4c96330d46d06e479386e179c27a32..6e8b2e0a2a6bafa69eefee375c770b500e85686b 100644 (file)
 use declare;
 use llvm;
 use monomorphize::Instance;
-use rustc::dep_graph::DepNode;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
+use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc::ty::subst::Substs;
+use rustc::ty::subst::{Subst, Substs};
 use syntax::ast::{self, NodeId};
 use syntax::attr;
+use syntax_pos::Span;
+use syntax_pos::symbol::Symbol;
 use type_of;
-use back::symbol_names;
 use std::fmt::Write;
 use std::iter;
 
@@ -62,26 +63,15 @@ pub fn define(&self, ccx: &CrateContext<'a, 'tcx>) {
                   self.to_raw_string(),
                   ccx.codegen_unit().name());
 
-        // (*) This code executes in the context of a dep-node for the
-        // entire CGU. In some cases, we introduce dep-nodes for
-        // particular items that we are translating (these nodes will
-        // have read edges coming into the CGU node). These smaller
-        // nodes are not needed for correctness -- we always
-        // invalidate an entire CGU at a time -- but they enable
-        // finer-grained testing, since you can write tests that check
-        // that the incoming edges to a particular fn are from a
-        // particular set.
-
         match *self {
             TransItem::Static(node_id) => {
-                let def_id = ccx.tcx().hir.local_def_id(node_id);
-                let _task = ccx.tcx().dep_graph.in_task(DepNode::TransCrateItem(def_id)); // (*)
-                let item = ccx.tcx().hir.expect_item(node_id);
+                let tcx = ccx.tcx();
+                let item = tcx.hir.expect_item(node_id);
                 if let hir::ItemStatic(_, m, _) = item.node {
                     match consts::trans_static(&ccx, m, item.id, &item.attrs) {
                         Ok(_) => { /* Cool, everything's alright. */ },
                         Err(err) => {
-                            err.report(ccx.tcx(), item.span, "static");
+                            err.report(tcx, item.span, "static");
                         }
                     };
                 } else {
@@ -97,9 +87,6 @@ pub fn define(&self, ccx: &CrateContext<'a, 'tcx>) {
                 }
             }
             TransItem::Fn(instance) => {
-                let _task = ccx.tcx().dep_graph.in_task(
-                    DepNode::TransCrateItem(instance.def_id())); // (*)
-
                 base::trans_instance(&ccx, instance);
             }
         }
@@ -118,7 +105,7 @@ pub fn predefine(&self,
                self.to_raw_string(),
                ccx.codegen_unit().name());
 
-        let symbol_name = ccx.symbol_cache().get(*self);
+        let symbol_name = self.symbol_name(ccx.tcx());
 
         debug!("symbol {}", &symbol_name);
 
@@ -184,20 +171,34 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>,
         ccx.instances().borrow_mut().insert(instance, lldecl);
     }
 
-    pub fn compute_symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
+    pub fn symbol_name(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::SymbolName {
         match *self {
-            TransItem::Fn(instance) => symbol_names::symbol_name(instance, tcx),
+            TransItem::Fn(instance) => tcx.symbol_name(instance),
             TransItem::Static(node_id) => {
                 let def_id = tcx.hir.local_def_id(node_id);
-                symbol_names::symbol_name(Instance::mono(tcx, def_id), tcx)
+                tcx.symbol_name(Instance::mono(tcx, def_id))
             }
             TransItem::GlobalAsm(node_id) => {
                 let def_id = tcx.hir.local_def_id(node_id);
-                format!("global_asm_{:?}", def_id)
+                ty::SymbolName {
+                    name: Symbol::intern(&format!("global_asm_{:?}", def_id)).as_str()
+                }
             }
         }
     }
 
+    pub fn local_span(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<Span> {
+        match *self {
+            TransItem::Fn(Instance { def, .. }) => {
+                tcx.hir.as_local_node_id(def.def_id())
+            }
+            TransItem::Static(node_id) |
+            TransItem::GlobalAsm(node_id) => {
+                Some(node_id)
+            }
+        }.map(|node_id| tcx.hir.span(node_id))
+    }
+
     pub fn instantiation_mode(&self,
                               tcx: TyCtxt<'a, 'tcx, 'tcx>)
                               -> InstantiationMode {
@@ -250,6 +251,21 @@ pub fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option<llvm::Link
         }
     }
 
+    /// Returns whether this instance is instantiable - whether it has no unsatisfied
+    /// predicates.
+    pub fn is_instantiable(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
+        debug!("is_instantiable({:?})", self);
+        let (def_id, substs) = match *self {
+            TransItem::Fn(ref instance) => (instance.def_id(), instance.substs),
+            TransItem::Static(node_id) => (tcx.hir.local_def_id(node_id), Substs::empty()),
+            // global asm never has predicates
+            TransItem::GlobalAsm(..) => return true
+        };
+
+        let predicates = tcx.predicates_of(def_id).predicates.subst(tcx, substs);
+        traits::normalize_and_test_predicates(tcx, predicates)
+    }
+
     pub fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String {
         let hir_map = &tcx.hir;
 
@@ -444,7 +460,7 @@ pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String) {
             },
             ty::TyClosure(def_id, ref closure_substs) => {
                 self.push_def_path(def_id, output);
-                let generics = self.tcx.item_generics(self.tcx.closure_base_def_id(def_id));
+                let generics = self.tcx.generics_of(self.tcx.closure_base_def_id(def_id));
                 let substs = closure_substs.substs.truncate_to(self.tcx, generics);
                 self.push_type_params(substs, iter::empty(), output);
             }