lean4-htt/src/Lean/Meta/Eval.lean
Eric Wieser f22998edfe
fix: collect level parameters in evalExpr (#3090)
`elabEvalUnsafe` already does something similar: it also instantiates
universe metavariables, but it is not clear to me whether that is
sensible here.
To be conservative, I leave it out of this PR.

See https://github.com/leanprover/lean4/pull/3090#discussion_r1432007590
for a comparison between `#eval` and `Meta.evalExpr`. This PR is not
trying to fully align them, but just to fix one particular misalignment
that I am impacted by.

Closes #3091
2024-09-27 11:55:33 +02:00

41 lines
1.5 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
}
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