mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Compute the ParamEnv only once and use it to call tcx.const_eval
This commit is contained in:
parent
a678044c77
commit
64fbf5d5ad
@ -61,7 +61,7 @@ pub fn eval_body_with_mir<'a, 'mir, 'tcx>(
|
||||
mir: &'mir mir::Mir<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Option<(Value, Pointer, Ty<'tcx>)> {
|
||||
let (res, ecx) = eval_body_and_ecx(tcx, cid, Some(mir), param_env);
|
||||
let (res, ecx, _) = eval_body_and_ecx(tcx, cid, Some(mir), param_env);
|
||||
match res {
|
||||
Ok(val) => Some(val),
|
||||
Err(mut err) => {
|
||||
@ -76,7 +76,7 @@ pub fn eval_body<'a, 'tcx>(
|
||||
cid: GlobalId<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> Option<(Value, Pointer, Ty<'tcx>)> {
|
||||
let (res, ecx) = eval_body_and_ecx(tcx, cid, None, param_env);
|
||||
let (res, ecx, _) = eval_body_and_ecx(tcx, cid, None, param_env);
|
||||
match res {
|
||||
Ok(val) => Some(val),
|
||||
Err(mut err) => {
|
||||
@ -91,9 +91,12 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
|
||||
cid: GlobalId<'tcx>,
|
||||
mir: Option<&'mir mir::Mir<'tcx>>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> (EvalResult<'tcx, (Value, Pointer, Ty<'tcx>)>, EvalContext<'a, 'mir, 'tcx, CompileTimeEvaluator>) {
|
||||
) -> (EvalResult<'tcx, (Value, Pointer, Ty<'tcx>)>, EvalContext<'a, 'mir, 'tcx, CompileTimeEvaluator>, Span) {
|
||||
debug!("eval_body: {:?}, {:?}", cid, param_env);
|
||||
let mut ecx = EvalContext::new(tcx, param_env, CompileTimeEvaluator, ());
|
||||
// we start out with the best span we have
|
||||
// and try improving it down the road when more information is available
|
||||
let mut span = tcx.def_span(cid.instance.def_id());
|
||||
let res = (|| {
|
||||
let mut mir = match mir {
|
||||
Some(mir) => mir,
|
||||
@ -102,6 +105,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
|
||||
if let Some(index) = cid.promoted {
|
||||
mir = &mir.promoted[index];
|
||||
}
|
||||
span = mir.span;
|
||||
let layout = ecx.layout_of(mir.return_ty().subst(tcx, cid.instance.substs))?;
|
||||
let alloc = tcx.interpret_interner.get_cached(cid.instance.def_id());
|
||||
let alloc = match alloc {
|
||||
@ -120,8 +124,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
|
||||
if tcx.is_static(cid.instance.def_id()).is_some() {
|
||||
tcx.interpret_interner.cache(cid.instance.def_id(), ptr.alloc_id);
|
||||
}
|
||||
let span = tcx.def_span(cid.instance.def_id());
|
||||
let internally_mutable = !layout.ty.is_freeze(tcx, param_env, span);
|
||||
let internally_mutable = !layout.ty.is_freeze(tcx, param_env, mir.span);
|
||||
let mutability = tcx.is_static(cid.instance.def_id());
|
||||
let mutability = if mutability == Some(hir::Mutability::MutMutable) || internally_mutable {
|
||||
Mutability::Mutable
|
||||
@ -152,7 +155,7 @@ fn eval_body_and_ecx<'a, 'mir, 'tcx>(
|
||||
};
|
||||
Ok((value, ptr, layout.ty))
|
||||
})();
|
||||
(res, ecx)
|
||||
(res, ecx, span)
|
||||
}
|
||||
|
||||
pub struct CompileTimeEvaluator;
|
||||
@ -499,7 +502,7 @@ pub fn const_eval_provider<'a, 'tcx>(
|
||||
}
|
||||
};
|
||||
|
||||
let (res, ecx) = eval_body_and_ecx(tcx, cid, None, key.param_env);
|
||||
let (res, ecx, span) = eval_body_and_ecx(tcx, cid, None, key.param_env);
|
||||
res.map(|(miri_value, _, miri_ty)| {
|
||||
tcx.mk_const(ty::Const {
|
||||
val: ConstVal::Value(miri_value),
|
||||
@ -509,7 +512,6 @@ pub fn const_eval_provider<'a, 'tcx>(
|
||||
if tcx.is_static(def_id).is_some() {
|
||||
ecx.report(&mut err, true, None);
|
||||
}
|
||||
let span = ecx.frame().span;
|
||||
ConstEvalErr {
|
||||
kind: err.into(),
|
||||
span,
|
||||
|
@ -21,11 +21,12 @@ use rustc::ty::layout::LayoutOf;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::ty::{TyCtxt, self, Instance};
|
||||
use rustc::mir::interpret::{Value, PrimVal, GlobalId};
|
||||
use interpret::{eval_body_with_mir, eval_body, mk_borrowck_eval_cx, unary_op, ValTy};
|
||||
use interpret::{eval_body_with_mir, mk_borrowck_eval_cx, unary_op, ValTy};
|
||||
use transform::{MirPass, MirSource};
|
||||
use syntax::codemap::Span;
|
||||
use rustc::ty::subst::Substs;
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc::ty::ParamEnv;
|
||||
|
||||
pub struct ConstProp;
|
||||
|
||||
@ -56,6 +57,7 @@ struct ConstPropagator<'b, 'a, 'tcx:'a+'b> {
|
||||
source: MirSource,
|
||||
places: IndexVec<Local, Option<Const<'tcx>>>,
|
||||
can_const_prop: IndexVec<Local, bool>,
|
||||
param_env: ParamEnv<'tcx>,
|
||||
}
|
||||
|
||||
impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
|
||||
@ -64,24 +66,40 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource,
|
||||
) -> ConstPropagator<'b, 'a, 'tcx> {
|
||||
let param_env = tcx.param_env(source.def_id);
|
||||
ConstPropagator {
|
||||
mir,
|
||||
tcx,
|
||||
source,
|
||||
param_env,
|
||||
can_const_prop: CanConstProp::check(mir),
|
||||
places: IndexVec::from_elem(None, &mir.local_decls),
|
||||
}
|
||||
}
|
||||
|
||||
fn const_eval(&self, cid: GlobalId<'tcx>, span: Span) -> Option<Const<'tcx>> {
|
||||
let value = match self.tcx.const_eval(self.param_env.and(cid)) {
|
||||
Ok(val) => val,
|
||||
// FIXME: report some errors
|
||||
Err(_) => return None,
|
||||
};
|
||||
let val = match value.val {
|
||||
ConstVal::Value(v) => v,
|
||||
_ => bug!("eval produced: {:?}", value),
|
||||
};
|
||||
let val = (val, value.ty, span);
|
||||
trace!("evaluated {:?} to {:?}", cid, val);
|
||||
Some(val)
|
||||
}
|
||||
|
||||
fn eval_constant(&mut self, c: &Constant<'tcx>) -> Option<Const<'tcx>> {
|
||||
match c.literal {
|
||||
Literal::Value { value } => match value.val {
|
||||
ConstVal::Value(v) => Some((v, value.ty, c.span)),
|
||||
ConstVal::Unevaluated(did, substs) => {
|
||||
let param_env = self.tcx.param_env(self.source.def_id);
|
||||
let instance = Instance::resolve(
|
||||
self.tcx,
|
||||
param_env,
|
||||
self.param_env,
|
||||
did,
|
||||
substs,
|
||||
)?;
|
||||
@ -89,10 +107,7 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
let (value, _, ty) = eval_body(self.tcx, cid, param_env)?;
|
||||
let val = (value, ty, c.span);
|
||||
trace!("evaluated {:?} to {:?}", c, val);
|
||||
Some(val)
|
||||
self.const_eval(cid, c.span)
|
||||
},
|
||||
},
|
||||
// evaluate the promoted and replace the constant with the evaluated result
|
||||
@ -108,8 +123,9 @@ impl<'b, 'a, 'tcx:'b> ConstPropagator<'b, 'a, 'tcx> {
|
||||
instance,
|
||||
promoted: Some(index),
|
||||
};
|
||||
let param_env = self.tcx.param_env(self.source.def_id);
|
||||
let (value, _, ty) = eval_body_with_mir(self.tcx, cid, self.mir, param_env)?;
|
||||
// cannot use `const_eval` here, because that would require having the MIR
|
||||
// for the current function available, but we're producing said MIR right now
|
||||
let (value, _, ty) = eval_body_with_mir(self.tcx, cid, self.mir, self.param_env)?;
|
||||
let val = (value, ty, c.span);
|
||||
trace!("evaluated {:?} to {:?}", c, val);
|
||||
Some(val)
|
||||
|
Loading…
Reference in New Issue
Block a user