Skip to content

Commit 6d77e45

Browse files
committed
Auto merge of #66866 - oli-obk:const_fn_memoization, r=RalfJung
Only memoize const fn calls during const eval Miri and other engines may want to execute the function in order to detect UB inside of them. r? @RalfJung
2 parents c4f1304 + af8f141 commit 6d77e45

File tree

4 files changed

+20
-19
lines changed

4 files changed

+20
-19
lines changed

src/librustc_mir/const_eval.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -328,20 +328,32 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
328328
false // for now, we don't enforce validity
329329
}
330330

331-
fn find_fn(
331+
fn find_mir_or_eval_fn(
332332
ecx: &mut InterpCx<'mir, 'tcx, Self>,
333333
instance: ty::Instance<'tcx>,
334334
args: &[OpTy<'tcx>],
335335
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
336336
_unwind: Option<mir::BasicBlock> // unwinding is not supported in consts
337337
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
338-
debug!("eval_fn_call: {:?}", instance);
338+
debug!("find_mir_or_eval_fn: {:?}", instance);
339+
339340
// Only check non-glue functions
340341
if let ty::InstanceDef::Item(def_id) = instance.def {
341342
// Execution might have wandered off into other crates, so we cannot do a stability-
342343
// sensitive check here. But we can at least rule out functions that are not const
343344
// at all.
344-
if !ecx.tcx.is_const_fn_raw(def_id) {
345+
if ecx.tcx.is_const_fn_raw(def_id) {
346+
// If this function is a `const fn` then as an optimization we can query this
347+
// evaluation immediately.
348+
//
349+
// For the moment we only do this for functions which take no arguments
350+
// (or all arguments are ZSTs) so that we don't memoize too much.
351+
if args.iter().all(|a| a.layout.is_zst()) {
352+
let gid = GlobalId { instance, promoted: None };
353+
ecx.eval_const_fn_call(gid, ret)?;
354+
return Ok(None);
355+
}
356+
} else {
345357
// Some functions we support even if they are non-const -- but avoid testing
346358
// that for const fn! We certainly do *not* want to actually call the fn
347359
// though, so be sure we return here.

src/librustc_mir/interpret/machine.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
146146
/// nor just jump to `ret`, but instead push their own stack frame.)
147147
/// Passing `dest`and `ret` in the same `Option` proved very annoying when only one of them
148148
/// was used.
149-
fn find_fn(
149+
fn find_mir_or_eval_fn(
150150
ecx: &mut InterpCx<'mir, 'tcx, Self>,
151151
instance: ty::Instance<'tcx>,
152152
args: &[OpTy<'tcx, Self::PointerTag>],

src/librustc_mir/interpret/terminator.rs

+3-14
Original file line numberDiff line numberDiff line change
@@ -266,20 +266,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
266266
ty::InstanceDef::DropGlue(..) |
267267
ty::InstanceDef::CloneShim(..) |
268268
ty::InstanceDef::Item(_) => {
269-
// If this function is a `const fn` then as an optimization we can query this
270-
// evaluation immediately.
271-
//
272-
// For the moment we only do this for functions which take no arguments
273-
// (or all arguments are ZSTs) so that we don't memoize too much.
274-
if self.tcx.is_const_fn_raw(instance.def.def_id()) &&
275-
args.iter().all(|a| a.layout.is_zst())
276-
{
277-
let gid = GlobalId { instance, promoted: None };
278-
return self.eval_const_fn_call(gid, ret);
279-
}
280-
281269
// We need MIR for this fn
282-
let body = match M::find_fn(self, instance, args, ret, unwind)? {
270+
let body = match M::find_mir_or_eval_fn(self, instance, args, ret, unwind)? {
283271
Some(body) => body,
284272
None => return Ok(()),
285273
};
@@ -445,7 +433,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
445433

446434
/// Evaluate a const function where all arguments (if any) are zero-sized types.
447435
/// The evaluation is memoized thanks to the query system.
448-
fn eval_const_fn_call(
436+
// FIXME: Consider moving this to `const_eval.rs`.
437+
pub (crate) fn eval_const_fn_call(
449438
&mut self,
450439
gid: GlobalId<'tcx>,
451440
ret: Option<(PlaceTy<'tcx, M::PointerTag>, mir::BasicBlock)>,

src/librustc_mir/transform/const_prop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for ConstPropMachine {
128128
false
129129
}
130130

131-
fn find_fn(
131+
fn find_mir_or_eval_fn(
132132
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
133133
_instance: ty::Instance<'tcx>,
134134
_args: &[OpTy<'tcx>],

0 commit comments

Comments
 (0)