lean4-htt/src/Lean/Meta/Eval.lean
Sebastian Ullrich d01e038210
feat: asynchronous code generation (#6770)
This PR enables code generation to proceed in parallel to further
elaboration.

It does not aim to make further refinements such as generating code for
different declarations in parallel or removing the dependency on kernel
checking.
2025-02-03 17:17:18 +00:00

48 lines
1.9 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/-
Copyright (c) 2022 Sebastian Ullrich. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Sebastian Ullrich, Leonardo de Moura
-/
prelude
import Lean.AddDecl
import Lean.Meta.Check
import Lean.Util.CollectLevelParams
namespace Lean.Meta
unsafe def evalExprCore (α) (value : Expr) (checkType : Expr → MetaM Unit) (safety := DefinitionSafety.safe) : MetaM α :=
withoutModifyingEnv do
let name ← mkFreshUserName `_tmp
let value ← instantiateMVars value
let us := collectLevelParams {} value |>.params
if value.hasMVar then
throwError "failed to evaluate expression, it contains metavariables{indentExpr value}"
let type ← inferType value
checkType type
let decl := Declaration.defnDecl {
name, levelParams := us.toList, type
value, hints := ReducibilityHints.opaque,
safety
}
-- compilation will invariably wait on `checked`, do it now and tag as blocker
unless (← IO.hasFinished (← getEnv).checked) do
withTraceNode `Elab.block (fun _ => pure "") do
let _ ← IO.wait (← getEnv).checked
-- now that we've already waited, async would just introduce (minor) overhead and trigger
-- `Task.get` blocking debug code
withOptions (Elab.async.set · false) do
addAndCompile decl
evalConst α name
unsafe def evalExpr' (α) (typeName : Name) (value : Expr) (safety := DefinitionSafety.safe) : MetaM α :=
evalExprCore (safety := safety) α value fun type => do
let type ← whnfD type
unless type.isConstOf typeName do
throwError "unexpected type at evalExpr{indentExpr type}"
unsafe def evalExpr (α) (expectedType : Expr) (value : Expr) (safety := DefinitionSafety.safe) : MetaM α :=
evalExprCore (safety := safety) α value fun type => do
unless ← isDefEq type expectedType do
throwError "unexpected type at `evalExpr` {← mkHasTypeButIsExpectedMsg type expectedType}"
end Lean.Meta