1
Fork 0

properly fill a promoted's required_consts

then we can also make all_required_consts_are_checked a constant instead of a function
This commit is contained in:
Ralf Jung 2024-03-21 13:53:00 +01:00
parent bf021ea625
commit 173d1bd36b
13 changed files with 121 additions and 54 deletions

View file

@ -46,11 +46,8 @@ impl<'mir, 'tcx: 'mir> interpret::Machine<'mir, 'tcx> for DummyMachine {
type MemoryKind = !;
const PANIC_ON_ALLOC_FAIL: bool = true;
#[inline(always)]
fn all_required_consts_are_checked(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
// We want to just eval random consts in the program, so `eval_mir_const` can fail.
false
}
// We want to just eval random consts in the program, so `eval_mir_const` can fail.
const ALL_CONSTS_ARE_PRECHECKED: bool = false;
#[inline(always)]
fn enforce_alignment(_ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {

View file

@ -375,20 +375,6 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
const PANIC_ON_ALLOC_FAIL: bool = false; // will be raised as a proper error
#[inline]
fn all_required_consts_are_checked(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
// Generally we expect required_consts to be properly filled, except for promoteds where
// storing these consts shows up negatively in benchmarks. A promoted can only be relevant
// if its parent MIR is relevant, and the consts in the promoted will be in the parent's
// `required_consts`, so we are still sure to catch any const-eval bugs, just a bit less
// directly.
if ecx.frame_idx() == 0 && ecx.frame().body.source.promoted.is_some() {
false
} else {
true
}
}
#[inline(always)]
fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool {
matches!(ecx.machine.check_alignment, CheckAlignment::Error)

View file

@ -1179,9 +1179,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
M::eval_mir_constant(self, *val, span, layout, |ecx, val, span, layout| {
let const_val = val.eval(*ecx.tcx, ecx.param_env, span).map_err(|err| {
if M::all_required_consts_are_checked(self)
&& !matches!(err, ErrorHandled::TooGeneric(..))
{
if M::ALL_CONSTS_ARE_PRECHECKED && !matches!(err, ErrorHandled::TooGeneric(..)) {
// Looks like the const is not captued by `required_consts`, that's bad.
bug!("interpret const eval failure of {val:?} which is not in required_consts");
}

View file

@ -142,7 +142,7 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
/// Determines whether `eval_mir_constant` can never fail because all required consts have
/// already been checked before.
fn all_required_consts_are_checked(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;
const ALL_CONSTS_ARE_PRECHECKED: bool = true;
/// Whether memory accesses should be alignment-checked.
fn enforce_alignment(ecx: &InterpCx<'mir, 'tcx, Self>) -> bool;