perf: cache visited exprs at `CheckAssignmentQuick`
diff --git a/src/Lean/Meta/ExprDefEq.lean b/src/Lean/Meta/ExprDefEq.lean index 0750964..12f2447 100644 --- a/src/Lean/Meta/ExprDefEq.lean +++ b/src/Lean/Meta/ExprDefEq.lean
@@ -895,23 +895,27 @@ namespace CheckAssignmentQuick -partial def check +unsafe def checkImpl (hasCtxLocals : Bool) (mctx : MetavarContext) (lctx : LocalContext) (mvarDecl : MetavarDecl) (mvarId : MVarId) (fvars : Array Expr) (e : Expr) : Bool := - let rec visit (e : Expr) : Bool := Id.run do + let rec visit (e : Expr) : StateM (PtrSet Expr) Bool := do if !e.hasExprMVar && !e.hasFVar then return true + if (← get).contains e then + return true + modify fun visited => visited.insert e match e with | .mdata _ b => visit b | .proj _ _ s => visit s - | .app f a => visit f && visit a - | .lam _ d b _ => visit d && visit b - | .forallE _ d b _ => visit d && visit b - | .letE _ t v b _ => visit t && visit v && visit b + | .app f a => visit f <&&> visit a + | .lam _ d b _ => visit d <&&> visit b + | .forallE _ d b _ => visit d <&&> visit b + | .letE _ t v b _ => visit t <&&> visit v <&&> visit b | .bvar .. | .sort .. | .const .. | .lit .. => return true | .fvar fvarId .. => - if mvarDecl.lctx.contains fvarId then return true + if mvarDecl.lctx.contains fvarId then + return true if let some (LocalDecl.ldecl ..) := lctx.find? fvarId then return false -- need expensive CheckAssignment.check if fvars.any fun x => x.fvarId! == fvarId then @@ -925,7 +929,13 @@ if !mvarDecl'.lctx.isSubPrefixOf mvarDecl.lctx fvars then return false -- use CheckAssignment.check let none := mctx.getDelayedMVarAssignmentCore? mvarId' | return false -- use CheckAssignment.check return true - visit e + if !e.hasExprMVar && !e.hasFVar then + true + else + visit e |>.run' mkPtrSet + +def check (hasCtxLocals : Bool) (mctx : MetavarContext) (lctx : LocalContext) (mvarDecl : MetavarDecl) (mvarId : MVarId) (fvars : Array Expr) (e : Expr) : Bool := + unsafe checkImpl hasCtxLocals mctx lctx mvarDecl mvarId fvars e end CheckAssignmentQuick