Metavariable introduced in pattern match
Nobody has claimed this yet.
- Dominant language
- Lean
- Stars
- 9.2k
- Forks
- 990
- Avg merge
- 1d 17h
- Merged PRs (30d)
- 175
Description
Description
When doing nested pattern matching, some function arguments built using (by ...) become metavariables in other terms that are being matched.
def Rewriter.createOpTest (ctx: Nat) (a: Option Nat) (h : pred ctx) : Option Nat :=
let ctx := foo ctx (by apply h) -- This `(by apply h)`
match _ : option_foo ctx (by grind [pred_foo]) with -- is a metavariable here, making grind fails
| none => none
| some ctx =>
match _ : a with -- Without this seemingly unrelated match, there is no issue
| some a => none
| none => none
Steps to Reproduce
def pred (a : Nat) : Prop := sorry
def foo (a : Nat) (h : pred a) : Nat := by sorry
def option_foo (a : Nat) (h : pred a) : Option Nat := by sorry
theorem pred_foo : pred (foo ctx hop) ↔ pred ctx := by sorry
def test (ctx: Nat) (a: Option Nat) (h : pred ctx) : Option Nat :=
let ctx := foo ctx (by apply h) -- replacing (by apply h) with h fixes the issue
match _ : option_foo ctx (by grind [pred_foo]) with -- grind fails because there is a metavariable at the `(by apply h)` location
| none => none
| some ctx =>
-- Removing this match removes the issue
match _ : a with
| some a => none
| none => none
-- First workaround
def testWorkaround (ctx: Nat) (a: Option Nat) (h : pred ctx) : Option Nat :=
let ctx := foo ctx (by apply h) -- replacing (by apply h) with h fixes the issue
match _ : option_foo ctx (by grind [pred_foo]) with -- grind fails because there is a metavariable at the `(by apply h)` location
| none => none
| some ctx => none -- Not matching on `a` removes the issue
-- Second workaround
def testWorkaround₂ (ctx: Nat) (a: Option Nat) (h : pred ctx) : Option Nat :=
let ctx := foo ctx (by apply h) -- replacing (by apply h) with h fixes the issue
let b := option_foo ctx (by grind [pred_foo]) -- Moving the matched term in a variable first fixes the issue
match _ : b with
| none => none
| some ctx =>
-- Removing this match removes the issue
match _ : a with
| some a => none
| none => none`
Expected behavior: [Clear and concise description of what you expect to happen]
The (by grind [pred_foo]) line 8 should succeed, and no metavariable should be in the hypotheses when building this term.
Actual behavior: [Clear and concise description of what actually happens]
(by grind [pred_foo]) fails as there is a metavariable, with the error unknown metavariable ?_uniq.587`
Note that the bug is not due to grind, but rather to the metavariable being present.
Versions
4.28.0-nightly-2025-12-28
This was working before in 4.28.0-nightly-2025-12-09
Impact
Add 👍 to issues you consider important. If others are impacted by this issue, please ask them to add 👍 to it.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the self-contained reproducer in the issue using Lean 4.28.0-nightly-2025-12-28, focusing on nested pattern matching and the (by apply h) argument. Confirm the failure and compare the listed workarounds; done means (by grind [pred_foo]) succeeds without an unknown metavariable in the hypotheses.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100