diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 4ab5c9cc1c4..67d63e52b2b 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -49,17 +49,6 @@ pub(crate) fn mk_eval_cx<'mir, 'tcx>( InterpCx::new(tcx.at(span), param_env, CompileTimeInterpreter::new(), Default::default()) } -pub(crate) fn eval_promoted<'mir, 'tcx>( - tcx: TyCtxt<'tcx>, - cid: GlobalId<'tcx>, - body: &'mir mir::Body<'tcx>, - param_env: ty::ParamEnv<'tcx>, -) -> InterpResult<'tcx, MPlaceTy<'tcx>> { - let span = tcx.def_span(cid.instance.def_id()); - let mut ecx = mk_eval_cx(tcx, span, param_env); - eval_body_using_ecx(&mut ecx, cid, body, param_env) -} - fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, 'tcx>, op: OpTy<'tcx>, @@ -360,7 +349,7 @@ fn find_fn( } } // This is a const fn. Call it. - Ok(Some(match ecx.load_mir(instance.def) { + Ok(Some(match ecx.load_mir(instance.def, None) { Ok(body) => body, Err(err) => { if let err_unsup!(NoMirFor(ref path)) = err.kind { @@ -664,14 +653,8 @@ pub fn const_eval_raw_provider<'tcx>( Default::default() ); - let res = ecx.load_mir(cid.instance.def); - res.map(|body| { - if let Some(index) = cid.promoted { - &tcx.promoted_mir(def_id)[index] - } else { - body - } - }).and_then( + let res = ecx.load_mir(cid.instance.def, cid.promoted); + res.and_then( |body| eval_body_using_ecx(&mut ecx, cid, body, key.param_env) ).and_then(|place| { Ok(RawConst { diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index 6f48396cdd7..ac01d436bdc 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -294,6 +294,7 @@ pub fn type_is_freeze(&self, ty: Ty<'tcx>) -> bool { pub fn load_mir( &self, instance: ty::InstanceDef<'tcx>, + promoted: Option, ) -> InterpResult<'tcx, &'tcx mir::Body<'tcx>> { // do not continue if typeck errors occurred (can only occur in local crate) let did = instance.def_id(); @@ -303,7 +304,10 @@ pub fn load_mir( { throw_inval!(TypeckError) } - trace!("load mir {:?}", instance); + trace!("load mir(instance={:?}, promoted={:?})", instance, promoted); + if let Some(promoted) = promoted { + return Ok(&self.tcx.promoted_mir(did)[promoted]); + } match instance { ty::InstanceDef::Item(def_id) => if self.tcx.is_mir_available(did) { Ok(self.tcx.optimized_mir(did)) diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 790595b4fee..9aeef16ba1e 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -27,7 +27,7 @@ ImmTy, MemoryKind, StackPopCleanup, LocalValue, LocalState, }; use crate::const_eval::{ - CompileTimeInterpreter, error_to_const_error, eval_promoted, mk_eval_cx, + CompileTimeInterpreter, error_to_const_error, mk_eval_cx, }; use crate::transform::{MirPass, MirSource}; @@ -297,11 +297,8 @@ fn eval_place(&mut self, place: &Place<'tcx>, source_info: SourceInfo) -> Option instance, promoted: Some(*promoted), }; - // 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 res = self.use_ecx(source_info, |this| { - let body = &this.tcx.promoted_mir(this.source.def_id())[*promoted]; - eval_promoted(this.tcx, cid, body, this.param_env) + this.ecx.const_eval_raw(cid) })?; trace!("evaluated promoted {:?} to {:?}", promoted, res); res.into()