On-demand is_const_fn
This commit is contained in:
parent
e40ef964fe
commit
9f710530a7
@ -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),
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -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,
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user