fix: fixes #1380
This commit is contained in:
parent
a2ccf8f122
commit
a6c53cf974
3 changed files with 26 additions and 2 deletions
|
|
@ -150,10 +150,11 @@ private def mkTacticMVar (type : Expr) (tacticCode : Syntax) : TermElabM Expr :=
|
|||
|
||||
/-- `by tac` constructs a term of the expected type by running the tactic(s) `tac`. -/
|
||||
@[builtinTermElab byTactic] def elabByTactic : TermElab := fun stx expectedType? => do
|
||||
tryPostponeIfNoneOrMVar expectedType?
|
||||
match expectedType? with
|
||||
| some expectedType => mkTacticMVar expectedType stx
|
||||
| none => throwError ("invalid 'by' tactic, expected type has not been provided")
|
||||
| none =>
|
||||
tryPostpone
|
||||
throwError ("invalid 'by' tactic, expected type has not been provided")
|
||||
|
||||
@[builtinTermElab noImplicitLambda] def elabNoImplicitLambda : TermElab := fun stx expectedType? =>
|
||||
elabTerm stx[1] (mkNoImplicitLambdaAnnotation <$> expectedType?)
|
||||
|
|
|
|||
|
|
@ -329,6 +329,20 @@ mutual
|
|||
/- Recall, `tacticCode` is the whole `by ...` expression. -/
|
||||
let code := tacticCode[1]
|
||||
instantiateMVarDeclMVars mvarId
|
||||
/-
|
||||
TODO: consider using `runPendingTacticsAt` at `mvarId` local context and target type.
|
||||
Issue #1380 demonstrates that the goal may still contain pending metavariables.
|
||||
It happens in the following scenario we have a term `foo A (by tac)` where `A` has been postponed
|
||||
and contains nested `by ...` terms. The pending metavar list contains two metavariables: ?m1 (for `A`) and
|
||||
`?m2` (for `by tac`). When `A` is resumed, it creates a new metavariable `?m3` for the nested `by ...` term in `A`.
|
||||
`?m3` is after `?m2` in the to-do list. Then, we execute `by tac` for synthesizing `?m2`, but its type depends on
|
||||
`?m3`. We have considered putting `?m3` at `?m2` place in the to-do list, but this is not super robust.
|
||||
The ideal solution is to make sure a tactic "resolves" all pending metavariables nested in their local contex and target type
|
||||
before starting tactic execution. The procedure would be a generalization of `runPendingTacticsAt`. We can try to combine
|
||||
it with `instantiateMVarDeclMVars` to make sure we do not perform two traversals.
|
||||
Regarding issue #1380, we addressed the issue by avoiding the elaboration postponement step. However, the same issue can happen
|
||||
in more complicated scenarios.
|
||||
-/
|
||||
try
|
||||
let remainingGoals ← withInfoHole mvarId <| Tactic.run mvarId do
|
||||
withTacticInfoContext tacticCode (evalTactic code)
|
||||
|
|
|
|||
9
tests/lean/run/1380.lean
Normal file
9
tests/lean/run/1380.lean
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
theorem Nat.ne_of_gt {a b : Nat} (h : a < b) : b ≠ a := sorry
|
||||
theorem Nat.lt_succ_iff {m n : Nat} : m < succ n ↔ m ≤ n := sorry
|
||||
|
||||
variable (n v₁ v₂) (hv₁: v₁ < n + 1) (hv₂: v₂ < n + 1)
|
||||
theorem foo (_: ¬ Fin.mk v₂ hv₂ = Fin.mk v₁ hv₁ ): True := trivial
|
||||
set_option trace.Meta.Tactic.simp true in
|
||||
example (hv: v₁ < v₂) : True := foo n v₁ v₂ ‹_› ‹_› (by simp only[hv, Fin.mk.injEq, Nat.ne_of_gt, Nat.lt_succ_iff])
|
||||
|
||||
#check Fin.mk.injEq
|
||||
Loading…
Add table
Reference in a new issue