fix: preserve InfoTree when tactics fail

cc @Kha @Vtec234
This commit is contained in:
Leonardo de Moura 2021-02-17 15:20:33 -08:00
parent 64413e9d4a
commit 6263141f7b
2 changed files with 14 additions and 8 deletions

View file

@ -195,8 +195,13 @@ def mkInfoNode (info : Info) : m Unit := do
else
x
@[inline] def withInfoContext [MonadFinally m] (x : m α) (mkInfo : m Info) : m α :=
withInfoContext' x fun _ => return Sum.inl (← mkInfo)
@[inline] def withInfoContext [MonadFinally m] (x : m α) (mkInfo : m Info) : m α := do
if (← getInfoState).enabled then
let treesSaved ← getResetInfoTrees
Prod.fst <$> MonadFinally.tryFinally' x fun _ => do
modifyInfoTrees fun trees => treesSaved.push <| InfoTree.node (← mkInfo) trees
else
x
def getInfoHoleIdAssignment? (mvarId : MVarId) : m (Option InfoTree) :=
return (← getInfoState).assignment[mvarId]
@ -218,12 +223,11 @@ def withMacroExpansionInfo [MonadFinally m] [Monad m] [MonadInfoTree m] [MonadLC
@[inline] def withInfoHole [MonadFinally m] [Monad m] [MonadInfoTree m] (mvarId : MVarId) (x : m α) : m α := do
if (← getInfoState).enabled then
let treesSaved ← getResetInfoTrees
Prod.fst <$> MonadFinally.tryFinally' x fun a? => do
match a? with
| none => modifyInfoTrees fun _ => treesSaved
| some a => modifyInfoState fun s =>
assert! s.trees.size == 1 -- if size is not one, then API is being misused.
{ s with trees := treesSaved, assignment := s.assignment.insert mvarId s.trees[0] }
Prod.fst <$> MonadFinally.tryFinally' x fun a? => modifyInfoState fun s =>
if s.trees.size > 0 then
{ s with trees := treesSaved, assignment := s.assignment.insert mvarId s.trees[s.trees.size - 1] }
else
{ s with trees := treesSaved }
else
x

View file

@ -45,9 +45,11 @@ def saveBacktrackableState : TacticM BacktrackableState := do
def BacktrackableState.restore (b : BacktrackableState) : TacticM Unit := do
setEnv b.env
setMCtx b.mctx
let infoState ← getInfoState -- we do not backtrack info state
let msgLog ← Term.getMessageLog -- we do not backtrack the message log
set b.term
Term.setMessageLog msgLog
modifyInfoState fun _ => infoState
modify fun s => { s with goals := b.goals }
@[inline] protected def tryCatch {α} (x : TacticM α) (h : Exception → TacticM α) : TacticM α := do