fix: tactic cache corruption

This commit is contained in:
Leonardo de Moura 2022-04-17 15:52:21 -07:00
parent 607a590238
commit d9f007e4dd
2 changed files with 9 additions and 4 deletions

View file

@ -125,8 +125,8 @@ structure CacheKey where
deriving BEq, Hashable, Inhabited
structure Cache where
pre : Std.HashMap CacheKey Snapshot := {}
post : Std.HashMap CacheKey Snapshot := {}
pre : Std.PHashMap CacheKey Snapshot := {}
post : Std.PHashMap CacheKey Snapshot := {}
deriving Inhabited
end Tactic

View file

@ -128,17 +128,22 @@ def compileNextCmd (inputCtx : Parser.InputContext) (snap : Snapshot) (hasWidget
return endSnap
else
let cmdStateRef ← IO.mkRef { snap.cmdState with messages := msgLog }
/- The same snapshot may be executed by different tasks. So, to make sure `elabCommandTopLevel` has exclusive
access to the cache, we create a fresh reference here. Before this change, the
following `snap.tacticCache.modify` would reset the tactic post cache while another snapshot was still using it. -/
let tacticCacheNew ← IO.mkRef (← snap.tacticCache.get)
let cmdCtx : Elab.Command.Context := {
cmdPos := snap.endPos
fileName := inputCtx.fileName
fileMap := inputCtx.fileMap
tacticCache? := some snap.tacticCache
tacticCache? := some tacticCacheNew
}
let (output, _) ← IO.FS.withIsolatedStreams <| liftM (m := BaseIO) do
Elab.Command.catchExceptions
(getResetInfoTrees *> Elab.Command.elabCommandTopLevel cmdStx)
cmdCtx cmdStateRef
snap.tacticCache.modify fun { pre, post } => { pre := post, post := {} }
let postNew := (← tacticCacheNew.get).post
snap.tacticCache.modify fun { pre, post } => { pre := postNew, post := {} }
let mut postCmdState ← cmdStateRef.get
if !output.isEmpty then
postCmdState := {