about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorTaylor Cramer <cramertj@google.com>2017-06-11 21:16:26 -0700
committerTaylor Cramer <cramertj@google.com>2017-06-13 23:10:59 -0700
commit9f710530a7c0be1acaa099b12163ec1af8b8cf30 (patch)
tree9436a2b30746e14a32545a03fdf37be8a26aeee2 /src
parente40ef964fe491b19c22dfb8dd36d1eab14223c36 (diff)
downloadrust-9f710530a7c0be1acaa099b12163ec1af8b8cf30.tar.gz
rust-9f710530a7c0be1acaa099b12163ec1af8b8cf30.zip
On-demand is_const_fn
Diffstat (limited to 'src')
-rw-r--r--src/librustc/dep_graph/dep_node.rs1
-rw-r--r--src/librustc/middle/cstore.rs2
-rw-r--r--src/librustc/ty/maps.rs9
-rw-r--r--src/librustc_const_eval/eval.rs2
-rw-r--r--src/librustc_driver/driver.rs1
-rw-r--r--src/librustc_metadata/cstore.rs2
-rw-r--r--src/librustc_metadata/cstore_impl.rs26
-rw-r--r--src/librustc_mir/transform/copy_prop.rs3
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs17
-rw-r--r--src/librustc_passes/consts.rs2
-rw-r--r--src/librustdoc/clean/inline.rs4
11 files changed, 39 insertions, 30 deletions
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index fda29ca7366..c987a37c420 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -339,6 +339,7 @@ define_dep_nodes!(
     ItemSignature(DefId),
     ItemVarianceConstraints(DefId),
     ItemVariances(DefId),
+    IsConstFn(DefId),
     IsForeignItem(DefId),
     TypeParamPredicates { item_id: DefId, param_id: DefId },
     SizedConstraint(DefId),
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 08c0adf110a..735da5ca380 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -243,7 +243,6 @@ pub trait CrateStore {
     fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem;
 
     // flags
-    fn is_const_fn(&self, did: DefId) -> bool;
     fn is_dllimport_foreign_item(&self, def: DefId) -> bool;
     fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool;
 
@@ -364,7 +363,6 @@ impl CrateStore for DummyCrateStore {
         { bug!("associated_item_cloned") }
 
     // flags
-    fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
     fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false }
     fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false }
 
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index 162a734aa19..6ee5bf1392f 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -476,6 +476,12 @@ impl<'tcx> QueryDescription for queries::is_object_safe<'tcx> {
     }
 }
 
