refactor: elaborate forIn notation without extra let (#6977)

This PR avoids a `let` in the elaboration of `forIn`. It was introduced
in https://github.com/leanprover/lean4/commit/f51328ff112 but nothing
seems to break when I simplify the code. This removes an unexpected `let
col✝ :=…` from the “Expected type” view in the Info View and from the
termination proofs.
This commit is contained in:
Joachim Breitner 2025-02-08 11:32:34 +01:00 committed by GitHub
parent 5eca093a89
commit 7c809a94af
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 85 additions and 10 deletions

View file

@ -26,12 +26,10 @@ private def throwForInFailure (forInInstance : Expr) : TermElabM Expr :=
@[builtin_term_elab forInMacro] def elabForIn : TermElab := fun stx expectedType? => do
match stx with
| `(for_in% $col $init $body) =>
match (← isLocalIdent? col) with
| none => elabTerm (← `(let col := $col; for_in% col $init $body)) expectedType?
| some colFVar =>
tryPostponeIfNoneOrMVar expectedType?
let colE ← elabTerm col none
let m ← getMonadForIn expectedType?
let colType ← inferType colFVar
let colType ← inferType colE
let elemType ← mkFreshExprMVar (mkSort (mkLevelSucc (← mkFreshLevelMVar)))
let forInInstance ← try
mkAppM ``ForIn #[m, colType, elemType]
@ -42,7 +40,7 @@ private def throwForInFailure (forInInstance : Expr) : TermElabM Expr :=
let forInFn ← mkConst ``forIn
elabAppArgs forInFn
(namedArgs := #[{ name := `m, val := Arg.expr m}, { name := `α, val := Arg.expr elemType }, { name := `self, val := Arg.expr inst }])
(args := #[Arg.stx col, Arg.stx init, Arg.stx body])
(args := #[Arg.expr colE, Arg.stx init, Arg.stx body])
(expectedType? := expectedType?)
(explicit := false) (ellipsis := false) (resultIsOutParamSupport := false)
| .undef => tryPostpone; throwForInFailure forInInstance
@ -52,12 +50,10 @@ private def throwForInFailure (forInInstance : Expr) : TermElabM Expr :=
@[builtin_term_elab forInMacro'] def elabForIn' : TermElab := fun stx expectedType? => do
match stx with
| `(for_in'% $col $init $body) =>
match (← isLocalIdent? col) with
| none => elabTerm (← `(let col := $col; for_in'% col $init $body)) expectedType?
| some colFVar =>
tryPostponeIfNoneOrMVar expectedType?
let colE ← elabTerm col none
let m ← getMonadForIn expectedType?
let colType ← inferType colFVar
let colType ← inferType colE
let elemType ← mkFreshExprMVar (mkSort (mkLevelSucc (← mkFreshLevelMVar)))
let forInInstance ←
try
@ -70,7 +66,7 @@ private def throwForInFailure (forInInstance : Expr) : TermElabM Expr :=
let forInFn ← mkConst ``forIn'
elabAppArgs forInFn
(namedArgs := #[{ name := `m, val := Arg.expr m}, { name := `α, val := Arg.expr elemType}, { name := `self, val := Arg.expr inst }])
(args := #[Arg.expr colFVar, Arg.stx init, Arg.stx body])
(args := #[Arg.expr colE, Arg.stx init, Arg.stx body])
(expectedType? := expectedType?)
(explicit := false) (ellipsis := false) (resultIsOutParamSupport := false)
| .undef => tryPostpone; throwForInFailure forInInstance

View file

@ -0,0 +1,79 @@
set_option pp.mvars.anonymous false
/--
error: failed to construct 'ForIn' instance for collection
?_
and monad
Id
-/
#guard_msgs in
example {c} := Id.run do
for x in c do
pure ()
pure ()
/--
error: don't know how to synthesize implicit argument 'ρ'
@forIn Id (List ?_) ?_ instForInOfForIn' PUnit Id.instMonad [] PUnit.unit fun x r => do
pure ()
pure (ForInStep.yield PUnit.unit)
context:
⊢ Type _
---
error: failed to infer binder type
---
error: don't know how to synthesize implicit argument 'α'
@List.nil ?_
context:
⊢ Type _
-/
#guard_msgs in
example : Unit := Id.run do
for x in [] do
pure ()
pure ()
/--
error: failed to construct `ForIn'` instance for collection
?_
and monad
Id
-/
#guard_msgs in
example {c} := Id.run do
for h : x in c do
pure ()
pure ()
/--
error: don't know how to synthesize implicit argument 'd'
@forIn' Id (List ?_) ?_ inferInstance List.instForIn'InferInstanceMembership PUnit Id.instMonad [] PUnit.unit
fun x h r => do
pure ()
pure (ForInStep.yield PUnit.unit)
context:
⊢ outParam (Membership ?_ (List ?_))
---
error: don't know how to synthesize implicit argument 'ρ'
@forIn' Id (List ?_) ?_ inferInstance List.instForIn'InferInstanceMembership PUnit Id.instMonad [] PUnit.unit
fun x h r => do
pure ()
pure (ForInStep.yield PUnit.unit)
context:
⊢ Type _
---
error: failed to infer binder type
---
error: failed to infer binder type
---
error: don't know how to synthesize implicit argument 'α'
@List.nil ?_
context:
⊢ Type _
-/
#guard_msgs in
example : Unit := Id.run do
for h : x in [] do
pure ()
pure ()