fix: add checkSystem calls to long-running elaboration paths (#13220)
This PR adds `checkSystem` calls to several code paths that can run for extended periods without checking for cancellation, heartbeat limits, or stack overflow. This improves responsiveness of the cancellation mechanism in the language server. Affected paths: - `simpLoop` step loop (`Simp/Main.lean`) - `simp` rewrite candidate loops (`Rewrite.lean`) - `simpAppUsingCongr` argument traversal (`Types.lean`) - `synthesizeSyntheticMVarsStep` mvar loop (`SyntheticMVars.lean`) - `abstractNestedProofs` visitor (`AbstractNestedProofs.lean`) - `transform`/`transformWithCache` visitors (`Transform.lean`) - LCNF compiler pass runner loop (`LCNF/Main.lean`) - LCNF checker recursive traversal (`LCNF/Check.lean`) - `whnfImp` top-level reduction (`WHNF.lean`) Intentionally *not* instrumented (too hot, measurable regression): - `whnfCore.go` inner recursion - `simpImpl` entry point (redundant with `simpLoop`) - LCNF `simp` inner recursion (0.4% regression on `big_do`) Also adds a docstring to `checkInterrupted` clarifying its relationship to `checkSystem`. Found using `LEAN_CHECK_SYSTEM_INTERVAL_MS` monitoring from #13218. Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
978bde4a0f
commit
402a6096b9
10 changed files with 13 additions and 2 deletions
|
|
@ -232,6 +232,7 @@ partial def checkCases (c : Cases .pure) : CheckM Unit := do
|
|||
withParams params do check k
|
||||
|
||||
partial def check (code : Code .pure) : CheckM Unit := do
|
||||
checkSystem "LCNF check"
|
||||
match code with
|
||||
| .let decl k => checkLetDecl decl; withFVarId decl.fvarId do check k
|
||||
| .fun decl k =>
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ where
|
|||
profileitM Exception profilerName (← getOptions) do
|
||||
let mut state : (pu : Purity) × Array (Decl pu) := ⟨inPhase, decls⟩
|
||||
for pass in passes do
|
||||
checkSystem "LCNF compiler"
|
||||
state ← withTraceNode `Compiler (fun _ => return m!"compiler phase: {pass.phase}, pass: {pass.name}") do
|
||||
let decls ← withPhase pass.phase do
|
||||
state.fst.withAssertPurity pass.phase.toPurity fun h => do
|
||||
|
|
|
|||
|
|
@ -453,6 +453,9 @@ Throws an internal interrupt exception if cancellation has been requested. The e
|
|||
caught by `try catch` but is intended to be caught by `Command.withLoggingExceptions` at the top
|
||||
level of elaboration. In particular, we want to skip producing further incremental snapshots after
|
||||
the exception has been thrown.
|
||||
|
||||
Like `checkSystem` but without the global heartbeat check, for callers that have their own
|
||||
heartbeat tracking (e.g. `SynthInstance`).
|
||||
-/
|
||||
@[inline] def checkInterrupted : CoreM Unit := do
|
||||
if let some tk := (← read).cancelTk? then
|
||||
|
|
|
|||
|
|
@ -582,6 +582,7 @@ mutual
|
|||
-- We use `filterRevM` instead of `filterM` to make sure we process the synthetic metavariables using the order they were created.
|
||||
-- It would not be incorrect to use `filterM`.
|
||||
let remainingPendingMVars ← pendingMVars.filterRevM fun mvarId => do
|
||||
checkSystem "synthesize pending MVars"
|
||||
-- We use `traceM` because we want to make sure the metavar local context is used to trace the message
|
||||
traceM `Elab.postpone (mvarId.withContext do addMessageContext m!"resuming {mkMVar mvarId}")
|
||||
let succeeded ← synthesizeSyntheticMVar mvarId postponeOnError runTactics
|
||||
|
|
|
|||
|
|
@ -70,6 +70,7 @@ structure Context where
|
|||
abbrev M := ReaderT Context $ MonadCacheT ExprStructEq Expr MetaM
|
||||
|
||||
partial def visit (e : Expr) : M Expr := do
|
||||
checkSystem "abstract nested proofs"
|
||||
if e.isAtomic then
|
||||
pure e
|
||||
else
|
||||
|
|
|
|||
|
|
@ -714,7 +714,6 @@ where
|
|||
set_option compiler.ignoreBorrowAnnotation true in
|
||||
@[export lean_simp]
|
||||
def simpImpl (e : Expr) : SimpM Result := withIncRecDepth do
|
||||
checkSystem "simp"
|
||||
if (← isProof e) then
|
||||
return { expr := e }
|
||||
trace[Meta.Tactic.simp.heads] "{repr e.toHeadIndex}"
|
||||
|
|
|
|||
|
|
@ -219,6 +219,7 @@ where
|
|||
else
|
||||
let candidates := candidates.insertionSort fun e₁ e₂ => e₁.1.priority > e₂.1.priority
|
||||
for (thm, numExtraArgs) in candidates do
|
||||
checkSystem "simp"
|
||||
if inErasedSet thm then continue
|
||||
if rflOnly then
|
||||
unless thm.rfl do
|
||||
|
|
@ -246,6 +247,7 @@ where
|
|||
else
|
||||
let candidates := candidates.insertionSort fun e₁ e₂ => e₁.priority > e₂.priority
|
||||
for thm in candidates do
|
||||
checkSystem "simp"
|
||||
unless inErasedSet thm || (rflOnly && !thm.rfl) do
|
||||
let result? ← withNewMCtxDepth do
|
||||
let val ← thm.getValue
|
||||
|
|
|
|||
|
|
@ -722,6 +722,7 @@ def simpAppUsingCongr (e : Expr) : SimpM Result := do
|
|||
if i == 0 then
|
||||
simp f
|
||||
else
|
||||
checkSystem "simp"
|
||||
let i := i - 1
|
||||
let .app f a := e | unreachable!
|
||||
let fr ← visit f i
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ partial def transform {m} [Monad m] [MonadLiftT CoreM m] [MonadControlT CoreM m]
|
|||
let _ : MonadLiftT (ST IO.RealWorld) m := { monadLift := fun x => liftM (m := CoreM) (liftM (m := ST IO.RealWorld) x) }
|
||||
let rec visit (e : Expr) : MonadCacheT ExprStructEq Expr m Expr :=
|
||||
checkCache { val := e : ExprStructEq } fun _ => Core.withIncRecDepth do
|
||||
Core.checkSystem "transform"
|
||||
let rec visitPost (e : Expr) : MonadCacheT ExprStructEq Expr m Expr := do
|
||||
match (← post e) with
|
||||
| .done e => pure e
|
||||
|
|
@ -107,6 +108,7 @@ partial def transformWithCache {m} [Monad m] [MonadLiftT MetaM m] [MonadControlT
|
|||
let _ : MonadLiftT (ST IO.RealWorld) m := { monadLift := fun x => liftM (m := MetaM) (liftM (m := ST IO.RealWorld) x) }
|
||||
let rec visit (e : Expr) : MonadCacheT ExprStructEq Expr m Expr :=
|
||||
checkCache { val := e : ExprStructEq } fun _ => Meta.withIncRecDepth do
|
||||
(Core.checkSystem "transform" : MetaM Unit)
|
||||
let rec visitPost (e : Expr) : MonadCacheT ExprStructEq Expr m Expr := do
|
||||
match (← post e) with
|
||||
| .done e => pure e
|
||||
|
|
|
|||
|
|
@ -650,7 +650,7 @@ expand let-expressions, expand assigned meta-variables, unfold aux declarations.
|
|||
partial def whnfCore (e : Expr) : MetaM Expr :=
|
||||
go e
|
||||
where
|
||||
go (e : Expr) : MetaM Expr :=
|
||||
go (e : Expr) : MetaM Expr := do
|
||||
whnfEasyCases e fun e => do
|
||||
trace[Meta.whnf] e
|
||||
match e with
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue