Prepare for using miri in trans

This commit is contained in:
Alexander Regueiro 2018-01-02 23:22:09 +00:00 committed by Oliver Schneider
parent 4c9b1b13dd
commit b2b101befc
No known key found for this signature in database
GPG key ID: A69F8D225B3AD7D9
18 changed files with 286 additions and 130 deletions

View file

@ -60,15 +60,15 @@
//! user of the `DepNode` API of having to know how to compute the expected
//! fingerprint for a given set of node parameters.
use mir::interpret::{GlobalId};
use hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
use hir::map::DefPathHash;
use hir::{HirId, ItemLocalId};
use ich::Fingerprint;
use ich::{Fingerprint, StableHashingContext};
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty};
use ty::subst::Substs;
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
use ich::StableHashingContext;
use std::fmt;
use std::hash::Hash;
use syntax_pos::symbol::InternedString;
@ -518,7 +518,7 @@ define_dep_nodes!( <'tcx>
[] TypeckTables(DefId),
[] UsedTraitImports(DefId),
[] HasTypeckTables(DefId),
[] ConstEval { param_env: ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)> },
[] ConstEval { param_env: ParamEnvAnd<'tcx, GlobalId<'tcx>> },
[] CheckMatch(DefId),
[] SymbolName(DefId),
[] InstanceSymbolName { instance: Instance<'tcx> },

View file

@ -585,3 +585,5 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for mir::ClosureOutlivesSubjec
}
}
}
impl_stable_hash_for!(struct mir::interpret::GlobalId<'tcx> { instance, promoted });

View file

@ -926,13 +926,13 @@ impl<'gcx> HashStable<StableHashingContext<'gcx>> for ty::InstanceDef<'gcx> {
ty::InstanceDef::ClosureOnceShim { call_once } => {
call_once.hash_stable(hcx, hasher);
}
ty::InstanceDef::DropGlue(def_id, t) => {
ty::InstanceDef::DropGlue(def_id, ty) => {
def_id.hash_stable(hcx, hasher);
t.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
ty::InstanceDef::CloneShim(def_id, t) => {
ty::InstanceDef::CloneShim(def_id, ty) => {
def_id.hash_stable(hcx, hasher);
t.hash_stable(hcx, hasher);
ty.hash_stable(hcx, hasher);
}
}
}

View file

@ -9,6 +9,9 @@
// except according to those terms.
use infer::{RegionObligation, InferCtxt};
use middle::const_val::ConstEvalErr;
use middle::const_val::ErrKind::TypeckError;
use mir::interpret::GlobalId;
use ty::{self, Ty, TypeFoldable, ToPolyTraitRef, ToPredicate};
use ty::error::ExpectedFound;
use rustc_data_structures::obligation_forest::{ObligationForest, Error};
@ -514,17 +517,34 @@ fn process_predicate<'a, 'gcx, 'tcx>(
}
Some(param_env) => {
match selcx.tcx().lift_to_global(&substs) {
Some(substs) => {
let instance = ty::Instance::resolve(
selcx.tcx().global_tcx(),
param_env,
def_id,
substs,
);
if let Some(instance) = instance {
let cid = GlobalId {
instance,
promoted: None,
};
match selcx.tcx().at(obligation.cause.span)
.const_eval(param_env.and(cid)) {
Ok(_) => Ok(Some(vec![])),
Err(e) => Err(CodeSelectionError(ConstEvalFailure(e)))
}
} else {
Err(CodeSelectionError(ConstEvalFailure(ConstEvalErr {
span: selcx.tcx().def_span(def_id),
kind: TypeckError,
})))
}
},
None => {
pending_obligation.stalled_on = substs.types().collect();
Ok(None)
}
Some(substs) => {
match selcx.tcx().at(obligation.cause.span)
.const_eval(param_env.and((def_id, substs))) {
Ok(_) => Ok(Some(vec![])),
Err(e) => Err(CodeSelectionError(ConstEvalFailure(e)))
}
}
}
}
}

View file

