On-demand is_const_fn

This commit is contained in:
Taylor Cramer 2017-06-11 21:16:26 -07:00
parent e40ef964fe
commit 9f710530a7
11 changed files with 39 additions and 30 deletions

View File

@ -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),

View File

@ -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 }

View File

@ -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,

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)
};
}
}

View File

@ -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