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.
48 lines
1.9 KiB
Text
48 lines
1.9 KiB
Text
/-
|
||
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
|