@ -29,6 +29,7 @@ use hir::def_id::DefId;
use infer::{InferCtxt, InferOk};
use infer::type_variable::TypeVariableOrigin;
use middle::const_val::ConstVal;
use mir::interpret::{GlobalId};
use rustc_data_structures::snapshot_map::{Snapshot, SnapshotMap};
use syntax::symbol::Symbol;
use ty::subst::{Subst, Substs};
@ -400,12 +401,17 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
if let ConstVal::Unevaluated(def_id, substs) = constant.val {
if substs.needs_infer() {
let identity_substs = Substs::identity_for_item(self.tcx(), def_id);
let data = self.param_env.and((def_id, identity_substs));
match self.tcx().lift_to_global(&data) {
Some(data) => {
match self.tcx().const_eval(data) {
let tcx = self.selcx.tcx().global_tcx();
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
if substs.needs_infer() {
let identity_substs = Substs::identity_for_item(tcx, def_id);
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
if let Some(instance) = instance {
let cid = GlobalId {
instance,
promoted: None
};
match tcx.const_eval(param_env.and(cid)) {
Ok(evaluated) => {
let evaluated = evaluated.subst(self.tcx(), substs);
return self.fold_const(evaluated);
@ -413,18 +419,20 @@ impl<'a, 'b, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for AssociatedTypeNormalizer<'a,
Err(_) => {}
}
}
None => {}
}
} else {
let data = self.param_env.and((def_id, substs));
match self.tcx().lift_to_global(&data) {
Some(data) => {
match self.tcx().const_eval(data) {
Ok(evaluated) => return self.fold_const(evaluated),
Err(_) => {}
} else {
if let Some(substs) = self.tcx().lift_to_global(&substs) {
let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
if let Some(instance) = instance {
let cid = GlobalId {
instance,
promoted: None
};
match tcx.const_eval(param_env.and(cid)) {
Ok(evaluated) => return self.fold_const(evaluated),
Err(_) => {}
}
}
}
None => {}
}
}
}

View file

@ -42,6 +42,7 @@ use ty::{self, ToPredicate, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
use ty::fast_reject;
use ty::relate::TypeRelation;
use middle::lang_items;
use mir::interpret::{GlobalId};
use rustc_data_structures::bitvec::BitVector;
use std::iter;
@ -732,11 +733,26 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
}
ty::Predicate::ConstEvaluatable(def_id, substs) => {
match self.tcx().lift_to_global(&(obligation.param_env, substs)) {
let tcx = self.tcx();
match tcx.lift_to_global(&(obligation.param_env, substs)) {
Some((param_env, substs)) => {
match self.tcx().const_eval(param_env.and((def_id, substs))) {
Ok(_) => EvaluatedToOk,
Err(_) => EvaluatedToErr
let instance = ty::Instance::resolve(
tcx.global_tcx(),
param_env,
def_id,
substs,
);
if let Some(instance) = instance {
let cid = GlobalId {
instance,
promoted: None
};
match self.tcx().const_eval(param_env.and(cid)) {
Ok(_) => EvaluatedToOk,
Err(_) => EvaluatedToErr
}
} else {
EvaluatedToErr
}
}
None => {

View file

@ -10,9 +10,10 @@
use dep_graph::SerializedDepNodeIndex;
use hir::def_id::{CrateNum, DefId, DefIndex};
use mir::interpret::{GlobalId};
use ty::{self, Ty, TyCtxt};
use ty::maps::queries;
use ty::subst::Substs;
use ty::maps::queries;
use std::hash::Hash;
use syntax_pos::symbol::InternedString;
@ -152,8 +153,8 @@ impl<'tcx> QueryDescription<'tcx> for queries::reachable_set<'tcx> {
}
impl<'tcx> QueryDescription<'tcx> for queries::const_eval<'tcx> {
fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>) -> String {
format!("const-evaluating `{}`", tcx.item_path_str(key.value.0))
fn describe(tcx: TyCtxt, key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>) -> String {
format!("const-evaluating `{}`", tcx.item_path_str(key.value.instance.def.def_id()))
}
}

View file

@ -53,6 +53,16 @@ impl<'tcx> Key for ty::Instance<'tcx> {
}
}
impl<'tcx> Key for mir::interpret::GlobalId<'tcx> {
fn map_crate(&self) -> CrateNum {
self.instance.map_crate()
}
fn default_span(&self, tcx: TyCtxt) -> Span {
self.instance.default_span(tcx)
}
}
impl Key for CrateNum {
fn map_crate(&self) -> CrateNum {
*self

View file

@ -29,6 +29,7 @@ use middle::lang_items::{LanguageItems, LangItem};
use middle::exported_symbols::{SymbolExportLevel, ExportedSymbol};
use mir::mono::{CodegenUnit, Stats};
use mir;
use mir::interpret::{GlobalId};
use session::{CompileResult, CrateDisambiguator};
use session::config::OutputFilenames;
use traits::Vtable;
@ -210,7 +211,7 @@ define_maps! { <'tcx>
/// Results of evaluating const items or constants embedded in
/// other items (such as enum variant explicit discriminants).
[] fn const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>)
[] fn const_eval: const_eval_dep_node(ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-> const_val::EvalResult<'tcx>,
[] fn check_match: CheckMatch(DefId)
@ -450,7 +451,7 @@ fn typeck_item_bodies_dep_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
DepConstructor::TypeckBodiesKrate
}
fn const_eval_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, (DefId, &'tcx Substs<'tcx>)>)
fn const_eval_dep_node<'tcx>(param_env: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
-> DepConstructor<'tcx> {
DepConstructor::ConstEval { param_env }
}

View file

@ -26,7 +26,7 @@ use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangIte
use middle::privacy::AccessLevels;
use middle::resolve_lifetime::ObjectLifetimeDefault;
use mir::Mir;
use mir::interpret::{Value, PrimVal};
use mir::interpret::{GlobalId, Value, PrimVal};
use mir::GeneratorLayout;
use session::CrateDisambiguator;
use traits;
@ -1835,7 +1835,12 @@ impl<'a, 'gcx, 'tcx> AdtDef {
let mut discr = prev_discr.map_or(initial, |d| d.wrap_incr());
if let VariantDiscr::Explicit(expr_did) = v.discr {
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
match tcx.const_eval(param_env.and((expr_did, substs))) {
let instance = ty::Instance::new(expr_did, substs);
let cid = GlobalId {
instance,
promoted: None
};
match tcx.const_eval(param_env.and(cid)) {
Ok(&ty::Const {
val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(b))),
..
@ -1885,7 +1890,12 @@ impl<'a, 'gcx, 'tcx> AdtDef {
}
ty::VariantDiscr::Explicit(expr_did) => {
let substs = Substs::identity_for_item(tcx.global_tcx(), expr_did);
match tcx.const_eval(param_env.and((expr_did, substs))) {
let instance = ty::Instance::new(expr_did, substs);
let cid = GlobalId {
instance,
promoted: None
};
match tcx.const_eval(param_env.and(cid)) {
Ok(&ty::Const {
val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(b))),
..

View file

@ -20,7 +20,7 @@ use ty::subst::{UnpackedKind, Substs};
use ty::{self, Ty, TyCtxt, TypeFoldable};
use ty::fold::{TypeVisitor, TypeFolder};
use ty::error::{ExpectedFound, TypeError};
use mir::interpret::{Value, PrimVal};
use mir::interpret::{GlobalId, Value, PrimVal};
use util::common::ErrorReported;
use std::rc::Rc;
use std::iter;
@ -489,17 +489,29 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
match tcx.lift_to_global(&substs) {
Some(substs) => {
match tcx.const_eval(param_env.and((def_id, substs))) {
Ok(&ty::Const {
val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(b))),
..
}) => {
assert_eq!(b as u64 as u128, b);
return Ok(b as u64);
let instance = ty::Instance::resolve(
tcx.global_tcx(),
param_env,
def_id,
substs,
);
if let Some(instance) = instance {
let cid = GlobalId {
instance,
promoted: None
};
match tcx.const_eval(param_env.and(cid)) {
Ok(&ty::Const {
val: ConstVal::Value(Value::ByVal(PrimVal::Bytes(b))),
..
}) => {
assert_eq!(b as u64 as u128, b);
return Ok(b as u64);
}
_ => {}
}
_ => {}
}
}
},
None => {}
}
tcx.sess.delay_span_bug(tcx.def_span(def_id),

View file

@ -57,6 +57,7 @@ CopyImpls! {
::syntax::abi::Abi,
::hir::def_id::DefId,
::mir::Local,
::mir::Promoted,
::traits::Reveal,
::syntax_pos::Span,
}
@ -589,7 +590,7 @@ impl<'a, 'tcx> Lift<'tcx> for ConstEvalErr<'a> {
impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
type Lifted = interpret::EvalError<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
use mir::interpret::EvalErrorKind::*;
use ::mir::interpret::EvalErrorKind::*;
let kind = match self.kind {
MachineError(ref err) => MachineError(err.clone()),
FunctionPointerTyMismatch(a, b) => FunctionPointerTyMismatch(
@ -744,6 +745,42 @@ impl<'a, 'tcx> Lift<'tcx> for ty::layout::LayoutError<'a> {
}
}
impl<'a, 'tcx> Lift<'tcx> for ty::InstanceDef<'a> {
type Lifted = ty::InstanceDef<'tcx>;
fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<Self::Lifted> {
match *self {
ty::InstanceDef::Item(def_id) =>
Some(ty::InstanceDef::Item(def_id)),
ty::InstanceDef::Intrinsic(def_id) =>
Some(ty::InstanceDef::Intrinsic(def_id)),
ty::InstanceDef::FnPtrShim(def_id, ref ty) =>
Some(ty::InstanceDef::FnPtrShim(def_id, tcx.lift(ty)?)),
ty::InstanceDef::Virtual(def_id, n) =>
Some(ty::InstanceDef::Virtual(def_id, n)),
ty::InstanceDef::ClosureOnceShim { call_once } =>
Some(ty::InstanceDef::ClosureOnceShim { call_once }),
ty::InstanceDef::DropGlue(def_id, ref ty) =>
Some(ty::InstanceDef::DropGlue(def_id, tcx.lift(ty)?)),
ty::InstanceDef::CloneShim(def_id, ref ty) =>
Some(ty::InstanceDef::CloneShim(def_id, tcx.lift(ty)?)),
}
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for ty::Instance<'a> {
type Lifted = ty::Instance<'tcx>;
def, substs
}
}
BraceStructLiftImpl! {
impl<'a, 'tcx> Lift<'tcx> for interpret::GlobalId<'a> {
type Lifted = interpret::GlobalId<'tcx>;
instance, promoted
}
}
///////////////////////////////////////////////////////////////////////////
// TypeFoldable implementations.
//
@ -945,6 +982,19 @@ impl<'tcx> TypeFoldable<'tcx> for ty::instance::Instance<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for interpret::GlobalId<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
Self {
instance: self.instance.fold_with(folder),
promoted: self.promoted
}
}
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
self.instance.visit_with(visitor)
}
}
impl<'tcx> TypeFoldable<'tcx> for Ty<'tcx> {
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
let sty = match self.sty {