Skip to content

Commit 001bd77

Browse files
committed
Auto merge of rust-lang#79840 - dvtkrlbs:issue-79667, r=oli-obk
Remove memoization leftovers from constant evaluation machine Closes rust-lang#79667
2 parents bdd0a78 + a03feaa commit 001bd77

File tree

3 files changed

+17
-69
lines changed

3 files changed

+17
-69
lines changed

Diff for: compiler/rustc_middle/src/mir/interpret/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,6 @@ pub use self::pointer::{Pointer, PointerArithmetic};
132132
/// Uniquely identifies one of the following:
133133
/// - A constant
134134
/// - A static
135-
/// - A const fn where all arguments (if any) are zero-sized types
136135
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, TyEncodable, TyDecodable)]
137136
#[derive(HashStable, Lift)]
138137
pub struct GlobalId<'tcx> {

Diff for: compiler/rustc_mir/src/const_eval/eval_queries.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,19 @@ fn eval_body_using_ecx<'mir, 'tcx>(
3131
) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
3232
debug!("eval_body_using_ecx: {:?}, {:?}", cid, ecx.param_env);
3333
let tcx = *ecx.tcx;
34+
assert!(
35+
cid.promoted.is_some()
36+
|| matches!(
37+
ecx.tcx.def_kind(cid.instance.def_id()),
38+
DefKind::Const
39+
| DefKind::Static
40+
| DefKind::ConstParam
41+
| DefKind::AnonConst
42+
| DefKind::AssocConst
43+
),
44+
"Unexpected DefKind: {:?}",
45+
ecx.tcx.def_kind(cid.instance.def_id())
46+
);
3447
let layout = ecx.layout_of(body.return_ty().subst(tcx, cid.instance.substs))?;
3548
assert!(!layout.is_unsized());
3649
let ret = ecx.allocate(layout, MemoryKind::Stack);
@@ -40,15 +53,6 @@ fn eval_body_using_ecx<'mir, 'tcx>(
4053
let prom = cid.promoted.map_or(String::new(), |p| format!("::promoted[{:?}]", p));
4154
trace!("eval_body_using_ecx: pushing stack frame for global: {}{}", name, prom);
4255

43-
// Assert all args (if any) are zero-sized types; `eval_body_using_ecx` doesn't
44-
// make sense if the body is expecting nontrivial arguments.
45-
// (The alternative would be to use `eval_fn_call` with an args slice.)
46-
for arg in body.args_iter() {
47-
let decl = body.local_decls.get(arg).expect("arg missing from local_decls");
48-
let layout = ecx.layout_of(decl.ty.subst(tcx, cid.instance.substs))?;
49-
assert!(layout.is_zst())
50-
}
51-
5256
ecx.push_stack_frame(
5357
cid.instance,
5458
body,

Diff for: compiler/rustc_mir/src/const_eval/machine.rs

+4-59
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
use rustc_middle::mir;
2-
use rustc_middle::ty::layout::HasTyCtxt;
3-
use rustc_middle::ty::InstanceDef;
42
use rustc_middle::ty::{self, Ty};
53
use std::borrow::Borrow;
64
use std::collections::hash_map::Entry;
@@ -17,60 +15,13 @@ use rustc_span::symbol::{sym, Symbol};
1715
use rustc_target::abi::{Align, Size};
1816

1917
use crate::interpret::{
20-
self, compile_time_machine, AllocId, Allocation, Frame, GlobalId, ImmTy, InterpCx,
21-
InterpResult, Memory, OpTy, PlaceTy, Pointer, Scalar,
18+
self, compile_time_machine, AllocId, Allocation, Frame, ImmTy, InterpCx, InterpResult, Memory,
19+
OpTy, PlaceTy, Pointer, Scalar,
2220
};
2321

2422
use super::error::*;
2523

2624
impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
27-
/// Evaluate a const function where all arguments (if any) are zero-sized types.
28-
/// The evaluation is memoized thanks to the query system.
29-
///
30-
/// Returns `true` if the call has been evaluated.
31-
fn try_eval_const_fn_call(
32-
&mut self,
33-
instance: ty::Instance<'tcx>,
34-
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
35-
args: &[OpTy<'tcx>],
36-
) -> InterpResult<'tcx, bool> {
37-
trace!("try_eval_const_fn_call: {:?}", instance);
38-
// Because `#[track_caller]` adds an implicit non-ZST argument, we also cannot
39-
// perform this optimization on items tagged with it.
40-
if instance.def.requires_caller_location(self.tcx()) {
41-
return Ok(false);
42-
}
43-
// Only memoize instrinsics. This was added in #79594 while adding the `const_allocate` intrinsic.
44-
// We only memoize intrinsics because it would be unsound to memoize functions
45-
// which might interact with the heap.
46-
// Additionally, const_allocate intrinsic is impure and thus should not be memoized;
47-
// it will not be memoized because it has non-ZST args
48-
if !matches!(instance.def, InstanceDef::Intrinsic(_)) {
49-
return Ok(false);
50-
}
51-
// For the moment we only do this for functions which take no arguments
52-
// (or all arguments are ZSTs) so that we don't memoize too much.
53-
if args.iter().any(|a| !a.layout.is_zst()) {
54-
return Ok(false);
55-
}
56-
57-
let dest = match ret {
58-
Some((dest, _)) => dest,
59-
// Don't memoize diverging function calls.
60-
None => return Ok(false),
61-
};
62-
63-
let gid = GlobalId { instance, promoted: None };
64-
65-
let place = self.eval_to_allocation(gid)?;
66-
67-
self.copy_op(place.into(), dest)?;
68-
69-
self.return_to_block(ret.map(|r| r.1))?;
70-
trace!("{:?}", self.dump_place(*dest));
71-
Ok(true)
72-
}
73-
7425
/// "Intercept" a function call to a panic-related function
7526
/// because we have something special to do for it.
7627
/// If this returns successfully (`Ok`), the function should just be evaluated normally.
@@ -253,7 +204,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
253204
ecx: &mut InterpCx<'mir, 'tcx, Self>,
254205
instance: ty::Instance<'tcx>,
255206
args: &[OpTy<'tcx>],
256-
ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
207+
_ret: Option<(PlaceTy<'tcx>, mir::BasicBlock)>,
257208
_unwind: Option<mir::BasicBlock>, // unwinding is not supported in consts
258209
) -> InterpResult<'tcx, Option<&'mir mir::Body<'tcx>>> {
259210
debug!("find_mir_or_eval_fn: {:?}", instance);
@@ -263,13 +214,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
263214
// Execution might have wandered off into other crates, so we cannot do a stability-
264215
// sensitive check here. But we can at least rule out functions that are not const
265216
// at all.
266-
if ecx.tcx.is_const_fn_raw(def.did) {
267-
// If this function is a `const fn` then under certain circumstances we
268-
// can evaluate call via the query system, thus memoizing all future calls.
269-
if ecx.try_eval_const_fn_call(instance, ret, args)? {
270-
return Ok(None);
271-
}
272-
} else {
217+
if !ecx.tcx.is_const_fn_raw(def.did) {
273218
// Some functions we support even if they are non-const -- but avoid testing
274219
// that for const fn!
275220
ecx.hook_panic_fn(instance, args)?;

0 commit comments

Comments
 (0)