fix: check must check projections (#6398)
This PR ensures `Meta.check` check projections. closes #5660
This commit is contained in:
parent
791bea027f
commit
0340f904b3
3 changed files with 74 additions and 5 deletions
|
|
@ -209,6 +209,12 @@ def checkApp (f a : Expr) : MetaM Unit := do
|
|||
throwAppTypeMismatch f a
|
||||
| _ => throwFunctionExpected (mkApp f a)
|
||||
|
||||
def checkProj (structName : Name) (idx : Nat) (e : Expr) : MetaM Unit := do
|
||||
let structType ← whnf (← inferType e)
|
||||
let projType ← inferType (mkProj structName idx e)
|
||||
if (← isProp structType) && !(← isProp projType) then
|
||||
throwError "invalid projection{indentExpr (mkProj structName idx e)}\nfrom type{indentExpr structType}"
|
||||
|
||||
private partial def checkAux (e : Expr) : MetaM Unit := do
|
||||
check e |>.run
|
||||
where
|
||||
|
|
@ -221,7 +227,7 @@ where
|
|||
| .const c lvls => checkConstant c lvls
|
||||
| .app f a => check f; check a; checkApp f a
|
||||
| .mdata _ e => check e
|
||||
| .proj _ _ e => check e
|
||||
| .proj s i e => check e; checkProj s i e
|
||||
| _ => return ()
|
||||
|
||||
checkLambdaLet (e : Expr) : MonadCacheT ExprStructEq Unit MetaM Unit :=
|
||||
|
|
|
|||
|
|
@ -99,7 +99,9 @@ private def inferProjType (structName : Name) (idx : Nat) (e : Expr) : MetaM Exp
|
|||
let structType ← whnf structType
|
||||
let failed {α} : Unit → MetaM α := fun _ => do
|
||||
throwError "invalid projection{indentExpr (mkProj structName idx e)}\nfrom type{indentExpr structType}"
|
||||
matchConstStructure structType.getAppFn failed fun structVal structLvls ctorVal =>
|
||||
matchConstStructure structType.getAppFn failed fun structVal structLvls ctorVal => do
|
||||
unless structVal.name == structName do
|
||||
failed ()
|
||||
let structTypeArgs := structType.getAppArgs
|
||||
if structVal.numParams + structVal.numIndices != structTypeArgs.size then
|
||||
failed ()
|
||||
|
|
@ -108,7 +110,7 @@ private def inferProjType (structName : Name) (idx : Nat) (e : Expr) : MetaM Exp
|
|||
for i in [:idx] do
|
||||
ctorType ← whnf ctorType
|
||||
match ctorType with
|
||||
| Expr.forallE _ _ body _ =>
|
||||
| .forallE _ _ body _ =>
|
||||
if body.hasLooseBVars then
|
||||
ctorType := body.instantiate1 <| mkProj structName i e
|
||||
else
|
||||
|
|
@ -116,8 +118,8 @@ private def inferProjType (structName : Name) (idx : Nat) (e : Expr) : MetaM Exp
|
|||
| _ => failed ()
|
||||
ctorType ← whnf ctorType
|
||||
match ctorType with
|
||||
| Expr.forallE _ d _ _ => return d.consumeTypeAnnotations
|
||||
| _ => failed ()
|
||||
| .forallE _ d _ _ => return d.consumeTypeAnnotations
|
||||
| _ => failed ()
|
||||
|
||||
def throwTypeExcepted {α} (type : Expr) : MetaM α :=
|
||||
throwError "type expected{indentExpr type}"
|
||||
|
|
|
|||
61
tests/lean/run/5660.lean
Normal file
61
tests/lean/run/5660.lean
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import Lean
|
||||
|
||||
|
||||
def ex : ∃ x : Nat, x = 1 :=
|
||||
⟨1, rfl⟩
|
||||
|
||||
open Lean Meta
|
||||
|
||||
/--
|
||||
error: invalid projection
|
||||
ex.3
|
||||
from type
|
||||
∃ x, x = 1
|
||||
-/
|
||||
#guard_msgs in
|
||||
run_meta check (Expr.proj ``Exists 2 (mkConst ``ex)) -- should fail
|
||||
|
||||
/--
|
||||
error: invalid projection
|
||||
ex.1
|
||||
from type
|
||||
∃ x, x = 1
|
||||
-/
|
||||
#guard_msgs in
|
||||
run_meta check (Expr.proj ``Exists 0 (mkConst ``ex)) -- should fail
|
||||
|
||||
run_meta check (Expr.proj ``Exists 1 (mkConst ``ex))
|
||||
|
||||
def p := (1, 2)
|
||||
|
||||
/--
|
||||
error: invalid projection
|
||||
p.1
|
||||
from type
|
||||
Nat × Nat
|
||||
-/
|
||||
#guard_msgs in
|
||||
run_meta check (Expr.proj ``Exists 0 (mkConst ``p)) -- should fail
|
||||
|
||||
run_meta check (Expr.proj ``Prod 0 (mkConst ``p))
|
||||
run_meta check (Expr.proj ``Prod 1 (mkConst ``p))
|
||||
|
||||
/--
|
||||
error: invalid projection
|
||||
p.3
|
||||
from type
|
||||
Nat × Nat
|
||||
-/
|
||||
#guard_msgs in
|
||||
run_meta check (Expr.proj ``Prod 2 (mkConst ``p)) -- should fail
|
||||
|
||||
def n := 1
|
||||
|
||||
/--
|
||||
error: invalid projection
|
||||
n.1
|
||||
from type
|
||||
Nat
|
||||
-/
|
||||
#guard_msgs in
|
||||
run_meta check (Expr.proj ``Nat 0 (mkConst ``n)) -- should fail
|
||||
Loading…
Add table
Reference in a new issue