Skip to content

Commit

Permalink
Only memoize const fn calls during const eval
Browse files Browse the repository at this point in the history
Miri and other engines may want to execute the function in order to detect UB inside of them.
  • Loading branch information
oli-obk committed Nov 29, 2019
1 parent 4752c05 commit 735a610
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 13 deletions.
14 changes: 14 additions & 0 deletions src/librustc_mir/const_eval.rs
Expand Up @@ -336,6 +336,20 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
_unwind: Option<mir::BasicBlock> // unwinding is not supported in consts
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
debug!("eval_fn_call: {:?}", instance);

// If this function is a `const fn` then as an optimization we can query this
// evaluation immediately.
//
// For the moment we only do this for functions which take no arguments
// (or all arguments are ZSTs) so that we don't memoize too much.
if ecx.tcx.is_const_fn_raw(instance.def.def_id()) &&
args.iter().all(|a| a.layout.is_zst())
{
let gid = GlobalId { instance, promoted: None };
ecx.eval_const_fn_call(gid, ret)?;
return Ok(None);
}

// Only check non-glue functions
if let ty::InstanceDef::Item(def_id) = instance.def {
// Execution might have wandered off into other crates, so we cannot do a stability-
Expand Down
14 changes: 1 addition & 13 deletions src/librustc_mir/interpret/terminator.rs
Expand Up @@ -284,18 +284,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ty::InstanceDef::DropGlue(..) |
ty::InstanceDef::CloneShim(..) |
ty::InstanceDef::Item(_) => {
// If this function is a `const fn` then as an optimization we can query this
// evaluation immediately.
//
// For the moment we only do this for functions which take no arguments
// (or all arguments are ZSTs) so that we don't memoize too much.
if self.tcx.is_const_fn_raw(instance.def.def_id()) &&
args.iter().all(|a| a.layout.is_zst())
{
let gid = GlobalId { instance, promoted: None };
return self.eval_const_fn_call(gid, ret);
}

// We need MIR for this fn
let body = match M::find_fn(self, instance, args, ret, unwind)? {
Some(body) => body,
Expand Down Expand Up @@ -463,7 +451,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

/// Evaluate a const function where all arguments (if any) are zero-sized types.
/// The evaluation is memoized thanks to the query system.
fn eval_const_fn_call(
pub (crate) fn eval_const_fn_call(
&mut self,
gid: GlobalId<'tcx>,
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,
Expand Down

0 comments on commit 735a610

Please sign in to comment.