parent
a6d186a81d
commit
e237e12478
3 changed files with 42 additions and 45 deletions
|
|
@ -79,12 +79,6 @@ structure Context where
|
|||
maxHeartbeats : Nat := getMaxHeartbeats options
|
||||
currMacroScope : MacroScope := firstFrontendMacroScope
|
||||
/--
|
||||
If `catchRuntimeEx = false`, then given `try x catch ex => h ex`,
|
||||
an runtime exception occurring in `x` is not handled by `h`.
|
||||
Recall that runtime exceptions are `maxRecDepth` or `maxHeartbeats`.
|
||||
-/
|
||||
catchRuntimeEx : Bool := false
|
||||
/--
|
||||
If `diag := true`, different parts of the system collect diagnostics.
|
||||
Use the `set_option diag true` to set it to true.
|
||||
-/
|
||||
|
|
@ -415,30 +409,36 @@ in these monads, but on `CommandElabM`. See issues #2775 and #2744 as well as `M
|
|||
try
|
||||
x
|
||||
catch ex =>
|
||||
if ex.isRuntime && !(← read).catchRuntimeEx then
|
||||
throw ex
|
||||
if ex.isRuntime then
|
||||
throw ex -- We should use `tryCatchRuntimeEx` for catching runtime exceptions
|
||||
else
|
||||
h ex
|
||||
|
||||
@[inline] protected def Core.tryCatchRuntimeEx (x : CoreM α) (h : Exception → CoreM α) : CoreM α := do
|
||||
try
|
||||
x
|
||||
catch ex =>
|
||||
h ex
|
||||
|
||||
instance : MonadExceptOf Exception CoreM where
|
||||
throw := throw
|
||||
tryCatch := Core.tryCatch
|
||||
|
||||
@[inline] def Core.withCatchingRuntimeEx (flag : Bool) (x : CoreM α) : CoreM α :=
|
||||
withReader (fun ctx => { ctx with catchRuntimeEx := flag }) x
|
||||
class MonadRuntimeException (m : Type → Type) where
|
||||
tryCatchRuntimeEx (body : m α) (handler : Exception → m α) : m α
|
||||
|
||||
export MonadRuntimeException (tryCatchRuntimeEx)
|
||||
|
||||
instance : MonadRuntimeException CoreM where
|
||||
tryCatchRuntimeEx := Core.tryCatchRuntimeEx
|
||||
|
||||
@[inline] instance [MonadRuntimeException m] : MonadRuntimeException (ReaderT ρ m) where
|
||||
tryCatchRuntimeEx := fun x c r => tryCatchRuntimeEx (x r) (fun e => (c e) r)
|
||||
|
||||
@[inline] instance [MonadRuntimeException m] : MonadRuntimeException (StateRefT' ω σ m) where
|
||||
tryCatchRuntimeEx := fun x c s => tryCatchRuntimeEx (x s) (fun e => c e s)
|
||||
|
||||
@[inline] def mapCoreM [MonadControlT CoreM m] [Monad m] (f : forall {α}, CoreM α → CoreM α) {α} (x : m α) : m α :=
|
||||
controlAt CoreM fun runInBase => f <| runInBase x
|
||||
|
||||
/--
|
||||
Execute `x` with `catchRuntimeEx = flag`. That is, given `try x catch ex => h ex`,
|
||||
if `x` throws a runtime exception, the handler `h` will be invoked if `flag = true`
|
||||
Recall that
|
||||
-/
|
||||
@[inline] def withCatchingRuntimeEx [MonadControlT CoreM m] [Monad m] (x : m α) : m α :=
|
||||
mapCoreM (Core.withCatchingRuntimeEx true) x
|
||||
|
||||
@[inline] def withoutCatchingRuntimeEx [MonadControlT CoreM m] [Monad m] (x : m α) : m α :=
|
||||
mapCoreM (Core.withCatchingRuntimeEx false) x
|
||||
|
||||
end Lean
|
||||
|
|
|
|||
|
|
@ -633,12 +633,9 @@ def main (type : Expr) (maxResultSize : Nat) : MetaM (Option AbstractMVarsResult
|
|||
let action : SynthM (Option AbstractMVarsResult) := do
|
||||
newSubgoal (← getMCtx) key mvar Waiter.root
|
||||
synth
|
||||
-- TODO: it would be nice to have a nice notation for the following idiom
|
||||
withCatchingRuntimeEx
|
||||
try
|
||||
withoutCatchingRuntimeEx do
|
||||
action.run { maxResultSize := maxResultSize, maxHeartbeats := getMaxHeartbeats (← getOptions) } |>.run' {}
|
||||
catch ex =>
|
||||
tryCatchRuntimeEx
|
||||
(action.run { maxResultSize := maxResultSize, maxHeartbeats := getMaxHeartbeats (← getOptions) } |>.run' {})
|
||||
fun ex =>
|
||||
if ex.isRuntime then
|
||||
throwError "failed to synthesize{indentExpr type}\n{ex.toMessageData}"
|
||||
else
|
||||
|
|
|
|||
|
|
@ -662,30 +662,30 @@ def main (e : Expr) (ctx : Context) (stats : Stats := {}) (methods : Methods :=
|
|||
trace[Meta.Tactic.simp.numSteps] "{s.numSteps}"
|
||||
return (r, { s with })
|
||||
where
|
||||
simpMain (e : Expr) : SimpM Result := withCatchingRuntimeEx do
|
||||
try
|
||||
withoutCatchingRuntimeEx <| simp e
|
||||
catch ex =>
|
||||
reportDiag (← get).diag
|
||||
if ex.isRuntime then
|
||||
throwNestedTacticEx `simp ex
|
||||
else
|
||||
throw ex
|
||||
simpMain (e : Expr) : SimpM Result :=
|
||||
tryCatchRuntimeEx
|
||||
(simp e)
|
||||
fun ex => do
|
||||
reportDiag (← get).diag
|
||||
if ex.isRuntime then
|
||||
throwNestedTacticEx `simp ex
|
||||
else
|
||||
throw ex
|
||||
|
||||
def dsimpMain (e : Expr) (ctx : Context) (stats : Stats := {}) (methods : Methods := {}) : MetaM (Expr × Stats) := do
|
||||
withSimpContext ctx do
|
||||
let (r, s) ← dsimpMain e methods.toMethodsRef ctx |>.run { stats with }
|
||||
pure (r, { s with })
|
||||
where
|
||||
dsimpMain (e : Expr) : SimpM Expr := withCatchingRuntimeEx do
|
||||
try
|
||||
withoutCatchingRuntimeEx <| dsimp e
|
||||
catch ex =>
|
||||
reportDiag (← get).diag
|
||||
if ex.isRuntime then
|
||||
throwNestedTacticEx `simp ex
|
||||
else
|
||||
throw ex
|
||||
dsimpMain (e : Expr) : SimpM Expr :=
|
||||
tryCatchRuntimeEx
|
||||
(dsimp e)
|
||||
fun ex => do
|
||||
reportDiag (← get).diag
|
||||
if ex.isRuntime then
|
||||
throwNestedTacticEx `simp ex
|
||||
else
|
||||
throw ex
|
||||
|
||||
end Simp
|
||||
open Simp (SimprocsArray Stats)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue