Don't abort const eval due to long running evals, just warn
This commit is contained in:
parent
99d4886ead
commit
4f6d118048
6 changed files with 9 additions and 18 deletions
|
@ -550,7 +550,6 @@ for ::mir::interpret::EvalError<'gcx> {
|
|||
InvalidPointerMath |
|
||||
ReadUndefBytes |
|
||||
DeadLocal |
|
||||
ExecutionTimeLimitReached |
|
||||
StackFrameLimitReached |
|
||||
OutOfTls |
|
||||
TlsOutOfBounds |
|
||||
|
|
|
@ -65,7 +65,6 @@ pub enum EvalErrorKind<'tcx> {
|
|||
Intrinsic(String),
|
||||
OverflowingMath,
|
||||
InvalidChar(u128),
|
||||
ExecutionTimeLimitReached,
|
||||
StackFrameLimitReached,
|
||||
OutOfTls,
|
||||
TlsOutOfBounds,
|
||||
|
@ -188,8 +187,6 @@ impl<'tcx> Error for EvalError<'tcx> {
|
|||
"mir not found",
|
||||
InvalidChar(..) =>
|
||||
"tried to interpret an invalid 32-bit value as a char",
|
||||
ExecutionTimeLimitReached =>
|
||||
"the expression was too complex to be evaluated or resulted in an infinite loop",
|
||||
StackFrameLimitReached =>
|
||||
"reached the configured maximum number of stack frames",
|
||||
OutOfTls =>
|
||||
|
|
|
@ -112,8 +112,6 @@ pub struct Session {
|
|||
|
||||
/// The maximum number of stackframes allowed in const eval
|
||||
pub const_eval_stack_frame_limit: usize,
|
||||
/// The maximum number miri steps per constant
|
||||
pub const_eval_step_limit: usize,
|
||||
|
||||
/// The metadata::creader module may inject an allocator/panic_runtime
|
||||
/// dependency if it didn't already find one, and this tracks what was
|
||||
|
@ -1103,7 +1101,6 @@ pub fn build_session_(
|
|||
recursion_limit: Once::new(),
|
||||
type_length_limit: Once::new(),
|
||||
const_eval_stack_frame_limit: 100,
|
||||
const_eval_step_limit: 1_000_000,
|
||||
next_node_id: OneThread::new(Cell::new(NodeId::new(1))),
|
||||
injected_allocator: Once::new(),
|
||||
allocator_kind: Once::new(),
|
||||
|
|
|
@ -509,7 +509,6 @@ impl<'a, 'tcx> Lift<'tcx> for interpret::EvalError<'a> {
|
|||
Intrinsic(ref s) => Intrinsic(s.clone()),
|
||||
OverflowingMath => OverflowingMath,
|
||||
InvalidChar(c) => InvalidChar(c),
|
||||
ExecutionTimeLimitReached => ExecutionTimeLimitReached,
|
||||
StackFrameLimitReached => StackFrameLimitReached,
|
||||
OutOfTls => OutOfTls,
|
||||
TlsOutOfBounds => TlsOutOfBounds,
|
||||
|
|
|
@ -45,7 +45,7 @@ pub struct EvalContext<'a, 'mir, 'tcx: 'a + 'mir, M: Machine<'mir, 'tcx>> {
|
|||
/// The maximum number of terminators that may be evaluated.
|
||||
/// This prevents infinite loops and huge computations from freezing up const eval.
|
||||
/// Remove once halting problem is solved.
|
||||
pub(crate) steps_remaining: usize,
|
||||
pub(crate) terminators_remaining: usize,
|
||||
}
|
||||
|
||||
/// A stack frame.
|
||||
|
@ -195,7 +195,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
memory: Memory::new(tcx, memory_data),
|
||||
stack: Vec::new(),
|
||||
stack_limit: tcx.sess.const_eval_stack_frame_limit,
|
||||
steps_remaining: tcx.sess.const_eval_step_limit,
|
||||
terminators_remaining: 1_000_000,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,7 +538,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
|
|||
}
|
||||
|
||||
Aggregate(ref kind, ref operands) => {
|
||||
self.inc_step_counter_and_check_limit(operands.len())?;
|
||||
self.inc_step_counter_and_check_limit(operands.len());
|
||||
|
||||
let (dest, active_field_index) = match **kind {
|
||||
mir::AggregateKind::Adt(adt_def, variant_index, _, active_field_index) => {
|
||||
|
|
|
@ -8,12 +8,11 @@ use rustc::mir::interpret::EvalResult;
|
|||
use super::{EvalContext, Machine};
|
||||
|
||||
impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
||||
pub fn inc_step_counter_and_check_limit(&mut self, n: usize) -> EvalResult<'tcx> {
|
||||
self.steps_remaining = self.steps_remaining.saturating_sub(n);
|
||||
if self.steps_remaining > 0 {
|
||||
Ok(())
|
||||
} else {
|
||||
err!(ExecutionTimeLimitReached)
|
||||
pub fn inc_step_counter_and_check_limit(&mut self, n: usize) {
|
||||
self.terminators_remaining = self.terminators_remaining.saturating_sub(n);
|
||||
if self.terminators_remaining == 0 {
|
||||
self.tcx.sess.span_warn(self.frame().span, "Constant evaluating a complex constant, this might take some time");
|
||||
self.terminators_remaining = 1_000_000;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +35,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
|
|||
return Ok(true);
|
||||
}
|
||||
|
||||
self.inc_step_counter_and_check_limit(1)?;
|
||||
self.inc_step_counter_and_check_limit(1);
|
||||
|
||||
let terminator = basic_block.terminator();
|
||||
assert_eq!(old_frames, self.cur_frame());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue