Skip to content

Commit 3cdd019

Browse files
committed
Auto merge of #106227 - bryangarza:ctfe-limit, r=oli-obk
Use stable metric for const eval limit instead of current terminator-based logic This patch adds a `MirPass` that inserts a new MIR instruction `ConstEvalCounter` to any loops and function calls in the CFG. This instruction is used during Const Eval to count against the `const_eval_limit`, and emit the `StepLimitReached` error, replacing the current logic which uses Terminators only. The new method of counting loops and function calls should be more stable across compiler versions (i.e., not cause crates that compiled successfully before, to no longer compile when changes to the MIR generation/optimization are made). Also see: #103877
2 parents bcb064a + bdb815a commit 3cdd019

File tree

50 files changed

+400
-20
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+400
-20
lines changed

compiler/rustc_borrowck/src/dataflow.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,7 @@ impl<'tcx> rustc_mir_dataflow::GenKillAnalysis<'tcx> for Borrows<'_, 'tcx> {
393393
| mir::StatementKind::AscribeUserType(..)
394394
| mir::StatementKind::Coverage(..)
395395
| mir::StatementKind::Intrinsic(..)
396+
| mir::StatementKind::ConstEvalCounter
396397
| mir::StatementKind::Nop => {}
397398
}
398399
}

compiler/rustc_borrowck/src/invalidation.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
9191
LocalMutationIsAllowed::Yes,
9292
);
9393
}
94-
StatementKind::Nop
94+
StatementKind::ConstEvalCounter
95+
| StatementKind::Nop
9596
| StatementKind::Retag { .. }
9697
| StatementKind::Deinit(..)
9798
| StatementKind::SetDiscriminant { .. } => {

compiler/rustc_borrowck/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,8 @@ impl<'cx, 'tcx> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx> for MirBorrowckCtx
609609
StatementKind::AscribeUserType(..)
610610
// Doesn't have any language semantics
611611
| StatementKind::Coverage(..)
612-
// Does not actually affect borrowck
612+
// These do not actually affect borrowck
613+
| StatementKind::ConstEvalCounter
613614
| StatementKind::StorageLive(..) => {}
614615
StatementKind::StorageDead(local) => {
615616
self.access_place(

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
12581258
| StatementKind::StorageDead(..)
12591259
| StatementKind::Retag { .. }
12601260
| StatementKind::Coverage(..)
1261+
| StatementKind::ConstEvalCounter
12611262
| StatementKind::Nop => {}
12621263
StatementKind::Deinit(..) | StatementKind::SetDiscriminant { .. } => {
12631264
bug!("Statement not allowed in this MIR phase")

compiler/rustc_codegen_cranelift/src/base.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -794,6 +794,7 @@ fn codegen_stmt<'tcx>(
794794
StatementKind::StorageLive(_)
795795
| StatementKind::StorageDead(_)
796796
| StatementKind::Deinit(_)
797+
| StatementKind::ConstEvalCounter
797798
| StatementKind::Nop
798799
| StatementKind::FakeRead(..)
799800
| StatementKind::Retag { .. }

compiler/rustc_codegen_cranelift/src/constant.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
530530
| StatementKind::Retag(_, _)
531531
| StatementKind::AscribeUserType(_, _)
532532
| StatementKind::Coverage(_)
533+
| StatementKind::ConstEvalCounter
533534
| StatementKind::Nop => {}
534535
}
535536
}

compiler/rustc_codegen_ssa/src/mir/statement.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
9191
mir::StatementKind::FakeRead(..)
9292
| mir::StatementKind::Retag { .. }
9393
| mir::StatementKind::AscribeUserType(..)
94+
| mir::StatementKind::ConstEvalCounter
9495
| mir::StatementKind::Nop => {}
9596
}
9697
}

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
561561
throw_unsup_format!("pointer arithmetic or comparison is not supported at compile-time");
562562
}
563563

564-
fn before_terminator(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
565-
// The step limit has already been hit in a previous call to `before_terminator`.
564+
fn increment_const_eval_counter(ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
565+
// The step limit has already been hit in a previous call to `increment_const_eval_counter`.
566566
if ecx.machine.steps_remaining == 0 {
567567
return Ok(());
568568
}

compiler/rustc_const_eval/src/interpret/machine.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,18 @@ pub trait Machine<'mir, 'tcx>: Sized {
244244
}
245245

246246
/// Called before a basic block terminator is executed.
247-
/// You can use this to detect endlessly running programs.
248247
#[inline]
249248
fn before_terminator(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
250249
Ok(())
251250
}
252251

252+
/// Called when the interpreter encounters a `StatementKind::ConstEvalCounter` instruction.
253+
/// You can use this to detect long or endlessly running programs.
254+
#[inline]
255+
fn increment_const_eval_counter(_ecx: &mut InterpCx<'mir, 'tcx, Self>) -> InterpResult<'tcx> {
256+
Ok(())
257+
}
258+
253259
/// Called before a global allocation is accessed.
254260
/// `def_id` is `Some` if this is the "lazy" allocation of a static.
255261
#[inline]

compiler/rustc_const_eval/src/interpret/step.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
129129
// FIXME(#73156): Handle source code coverage in const eval
130130
Coverage(..) => {}
131131

132+
ConstEvalCounter => {
133+
M::increment_const_eval_counter(self)?;
134+
}
135+
132136
// Defined to do nothing. These are added by optimization passes, to avoid changing the
133137
// size of MIR constantly.
134138
Nop => {}

0 commit comments

Comments
 (0)