+impl<'tcx> QueryDescription for queries::is_const_fn<'tcx> {
+    fn describe(tcx: TyCtxt, def_id: DefId) -> String {
+        format!("checking if item is const fn: `{}`", tcx.item_path_str(def_id))
+    }
+}
+
 macro_rules! define_maps {
     (<$tcx:tt>
      $($(#[$attr:meta])*
@@ -791,6 +797,9 @@ define_maps! { <'tcx>
     [] adt_sized_constraint: SizedConstraint(DefId) -> &'tcx [Ty<'tcx>],
     [] adt_dtorck_constraint: DtorckConstraint(DefId) -> ty::DtorckConstraint<'tcx>,
 
+    /// True if this is a const fn
+    [] is_const_fn: IsConstFn(DefId) -> bool,
+
     /// True if this is a foreign item (i.e., linked via `extern { ... }`).
     [] is_foreign_item: IsForeignItem(DefId) -> bool,
 
diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs
index ec7510546a0..4ce985568ce 100644
--- a/src/librustc_const_eval/eval.rs
+++ b/src/librustc_const_eval/eval.rs
@@ -351,7 +351,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
                 signal!(e, TypeckError)
             }
           } else {
-            if tcx.sess.cstore.is_const_fn(def_id) {
+            if tcx.is_const_fn(def_id) {
                 tcx.sess.cstore.item_body(tcx, def_id)
             } else {
                 signal!(e, TypeckError)
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index bca82ff9a46..ac26b04cb7a 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -899,6 +899,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
     reachable::provide(&mut local_providers);
     rustc_const_eval::provide(&mut local_providers);
     middle::region::provide(&mut local_providers);
+    cstore::provide_local(&mut local_providers);
 
     let mut extern_providers = ty::maps::Providers::default();
     cstore::provide(&mut extern_providers);
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index e572be9ffe7..4e05244e2d5 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -34,7 +34,7 @@ pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePrefere
 pub use rustc::middle::cstore::NativeLibraryKind::*;
 pub use rustc::middle::cstore::{CrateSource, LinkMeta, LibSource};
 
-pub use cstore_impl::provide;
+pub use cstore_impl::{provide, provide_local};
 
 // A map from external crate numbers (as decoded from some crate file) to
 // local crate numbers (as generated during this session). Each external
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 4cbcfe15c0c..00c1fdb177d 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -23,6 +23,7 @@ use rustc::ty::{self, TyCtxt};
 use rustc::ty::maps::Providers;
 use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE};
 use rustc::hir::map::{DefKey, DefPath, DisambiguatedDefPathData, DefPathHash};
+use rustc::hir::map::blocks::FnLikeNode;
 use rustc::hir::map::definitions::{DefPathTable, GlobalMetaDataKind};
 use rustc::util::nodemap::{NodeSet, DefIdMap};
 use rustc_back::PanicStrategy;
@@ -106,6 +107,7 @@ provide! { <'tcx> tcx, def_id, cdata
     closure_kind => { cdata.closure_kind(def_id.index) }
     closure_type => { cdata.closure_ty(def_id.index, tcx) }
     inherent_impls => { Rc::new(cdata.get_inherent_implementations_for_type(def_id.index)) }
+    is_const_fn => { cdata.is_const_fn(def_id.index) }
     is_foreign_item => { cdata.is_foreign_item(def_id.index) }
     is_default_impl => { cdata.is_default_impl(def_id.index) }
     describe_def => { cdata.get_def(def_id.index) }
@@ -131,6 +133,24 @@ provide! { <'tcx> tcx, def_id, cdata
     is_mir_available => { cdata.is_item_mir_available(def_id.index) }
 }
 
+pub fn provide_local<'tcx>(providers: &mut Providers<'tcx>) {
+    fn is_const_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool {
+        let node_id = tcx.hir.as_local_node_id(def_id)
+                             .expect("Non-local call to local provider is_const_fn");
+
+        if let Some(fn_like) = FnLikeNode::from_node(tcx.hir.get(node_id)) {
+            fn_like.constness() == hir::Constness::Const
+        } else {
+            false
+        }
+    }
+
+    *providers = Providers {
+        is_const_fn,
+        ..*providers
+    };
+}
+
 impl CrateStore for cstore::CStore {
     fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc<Any> {
         self.get_crate_data(krate)
@@ -172,12 +192,6 @@ impl CrateStore for cstore::CStore {
         self.get_crate_data(def.krate).get_associated_item(def.index)
     }
 
-    fn is_const_fn(&self, did: DefId) -> bool
-    {
-        self.read_dep_node(did);
-        self.get_crate_data(did.krate).is_const_fn(did.index)
-    }
-
     fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool
     {
         self.do_is_statically_included_foreign_item(def_id)
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index 08a4961c6cd..dec0717e9e3 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -34,7 +34,6 @@ use rustc::mir::transform::{MirPass, MirSource};
 use rustc::mir::visit::MutVisitor;
 use rustc::ty::TyCtxt;
 use util::def_use::DefUseAnalysis;
-use transform::qualify_consts;
 
 pub struct CopyPropagation;
 
@@ -55,7 +54,7 @@ impl MirPass for CopyPropagation {
                 return
             }
             MirSource::Fn(function_node_id) => {
-                if qualify_consts::is_const_fn(tcx, tcx.hir.local_def_id(function_node_id)) {
+                if tcx.is_const_fn(tcx.hir.local_def_id(function_node_id)) {
                     // Don't run on const functions, as, again, trans might not be able to evaluate
                     // the optimized IR.
                     return
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index d60e761bc0b..8342d0ff491 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -19,7 +19,6 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc::hir;
 use rustc::hir::map as hir_map;
 use rustc::hir::def_id::DefId;
-use rustc::hir::map::blocks::FnLikeNode;
 use rustc::traits::{self, Reveal};
 use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
 use rustc::ty::cast::CastTy;
@@ -109,18 +108,6 @@ impl fmt::Display for Mode {
     }
 }
 
-pub fn is_const_fn(tcx: TyCtxt, def_id: DefId) -> bool {
-    if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
-        if let Some(fn_like) = FnLikeNode::from_node(tcx.hir.get(node_id)) {
-            fn_like.constness() == hir::Constness::Const
-        } else {
-            false
-        }
-    } else {
-        tcx.sess.cstore.is_const_fn(def_id)
-    }
-}
-
 struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     mode: Mode,
     span: Span,
@@ -766,7 +753,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                 ty::TyFnDef(def_id, _, f) => {
                     (f.abi() == Abi::PlatformIntrinsic &&
                      self.tcx.item_name(def_id).as_str().starts_with("simd_shuffle"),
-                     is_const_fn(self.tcx, def_id))
+                     self.tcx.is_const_fn(def_id))
                 }
                 _ => (false, false)
             };
@@ -957,7 +944,7 @@ impl MirPass for QualifyAndPromoteConstants {
         let def_id = tcx.hir.local_def_id(id);
         let mode = match src {
             MirSource::Fn(_) => {
-                if is_const_fn(tcx, def_id) {
+                if tcx.is_const_fn(def_id) {
                     Mode::ConstFn
                 } else {
                     Mode::Fn
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs
index e539cc1ae8b..bec4c083905 100644
--- a/src/librustc_passes/consts.rs
+++ b/src/librustc_passes/consts.rs
@@ -101,7 +101,7 @@ impl<'a, 'gcx> CheckCrateVisitor<'a, 'gcx> {
                 fn_like.constness() == hir::Constness::Const
             })
         } else {
-            self.tcx.sess.cstore.is_const_fn(def_id)
+            self.tcx.is_const_fn(def_id)
         };
     }
 }
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index a5797a5224d..aeade470482 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -151,7 +151,7 @@ pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait {
 fn build_external_function(cx: &DocContext, did: DefId) -> clean::Function {
     let sig = cx.tcx.type_of(did).fn_sig();
 
-    let constness = if cx.tcx.sess.cstore.is_const_fn(did) {
+    let constness = if cx.tcx.is_const_fn(did) {
         hir::Constness::Const
     } else {
         hir::Constness::NotConst
@@ -352,7 +352,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
                     clean::TyMethodItem(clean::TyMethod {
                         unsafety, decl, generics, abi
                     }) => {
-                        let constness = if tcx.sess.cstore.is_const_fn(item.def_id) {
+                        let constness = if tcx.is_const_fn(item.def_id) {
                             hir::Constness::Const
                         } else {
                             hir::Constness::NotConst